Hellow ppl...i try to make a kind of hand gesture detection using a 2x2 IR sensor matrix. Reading the value and seting things up is no problem but i have a big issue....i dont know and i can`t find how to write the code for something like this: if sensors x & z are "1" and become 0 followed by c & a are "1" and become "0" then check for x & z are "0" and become 1 followed by c & a are "0" and become "1" then display "hand moved from left to right"
z,x,c,a -- are IR sensors and im using arduino uno
Code:
int s1 = 4;
int s2 = 5;
int s3 = 6;
int s4 = 7;
int z,x,c,a;
void setup()
{
pinMode(s1, INPUT);
pinMode(s2, INPUT);
pinMode(s3, INPUT);
pinMode(s4, INPUT);
Serial.begin(9600);
}
void loop()
{
x = digitalRead(s1);
z = digitalRead(s2);
c = digitalRead(s3);
a = digitalRead(s4);
Serial.println(x);
Serial.println(z);
Serial.println(c);
Serial.println(a);
delay(50);
if((x == 0) && (z == 0) && (c == 1) && (a == 1))
{delay(500);
if((x == 0) && (z == 0) && (c == 0) && (a == 0))
{delay(500);
if((x == 1) && (z == 1) && (c == 0) && (a == 0))
{delay(500);
Serial.println("from left to right");
}
}
}
The idea is..the sensor is outputing Logic "1" when not detecting and logic "0" when detecting. If i move my hand from left to right 1st 2 sensors become "0" from "1" when i start to move my hand...then all 4 are "0" when my hand is above ...then 1st 2 are "1" and last 2 are "0" when my hand is almost to right and in the last all 4 are "1" when my hand is in the right side (out of sensors)
I know im doing something wrong in code line but as i say i dont know the code for x followed by z followed by c and so on.
If you have anny other option on code or sensor (pref cheap ones) im all opened.
Nothing is going to happen to your variables during the delays. To detect changes you have to read the inputs again. The crudest method would be to re-read the inputs after each delay. I don't think that will work with a fixed delay because the sequence of events will depend on the timing.
The four inputs can be in 16 different states. I think the first step should be a function that returns the current state. Then you can write a sketch that outputs the number each time it changes so you can start seeing what gestures cause what unique sequences of states. Then you can write a sketch to start looking for sequences of state to which you can assign meaning.
Following johnwasser's suggestion, below is a function which will return the state of the sensors (0 to 15).
In one approach, create a table of the 16 possible values, and do up to 16 different things depending on which value matched the sensor state.
byte sensorstate() {
byte x = digitalRead(s1);
x = x | digitalRead(s2) << 1;
x = x | digitalRead(s3) << 2;
x = x | digitalRead(s4) << 3;
return x;
Think about the left to right gesture in your code as having three states corresponding to the three if statements.
In loop() look for the first state. When the first state is found look for the second state and when that is found look for the third state. After all three states have been found the gesture is complete.
There should be a timeout when waiting for a state because if the first state is found but not the second you want to start over, looking for the first state.
Some example code:
int gestureState = 0; // state in gesture
unsigned long stateStart; // time state began
const unsigned long STATE_TIMEOUT = 500UL; // how long to wait for next state
void loop()
{
x = digitalRead(s1);
z = digitalRead(s2);
c = digitalRead(s3);
a = digitalRead(s4);
Serial.println(x);
Serial.println(z);
Serial.println(c);
Serial.println(a);
delay(50);
switch (gestureState)
{
case 0:
//if swipe is begining
if ((x == 0) && (z == 0) && (c == 1) && (a == 1))
{
// advance state, mark time
gestureState++;
stateStart = millis();
} // if
break;
case 1:
// if swipe continues
if ((x == 0) && (z == 0) && (c == 0) && (a == 0))
{
// advance state, mark time
gestureState++;
stateStart = millis();
} else if ( timeOut() ) {
// swipe did not continue
gestureState = 0;
} // else
break;
case 2:
// if swipe complete
if ((x == 1) && (z == 1) && (c == 0) && (a == 0)) {
Serial.println("from left to right");
gestureState = 0;
} else if ( timeOut() ) {
// swipe did not complete
gestureState = 0;
}
default:
break;
}
}
// return true if swipe timed out
bool timeOut() {
return (millis() - stateStart >= STATE_TIMEOUT);
}