controlling led state?

I have a (working) program which sends a midi signal and illumates 1 of 4 leds. I want one of them to act independantly, switching on for the first press, then off for the second, so I can tell if overdub is triggered.

The new (problem) code is lines 74-81 (case 1), where ovrLED should store the state and act accordingly. However, it switches the light on, then it stays on.

I hope this makes sense?

// midi controller for line 6 M13 to control looper
// dec 2018

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#define SWITCH1 2 //rec
#define SWITCH2 3 // stop/OD
#define SWITCH3 4 // play
#define SWITCH4 5 // stop
# define LED1 8
# define LED2 9
# define LED3 7
# define LED4 6

#define SWITCHES 4    // how many switches?
#define BOUNCEDELAY 100
int switches[SWITCHES] = { SWITCH1, SWITCH2, SWITCH3, SWITCH4 };
int switchState[SWITCHES] = { HIGH, HIGH, HIGH, HIGH };   // Initial state of switch is high due to internal pullup
int leds[SWITCHES] = { LED1, LED2, LED3, LED4 };
int currentSwitch = 0;
int thisLed = 0;
int activeLed = 0;
int ovrLED = 0;
int currentProgram = 22;   // current program - sent to the output

void setup()
{
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  MIDI.begin(1);
  // Setup Switches and activation LEDs
  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    pinMode( switches[currentSwitch], INPUT );          // Set pin for switch
    digitalWrite( switches[currentSwitch], HIGH );      // Turn on internal pullup
    pinMode( leds[currentSwitch], OUTPUT );             // Set pin for LED
  }

  for ( int i = 0; i < 4; i++ )
  {
    for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
    {
      digitalWrite( leds[thisLed], HIGH );
      delay(100);
      digitalWrite( leds[thisLed], LOW );
    }
  }

}

void loop()
{

  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    if ( (digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH) )
    {
      switch ( currentSwitch )
      {
        case 0:
          MIDI.sendControlChange(50, 122, 1); // rec
          lightPin(currentSwitch);
          break;
        case 1:
          MIDI.sendControlChange(50, 10, 1);  // overdub
          if (ovrLED == 0 ) {
            lightPin(currentSwitch );
            ovrLED = 1;
          }
          else              {
            analogWrite(currentSwitch, 0);
            ovrLED = 0;
          }
          break;
        case 2:
          MIDI.sendControlChange(28, 122, 1); // play
          lightPin(currentSwitch );
          break;
        case 3:
          MIDI.sendControlChange(28, 22, 1); // stop
          lightPin(currentSwitch );
          break;
      }
      delay( BOUNCEDELAY );
    }
    switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
  }
}

void lightPin( int activeLed )    // switch chosen LED on, others off
{
  for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
  {
    if (activeLed == thisLed)
    {
      digitalWrite( leds[thisLed], HIGH );
    }
    else
    {
      digitalWrite( leds[thisLed], LOW );
    }
  }
}

What is the purpose of the analogWrite(currentSwitch, 0)?

Steve

slipstick:
What is the purpose of the analogWrite(currentSwitch, 0)?

Steve

to switch the led off every second time the switch is pressed...

But why analogWrite; in lightPin you use digitalWrite :wink:

Anyway

lightPin loops through the leds array and controls all leds. You’ll need exclude the overdub led from the array. This might imply that you also have to exclude the corresponding switch and switchState from the respective arrays.

That’s the help for now on the subject.

Your leds represent something. I think LED2 is the overdub led. So instead of

#define LED2 9

Use something like

#define LEDOVERDUB 9

No idea what the other leds represent.

sterretje:
But why analogWrite; in lightPin you use digitalWrite :wink:

Anyway

lightPin loops through the leds array and controls all leds. You’ll need exclude the overdub led from the array. This might imply that you also have to exclude the corresponding switch and switchState from the respective arrays.

That’s the help for now on the subject.

Your leds represent something. I think LED2 is the overdub led. So instead of

#define LED2 9

Use something like

#define LEDOVERDUB 9

thanks for the feeedback, have renamed the leds and switchd to digitalwrite, good points.

The idea is the ovrLED status determines if lightpin is called, or if the led is simply to be switched off? I’ve added remarks to show my logic(!)

