Couple of Questions - Programing

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
meseta
 
Posts: 82
Joined: Tue Aug 02, 2011 7:57 pm

Re: Couple of Questions - Programing

Post by meseta »

Hi Reinhart,

It looks like you can replace the If/Elseif block of code with a Switch/case block, which looks something like this:

Code: Select all

switch(case)
{
case 1:
digitalWrite(ledPin5, HIGH);
digitalWrite(ledPin6, LOW);
digitalWrite(ledPin7, LOW);
break;
case 2:
...
break;
...
...
..
}
Switch/case are a perfect replacement for a long if/elseif chain.

However, if you're looking to reduce the amount of code, then writing a function to set the pins based on an input number would remove the need for the if/elseif/switch/case block altogether. The function would look something like this (I'm not 100% sure on the function syntax Arduino is expecting, so this might not be quite right)

Code: Select all

void pinoutput(int count)
{
digitalWrite(ledPin1, count & 0b1);
digitalWrite(ledPin2, (count >> 1) & 0b1);
digitalWrite(ledPin3, (count >> 2) & 0b1);
digitalWrite(ledPin4, (count >> 3) & 0b1);
}
Basically all variables are stored as binary anyway, so to light up some LEDs in a binary sequence would best be done by simply reading the raw binary values stored rather than writing code to handle a binary conversion as you have done. To do this I have employed some binary operations to the variable, let me know if any of the following doesn't make sense to you, I will try to explain in more detail, for now I will assume you know a little about binary and binary operations.

I left-shift the bits so that the bit that I am interested in is in the LSB position. For example for the 2nd pin, I'm interested in the 2nd bit of the variable count. By doing (count >> 1), the 2nd bit of the variable ends up in the lowest position (after being left-shifted once); if count = 5, then the binary would have been 0b0101, after being left-shifted, it would be 0b0010, (the lowest bit drops off the end, I'm only showing 4 bits of the int here, the rest should be zeros).

Then because digitalWrite() expects a 1 or 0 (HIGH or LOW), I mask out all the other bits using a binary AND operation, for example the 0b0010 from before, we're really only interested in the last bit, not the other bits. so doing (count >> 1) & 0b1; effectively sets all bits other than the LSB to zero.

The final code looks something like this:

Code: Select all

/*
* count
*
* This is another basic Arduino example. It
* uses 7 led's to count from 0 to 9 in binary
* on the first 4 pins, and counts from 0 to 5
* in binary on the last 3 pins. It also outputs
* the number of the last 3 pins to the serial port.
*/

int ledPin1 = 7;
int ledPin2 = 6;
int ledPin3 = 5;
int ledPin4 = 4;
int ledPin5 = 8;
int ledPin6 = 9;
int ledPin7 = 10;
int count = 0;
int i;

void setup()
{
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
    pinMode(ledPin3, OUTPUT);
    pinMode(ledPin4, OUTPUT);
    pinMode(ledPin5, OUTPUT);
    pinMode(ledPin6, OUTPUT);
    pinMode(ledPin7, OUTPUT);
    Serial.begin(9600);
    Serial.println(count);
}

void loop()
{
    for(i=0;i<10;i++)
    {
    digit1output(i);
    delay(1000);
    }

    count = ++count;
    if(count > 5) {
    count = 0;
    }
    digit2output(i);

    Serial.println(count);
}

void digit1output(int count)
{
    digitalWrite(ledPin1, count & 0b1);
    digitalWrite(ledPin2, (count >> 1) & 0b1);
    digitalWrite(ledPin3, (count >> 2) & 0b1);
    digitalWrite(ledPin4, (count >> 3) & 0b1);
}

void digit2output(int count)
{
    digitalWrite(ledPin5, count & 0b1);
    digitalWrite(ledPin6, (count >> 1) & 0b1);
    digitalWrite(ledPin7, (count >> 2) & 0b1);
}
However, you can do one better than this, you could use some mathematics to turn a number between 0 and 59 into two numbers to separately represent the tens and the units:

Code: Select all

/*
* count
*
* This is another basic Arduino example. It
* uses 7 led's to count from 0 to 9 in binary
* on the first 4 pins, and counts from 0 to 5
* in binary on the last 3 pins. It also outputs
* the number of the last 3 pins to the serial port.
*/

int ledPin1 = 7;
int ledPin2 = 6;
int ledPin3 = 5;
int ledPin4 = 4;
int ledPin5 = 8;
int ledPin6 = 9;
int ledPin7 = 10;
int count = 0;

void setup()
{
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
    pinMode(ledPin3, OUTPUT);
    pinMode(ledPin4, OUTPUT);
    pinMode(ledPin5, OUTPUT);
    pinMode(ledPin6, OUTPUT);
    pinMode(ledPin7, OUTPUT);
    Serial.begin(9600);
    Serial.println(count);
}

void loop()
{
    count++;
    if(count > 59) {
        count = 0;
    }
    twodigit(count);
    delay(1000);
}

void twodigit(int count)
{
    int tens, units;
    units = count % 10;
    tens = (count - digit2)/10
    
    digitalWrite(ledPin1, units & 0b1);
    digitalWrite(ledPin2, (units >> 1) & 0b1);
    digitalWrite(ledPin3, (units >> 2) & 0b1);
    digitalWrite(ledPin4, (units >> 3) & 0b1);
    
    digitalWrite(ledPin5, tens & 0b1);
    digitalWrite(ledPin6, (tens >> 1) & 0b1);
    digitalWrite(ledPin7, (tens >> 2) & 0b1);
    
    Serial.println(tens);
}
The units can be found by doing a modulo 10 on count using count % 10; this gives the remainder after count is divided by 10. Then subtracting this from count gives a value that is exactly divisible by 10 - dividing that by 10 gives an exact value representing the tens. (You could of course directly divide count by 10, but I don't remember if the value got rounded up or down, this way is a bit clearer.

hope this helps!

Disclaimer: I am not an Arduino expert, I have almost never used the Arduino, so some of my syntax might not be correct. My experience is in PICs and ARM, but code is in C all the same.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”