Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: [1] 2   Go Down
Author Topic: While loop & Reset  (Read 2095 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,
   I am trying to do a Reset after the user enters his numbers. I am also trying to fix my while loops because once in the loop it just stays there and if the user tries the other combination it wouldn't allow him because of the while loop.
I know the problem is because of the condition I have inside my while loop (i.e the 1) but I don't know what condition to put inside it so when the user start pressing the keys the program will reset the previous input and let the user put the new combination.
The program works but I have to reset using the reset button of the arduino. I want some reset in the code.
Thank you very very much. Here is my code:
Code:
#include <Keypad.h>
#include <Password.h>
int IOXpin =2;
Password Disp1 = Password( "20" );
Password Disp2 = Password( "200" );

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {
    '1','2','3'                      }
  ,
  {
    '4','5','6'                      }
  ,
  {
    '7','8','9'                      }
  ,
  {
    '*','0','#'                      }
};

byte rowPins[ROWS] = {
  5, 4, 3, 12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
  pinMode(IOXpin, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop(){
  digitalWrite(IOXpin, HIGH);
  keypad.getKey();
  char key = keypad.getKey();
  Serial.println(key);
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
    Serial.print("Pressed: ");
    Serial.println(eKey);
    switch (eKey){
    case '*':
      checkDisp1();
      break;
    case '#':
      checkDisp2();
    case '1':
      Disp1.reset();
      Disp2.reset();
      break;
    default:
      Disp1.append(eKey);
      Disp2.append(eKey);
    }
  }
}

void checkDisp1(){
  if (Disp1.evaluate()){
    Serial.println("Dispensing 20 uL");
    //Add code to run if it works
    while(1)
    {
      digitalWrite(IOXpin, LOW);
      delay(100);
      digitalWrite(IOXpin, HIGH);
      delay(100);
    }
  }
  else{
    Serial.println("Not Available!! Reset using 1");
    //add code to run if it did not work
    digitalWrite(IOXpin, HIGH);
  }
}
void checkDisp2(){
  if (Disp2.evaluate()){
    Serial.println("Dispensing 200 uL");
    //Add code to run if it works
    while(1)
    {
      digitalWrite(IOXpin, LOW);
      delay(1000);
      digitalWrite(IOXpin, HIGH);
      delay(1000);
    }
  }
  else{
    Serial.println("Not Available!! Reset using 1");
    //add code to run if it did not work
    digitalWrite(IOXpin, HIGH);
  }
}



Logged

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1026
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is it time dependent? Use millis() and check for a time out and then reset the values.

Configure it so the user hits some key to start the entry sequence. Like a "command" key
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No it's not time dependent. I just want to sense when the user start touching the keys and that should trigger something to reset the previous entry and leave the loop. Turn pin 2 high and then it's ready to check the new entry.if it's correct it will enter the second loop if not it'll go to the second condition(not available!!)
Thanks
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 671
Posts: 51669
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  keypad.getKey();
  char key = keypad.getKey();
  Serial.println(key);
Read the keypad, and throw the value away. Read it again, and print the key being pressed, even if no key is being pressed. Why?

Code:
    while(1)
    {
      digitalWrite(IOXpin, LOW);
      delay(100);
      digitalWrite(IOXpin, HIGH);
      delay(100);
    }
If this statement is ever reached, the infinite loop is the only thing that the code will ever do. Not the greatest idea to not include a way to get out of this loop. Fortunately, the Arduino people did provide a way - the reset button.

Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I appreciate the response, but what you trying to say with you answer. I have a problem with loop how can we solve it?
Logged

California
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3453
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I appreciate the response, but what you trying to say with you answer. I have a problem with loop how can we solve it?

Use a variable to determine if we need to blink the LED:
Code:
int blinkLED = 0; // Global scope
Instead of an infinite loop, we can remove the delays:
Code:
const unsigned long interval = 250; // Global Scope
unsigned long lastEdgeTime = 0; // time since last switch
int blinkingLEDState = LOW; // Start with low
In our Arduino's loop, we constantly check how long it's been since we turned on/off the LED:
Code:
if((blinkLED==1)&&(millis() -  lastEdgeTime  > interval) ) { // check if it's been at least interval time since last switch and we should be blinking it
  lastEdgeTime  = millis(); // reset our interval timer
  blinkingLEDState = blinkingLEDState==HIGH?LOW:HIGH; // switch from HIGH to LOW or LOW to HIGH
  digitalWrite(IOXpin, blinkingLEDState); // write to the pin
}
So what this allows you to do is not use delays and constantly run the loop so that you can check for user input. When the user does something such that you don't need to blink the LED, simple set blinkLED to 0 and turn it off.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you very much. I think what you suggested is almost working the only problem is I want to turn on and off IOXpin exactly the amount of time I had on my while loop. Because I am trying to control a pump. This pump has a pin when you apply 5v to it, it stops and when you apply 0V it turns on. Basically, you stop it with turning the IOXpin high.
Here is the changes I did to my code. And thanks again for the help.
Code:
#include <Keypad.h>
#include <Password.h>
int blinkLED =0; //Global variable to see if we need to turn the


const unsigned long interval = 250; // Global Scope     
//pin IOX high or not
unsigned long lastEdgeTime = 0; // time since last switch
int blinkingLEDState = LOW; // Start with low


int IOXpin =2;
Password Disp1 = Password( "20" );
Password Disp2 = Password( "200" );

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {
    '1','2','3'                          }
  ,
  {
    '4','5','6'                          }
  ,
  {
    '7','8','9'                          }
  ,
  {
    '*','0','#'                          }
};