// midi controller for line 6 M13 to control looper
// dec 2018

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#define recSWITCH 2 //rec
#define ovrSWITCH 3 // stop/OD
#define playSWITCH 4 // play
#define stopSWITCH 5 // stop
# define recLED 8
# define ovrLED 9
# define playLED 7
# define stopLED 6

#define SWITCHES 4    // how many switches?
#define BOUNCEDELAY 100
int switches[SWITCHES] = { recSWITCH, ovrSWITCH, playSWITCH, stopSWITCH };
int switchState[SWITCHES] = { HIGH, HIGH, HIGH, HIGH };   // Initial state of switch is high due to internal pullup
int leds[SWITCHES] = { recLED, ovrLED, playLED, stopLED };
int currentSwitch = 0;
int thisLed = 0;
int activeLed = 0;
int ovrLEDstatus = 0;
// int currentProgram = 22;   // current program - sent to the output

void setup()
{
  pinMode(recLED, OUTPUT);
  pinMode(ovrLED, OUTPUT);
  pinMode(playLED, OUTPUT);
  pinMode(stopLED, OUTPUT);
  MIDI.begin(1);
  // Setup Switches and activation LEDs
  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    pinMode( switches[currentSwitch], INPUT );          // Set pin for switch
    digitalWrite( switches[currentSwitch], HIGH );      // Turn on internal pullup
    pinMode( leds[currentSwitch], OUTPUT );             // Set pin for LED
  }

  for ( int i = 0; i < 4; i++ ) // startup flashes
  {
    for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
    {
      digitalWrite( leds[thisLed], HIGH );
      delay(100);
      digitalWrite( leds[thisLed], LOW );
    }
  }

}

void loop()
{

  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    if ( (digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH) )
    {
      switch ( currentSwitch )
      {
        case 0:
          MIDI.sendControlChange(50, 122, 1); // rec
          lightPin(currentSwitch);
          break;
        case 1:
          MIDI.sendControlChange(50, 10, 1);  // overdub
          if (ovrLEDstatus == 0 ) {
            lightPin(currentSwitch ); // light up overled
            ovrLEDstatus = 1; // store that overled is on
          }
          else              {
            digitalWrite(currentSwitch, LOW); // switch overdub LED off
            ovrLEDstatus = 0; // switch overled status
          }
          break;
        case 2:
          MIDI.sendControlChange(28, 122, 1); // play
          lightPin(currentSwitch );
          break;
        case 3:
          MIDI.sendControlChange(28, 22, 1); // stop
          lightPin(currentSwitch );
          break;
      }
      delay( BOUNCEDELAY );
    }
    switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
  }
}

void lightPin( int activeLed )    // switch chosen LED on, others off
{
  for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
  {
    if (activeLed == thisLed)
    {
      digitalWrite( leds[thisLed], HIGH );
    }
    else
    {
      digitalWrite( leds[thisLed], LOW );
    }
  }
}

switching on for the first press, then off for the second,

You need to detect when the press occurs rather than its current state. Have a look at the StateChangeDetection example in the IDE

UKHeliBob:
You need to detect when the press occurs rather than its current state. Have a look at the StateChangeDetection example in the IDE

I will look into this, thanks. But shouldn't the state should reflect each press, then follow the if/else? I'm using the principle from this page

Solved it - the variable wasn't containing what I thought it would

digitalWrite(currentSwitch, LOW);

should have been

digitalWrite(ovrLED, LOW); // switch overdub LED off

Now I’d like the led to blink instead of staying on, but I can’t see how to operate the blink loop while the code is still scanning for a new footswitch press? Can I make a subroutine start blinking then go back to the flow of code?

Thanks for any help…

Refer to the first pinned post on the 'project guidance' topic.

nickrobinson:
Now I’d like the led to blink instead of staying on, but I can’t see how to operate the blink loop while the code is still scanning for a new footswitch press? Can I make a subroutine start blinking then go back to the flow of code?

Thanks for any help…

Have a look at Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.

dougp:
Refer to the first pinned post on the ‘project guidance’ topic.

Thanks for this and I’m sorry to try your patience but it seems to be taking a quantum leap for a solution and I can’t post in that thread.

My thinking is that all I need to do is take the blink out of the loop that waits for a switch press, then use a variable to decide whether to blink (once) or not. As the main loop executes, it should keep blinking. The variable is ovrLEDstatus and using print satements, I can see that this indeed switching between 1 and 0 with a footpress. However, the blink code inside the if statement has no effect.

