Pages: [1]   Go Down
Author Topic: Single switch, multiple mode sketch question (answered, video of final product)  (Read 591 times)
0 Members and 1 Guest are viewing this topic.
Houston, Texas
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys, I've never programmed before so I need some advice on this sketch I've created to control 12 leds I'm going to attach to my longboard. Basically it cycles through 10 different modes using a single push button, and then each of the 10 modes has 12 different led configurations based on a hall sensor. My Uno is still in the mail and I've made this sketch while waiting for it to arrive. Any advice on how to simplify this sketch at all would be very nice because it is extremely long as of right now... Actually, I had to cut the last 8 modes in order for it to fit in one post... The last 8 are formatted just like the 2nd mode, just different led configurations.
Here's what I've got:
Code:
//Longboard v.1

const int led0 = 0;
const int led1 = 1;
const int led2 = 2;
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7 = 7;
const int led8 = 8;
const int led9 = 9;
const int led10 = 10;
const int led11 = 11;
const int button = 12;
const int hall = 13;

boolean lastButton = LOW;
boolean currentButton = LOW;
int ledMode = 0;

boolean lastHall = LOW;
boolean currentHall = LOW;
int hallMode = 0;

void setup()
{
  pinMode(hall, INPUT);
  pinMode(button, INPUT);
  pinMode(led0, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(led9, OUTPUT);
  pinMode(led10, OUTPUT);
  pinMode(led11, OUTPUT);
}

//debounce for button
boolean debounce(boolean last)
{
  boolean current = digitalRead(button);
  if (last != current)
  {
    delay(5);
    current = digitalRead(button);
  }
  return current;
}

//debounce for hall sensor
boolean debounce2(boolean last2)
{
  boolean current2 = digitalRead(hall);
  if (last2 != current2)
  {
    delay(5);
    current2 = digitalRead(hall);
  }
  return current2;
}

void loop()
{
  
//button tracking
 currentButton = debounce(lastButton);
 
 if (lastButton == LOW && currentButton = HIGH)
 {
   ledMode = ledMode + 1;
 }
  lastButton = currentButton;
  if (ledMode > 9) ledMode = 0;
  
//hall tracking
  currentHall = debounce2(lastHall);
 
 if (lastHall == LOW && currentHall = HIGH)
 {
   hallMode = hallMode + 1;
 }
  lastHall = currentHall;
  if (hallMode > 11) hallMode = 0;
  
//Mode 0 - All On
  if (ledMode == 0)
  {
    digitalWrite(led0, HIGH);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, HIGH);
    digitalWrite(led8, HIGH);
    digitalWrite(led9, HIGH);
    digitalWrite(led10, HIGH);
    digitalWrite(led11, HIGH);
  }
//Mode 1 - 1 led tracking
  if (ledMode == 1)
  {
    if (hallMode == 0)
    {
      digitalWrite(led0, HIGH);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 1)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, HIGH);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 2)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 3)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, HIGH);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 4)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, HIGH);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 5)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, HIGH);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 6)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, HIGH);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 7)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, HIGH);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 8)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, HIGH);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 9)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, HIGH);
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 10)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, HIGH);
      digitalWrite(led11, LOW);
    }
    if (hallMode == 11)
    {
      digitalWrite(led0, LOW);
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);
      digitalWrite(led7, LOW);
      digitalWrite(led8, LOW);
      digitalWrite(led9, LOW);
      digitalWrite(led10, LOW);
      digitalWrite(led11, HIGH);
    }
  }
« Last Edit: February 01, 2013, 01:01:23 am by abecks44 » Logged

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


Code:
const int led0 = 0;
const int led1 = 1;
const int led2 = 2;
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7 = 7;
const int led8 = 8;
const int led9 = 9;
const int led10 = 10;
const int led11 = 11;
const int button = 12;
const int hall = 13;
One array == 13 lines of code. I'm willing to bet, without even looking, that the rest of your code would shrink a similar amount. (I lied; I looked; it would,)
Logged

