I have a keypad which is connected to arduino (with one analog pin).In the arduino code, I have created a circular queue which stores the inputs by pressing on keypad. Now when a key is pressed on keypad, it is stored as the first element in the queue. If an another key is pressed, it is stored as second element in the queue until is queue is full.(The keypad pins are connected using a voltage divider for each pin, so each and every key pressed on keypad will be recognized by arduino based on voltage for the key. The keys and voltages are stored in an array, as follows):
int keyboardPin = 0; // analog pin to which keypad is connected
int keyboardValue = 0; // Initial reading of analog pin 0 (A0) (it is zero as no key is pressed initially)
char keypad[16] = {'1','2','3','4','5','6','7','8','9'};
int treshold[16] = {590,568,548,426,415,404,334,326,320}; // Volatge values corresponding to each pin
int front=0,rear=0,size=6; // implementing circular queue using array
char cQueue[6];
int speed = 6,timer=0;
void setup(){
cQueue[0] = '1'; // the first element of queue is '1' by default at the start
}
void loop(){
keyboardValue = analogRead(keyboardPin); // Reading the value from A0 when key is pressed
while(keyboardValue > 5) { // Runs when a key is pressed
for(int i=0;i<8;i++){
if((treshold[i] - keyboardValue) == 0){
Serial.println(keypad[i]); // Printing the key pressed
enQueue(keypad[i]); // Storing the key pressed in the queue
break;
}
break;
} // end of for
keyboardValue = 0;
liftStops(cQueue[front+1]);// function to be run in background (front + 1) because the key pressed by the user should be the argument of function
break;
} // end of while
} // end of loop
int isFull(){ // to check if queue is full
if( (f1 == r1 + 1) || (f1 == 0 && r1 == stops1-1)) {
return 1;
}
return 0;
}
void enQueue(char element){ // adding key pressed to queue
if(isFull()){
Serial.println("Lift full");
}else{
r1 = (r1 + 1) % stops1;
qlift1[r1] = element;
}
}
int deQueue(){ // removing the front element of queue
char element;
element = qlift1[f1];
f1 = (f1 + 1) % stops1;
return(element);
}
At the start of program, 1st element of queue is loaded with '1' (in setup function). When key is pressed, it is added as 2nd element of the queue.
There is a function which should run in the background as soon as a key is pressed. The function is:
void liftStops(char keyPress){ // defined after the loop() function
while(timer<100){
distance = (speed*timer);
motorClockwise();
Serial.println(distance);
if(keyPress == '1' && distance == 0){
motorStop();
deQueue();
return;
}else if(keyPress == '2' && distance == 30){
motorStop();
deQueue();
return;
}else if(keyPress == '3' && distance == 60){
motorStop();
deQueue();
return;
}else if(keyPress == '4' && distance == 90){
motorStop();
deQueue();
return;
}
timer = timer+0.167;
delay(200);
}
}
The element hold indicated by front
variable in the queue is passed as a parameter to the liftStops()
function. There is a motor in the circuit and the motorClockwise()
rotates motor clockwise,motorStop()
will stop the motor.
When the program is run for first time , if I press '2', it is stored as second element in the queue. The function liftStops()
starts with '2' as its argument. Now the liftStops()
function runs till distance == 30
and motor stops. Now deQueue()
function is called and the element indicated by front gets eliminated('1' gets eliminated in the above case). After this,if I press '3', liftStops()
runs till distance == 60
and the element indicated by front gets eliminated('2' in this case).
If I press a key when the liftStops()
execution didn't finish, nothing is added to queue. I want the liftStops()
function to run in background so that each and every key I press at any point of time gets stored in queue and the liftStops()
function runs for every element in queue one after another.
Thanks.
millis()
instead ofdelay()
(see the Blink Without Delay Arduino tutorial), then you won't need to run anything in the background.millis()
, but I couldn't achieve the desired output.