// midi controller for line 6 M13 to control looper
// dec 2018

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#define recSWITCH 2 //rec
#define ovrSWITCH 3 // stop/OD
#define playSWITCH 4 // play
#define stopSWITCH 5 // stop
# define recLED 8
# define ovrLED 9
# define playLED 7
# define stopLED 6

#define SWITCHES 4    // how many switches?
#define BOUNCEDELAY 100
int switches[SWITCHES] = { recSWITCH, ovrSWITCH, playSWITCH, stopSWITCH };
int switchState[SWITCHES] = { HIGH, HIGH, HIGH, HIGH };   // Initial state of switch is high due to internal pullup
int leds[SWITCHES] = { recLED, ovrLED, playLED, stopLED };
int currentSwitch = 0;
int thisLed = 0;
int activeLed = 0;
int ovrLEDstatus = 0;
// int currentProgram = 22;   // current program - sent to the output

void setup()
{
  pinMode(recLED, OUTPUT);
  pinMode(ovrLED, OUTPUT);
  pinMode(playLED, OUTPUT);
  pinMode(stopLED, OUTPUT);
  MIDI.begin(1);
  // Setup Switches and activation LEDs
  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    pinMode( switches[currentSwitch], INPUT );          // Set pin for switch
    digitalWrite( switches[currentSwitch], HIGH );      // Turn on internal pullup
    pinMode( leds[currentSwitch], OUTPUT );             // Set pin for LED
  }

  for ( int i = 0; i < 4; i++ ) // startup flashes
  {
    for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
    {
      digitalWrite( leds[thisLed], HIGH );
      delay(100);
      digitalWrite( leds[thisLed], LOW );
    }
  }
  Serial.begin(9600);      // open the serial port at 9600 bps:
}


void loop()
{
  //Serial.print("led  is ");       Serial.println(ovrLEDstatus);

  if (ovrLEDstatus)  // blink once if set
  {
    digitalWrite( ovrLED, HIGH );
    delay(200);
    digitalWrite( ovrLED, LOW );
  }
// then proceed to loop waiting for foot switch presses
  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    if ( (digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH) )
    {
      switch ( currentSwitch )
      {
        case 0:
          MIDI.sendControlChange(50, 122, 1); // rec
          lightPin(currentSwitch);
          break;
        case 1:
          MIDI.sendControlChange(50, 10, 1);  // overdub
          if (ovrLEDstatus == 0 ) {
            lightPin(currentSwitch ); // light up overled
            ovrLEDstatus = 1; // store that overled is on
          }
          else              {
            digitalWrite(ovrLED, LOW); // switch overdub LED off
            ovrLEDstatus = 0; // switch overled status
          }
          break;
        case 2:
          MIDI.sendControlChange(28, 122, 1); // play
          lightPin(currentSwitch );
          break;
        case 3:
          MIDI.sendControlChange(28, 22, 1); // stop
          lightPin(currentSwitch );
          break;
      }
      delay( BOUNCEDELAY );
    }
    switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
  }
}

void lightPin( int activeLed )    // switch chosen LED on, others off
{
  for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
  {
    if (activeLed == thisLed)
    {
      digitalWrite( leds[thisLed], HIGH );
    }
    else
    {
      digitalWrite( leds[thisLed], LOW );
    }
  }
}

void intro ()
{
  for ( int i = 0; i < 4; i++ ) // startup flashes
  {
    for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
    {
      digitalWrite( leds[thisLed], HIGH );
      delay(100);
      digitalWrite( leds[thisLed], LOW );
    }
  }
}

Put the blink code in a function and call it from loop() only if ovrLEDstatus is 1

Use the BWoD principle in the blink function

UKHeliBob:
Put the blink code in a function and call it from loop() only if ovrLEDstatus is 1

OK, will look into that, but I don't understand why doesn't the current if statement do the same? The code blinks merrily with the other code removed...

A simple solution - I hadn't set a delay after led out, so it was working! The only issue is that the longer the blink delay, the more the "read switch" code is slowed down and the less sensitive the footswitch is, so it flashes fairly quickly :wink:

Thanks for all your help - it's been a massive learning curve but I feel empowered!

The only issue is that the longer the blink delay, the more the "read switch" code is slowed down and the less sensitive the footswitch is,

Solution : use millis() for timing instead of delay()