Hi all,
First off I am new to arduino so please forgive me if this is a stupid question. I am trying to use the MAP function but it doesn't seem to be working correctly.
#include <dcmotor.h>;
DCMotor motor1(12,11,2);
int potPin = A9;
double orderAngle;
void setup()
{
Serial.begin(9600);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(2,OUTPUT);
motor1.SetTurnSpeed(155);
}
void loop()
{
if (Serial.available())
{
analogReadResolution(12);
orderAngle = Serial.parseFloat();
Serial.print("order Recieved");
Serial.println(orderAngle);
ObeyServoOrder(orderAngle);
}
PrintServoPosition(orderAngle);
}
void ObeyServoOrder(double orderAngle)
{
double potRest = (double)analogRead(potPin);
double currAngle = map(potRest,0,4095,0,360);
orderAngle = constrain(orderAngle,0,359);
while (abs(orderAngle - currAngle) > 1) //there is a posn error. my error tolerance = 5 degrees
{
potRest = (double)analogRead(potPin); //1023 * 10;
currAngle = map(potRest,0,4095,0,360);
if (orderAngle > currAngle)
{
//turn right
Serial.print("Current");
Serial.print(currAngle);
Serial.print("Order");
Serial.print(orderAngle);
Serial.println("Turning Right");
motor1.SetTurnDirection(right);
motor1.Turn();
} else
{
//turn left
Serial.print("Current");
Serial.print(currAngle);
Serial.print("Order");
Serial.print(orderAngle);
Serial.println("Turning Left");
motor1.SetTurnDirection(left);
motor1.Turn();
}
}
motor1.Stop(); //if there is no error, stop the motor
}
void PrintServoPosition(double orderAngle)
{
double potRest = (double)analogRead(potPin); //1023 * 10
double currAngle = map(potRest,0,4095,0,360);
Serial.print("Ordered Angle");
Serial.print(orderAngle);
Serial.print("Position");
Serial.println(currAngle);
delay(50);
}
Here are the corresponding analog inputs for the corresponding 0-359 deg positions
OrderAngle = Pot position
90deg = 2682
150deg = 2258
180deg = 2111
240deg = 1766
270deg = 1589
330deg = 924
0 deg = 90
30deg = 3669
What do I need to do to get to go to the correct commanded positions?
I'm using a Teensy 3.1 which is reading the pot in 12bit I tried all your examples, still getting bad results of not going to the correct location and sometimes different spots. I tested the pot with a little program it is very steady and accurate on the input side.
The semicolon is pointless here, include directives aren't C statements.
void loop()
{
if (Serial.available())
{
analogReadResolution (12) ;
You should set the analog resolution once, in setup(), then read and discard
one analog reading to resynchronise the ADC hardware - you may be reseting the ADC
hardware everytime round loop with this and making analogRead() produce nonsense
(not sure, but certain changes to the ADC do require a read-and-discard afterwards).
737nut:
OrderAngle = Pot position
90deg = 2682
150deg = 2258
180deg = 2111
240deg = 1766
270deg = 1589
330deg = 924
0 deg = 90
30deg = 3669
What do I need to do to get to go to the correct commanded positions?
Looking at those values there's no direct corelationship between them. If you add 30 to the pot angle you then get something that approaches a curve, but it's got a distinct kink in it.
Mark and Ken,
Thanks for the help, I will try tomorrow as I am away from the shop today. I agree, there is a strange correlation going on here. The strange part is it a compass instrument and the same scale 360degs. Maybe my pot has a bad spot? I'll do some more testing tomorrow.
Thanks again
Rob
Looking at those values again, it gives me the impression that you have a diode in the circuit with the pot. So at some critical point, it's forward voltage is being exceded and thus throwing the value.
I'll draw it up when I get home. It's real simple though, Using the 3.3V out of the Teensy to one side of pot, Wiper on A9 for the analog in, and GND going to the Gnd on the Teensy. I swapped the power and GND yesterday on the pot to get it to match up to the range better. Although map function is supposed to work either way. The only place it is accurate is the 180deg point. Dead on everytime. The pot i'm using is 10K continuous turn high precision mil spec pot. I think it is all code related so I will make the changes tonight mentioned above.
Rob
737nut:
I'll draw it up when I get home. It's real simple though, Using the 3.3V out of the Teensy to one side of pot, Wiper on A9 for the analog in, and GND going to the Gnd on the Teensy. I swapped the power and GND yesterday on the pot to get it to match up to the range better. Although map function is supposed to work either way. The only place it is accurate is the 180deg point. Dead on everytime. The pot i'm using is 10K continuous turn high precision mil spec pot. I think it is all code related so I will make the changes tonight mentioned above.
Rob
Actually, I did notice that my solution posted above, goes the wrong way. (I've used your value columns the wrong way around). I'll have a look at switching it.
I tried moving analogReadres(12) to setup, had no effect on ops.
I think i am going to switch to a magnetic position sensor that will do a true 360 reading. I did some testing last night and my dead spot is a little bigger than i originally thought. I have roughly a 10-15deg dead spot were the pot goes open.
I am going to use the AS5045 sensor so I will have to add some SPI code to read the 12bit position info from the sensor. I think this will make it work much better though.
Rob
Also, if I do this 360/4095=.0879 If I take the current pot input * .0879 it matches up nicely with the Compass degrees. So can get rid of the mp function and insert this math instead? Not sure how or if it will work.
You take the analog input (0 to 4095) and divide it by 4095
to find the fraction of a full resistance sweep of the pot you have dialed up.
You then multiply that fraction by 360, representing degrees in a full circle,
to get the amount of degrees your pot position represents.
So half way will be 2048 on the analog input, divided by 4095 is close to 0.5,
now 0.5 times 360 = 180 degrees of rotation output.
Tom....
ps. I hope you realise that a continuous turn pot has a point where the wiper will change from 10k to zero K and start again?
You have to find this position to locate you zero degrees mechanical position of the pot.