I want to implement a look-up table of sorts, in order to control two stepper motors (might be servos to start with).
Anyway, I want to be able to pass a parameter to some variable, and then, based on that parameter (for example a voltage reading), return a degree value for say servo one, and a degree value for servo two, to move to a particular location (I guess same could be implemented with steppers....).
My challenge is how to create such a table, and then have it referenced through some function/example sketch....
For example, something like this:
Voltage =1.2 => Servo 1 go to 23Deg,, Servo 2 go to 50 Deg..
Voltagre= 1.5 => Servo 1 goto 30 Deg, Servo2 go to 120 Deg...
.
.
.
.
.
Table could have have say a 100 or even more such values, depending on memory off course (thinking also to have this table on a flash card)...
I’m not sure if this is the best way, but the first thing that comes to mind is to take the value and in a for loop, compare it to the values in an array.
Something like this maybe:
float arrayValues[]={1.25, 2.3, 3.75, 4.22, 5.12};
float measuredValue = 0;
byte x=0;
float y=0;
void setup(){
//setup the motors
}
void loop(){
measuredValue = analogRead(0);
for(x=0;x<4;x++){
y = measuredValue-arrayValues[x];
if(abs(y)<1)
break;
}
if (x=1){
//motor A do something
//motor B do something
}
if (x=2){
//motor A do something
//motor B do something
}
if (x=3){
//motor A do something
//motor B do something
}
if (x=4){
//motor A do something
//motor B do something
}
}
gives a value between 0 and 1023 and you compare it with values in the 0…5 range. Think you need to add something like
measuredValue = 7.0 * measuredValue / 1023; ??
you can do the comparison directly in the for loop (flips the < to >= ) no need for the extra variable y
for( x = 0; x < 4 && abs(measuredValue - arrayValues) >= 1; x++);
Difference between assignment and comparison
if (x==1) <<<<<< not = but == is the compare
The lookup comparison can be made easier by not putting the middle values in the array but the max values per “state”.
==> you get rid of the abs() function making the code faster and more compact.
float arrayValues[] = { 2.25, 3.3, 4.75, 5.22, 6.12 }; // I added 1.0 to all the values of the original array
...
for( x=0; x<4 && measuredValue <=arrayValues[x]; x++);
...
So say i have 100 or more comparisons to do.....and each of the 100 values, needs to move the stepper/servos to some location, i would have to write 100 'if' statements?
Do not get me wrong, I am not lazy, just trying to figure out the best and most effecient way to go about this....i was thinking along the lines of some algorithm that depending on the value we read at some pin (close enough is ok), we do some sort of a process to extract the two values needed to move the motors....so something like pass the value i just read to a function, the function returns the two proper movement commands to the motors which correspond to that value which was passed....
Almost like each time the value is passed, parse say some file stored in flash or eeprom, and stop where this value is close enough to what we need, then return the two stepper values needed to move the motors corresponding to this value...
This file could be tab delimited or some other format, and contain entries which have three values...the first value is what we are trying to match...the second two values are the first stepper and second stepper commands...we then move to the next entry....etc.....
This way, we would only need to do this parsing as needed, stopping and matching to the location we need....Offcourse we would need to read this file each time, but a file containing say 100 such formatted entries would not be so large, and could afford the computational time....
We would then also have logic to say that if a match is not found, give the option of storing this new value, along with the two stepper locations to the user....
So say i have 100 or more comparisons to do…and each of the 100 values, needs to move the stepper/servos to some location, i would have to write 100 ‘if’ statements?
that might be possible, but there are two generic solution:
arrays => use the index of the found value to set the value of a servo
formulas => you might be able to catch the logic in a (simple?) formula so you can calculate the position
array’s example
#define MAXSERVOS 2
float arrayValues[] = { 2.25, 3.3, 4.75, 5.22, 6.12 }; // I added 1.0 to all the values of the original array
byte servoAngle[MAXSERVOS ][5] = { // 5 angles per servo
{ 0, 45, 90, 135, 180 },
{ 0,10,20,30,40 } };
...
// find the value in the array
for( x=0; x<4 && measuredValue <=arrayValues[x]; x++);
// use the index to set the servo's
for (int s=0; s< MAXSERVOS; s++)
{
servo[s].set(servoAngle[s][x]); // note the servos are in an array too!
}
...
that is in essence all (but you still have to type the whole array
formula example
measurement = analogRead(0);
// set the servo's
for (int s=0; s< MAXSERVOS; s++)
{
servo[s].set(func(s, measurement));
}
// the func(int s, float measurement) has to be elaborated, this is just an example.
float func(int s, float measurement)
{
float x = (measurement-512)/512.0; // map unto -1 .. 1
float angle = (asin(x) + s * 30) % 180;
return angle;
}
I think the idea of having multiple values for each entry in the are would work. Then you would start at position 0 in the array and increment it by 3 for the check every time in the for loop, and then use the two values after it when the for loop exits. If there was some kind of formula you could use for the positions though, that would probably be ideal.
I see...so use one array for the value, and then two other arrays for the stepper values, and use a loop to track them....
Any way to do this by parsing a file? I think it would be easier to have such a file populated, and then use some sort of a delimiter, to signify the end of the entry....
When we want to match something, have a loop parse the file, and when it finds the entry we need, parse the next two values, which would signify the values we need to position the servos/steppers...
Have been trying to find examples, but not finding anything meaningful....
Having this file also stored on flash, would save considerable memory by not having to allocate all the space needed for many arrays...