Go Down

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

spatula

Hi, the missing element in your description is what is the initial value that is incremented/decremented n times. I assume it is the last value computed by your function.

Obviously, incrementing a number n times is the same as adding n to the number. In code:
Code: [Select]

for (int i = 0; i < incr; i++)
{
 result++;
}


is equivalent to
Code: [Select]

result = result + incr; // can also be abbreviated result += incr;


Nobody would choose the first form, unless what you want is to show the intermediate results, i.e. switch the leds on and off until you reach the result. If this is the case you should state it in your description.

Another variation is: you don't keep the last result in memory, but just display it as a particular configuration of leds (each led is a bit, and the number is represented by the sequence of bits, i.e. on/off leds). This is interesting, because then each increment operation translates into toggling the current state of an led (with carry). But again, if this is what you want you should state it in your description.

About the code, as by previous suggestions you should start concentrating on the distinction between value keys and operator keys, without nesting the ifs (firstKey, secondKey). When an operator key is pressed perform the calculation and display the result, no need to remember the last operator key pressed in the next loops. To get a first working sketch, ignore the fact that entering 10 requires two value key presses.

littlewolf

What if I could set a counting default (for example counting up by 1 until another keys are pressed)
instead of memorizing the last sequence?
It would be interesting, once the counting has started, to be able to modify it
by pressing two keys in sequence. This would start the counter from the default sequence,
but later, after managing to make it working I would try to modify the counter again and to start
from the last sequence.
This way, my binary counter will become a basic 12 bits binary calculator.
Anyway, first of all I have to figure out how to set a default counting
and to test it.
Many thanks for your replies.
Regards

HazardsMind

Your if statements are driving me nuts, if key == '1', if key == '2'... Just make one that gets the key, stores it and converts it to a number. Use "number = key - '0' " to convert it.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

spatula


What if I could set a counting default (for example counting up by 1 until another keys are pressed)
instead of memorizing the last sequence?
It would be interesting, once the counting has started, to be able to modify it
by pressing two keys in sequence. This would start the counter from the default sequence,
but later, after managing to make it working I would try to modify the counter again and to start
from the last sequence.
This way, my binary counter will become a basic 12 bits binary calculator.
Anyway, first of all I have to figure out how to set a default counting
and to test it.
Many thanks for your replies.
Regards


Remember you'll be working within a loop, letting the counter run free may defeat your intention to show that something changes when you press a key. Anyway, I think I finally figured out what you want: from a given configuration of 12 LEDs move to a different configuration representing a value 1 bit more or 1 bit less. E.g. (taking the rightmost 4 bits only) from [0 1 0 0] to [0 1 0 1] to [0 1 1 0] if the counter is 2 and the operation is ++.

Have you worked out the algorithm?

HazardsMind



What if I could set a counting default (for example counting up by 1 until another keys are pressed)
instead of memorizing the last sequence?
It would be interesting, once the counting has started, to be able to modify it
by pressing two keys in sequence. This would start the counter from the default sequence,
but later, after managing to make it working I would try to modify the counter again and to start
from the last sequence.
This way, my binary counter will become a basic 12 bits binary calculator.
Anyway, first of all I have to figure out how to set a default counting
and to test it.
Many thanks for your replies.
Regards


Remember you'll be working within a loop, letting the counter run free may defeat your intention to show that something changes when you press a key. Anyway, I think I finally figured out what you want: from a given configuration of 12 LEDs move to a different configuration representing a value 1 bit more or 1 bit less. E.g. (taking the rightmost 4 bits only) from [0 1 0 0] to [0 1 0 1] to [0 1 1 0] if the counter is 2 and the operation is ++.

Have you worked out the algorithm?



If that's the case then he should be using HEX.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

HazardsMind

#20
Mar 16, 2013, 09:39 pm Last Edit: Mar 17, 2013, 05:43 am by HazardsMind Reason: 1
I got it to work on my end, and the way I did it was just using regular ints, however I think you need it in HEX, but anyways here is my way.

What you need to do is look at the incoming char and see if it does not equal '#' AND '*', and then store it in another variable.
Next convert that variable into an int with "var = (Key - '0')"
Now you press the # or * and using if statements for each, you either add or subtract the variable and put the result in a new variable.

Note I have a 4x4 keypad, and I used my 'A' key to clear my variables back to zero. I suggest you have something similar, otherwise you will need to set the final result back to 0 manually. OR, you can just hold the value and adjust it as you please.

I really don't know any other way to explain how to do this, other than just giving you the code. This should be clear enough to understand and get it to work.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

littlewolf

Hi guys,
I did my best and modified my code following your suggestions.
Now 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 i;
int x; // variable to be used for the
       // storage of the last sequence
int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
int number;
int counter;


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(){
 
   for(i=0; i<12; i++)
   { 
  pinMode(ledPin[i], OUTPUT);      // sets the digital pins as output
   }
}

void loop(){
 
  char key = customKeypad.getKey();
 
  if (key != '*' && key !='#'){
   
    number = key - '0' ;
   
    char key = customKeypad.getKey();
   
    if (key = '#') // increment binary counter
    {
     for(counter = 0; counter < 4096; counter = counter + number){
   
      digitalWrite(ledPin[i], HIGH);
      delay (1000);
    }
    }
   
    else if (key = '*') // decrement binary counter
    {
      for(counter = 0; counter < 4096; counter = counter - number ){
      digitalWrite(ledPin[i], HIGH);
      delay (1000);
      }
     
    }
   
  } //end of if
   
}

It now compiles without errors but I feel there is still something missing.
Can you have a look please?
Thanks again for your suggestions.
Regards


littlewolf

I would like to give to key '0' on keypad the value 10.
Also, I'm not sure that I should state the most and least significant bits in my code
and how to memorize the value in binary of the last sequence.
It would be interesting if I could stop the counter (with LEDs on HIGH)
when pressed any key
until the start of the new counter, so I can prove that the last sequence
plus or minus the new key pressed adds up to the new sequence.

HazardsMind

#23
Mar 17, 2013, 04:56 pm Last Edit: Mar 17, 2013, 05:27 pm by HazardsMind Reason: 1
There are still issues in your code, but at the moment, it looks like you want to enter a number and then count up to it. So for that part, I would get rid of the 4096 and replace that with "number" and just have counter increment or decrement to it.

Also digitalWrite(ledpin, HIGH) does not do anything right now, because it does not know what "i" is. Change i to counter.

Let the dissection begin.
Code: [Select]
void loop(){
 
  char key = customKeypad.getKey();
  if(key) {  //blocking from anything not needed.

  if (key != '*' && key !='#'){
      number = key - '0' ;
  } // end of sort
   
  if (key == '#') // increment binary counter
  {
     for(counter ; counter < number; counter++){ // Set counter = 0, at the top of code.
      digitalWrite(ledPin[counter], HIGH);
      delay (1000);
      } // end of inc 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 dec counter
  } // end of '*' 
} //end of if(key)
} // end of loop


Now, you only have 12 LEDs so why not enter 2 numbers and then decide to dec or inc them? Enter 1 and 2 to make 12, or 1 and 0 to get 10. It will be a little more coding but, give it a try. With these counters, the way you have them set up, you don't particularly need to you HEX anymore.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

littlewolf



Now, you only have 12 LEDs so why not enter 2 numbers and then decide to dec or inc them? Enter 1 and 2 to make 12, or 1 and 0 to get 10. It will be a little more coding but, give it a try. With these counters, the way you have them set up, you don't particularly need to you HEX anymore.


This is a great idea and seems much simpler.
Perhaps there is no more need to store the last LEDs configuration.
Using all the numbers from 0 to 99 seems more interesting.
Thank you for your help.
Hope I can do it.
Regards

littlewolf

Hi guys,
Sorry to bother you again but it still doesn't work.
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;
char firstKey;
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;
   }
   if ( keyPressed==2){
  Serial.println(firstKey);

  //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);
       unsigned long currentMillis = millis();
       if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
      } // end of millis
     
     
     } // 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);
      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
      } // end of millis
     
      } // end of decrement counter
     
    } // end of '*'
    keyPressed=0;
   } // end of keycount
  } //end of if(key)
   
} // end of loop


It only works when I insert the first input then, nothing.
I mean that it turns all the LEDs on (the number key pressed)
and keeps them on.
What about the binary counting?
Regards

littlewolf


HazardsMind

My GitHub:
https://github.com/AndrewMascolo?tab=repositories

lloyddean

This is posted with honest intent, not to criticize or discourage.

I posted some code earlier in an attempt to help, but then upon rereading your requirements decided that your requirements are ambiguous and deleted the post.

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

Post them, accept feed back, modify and repost the requirements and looping until they are completely stated and can be coded from.

Without good documented requirements you haven't much of a chance in completing your task as you don't even know what it is you're trying to accomplish let alone getting useful assistance for someone who only thinks they know what you want.

I'm listening ...

lloyddean

Concerning your current code the following snip-it, occurring twice, does nothing

Code: [Select]

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


If a multiple association condition test succeeds then you may safely use 'else' to exclude additional tests.

Code: [Select]

if ( keyPressed == 1 )
{
...
}
else if ( keyPressed == 2 )
{
...

if ( key == '#' )
{
...
}
else if ( key == '*' )
{
...
}

...
}

Go Up