byte rowPins[ROWS] = {
  5, 4, 3, 12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
  pinMode(IOXpin, OUTPUT);
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop(){
  //digitalWrite(IOXpin, HIGH);
  keypad.getKey();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
    Serial.print("Pressed: ");
    Serial.println(eKey);
    switch (eKey){
    case '*':
      checkDisp1();
      break;
    case '#':
      checkDisp2();
    case '1':
      Disp1.reset();
      Disp2.reset();
      break;
    default:
      Disp1.append(eKey);
      Disp2.append(eKey);
      Serial.flush();
    }
  }
}

void checkDisp1(){
  if (Disp1.evaluate()){
    Serial.println("Dispensing 20 uL");

    //    while(1)
    //    {
    //      digitalWrite(IOXpin, LOW);
    //      delay(100);
    //      digitalWrite(IOXpin, HIGH);
    //      delay(5000);
    //    }


    if((blinkLED==1)&&(millis() -  lastEdgeTime  > interval) ) { // check if it's been at least interval time since last switch and we should be blinking it
      lastEdgeTime  = millis(); // reset our interval timer
      blinkingLEDState = blinkingLEDState==HIGH?LOW:HIGH; // switch from HIGH to LOW or LOW to HIGH
      digitalWrite(IOXpin, blinkingLEDState); // write to the pin
    }


  }

  else{
    Serial.println("Not Available, Reset!!");

    digitalWrite(IOXpin, HIGH);
  }
}
void checkDisp2(){
  if (Disp2.evaluate()){
    Serial.println("Dispensing 200 uL");

    //    while(1)
    //    {
    //      digitalWrite(IOXpin, LOW);
    //      delay(1000);
    //      digitalWrite(IOXpin, HIGH);
    //      delay(5000);
    //    }


    if((blinkLED==1)&&(millis() -  lastEdgeTime  > interval) ) { // check if it's been at least interval time since last switch and we should be blinking it
      lastEdgeTime  = millis(); // reset our interval timer
      blinkingLEDState = blinkingLEDState==HIGH;//?LOW:HIGH; // switch from HIGH to LOW or LOW to HIGH
      digitalWrite(IOXpin, blinkingLEDState); // write to the pin
    }




  }
  else{
    Serial.println("Not Available, Reset!!");

    digitalWrite(IOXpin, HIGH);
  }
}





Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Could you, please, provide some feedback on what I am doing wrong.
Thanks
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No answer?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 671
Posts: 51669
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Could you, please, provide some feedback on what I am doing wrong.
Could you please describe what that code is doing, and how what it does differs from what you want. With your vague handwaving, it's really hard to tell you how to fix the code.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, thank you very much,
Forget about the modification I did in the last post. Here is the one I have now:
Code:
#include <Keypad.h>
#include <Password.h>
int IOXpin =2;
Password Disp1 = Password( "20" );
Password Disp2 = Password( "200" );

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {
    '1','2','3'                      }
  ,
  {
    '4','5','6'                      }
  ,
  {
    '7','8','9'                      }
  ,
  {
    '*','0','#'                      }
};

byte rowPins[ROWS] = {
  5, 4, 3, 12}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
  pinMode(IOXpin, OUTPUT);
  Serial.begin(9600); // change this to 115200
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop(){
  digitalWrite(IOXpin, HIGH);
  keypad.getKey();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
  case PRESSED:
    Serial.print("Pressed: ");
    Serial.println(eKey);
    switch (eKey){
    case '*':
      checkDisp1();
      break;
    case '#':
      checkDisp2();
    case '1':
      Disp1.reset();
      Disp2.reset();
      break;
    default:
      Disp1.append(eKey);
      Disp2.append(eKey);
    }
  }
}