Houston, Texas
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have no idea how an array works, so any chance you could help me out with the format of the array I would use for this code?
Oh, and will the debounce functions I made work? Do I even need one for a hall sensor?
« Last Edit: January 31, 2013, 06:04:33 pm by abecks44 » Logged

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

http://arduino.cc/en/Reference/Array
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 109
Posts: 4061
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My first thought was to suggest holding the LED patterns in a byte array (on or off) and to run through them with a for loop turning the LEDs on or off as appropriate.  The array would need to be 3 dimensional, one dimension is the hall number, a second the mode number of the LED pattern and the third the pattern itself.  You would then only need one function to set the LEDs to any pattern defined by the array.  Call it with a hall number and mode number as a parameters and it will do its stuff.

BUT !!!!!!

Have you got enough memory to do that ?

An alternative approach would be to hold the LED patterns as bit patterns in an array which would save a considerable amount of space but could work in a similar way.  I look forward to seeing other suggestions.

Where does the Hall sensor come into this.  Does it pick up the speed of rotation of the wheels, which seems likely ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Offline Offline
Newbie
*
Karma: 1
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How about something like

Code:
int curMode = 0;
int curHallMode = 0;
unsigned int pattern = 0;
/* assumes LED1 is on pin 2 ... LED12 is on pin 13 */
int pinOffset = 2;

// Each mode has 12 patterns selected by hall mode, correct?                   
// So each 3 represents a pattern                                               
const unsigned int modes[][12] = {
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
    {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,},
};

int getMode() {
    // read the button, return the mode                                         
    return 0;
}

int getHallMode() {
    // read the hall sensor, return the hall mode                               
    return 0;
}

void setup() {
    // ins and outs                                                             
}

void loop() {
    curMode = getMode();
    curHallMode = getHallMode();
    pattern = modes[curMode][curHallMode];
    for (int i=0; i<12; i++)
digitalWrite(i + pinOffset, pattern >> i & 0x0001);
}


The patterns wont be visual at all as they are represented by integers. You could use bit fields but that would just complicate matters. Strings could be used to store the patterns "010001010001" but then you'd have to manipulate that string to write to the LEDs.
Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You seem curious, continue to be so ...

As alluded to by PaulS things could be made more compact and easier to read.

Minimal changes to your code (many more improvements possible).

Code:
// <http://arduino.cc/forum/index.php/topic,146206.msg1098539.html#new>

#define ENTRIES(ARRAY)      (sizeof(ARRAY) / sizeof(ARRAY[0]))


const uint8_t   pinLED_00       =  0;
const uint8_t   pinLED_01       =  1;
const uint8_t   pinLED_02       =  2;
const uint8_t   pinLED_03       =  3;
const uint8_t   pinLED_04       =  4;
const uint8_t   pinLED_05       =  5;
const uint8_t   pinLED_06       =  6;
const uint8_t   pinLED_07       =  7;
const uint8_t   pinLED_08       =  8;
const uint8_t   pinLED_09       =  9;
const uint8_t   pinLED_10       = 10;
const uint8_t   pinLED_11       = 11;

const uint8_t   pinBUTTON       = 12;
const uint8_t   pinSENSOR_HALL  = 13;

const uint8_t   pinsLED[]       =
{
      pinLED_11, pinLED_10, pinLED_09, pinLED_08
    , pinLED_07, pinLED_06, pinLED_05, pinLED_04
    , pinLED_03, pinLED_02, pinLED_01, pinLED_00
};


uint8_t modeHall                = 0;
uint8_t stateHallThen           = LOW;

uint8_t modeLED                 = 0;
uint8_t stateButtonThen         = LOW;


void setPattern(uint16_t pattern)
{
    for ( int i = ENTRIES(pinsLED); i--; pattern >>= 1 )
    {
        digitalWrite(pinsLED[i], ((pattern & 1) ? HIGH : LOW));
    }
}

uint8_t debounceButton(uint8_t stateThen)
{
    uint8_t state = digitalRead(pinBUTTON);
    if ( stateThen != state )
    {
        delay(5UL);
        state = digitalRead(pinBUTTON);
    }

    return state;
}

