Angle Sensing - Coding Help

Hi,

I am developing a medical device for measuring range of motion of patient’s knees. My design uses a Non-Contact Angle Sensor (Hall Sensor) which provides an analogue voltage output proportional to the angle.

I am inexperienced in Arduino programming and need help creating a code that will display a live angle on the LCD Shield screen depending on the voltage output from the sensor.

I am using an Arduino Duemilanove with an LCD keypad shield. The image shows how the wires from the angle sensor are connected to the Arduino (via the LCD pins)

I have completed successful testing with a PIC board (10Bit, 0-1023 Binary Range) but need help translating this to the Arduino:

  • The Max and Minimum Binary Voltage were recorded over the range 66 - 599.
  • It was necessary to MINUS 66 from this to provide a 0 - 533 range.
  • Next by dividing by a factor of 1.48 this provided a ANGLE RANGE of 0 - 360.

Any idea how I could write this into the Arduino code/ useful tutorials I could follow. This is the first step of my problem, the next is configuring the keypad buttons to display the MAXIMUM angle reached after use (and another to RESET this angle for the next time). (does the arduino have the internal memory to allow this, and is this complicated to code?)

Hopefully this makes sense.

Thanks,

Alex

  • The Max and Minimum Binary Voltage were recorded over the range 66 - 599.
  • It was necessary to MINUS 66 from this to provide a 0 - 533 range.
  • Next by dividing by a factor of 1.48 this provided a ANGLE RANGE of 0 - 360.

Arduino has a predefined function called map() that you might find useful:

/* Map an analog value to change range value*/
void setup() {}

void loop()
{
  int val = analogRead(0);
  val = map(val, 66, 599, 0, 360);
  }

Lefty

the next is configuring the keypad buttons to display the MAXIMUM angle reached after use

Which keypad do you have? How do you expect to use an input device for output?

the keypad is just built onto the LCD shield (shown in the picture). The plan is to just display an angle readout on the screen controlled by the voltage output of the angle sensor :confused: I might not be making much sense.. But here is my code so far, i've managed to get an angle readout on the screen but still a few problems: the displayed range is only 26 - 214 degrees. I'm not sure how to include the mapping function to resolve this. Any ideas?

Thanks,

Alex

#include <LCD4Bit_mod.h>

#include <stdio.h>

//create object to control an LCD.
//number of lines in display=1
LCD4Bit_mod lcd = LCD4Bit_mod(2);

// Max and min degree values - corresponding to 5v / 0v inputs - adjust as required
#define MAX_DEGREE 360
#define MIN_DEGREE 0

//put this at the top (global declaration)
char degrees[8];


// initialize the library with the numbers of the interface pins

int potPin = 2; // Analogue Input 2

int val = 0;
const float scale = (MAX_DEGREE - MIN_DEGREE)/1024.0; // scaling factor from Pot to Degrees

void setup() {
  pinMode(13, OUTPUT);
 // set up the LCD's number of columns and rows:
 lcd.init();
 // Print a message to the LCD.
 lcd.printIn("Degrees:");
}

void loop() {

 // read in from the pot, value from 0 to 1023
 val = analogRead(potPin);
 
 // Scale to degrees, then truncate to int
 int degree_val = (int)(scale * val);
 
    //convert a value for printing to LCD 
    sprintf(degrees, "%3d", degree_val);
    lcd.clear();
    lcd.printIn(degrees);
    
    delay(50); // slow things down a bit
}

Since MAX_DEGREE and MIN_DEGREE are int values, you are mixing integer and floating point arithmetic in calculating scale. You might not be getting the value that you expect in scale.

Try using Serial.begin() in setup(), and Serial.print() and Serial.println() in loop(), to print the value read from potPin. Verify that the values are indeed in the range 0 to 1023.

Since scale is a float and val is an int, and the result is to be saved in an int, you again have mixed integer and floating point arithmetic in calculating degree_val. It might be necessary to perform some casting to get the correct results. Use Serial.print() to see what is in val and degree_val. Do they match expectations?

Of course, you could just use the map() function, and not compute all the intermediate terms, since the result you are looking for is an int anyway.

I'm not sure how to include the mapping function to resolve this.

int degree_val = map(val, 0, 1023, MIN_DEGREE, MAX_DEGREE);

Thanks! the map function has worked perfectly, just had to change the range a bit. The other issue was that the number is printing to the screen but the text "Degrees" isn't. Can you spot why from my code?

The other issue was that the number is printing to the screen but the text "Degrees" isn't. Can you spot why from my code?

Probably because you print "Degrees:" in setup(), then call lcd.clear() to clear the screen, and don't print "Degrees:" again. Just a guess, though.