void checkDisp1(){
  if (Disp1.evaluate()){
    Serial.println("Dispensing 20 uL");
    //Add code to run if it works
    while(Disp2.evaluate() != '200')
    {
      digitalWrite(IOXpin, LOW);
      delay(100);
      digitalWrite(IOXpin, HIGH);
      delay(5000);
    }
  }
  else{
    Serial.println("Not Available, Reset!");
    //add code to run if it did not work
    digitalWrite(IOXpin, HIGH);
  }
}
void checkDisp2(){
  if (Disp2.evaluate()){
    Serial.println("Dispensing 200 uL");
    //Add code to run if it works
    while(1)
    {
      digitalWrite(IOXpin, LOW);
      delay(1000);
      digitalWrite(IOXpin, HIGH);
      delay(5000);
    }
  }
  else{
    Serial.println("Not Available, Reset!");
    //add code to run if it did not work
    digitalWrite(IOXpin, HIGH);
  }
}



              The code work like how the password code works:
Code:
/*
||  Simple Password Entry Using Matrix Keypad
||  4/5/2012 Updates Nathan Sobieck: Nathan@Sobisource.com
||
*/


//* is to validate password   
//# is to reset password attempt

/////////////////////////////////////////////////////////////////

#include <Password.h> //http://www.arduino.cc/playground/uploads/Code/Password.zip
#include <Keypad.h> //http://www.arduino.cc/playground/uploads/Code/Keypad.zip

Password password = Password( "1234" );

const byte ROWS = 4; // Four rows
const byte COLS = 4; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = { 9,8,7,6 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 5,4,3,2, };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){

  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop(){
  keypad.getKey();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
    case PRESSED:
Serial.print("Pressed: ");
Serial.println(eKey);
switch (eKey){
  case '*': checkPassword(); break;
  case '#': password.reset(); break;
  default: password.append(eKey);
     }
  }
}

void checkPassword(){
  if (password.evaluate()){
    Serial.println("Success");
    //Add code to run if it works
  }else{
    Serial.println("Wrong");
    //add code to run if it did not work
  }
}

So in my case when the user hits the right combination, I want to display the message "Dispensing whatever 20uL or 200uL" and it will start the loop (Turn a pin high for some time  and low for some time in a loop) in my case I am using pin 2.
I hope I clarified what I am looking for.
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 535
Posts: 19768
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
while(1)
    {
      digitalWrite(IOXpin, LOW);
      delay(1000);
      digitalWrite(IOXpin, HIGH);
      delay(5000);
    }

Describe in your own words what you think this will do.
Logged

http://gammon.com.au/electronics
Please post technical questions on the forum - not by personal message. Thanks!

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That loop need some work. I know because I put that "1" inside the while (i.e while(1)) that's why when the user inputs the right combination it just stays in loop because it's always true.
But What I want is if the user touched any key from the keypad it will exit the loop, that's simply what I am trying to do.
I tried putting inside the () of the while loop something like "key" or ekey thinking that variable stores the current reading but it didn't work.
Let me know if you have any help to provide us with.
Thanks
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 535
Posts: 19768
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So when they enter the right password you want it to dispense stuff for ever? I hope you have a lot of this stuff.
Logged

http://gammon.com.au/electronics
Please post technical questions on the forum - not by personal message. Thanks!

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At first the OIX pin will be set high. You can see that in the  beginning of my void loop setup. Because that pin stops my micro pump when it's high. So I want it high when you first power the system. Then when the user put the right combination it will go to my two loops, depending on the selection. If the user selected 20 then it will execute the first loop.
If the user didn't enter the right combination the pin IOX will stay high to keep the pump in the stop mode.
Now if the user entered the right combination, I will print a message (dispensing 20 ul) and the pin start turning high and low (see my time) until the user touches the keys again in which case the IOX pin will turn high to stop the pump again and wait for the next entry, if it's 200 then that's good it'll go to the second loop, if it's 20 it'll go back to the first loop if it's not one of these two the program should exit the loop and turn the pin IOX high again to stop the pump.
My problem is just how do you get out of the loop and reset the system, I need a condition (maybe getkey() function to tell me that the user touched the keys or something).
Please some sample code, just suggesting things doesn't help me
I hope this makes it clear
Thank you very much for your time.
Thank you.
Logged

Pages: [1] 2   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: