Go Down

Topic: Shift register to fade LED's on and keep them on until input (Read 2199 times) previous topic - next topic

bob500000

Ok so the loop break out is the following,

    if (justpressed[0]==2){

Break;

}

I need the button to able be pressed at anytime during the loop. Which then jumps to the second if, but if the button is pressed three times it sets the value back to 0 hence starting the cycle again.

Can you simplify the code for a double press, I have re-engineered that code from one that I use to control buttons on a wave shield.

Thanks for your help mike :)

Grumpy_Mike

Quote
I need the button to able be pressed at anytime during the loop.

If you need this then you need to be able to break out of a loop from a command in the interrupt service routine. You can not do this. You can only jump out of a loop when you check something and if you are going to check the state of the flag of the switches you might as well check the switches at the same time.

Now what you need to do is to write the whole program as a state machine, using the blink without delay technique. Look at that technique, it is as simple as it can get. Then grow it to cover your sequence.

So what you do it look at the milis timer and decide what you want to do next to advance the sequence, to look at the switches and so on.

As a final point you are altering the brightness of the LEDs by applying PWM to the shift register's output enable. This will always change the brightness of all the LEDs that are on, that is all the LEDs that have a one in the shift register. All the other LEDs will be off. So I think you can not get what you want with your current hardware setup. As I understand it you want one LED to fade up with some of the others being on and the rest being off.

bob500000

That is correct, I have 4 LEDs which need lighting up one at a time, these stay on but once it receives the interrupt from the button it shifts to the opposite and starts the loop with the last 4 LEDs each one fading up at a time.

If this is not possible, can you send me a wiring diagram to achieve what I need.

Grumpy_Mike

You can do this with software by using the shiftpwm library:-
http://www.elcojacobs.com/shiftpwm/

If you want to do it with hardware then you need another chip. There are lots of chips you can use for this but it is extra expense and some of the chips are surface mount only so you need good soldering skills.

bob500000

ok so an update, thanks for you advice, everything is running swimmingly although I do ask for your help once again.

So have two buttons that both need the option to be pressed twice, what I am after is setting a shift register to run the LSB outputs which produces 4 led's lit, then pressing the same button runs the method for MSB outputs to be lit, the things is I have set a boolean value to show when the button is pressed and when its not but can't for the life of me work out why its not doing what I want.

Do you have any ideas?

Heres my code so far.

Cheers :)

Code: [Select]
#include <Button.h>

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
int outputEnablePin = 3;
//Button trigger = Button(2,LOW);

byte leds = 0;
byte button[] = {2, 8, 9};
byte switch_value = 0;
boolean btnOn;

#define NUMBUTTONS sizeof(button)
byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

void setup() {
  setBrightness(0);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT);
  //pinMode(2,INPUT); //Trigger switch sits on pin 2
  Serial.begin(9600);
  Serial.println("Welcome");
  byte i;
 
   for (i=0; i< NUMBUTTONS; i++) {
    pinMode(button[i], INPUT);
    digitalWrite(button[i], HIGH);
  }
    //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;
}
//byte pressCount1 = 0;
SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  byte index;

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(button[index]);   // read the button
    /*   
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
   
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
          //switch_value = switch_value + 1;

      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {

/////////////////////////////////////////////////////
//This is Button 1 Press
/////////////////////////////////////////////////////
if (justpressed[0]) {
  button1();
  btnOn = true;
  justpressed[0] = 0;
  }
/////////////////////////////////////////////////////
//This is Button 2 Press
/////////////////////////////////////////////////////
 
if (justpressed[1]) {
  button2();
  //btnOn = false;
justpressed[1] = 0;
  }
 
/////////////////////////////////////////////////////
//This is Button 1 Pressed Twice
////////////////////////////////////////////////////
if (justpressed[0] && (btnOn == true)) { 
  button2();
justpressed[0] = 0;
switch_value = 0;
}
/////////////////////////////////////////////////////
//This is Button 2 Pressed Twice
////////////////////////////////////////////////////
btnOn=false;
}
   

void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);// Change the start LED to 1
   digitalWrite(latchPin, HIGH);
}

void updateShiftRegister2()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, leds);// Change the start LED to 8
   digitalWrite(latchPin, HIGH);
}

void setBrightness(byte brightness) // 0 to 255
{
  analogWrite(outputEnablePin, 255-brightness);
}

void button1(){
  for (int i = 0; i < 4; i++)
  {
    bitSet(leds, i);
    updateShiftRegister();
    delay(50);
    for (byte b = 0; b < 255; b++)
  {
    setBrightness(b);
    delay(20);
  }
  if (justpressed[1]) {
  break;
  }
  }
  //bitSet(leds,0);
  //delay(1000);
   
leds = 0;
   //switch_value = 0;
  setBrightness(255);
}

void button2(){
for (int i = 0; i < 4; i++)
  {
    bitSet(leds, i);
    updateShiftRegister2();
    delay(50);
    for (byte b = 0; b < 255; b++)
  {
    setBrightness(b);
    delay(20);
  }
  if (justpressed[0]) {
  break;
  }
  }
  //bitSet(leds,0);
  //delay(1000);
   
leds = 0;
   //switch_value = 0;
  setBrightness(255);
}

Grumpy_Mike

Quote
but can't for the life of me work out why its not doing what I want.

It would help with a better description of what you want.
There is a difference between a button being pressed and a button being pressed for a second time. You don't seem to be making that distinction on your code, do you need to?
What you want to think of is transitions, to detect a button pressed and button released. I think the just pressed is giving you the wrong thing to think about. It is that you need to detect and use that to trigger what you want to do.

bob500000

Ok

What I am after without it getting too confusing is:

I have 6 buttons, three of which are linked for this example we'll call them group 1 and the other three are linked we'll call them group 2

So by pressing any of group 1 once the LED will light up green

By pressing any of group 2 once the LED will light up red

If i pressed any of group 1 twice it then changes the led to red

if i pressed any of group 2 twice it then changes the led to green.

However as soon as I press any button 3 or more times then the led will go off.

Cheers

Grumpy_Mike

That is clearer, thanks. What you need is a state machine diagram.
http://en.wikipedia.org/wiki/State_diagram
Draw what you want to implement and then just monitor the switches for the appropriate transitions. Having that will make the coding easy. As it is your code is a jumble of logic that won't implement what you want.

Go Up