Go Down

Topic: Binary counting using 12 LEDs (Read 19080 times) previous topic - next topic

littlewolf



My suggestion (which you've seen stated here by others more than once) is to CLEARLY define your requirements.


The reason I'm trying to use "millis" is because when using "delay" the keypad
reads the input only once then does nothing.
I am trying to use the keypad to control the binary counting on LEDs.
There are number keys (0,1,2,3,4,5,6,7,8,9) and operator keys (* and #).
I want to use the operator keys to either increase (pressing #) or decrease
(pressing *) the binary counting by the value of the number keys pressed.
Perhaps it would be nice to read two number keys at the time (going up to 99)
followed by an operator key.
To make it even more simpler:
2+5+'#' would count up by 25 (in binary)
I will try your last suggestion and also "HasardsMind's" suggestion.
In fact I'm working now on them.
I'll let you know about my progress.
Regards

littlewolf

I think I made the matter worse.
The topic suggested by "HazardsMind" is not very useful.
I changed the if statements as suggested by "lloiddean"
and I think it should be fine. Then, I tried to add the first two keys
together and to store the result into the "sum".
Now, I get instead very big numbers instead (for example 9+9= 114 ).
The LEDs don't blink any more and I am not very sure about the loop
for getting the third key.
This is my code:
Code: [Select]
/* Binary counting using 12 LEDs and a keypad to control
the increasing or decreasing rate by the value
of the key pressed*/

#include <Keypad.h>

int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
int number=0;
int keyPressed=0;
int counter=0;
int sum=0;
char firstKey;
char secondKey;
long previousMillis = 0;
long interval = 1000;

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] = {31, 33, 35, 37}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 41, 43}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
 
   for(counter=0; counter<12; counter++)
   { 
  pinMode(ledPin[counter], OUTPUT);      // sets the digital pins as output
   }
}

void loop(){
 
  char key = customKeypad.getKey();
  /*if (key) {
    Serial.println(key);
  }*/
  if (key) { // blocking from anything not needed
   keyPressed= keyPressed+1;
   if (key != '*' && key !='#'){
   
    number =key - '0' ; // convert key to its value
  } // end of sort
   if (keyPressed ==1){
     firstKey=key;
   }
  else if ( keyPressed==2){
    secondKey=key;
    sum=firstKey+secondKey;
  Serial.println(sum);

  //Serial.println(number);
  if (keyPressed==3){
   keyPressed=key;  // I'm not sure about this loop
   
    if (key == '#') // increment binary counter
    {
       Serial.println("i"+firstKey);
       //digitalWrite(13, HIGH);
       //delay (1000);
     for(counter=0; counter< number; counter++){
      //digitalWrite(ledPin[counter-1], HIGH);
      digitalWrite(ledPin[counter], HIGH);
       unsigned long currentMillis = millis();
       if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
      } // end of millis
     
     
     } // end of increment counter
    } // end of '#'
   
   
    else if (key == '*') // decrement binary counter
    {
      for(counter; counter < number; counter-- ){
        if (counter < 0) counter = 0; // checks to see if
        // counter does past zero then set it back to zero
      digitalWrite(ledPin[counter], LOW);
      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
      } // end of millis
     
      } // end of decrement counter
     
    } // end of '*'
    } // end of keyPressed == 3
    keyPressed=0;
   } // end of keycount
  } //end of if(key)
   
} // end of loop


spatula


Now, I get instead very big numbers instead (for example 9+9= 114 ).


Guess what the ASCII value of '9' is? 57. In
Code: [Select]

sum=firstKey+secondKey;

you are adding the characters ('0'..'9'), not the numbers (0..9).

littlewolf



Guess what the ASCII value of '9' is? 57. In
Code: [Select]

sum=firstKey+secondKey;

you are adding the characters ('0'..'9'), not the numbers (0..9).

You are right.
I managed to do the code for addition.
Code: [Select]

#include <Keypad.h>

int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
int number1=0;
int number2=0;
int keyPressed=0;
int counter=0;
int sum=0;
char firstKey;
char secondKey;
long previousMillis = 0;
long interval = 1000;

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] = {31, 33, 35, 37}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 41, 43}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
 
   for(counter=0; counter<12; counter++)
   { 
  pinMode(ledPin[counter], OUTPUT);      // sets the digital pins as output
   }
}

void loop(){
 
  char key = customKeypad.getKey();
  /*if (key) {
    Serial.println(key);
  }*/
  if (key) { // blocking from anything not needed
   keyPressed= keyPressed+1;
   if (key != '*' && key !='#'){
   
  // number =key - '0' ; // convert key to its value
  } // end of sort
   if (keyPressed ==1){
     number1= key - '0';
     firstKey=key;
   }
  else if ( keyPressed==2){
    number2= key - '0';
    secondKey=key;
    sum=(number1 *10)+number2;
  Serial.println(sum);

  //Serial.println(number);
  if (sum){
    char key = customKeypad.getKey();
    // I'm not sure about this loop
   
    if (key == '#') // increment binary counter
    {
       Serial.println("i"+firstKey);
       //digitalWrite(13, HIGH);
       //delay (1000);
     for(counter=0; counter< sum; counter++){
      //digitalWrite(ledPin[counter-1], HIGH);
      digitalWrite(ledPin[counter], HIGH);
       unsigned long currentMillis = millis();
       if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
      } // end of millis
     
     
     } // end of increment counter
    } // end of '#'
   
   
    else if (key == '*') // decrement binary counter
    {
      for(counter; counter < sum; counter-- ){
        if (counter < 0) counter = 0; // checks to see if
        // counter does past zero then set it back to zero
      digitalWrite(ledPin[counter], LOW);
      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
      } // end of millis
     
      } // end of decrement counter
     
    } // end of '*'
    } // end of sum
    keyPressed=0;
   } // end of keycount
  } //end of if(key)
   
} // end of loop

Now, when I press two numbers I get the right sum on the serial monitor.
However, if I press '*' I get minus 6. Similarly, for '#' I get minus 13.
How do I convert the third key to either increase the decrease the counting?
At the moment my LEDs don't do anything.
I also have to convert the input to binary counting.
How do I do it?
Regards

HazardsMind

The reason your getting -6 and -13 for # and * is beacuse you took out,
Quote
if (key != '*' && key !='#'){
   
// number =key - '0' ; // convert key to its value
  } // end of sort

This part was making all the button work correctly. Try to do include this with "keyPressed ==1" and "keyPressed ==2".

Also that link I gave works fine. Im guessing you didn't fully understand it, no problem though. Your method will suffice.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

littlewolf

How do I get then the sum If I put it back?
It doesn't work.
For the sum I need:
sum=(number1 *10)+number2;
Can I do it differently?

HazardsMind

Code: [Select]
if (key != '*' && key !='#' && keyPressed ==1 ){
     number1= key - '0';
     firstKey=key;
   }


Repeat for second key press
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

littlewolf

Thanks,
It works but I can only press two number keys at the time.
If I press either * or # it stops everything
The * and # keys still don't do anything and the counting doesn't start.
Now, what next?

HazardsMind

#38
Apr 03, 2013, 05:32 pm Last Edit: Apr 03, 2013, 05:34 pm by HazardsMind Reason: 1
According to your code, you have everything inside keypress2, and with the "key != '*' && key !='#' ", it will never get to the other buttons. You need to fix your brackets. Keypress1 is fine, now do the same thing for Keypress2. You can keep the sum inside, but everything else must come out.

Im not home right now, nor did I bring my stuff with me to work.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

littlewolf

#39
Apr 03, 2013, 07:47 pm Last Edit: Apr 03, 2013, 07:49 pm by littlewolf Reason: 1

According to your code, you have everything inside keypress2, and with the "key != '*' && key !='#' ", it will never get to the other buttons. You need to fix your brackets. Keypress1 is fine, now do the same thing for Keypress2. You can keep the sum inside, but everything else must come out.


Thanks,
I really don't know how to close that bracket or more exactly, where is
the right place to put it. It shows me lots of errors.
Look, this is my modified code:
Code: [Select]
#include <Keypad.h>

int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
int number1=0;
int number2=0;
int keyPressed=0;
int counter=0;
int sum=0;
char firstKey;
char secondKey;
long previousMillis = 0;
long interval = 1000;

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] = {31, 33, 35, 37}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 41, 43}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
 Serial.begin(9600);
 
  for(counter=0; counter<12; counter++)
  {  
 pinMode(ledPin[counter], OUTPUT);      // sets the digital pins as output
  }
}

void loop(){
 
 char key = customKeypad.getKey();
 /*if (key) {
   Serial.println(key);
 }*/
 if (key) { // blocking from anything not needed
  keyPressed= keyPressed+1;
  if (key != '*' && key !='#'){
   
 // number =key - '0' ; // convert key to its value
 } // end of sort
  if (key != '*' && key !='#'&& keyPressed ==1){
    number1= key - '0';
    firstKey=key;
   } // end of key==1
 else if (key != '*' && key !='#'&& keyPressed==2){
   number2= key - '0';
   secondKey=key;
   sum=(number1 *10)+number2;
    // end or key==2
 
 //Serial.println(number);
 if (sum){
   char key = customKeypad.getKey();
   // I'm not sure about this loop
   
   if (key == '#') // increment binary counter
   {
      Serial.println("i"+firstKey);
      //digitalWrite(13, HIGH);
      //delay (1000);
    for(counter=0; counter< sum; counter++){
     //digitalWrite(ledPin[counter-1], HIGH);
     digitalWrite(ledPin[counter], HIGH);
      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > interval) {
       previousMillis = currentMillis;
     } // end of millis
   
     
    } // end of increment counter
   } // end of '#'
   
   
   else if (key == '*') // decrement binary counter
   {
     for(counter; counter < sum; counter-- ){
       if (counter < 0) counter = 0; // checks to see if
       // counter does past zero then set it back to zero
     digitalWrite(ledPin[counter], LOW);
     unsigned long currentMillis = millis();
     if(currentMillis - previousMillis > interval) {
       previousMillis = currentMillis;
     } // end of millis
   
     } // end of decrement counter
     
   } // end of '*'
   } // end of sum
   keyPressed=0;
  } // end of keycount
  }//end of if(key)
 
 }// end of loop

If I close the bracket after "end of key==2", see above, I also
have to close the loop which is worse.
I've been trying since this morning.
I really don't know

HazardsMind

This is not needed.
Quote
if (sum){
    char key = customKeypad.getKey();

Once you enter the two numbers, it should add them, then go back and allow you to enter # or *.

Code: [Select]
else if (key != '*' && key !='#'&& keyPressed==2){
    number2= key - '0';
    secondKey=key;
    sum=(number1 *10)+number2;
}// done with else if
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

lloyddean

#41
Apr 03, 2013, 08:16 pm Last Edit: Apr 03, 2013, 08:22 pm by lloyddean Reason: 1
I say again this code ...

Code: [Select]

unsigned long currentMillis = millis();
if ( currentMillis - previousMillis > interval )
{
previousMillis = currentMillis;
}


... performs absolutely NO USEFUL PURPOSE and might as well be replaced with ...

Code: [Select]

// WHAT ARE YOU LOOKING AT, NOTHING TO SEE HERE CARRY ON


... or, a lot less typing ...

Code: [Select]



Then I have qqusestion about this ...

Code: [Select]

else if ( key == '*' )
{
    // decrement binary counter
   
    for ( counter; counter < sum; counter-- )   // << DOES COUNTER HAVE A USEFUL VALUE HERE
    {


HazardsMind

This is what I originally gave you.
Quote
if (key == '*') // decrement binary counter
  {
      for(counter; counter > number; counter--) {
        if(counter < 0) counter = 0; // checks to see if counter does past zero then set it back to zero.        digitalWrite(ledPin[counter], LOW);
        delay (1000);
      }  // end of dec counter
  } // end of '*' 
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

littlewolf

Hi guys,
I modified the code again following the last suggestions.
It compiles but doesn't work when I connect the circuit.
This is my code:
Code: [Select]
#include <Keypad.h>

int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
int number=0;
int number1=0;
int number2=0;
int keyPressed=0;
int counter=0;
int sum=0;
char firstKey;
char secondKey;

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] = {31, 33, 35, 37}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 41, 43}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
 
   for(counter=0; counter<12; counter++)
   { 
  pinMode(ledPin[counter], OUTPUT);      // sets the digital pins as output
   }
}

void loop(){
 
  char key = customKeypad.getKey();
  /*if (key) {
    Serial.println(key);
  }*/
  if (key) { // blocking from anything not needed
   keyPressed= keyPressed+1;
   if (key != '*' && key !='#'){
   
  // number =key - '0' ; // convert key to its value
  } // end of sort
   if (key != '*' && key !='#'&& keyPressed ==1){
     number1= key - '0';
     firstKey=key;
    } // end of if
  else if (key != '*' && key !='#'&& keyPressed==2){
    number2= key - '0';
    secondKey=key;
    sum=(number1 *10)+number2;
  }// end of else if
 
  //Serial.println(number);

    if (key == '#') // increment binary counter
    {
       Serial.println("i"+firstKey);
       //digitalWrite(13, HIGH);
       //delay (1000);
     for(counter=0; counter< number; counter++){
      //digitalWrite(ledPin[counter-1], HIGH);
      digitalWrite(ledPin[counter], HIGH);
       delay(1000);
     
     } // end of increment counter
    } // end of '#'
   
   
    if (key == '*') // decrement binary counter
    {
      for(counter; counter > number; counter-- ){
        if (counter < 0) counter = 0; // checks to see if
        // counter does past zero then set it back to zero
      digitalWrite(ledPin[counter], LOW);
        delay(1000);
     
      } // end of decrement counter
     
    } // end of '*'
   
    keyPressed=0;
   
   }//end of if(key)
   
  }// end of loop

What is wrong now?
It doesn't show any character on serial monitor
and the LEDs don't blink.
I have a question for "HazardsMind".
Should I use sum or number in counter loop?
Since I used sum = (number1*10)+number2,
perhaps is better to use sum.
What else is missing from this code?
Thank you everyone for your help.
Regards

HazardsMind

#44
Apr 03, 2013, 09:58 pm Last Edit: Apr 03, 2013, 10:12 pm by HazardsMind Reason: 1
No longer needed.
Quote
if (key != '*' && key !='#'){
   
  // number =key - '0' ; // convert key to its value
  } // end of sort


Take out "else" from here:
Quote
else if (key != '*' && key !='#'&& keyPressed==2){
    number2= key - '0';
    secondKey=key;
    sum=(number1 *10)+number2;
  }// end of else if


Add serial.println(sum);

Right now your LEDs will only light up, not blink. You need to learn how to use the millis() timer properly.
Look into the blink without delay sketch.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Go Up