boolean debounceHall(boolean stateThen)
{
    uint8_t state = digitalRead(pinSENSOR_HALL);
    if ( stateThen != state )
    {
        delay(5UL);
        state = digitalRead(pinSENSOR_HALL);
    }

    return state;
}

void loop()
{
    // button tracking

    uint8_t stateButton = debounceButton(stateButtonThen);
    if ( (stateButtonThen == LOW) && (stateButton == HIGH) )
    {
        modeLED += 1;
    }

    stateButtonThen = stateButton;
    if ( modeLED > 9 )
    {
        modeLED = 0;
    }


    // hall tracking

    uint8_t stateHall = debounceHall(stateHallThen);
    if ( (stateHallThen == LOW) && (stateHall == HIGH) )
    {
        modeHall += 1;
    }

    stateHallThen = stateHall;
    if ( modeHall > 11 )
    {
        modeHall = 0;
    }

    // Mode 0 - All On

    if ( modeLED == 0 )
    {
        setPattern(0b0000111111111111);
    }

    // Mode 1 - 1 pinLED_ tracking
    if ( modeLED == 1 )
    {
        const uint16_t  pattern[] =
        {
              0b0000000000000001
            , 0b0000000000000010
            , 0b0000000000000100
            , 0b0000000000001000
            , 0b0000000000010000
            , 0b0000000000100000
            , 0b0000000001000000
            , 0b0000000010000000
            , 0b0000000100000000
            , 0b0000001000000000
            , 0b0000010000000000
            , 0b0000100000000000
        };

        setPattern(pattern[modeHall]);
    }
}

void setup()
{
    pinMode(pinSENSOR_HALL, INPUT);
    pinMode(pinBUTTON, INPUT);

    for (int i = ENTRIES(pinsLED); i--; )
    {
        pinMode(pinsLED[i], OUTPUT);
    }
}
« Last Edit: January 31, 2013, 11:31:02 pm by lloyddean » Logged

Houston, Texas
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for all the feedback guys, I actually just got my Uno a while ago, and now I'm going to spend the next couple hours trying to get this thing to work, but i still don't have the hall sensor yet... It seems like everyone is agreeing on the array thing, so I'm going to try and hopefully learn to do those.. And yes, the hall sensor is to get a gauge of how fast the board is moving. The whole point of the led patterns set the way they are is to get the effect of the leds being stationary over a single point over the ground while the board is actually moving.

Thanks for the help so far and keep posting array codes so I can try them out and learn how they work!

Oh, and lloyddean, the code you posted cycles through the 10 modes correctly, but it seems to be completely disregarding the hall sensor. I have the Uno hooked up to a breadboard of 12 leds and on mode 0 every led is on just like I wanted. Then on mode 1 just the first led is on just as I wanted as well, but when I push the hall sensor (it's currently a button b/c I don't have the actual hall sensor yet) nothing changes. Just that one led remains on.
If someone can find the problem with this I think I can build the rest of the modes myself, some help with this problem would be huge!

I also just noticed that when I press the hall button on any mode, the built in led turns on. I know the built in led is hooked up to pin 13 by default, but I'm still unsure if this is supposed to happen so I thought I'd include it.
« Last Edit: January 31, 2013, 11:30:13 pm by abecks44 » Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My mistake, as usual when I'm tired ...

Maybe fixed above.
Logged

Houston, Texas
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My mistake, as usual when I'm tired ...

Maybe fixed above.

Yeah, that did the trick! Works exactly the way I wanted, thank you sooo much. I'm going to get to work trying to code the rest of the modes now, thanks again.
Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great, your code going forward.
Logged

Houston, Texas
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I finished making all of the modes way faster than I thought I was, thanks for that code again lloyd. I thought I'd show you guys how it's working, so here's a video smiley-grin

Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
setPattern(0b0000111111111111);

Ah, I didn't realize you could use that syntax. I found the B01010010 syntax, but it said it was only good for a byte.

abecks44, it says your video is private.
Logged

Pages: [1]   Go Up
Jump to: