Binary counting using 12 LEDs

Hi guys,
I am currently working on a new project but, like always, I am a bit
struggling with the code.
My project include 12 LEDs connected to an Arduino Mega and a 4/3 keypad.
I would like to do binary counting using the LEDs and to change the rate of
increase or decrease using the keypad.
For example, by pressing 1 and "i++" or "i--"(I changed the "*" and "#" characters)
to either increase or decrease the counting by one.
Similarly, by pressing any other character, to either increase or decrease the counting
by its value.

Here is my code so far:

/* Binary counting using 12 LEDs and a keypad to change 
the increasing or decreasing rate */

#include <Keypad.h>
int i;
int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
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'},
	{'i--','10','i++'}
	};
/* I want to use i-- and i++ to either increase
or decrease the binary counting */

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 keypad = 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
  
  char key = keypad.getKey();
   
 if (key=1)
 {
   counter = i+1
 }
 else if(key=2)
 {
   counter= i+2
 }
 else if(key=3)
 {
 counter=i+3
 }
 else if etc....
  
  
  }
}

Could you help?
Regards

{'i--','10','i++'}

It doesn't work like that. You should have an IF statement look for '*' or '#' and change the counter accordingly.

key=1,key=2,key=3

Again, it does not work like that. If anything, it should be if(key == '1'), if(key == '2') and so on.

Now you want to look at the keypad press a number and then decide whether it should be incremented or decremented? Ok well then you need to have if so that if a key is pressed, it then looks at another incoming key and see if it is '#' or '*'. So your looking at an IF within an IF statement.

Something like this ...?

/* Binary counting using 12 LEDs and a keypad to change 
the increasing or decreasing rate */

#include <Keypad.h>
int i;
int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
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','#'}
	};
/* I want to use i-- and i++ to either increase
or decrease the binary counting */

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 keypad = 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
  
  char key = keypad.getKey();
   
 if (key==1)
 {
   if (key==*){
     counter=i+1 /* start counting up by 1 */
   } else if (key==-)
   {
     counter=i-1 /*etc  */
   }
 }
 else if(key==2)
 {
   if (key==*){
     counter=i+2
   } else if (key==-)
   {
     counter=i-2
   }
 }
 else if(key==3)
 {
 counter=i+3
 }
 else if etc....
  
  
  }
}

I'm not sure how to write the counter function.

character constants always have single quotes, so

 if (key==1)

needs to be

 if (key=='1')

and so on - the result of getKey() is one of the characters you put in the array so its a character code,
and the code for '1' is not 1. Put another way '1' denotes the character code used, you never
need to see it or even know that its actually 49.

And if you are comparing the same integer or character variable against a set of possibilities then the
switch statement is much neater:

  switch (key)
  {
  case '1': .....
    break ;
  case '*': ....
    break ;
  ......
  }
 if (key==1)
 {
   if (key==*){
     counter=i+1 /* start counting up by 1 */
   } else if (key==-)

If key equals '1' then it very well can't be '*' at the next 'if'

lloyddean:

 if (key==1)

{
   if (key==){
     counter=i+1 /
start counting up by 1 */
   } else if (key==-)




If key equals '1' then it very well can't be '*' at the next 'if'

That's why you read the key again. Also why is this not in the loop()?

What about this one?

/* Binary counting using 12 LEDs and a keypad to change 
the increasing or decreasing rate */

#include <Keypad.h>
int i;
int x;
int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
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','#'}
	};
/* I want to use i-- and i++ to either increase
or decrease the binary counting */

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 keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

void loop(){
  
  char key = keypad.getKey();
   
 if (key=='1')
 {
   /* getKey for case A and case B
   case A = increment
   case B = decrement
   */
 }
 else if(key=='2')
 {
   
 }
 else if(key=='3')
 {
 
 }
 else if(key=='4')
 {
  
 }
 else if(key=='5')
 {
  
 }
 else if(key=='6')
 {
   
 }
 else if(key=='7')
 {
   
 }
 else if(key=='8')
 {
   
 }
 else if(key=='9')
 {
   
 }
 else if(key=='0')
 {
   
 }


}

Hope it looks better although it still has errors.
Now I have to figure out how to do the counting

There is an easier way to write this code by using "digitalWrite" but this
will result in a very long and boring code.
I'm not sure yet how this keypad will control the binary counting.
Perhaps an attachInterrupt() might be needed to shift the code to a new loop.
I tried this with one switch only in order to control the LEDs but I wasn't able
to change "digitalWrite" into a counting loop.
I couldn't find any example on the internet of how to control a binary counting
using switches and I am a bit confused.

As you can see, I need your help.

Regards

Try this.
Look at the key, if it is not '#' or '' then store it in a variable, convert that variable to an int, and then wait for the key to be '#' or ''. Once key is '#' or '*', the code will decide whether to make it + or - the counter.

Hi, I'm trying to figure out what you want to do and I'm still unsure. The case I have in mind is a sort of simple calculator using postfix notation, so if you type "123+-" this is translated into ((2+3)-1). Your case is probably simpler because you seem to allow only a value followed by an operator, so you never get two consecutive values or two consecutive operators.

Both ways, you need to make a distinction between values and operators: if a value key is entered you have to save the value until an operator key is pressed (you may display the value, but that is not essential and depends on how you design your "user interface"); if an operator key is pressed you need to perform the calculation and display it. You also need to save the last result, as input to the next operation.

In the simple case, you need to keep the last result and the last value entered in a variable that is not changed on each loop(), as the counter and x variables in your code (but using more meaningful names may help understand what they are for). Nothing prevents you from storing the last result (or last value, but not both) in digitalPins. Looks boring to code, but also instructive.

P.S. just saw HazardsMind's comment, seems we are on the same track.

I believe the last two replies are good answers to my problem.
This is exactly what I want to do:
get a key
if the key is an integer
get the second key
if second key is '*' or '#'
then, either increase or decrease the counting by the
value of the key
I will try to modify the above code during this weekend when I have more time
You are welcome with more suggestions.
Thank you guys for your help.
Regards

spatula:
Hi, I'm trying to figure out what you want to do and I'm still unsure. The case I have in mind is a sort of simple calculator using postfix notation, so if you type "123+-" this is translated into ((2+3)-1). Your case is probably simpler because you seem to allow only a value followed by an operator, so you never get two consecutive values or two consecutive operators.

Both ways, you need to make a distinction between values and operators: if a value key is entered you have to save the value until an operator key is pressed (you may display the value, but that is not essential and depends on how you design your "user interface"); if an operator key is pressed you need to perform the calculation and display it. You also need to save the last result, as input to the next operation.

In the simple case, you need to keep the last result and the last value entered in a variable that is not changed on each loop(), as the counter and x variables in your code (but using more meaningful names may help understand what they are for). Nothing prevents you from storing the last result (or last value, but not both) in digitalPins. Looks boring to code, but also instructive.

P.S. just saw HazardsMind's comment, seems we are on the same track.

I'm struggling to do all of this.
This is my code for now.

/* 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;
int ledPin[12]={13,12,11,10,9,8,7,6,5,4,3,2};
int counter;
int firstKey;
int secondKey;
int mostSignificantBit;
int leastSignificantBit;

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

void loop(){
  
  char key = customKeypad.getKey();
   
 if (firstKey=='1')
 {
  if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   }
 }
 else if(firstKey=='2')
 {
    if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   }
 }
 else if(firstKey=='3')
 {
  if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   }
 }
 else if(firstKey=='4')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   }
 }
 else if(firstKey=='5')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   }
 }
 else if(firstKey=='6')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   } 
 }
 else if(firstKey=='7')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   } 
 }
 else if(firstKey=='8')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   }
 }
 else if(firstKey=='9')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   } 
 }
 else (firstKey=='0')
 {
   if (secondKey=='*'){
   for( 
  }
   else (secondKey=='#') {
     for (
   } 
 }


}

I just wanted to make sure I am going in the right direction.
Can you check my code please to see what else is missing.
Some code examples would be useful.
I still don't know how to declare all the variables needed for my code.
Regards

Your code as posted does not compile.

Apart from anything else the loop() function starts before the setup() function ends
I strongly suggest that you put each curly bracket in its own line so that you can see the indentation properly

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

void loop()
{

I would like to have Auto Formatted the code but it won't due to errors in it so I will leave that to you.

I still don't understand what you are trying to do. Can you please explain it again ?

UKHeliBob:
I still don't understand what you are trying to do. Can you please explain it again ?

Perhaps the title of my topic is the wrong one.
It should have been: "Increment/decrement binary counter by any number"
or perhaps "Control a binary counter with a keypad".

I will explain it again.
My project include an Arduino Mega, a 4/3 keypad and 12 LEDs.
I want to give the keypad keys (number keys) their values and for '*' and '#' an operator function (increment or decrement).
At any time I only want to press two keys, a value key (number keys) and an operator key.
The operator key will either increment or decrement the binary counting (displayed on LEDs) by the
value of the number key pressed.
Hope this is clear.
I had a look at the increment/decrement operators but coudn't find
how to increase the counting by 3 for example.
In my case I want to use all the numbers from 1 to 10.
Need your help.
Regards

How to increase a variable called number by 3

number += 3;

http://arduino.cc/en/Reference/IncrementCompound

or easier to understand perhaps

number =  number + 3;

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:

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

is equivalent to

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.

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

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.

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

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?

spatula:

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

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.