Hi Guys
I am busy building a rover but want to use only n joystick and to do this the joystick has to determine direction and throttle value.
Direction I have worked out , but mapping the movement of the joystick to always give a positive of between 0 and 255 in any direction is difficult.
the joystick center on the Y and X axial around 504(range 0-1023).
and my general approach was as follows.
const int Throttle_Direct_Y = A1;// The pins were sensor are attached
const int Direct_Left_Right_X = A2;
const int TxRxPin = 13;
int DirFinal;
int DirValue;
int SpdValue;
int ThrottleMap;
int ThrottleValue;
void setup()
{
Serial.begin(9600);
// buttons
pinMode(TxRxPin,OUTPUT);
// Sensor(s)
pinMode(Throttle_Direct_Y,INPUT);
pinMode(Direct_Left_Right_X,INPUT);
}
void loop()
{
//Speed reading and mapping
ThrottleValue = analogRead(Throttle_Direct_Y);
DirValue = analogRead(Direct_Left_Right_X);
Serial.print(ThrottleValue );
Serial.print(",");
Serial.println(DirValue);
// throttle code reading and mapping
if (ThrottleValue > 513)
{ ThrottleMap = map(ThrottleValue, 513, 1023, 0, 255);}
else
{ ThrottleMap = map(ThrottleValue, 513, 0, 0, 255);}
if (DirValue > 513)
{ ThrottleMap = map(DirValue, 513, 1023, 0, 255);}
else
{ ThrottleMap = map(DirValue, 513, 0, 0, 255);}
Serial.println(ThrottleMap);
//Direction reading and mapping
}
this does work on the Y axial but not the X axial or other way round if I play with the code.
can any one help me in getting the joystick to output a signal between 0-255 doesnt matter in what direction you push the stick.
Thank you for the quick reply.
i have thought of that but my problem is i need a single value that creates two values. so if i go that direction how do i combine the values
tel me try and explain again. when looking at the values from the joystick, if the joystick is center i get a value of 503 on both ThrottleValue and DirValue when i push forward the value changes from 503 to 1023 when pulling towards me the value changes from 503 to 0. this is the case for all directions.
I need only one value that is a combination of both DirValue and ThrottleValue that ranges from 0 -255 , this number can not/maynot be negative.
2 analogReads have values from 0..1023 so the possible positions are 1024*1024 = 1million++
You want to map this upon 256 distinct numbers. Note this number fits in a 8bit byte.
The easiest way is to map either direction on their own 4 bits (vallues 0..15)
ThrottleValue = analogRead(Throttle_Direct_Y); // 0..1023
DirValue = analogRead(Direct_Left_Right_X); // 0..1023
// first take care that we only have 16 value per variable !! this reduces precision.
ThrottleValue = ThrottleValue / 64; // 0..15
DirValue= DirValue/ 64; // 0..15
uint8_t oneValue = (ThrottleValue << 4) | DirValue; // ThrottleValue is in the high 4 bits and DirValueis in the low 4 bits.
// Note oneValue can have all values between 0..255, each of them revertible to a (reduced but unique) joystick position.
Thank you for the explanation, i have looked at it and will try it , as for the picture I have the same feeling the position for a number can not be determined as for example 42. maybe looking at my problem you might have other solution, the throttle is on Axial Y and it works correctly when mapped as normal, my problem is when turning left or right on the joystick the throttle value would reduce due to the fact left or right is horizontal to the throttle "0 " position and the rover would stop driving . this is why i am trying to map the range in any direction
Lowers resolution of reading to 16 (4-bits) and shifts Direction bits to upper byte, then ORs Throttle bits into lower byte.
So at a value of 119 (0111 0111) stick should be in the middle, at a value of 127 (0111 1111) have full throttle forward and at 112 (0111 0000) full throttle reverse, at a value of 15 (0000 1111) should have full throttle forward and full left direction where as at 240 (1111 0000) should have full reverse and full right direction and at 255 (1111 1111) full forward and full right direction.
Could also take a bit of resolution from the throttle say to enhance steering,
then middle position of the stick would be 123 (01111 011)
Rustie0125:
Thank you for the explanation, i have looked at it and will try it , as for the picture I have the same feeling the position for a number can not be determined as for example 42. maybe looking at my problem you might have other solution, the throttle is on Axial Y and it works correctly when mapped as normal, my problem is when turning left or right on the joystick the throttle value would reduce due to the fact left or right is horizontal to the throttle "0 " position and the rover would stop driving . this is why i am trying to map the range in any direction
OK suppose you have a function that could do what you want.
onevalue = func(ThrottleValue, DirValue);
what would the rest of your code looks like? How would you use that oneValue?
Thank you for your help. ! I have tried all of the codes above and they work in two positive directions of the axials but the problem is , the sticks centered should held a value of "0" and to any extreme of any direction it should held "255" the code you have above seems to assume that the values of the potentiometer starts at 0 it does not 0 would represent far left or reverse. and that means the center position is 505 give or take. there for the code should look more or less like this , but my figures are not correct
as for the rest of the code it is simple , im only sending a msg of ID, speed and direction to the rover at first, speed would be the value we are trying to calculate now , and direction I am only sending "1" for foraward "2"back "3" left "4" right , and on the rover side this is delth with in a switch case statement which applies the speed value to any direction
I found a solution, that seems to work. it is probably not the most elegant method but if there is a easier way of doing the same as what this is doing i will be glad to look at it !
Hi Rustie
... wasn't Rob posting this code!
if I understand it right, the way you describe above, ThrottleMap is a value of intensity and has no information for directions.
Apologies, so involved in the problem did not see it was someone else. thank you for the code. but the If statements has given best result sofar. in the working code this code is combined to held direction aswell. see below it is implemented
what i find very strange is the forward and reverse values are now neg , i resolved this by "abs" statement but when extracting just the throttle code it helds all positive results.
its working anyway. do you know of a other way of doing this ?
In Theory yes it would have to be ether or , this was only the starting point of the code and wanted to address that issue next, but as luck would have it. it seems to be working as is . when pushing forward and slightly to the right or left just enough to trigger the direction it goes there or it would appear to do both simultaneously but in the code it doesnt, it actually switches direction on the throttle value is 80% of lets say full forward or full right. but the rover doesn't seem to mind it to much( top speed on 1 kmph) and it has tracks not wheels
It looks like it uses the two least significant bits of the byte for direction, ie (XXXXXX 11) forwards, (XXXXXX 00) backwards, (XXXXXX 10) Right and (XXXXXX 01) left and the rest 6 bits for intensity, which would be the same for both motors. ?