NXT Measuring wheel

Here is a measuring wheel I made using the NXT and a mindsensors GlideWheel-AS. The NXT displays traveled distance in mm, cm, M, in, ft, or yd, and will automatically show the proper number of significant figures.


The only thing you have to modify in the code, is WHEEL_DIA (wheel diameter in mm), on line six. Note that nearly all (if not all) Lego technic tires have their size molded into the sidewall, in mm, in the format “diameter x width”; so the “RCX wheels” are “81.6 x 15”.

You can optionally modify AS_PORT and AS_ADDR as needed.

You will need the mindsensors library for the sensor, called “AngleSensor-lib.nxc”.

Here is the NXC program for the measuring wheel:

#include "AngleSensor-lib.nxc"

#define AS_PORT S1
#define AS_ADDR 0x30

#define WHEEL_DIA 81.6 // wheel diameter in mm
#define WHEEL_CIR (WHEEL_DIA * PI)

#define TICKS_PER_ROTATION 720

#define DISTANCE_PER_TICK (WHEEL_CIR / TICKS_PER_ROTATION)

long raw;
float Rotations;
float Distance_mm;
float Distance_cm;
float Distance_mt;
float Distance_in;
float Distance_ft;
float Distance_yd;
float Distance_Display;

#define UNITS 6
char unit = 1;

string Value_String;
byte digit;
byte x;
byte Display_Precision;
float Unit_Distance_Per_Tick;

task main(){
  SetSensorLowspeed(AS_PORT);
  AS_ResetAngle(S1, 0x30);
  while(true){

    if ( ButtonPressed(BTNCENTER, true)){
      while (ButtonPressed(BTNCENTER, true));
      AS_ResetAngle(S1, 0x30);
    }
    
    if ( ButtonPressed(BTNLEFT, true)){
      while (ButtonPressed(BTNLEFT, true));
      unit--;
      if(unit < 1)unit = UNITS;
    }

    if ( ButtonPressed(BTNRIGHT, true)){
      while (ButtonPressed(BTNRIGHT, true));
      unit++;
      if(unit > UNITS)unit = 1;
    }
    
    switch(unit){
      case 1:
        Unit_Distance_Per_Tick = DISTANCE_PER_TICK;
        TextOut(84, LCD_LINE1, "mm");
      break;
      case 2:
        Unit_Distance_Per_Tick = DISTANCE_PER_TICK / 10;
        TextOut(84, LCD_LINE1, "cm");
      break;
      case 3:
        Unit_Distance_Per_Tick = DISTANCE_PER_TICK / 1000;
        TextOut(84, LCD_LINE1, "M ");
      break;
      case 4:
        Unit_Distance_Per_Tick = DISTANCE_PER_TICK / 25.4;
        TextOut(84, LCD_LINE1, "In");
      break;
      case 5:
        Unit_Distance_Per_Tick = DISTANCE_PER_TICK / 304.8;
        TextOut(84, LCD_LINE1, "Ft");
      break;
      case 6:
        Unit_Distance_Per_Tick = DISTANCE_PER_TICK / 914.4;
        TextOut(84, LCD_LINE1, "Yd");
      break;
    }

    raw = AS_ReadRawValue(AS_PORT, AS_ADDR);
    
    Distance_Display = raw * Unit_Distance_Per_Tick;

    if(Unit_Distance_Per_Tick >= 1){
      Display_Precision = 0;
    }
    else{
      if(Unit_Distance_Per_Tick >= 0.1){
        Display_Precision = 1;
      }
      else{
        if(Unit_Distance_Per_Tick >= 0.01){
          Display_Precision = 2;
        }
        else{
          if(Unit_Distance_Per_Tick >= 0.001){
            Display_Precision = 3;
          }
          else{
            Display_Precision = 4;
          }
        }
      }
    }

    x = 0;
    if(Distance_Display >= 0){
      TextOut(x, LCD_LINE1, " ");
    }
    else{
      TextOut(x, LCD_LINE1, "-");
      Distance_Display *= (-1);
    }

    if(Distance_Display >= 10000000 && unit < 3){
      unit++;
    }

    x += 6;
    if(Distance_Display >= 1000000){
      digit = (Distance_Display / 1000000) %10;
      NumOut(x, LCD_LINE1, digit);
    }
    else{
      TextOut(x, LCD_LINE1, " ");
    }

    x += 6;
    if(Distance_Display >= 100000){
      digit = (Distance_Display / 100000) %10;
      NumOut(x, LCD_LINE1, digit);
    }
    else{
      TextOut(x, LCD_LINE1, " ");
    }

    x += 6;
    if(Distance_Display >= 10000){
      digit = (Distance_Display / 10000) %10;
      NumOut(x, LCD_LINE1, digit);
    }
    else{
      TextOut(x, LCD_LINE1, " ");
    }

    x += 6;
    if(Distance_Display >= 1000){
      digit = (Distance_Display / 1000) %10;
      NumOut(x, LCD_LINE1, digit);
    }
    else{
      TextOut(x, LCD_LINE1, " ");
    }
    
    x += 6;
    if(Distance_Display >= 100){
      digit = (Distance_Display / 100) %10;
      NumOut(x, LCD_LINE1, digit);
    }
    else{
      TextOut(x, LCD_LINE1, " ");
    }
    
    x += 6;
    if(Distance_Display >= 10){
      digit = (Distance_Display / 10) %10;
      NumOut(x, LCD_LINE1, digit);
    }
    else{
      TextOut(x, LCD_LINE1, " ");
    }
    
    x += 6;
    digit = Distance_Display %10;
    NumOut(x, LCD_LINE1, digit);

    x += 6;
    if(Display_Precision){
      TextOut(x, LCD_LINE1, ".");
      x += 6;
      digit = (Distance_Display * 10) %10;
      NumOut(x, LCD_LINE1, digit);

      x += 6;
      if(Display_Precision >= 2){

        digit = (Distance_Display * 100) %10;
        NumOut(x, LCD_LINE1, digit);
        
        x += 6;
        if(Display_Precision >= 3){
          digit = (Distance_Display * 1000) %10;
          NumOut(x, LCD_LINE1, digit);

          x += 6;
          if(Display_Precision >= 4){
            digit = (Distance_Display * 10000) %10;
            NumOut(x, LCD_LINE1, digit);
          }
          else{
            TextOut(x, LCD_LINE1, " ");
          }
        }
        else{
          TextOut(x, LCD_LINE1, "  ");
        }
      }
      else{
        TextOut(x, LCD_LINE1, "   ");
      }
    }
    else{
      TextOut(x, LCD_LINE1, "     ");
    }
  }
}
Advertisements
This entry was posted in Electronics, Mindsensors, Mindstorms, NXT. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s