USB shield does nothing until Arduino Digital inputs toggle several times. Why?

I’ve got a set of a few choices serial outputs being sent through a Keyes USB shield based on digital inputs on the arduino (various button presses). This works and works well BUT… it takes a bunch of button presses to get this thing to begin working. After it’s online, it works perfectly. But… why is it that I have to press buttons when I first turn it on for 20 seconds or so until it becomes active? It can be on for 2 hours but if no buttons are pressed it doesn’t start working. I’d prefer it work right away. Any tips would be appreciated!!

// #include <Usb.h>
// #include <usbhub.h>
#include <usbh_midi.h>
// #include <SoftPWM.h>

USB Usb;
USBH_MIDI Midi(&Usb);

byte Preset;

//Input pin declaration
int inPin1 = 2; // patch selection switch 1
int inPin2 = 3; // patch selection switch 2
int inPin3 = 4; // patch selection switch 3
int inPin4 = 5; // patch selection switch 4
int inPin5 = 6; // bank selection switch

// Output pin declaration
int outPin1 = 14; //indicator for patch 1/5
int outPin2 = 15; //indicator for patch 2/6
int outPin3 = 16; //indicator for patch 3/7
int outPin4 = 17; //indicator for patch 4/8
int outPinErr = 18; // ERROR - SOMETHING WRONG 

//BYPASS
byte PatchOff = 0x00; // Zoom A0 Bypass

//REVERBS and Chorus
byte PatchA1 = 0x01;  // Zoom A1 Less Verb
byte PatchB1 = 0x02;  // Zoom A2 Med Verb
byte PatchC1 = 0x03;  // Zoom A3 Max Verb
byte PatchD1 = 0x04;  // Zoom A4 Chorus Verb

//Chorus, VIBE, Trem
byte PatchA2 = 0x05;  // Zoom A5 Chorus
byte PatchB2 = 0x06;  // Zoom A6 Vibe
byte PatchC2 = 0x07;  // Zoom A7 Slow Trem
byte PatchD2 = 0x08;  // Zoom A8 Fast Trem

// byte PatchA3 = 0x27;  // Zoom D9
// byte PatchB3 = 0x28;  // Zoom E0
// byte PatchC3 = 0x29;  // Zoom E1
// byte PatchD3 = 0x2A;  // Zoom E2

//Current state of output pins
int state1 = LOW;
int state2 = LOW;
int state3 = LOW;
int state4 = LOW;


//Current reading from the input pins
int reading1 = HIGH;
int reading2 = HIGH;
int reading3 = HIGH;
int reading4 = HIGH;
int reading5 = HIGH;

// Previous reading from the input pins
int previous1 = LOW;
int previous2 = LOW;
int previous3 = LOW;
int previous4 = LOW;

// DEBOUNCE SEQUENCE ---
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 300;   // the debounce time, increase if the output flickers


// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button



void setup()
{
  pinMode(inPin1, INPUT_PULLUP);
  pinMode(inPin2, INPUT_PULLUP);
  pinMode(inPin3, INPUT_PULLUP);
  pinMode(inPin4, INPUT_PULLUP);
  pinMode(inPin5, INPUT_PULLUP);
  pinMode(outPin1, OUTPUT);
  pinMode(outPin2, OUTPUT);
  pinMode(outPin3, OUTPUT);
  pinMode(outPin4, OUTPUT);
  pinMode(outPinErr, OUTPUT);

  pinMode( 7, OUTPUT);  // For the sheild
  digitalWrite( 7, HIGH); // for the sheild

  if (Usb.Init() == -1)
  {
  digitalWrite(outPinErr, HIGH);
    while(1);               // Halt
  }
  delay(200);
  Preset = 1;
  
}

void loop()
{

  // read the pushbutton input pin:
  buttonState = digitalRead(inPin5);
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
  // if the state has changed, increment the counter
  if (buttonState == LOW) {
      // if the current state is LOW then the button went from off to on:
    buttonPushCounter++;
    // Delay a little bit to avoid bouncing
    delay(debounce);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
  }
  
  reading1 = digitalRead(inPin1);
  reading2 = digitalRead(inPin2);
  reading3 = digitalRead(inPin3);
  reading4 = digitalRead(inPin4);
//  reading5 = digitalRead(inPin5);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  {
    if (reading1 == LOW && previous1 == HIGH && millis() - time > debounce) {
      if (state1 == HIGH)
      {
        // Send program change for BYPASS / no effect
        SendMIDI(PatchOff);
        state1 = LOW;
      }
      else
      {
        //if (reading5 == HIGH)

         if (buttonPushCounter % 2 == 0) 
        {
          // Send program change for EFFECT - 1
          SendMIDI(PatchA1);
          state1 = HIGH;
          state2 = LOW;
          state3 = LOW;
          state4 = LOW;
        }
        else
        {
          // Send program change for EFFECT - 5
          SendMIDI(PatchA2);
          state1 = HIGH;
          state2 = LOW;
          state3 = LOW;
          state4 = LOW;
        }
      }
      time = millis();
    }
    digitalWrite(outPin1, state1);
    digitalWrite(outPin2, state2);
    digitalWrite(outPin3, state3);
    digitalWrite(outPin4, state4);
    previous1 = reading1;
  }
  {
    if (reading2 == LOW && previous2 == LOW && millis() - time > debounce) {
      if (state2 == HIGH)
      {
        // Send program change for BYPASS / no effect
        SendMIDI(PatchOff);
        state2 = LOW;
      }
      else
      {
        // if (reading5 == HIGH)
         if (buttonPushCounter % 2 == 0) 
        {
          // Send program change for EFFECT - 2
          SendMIDI(PatchB1);
          state1 = LOW;
          state2 = HIGH;
          state3 = LOW;
          state4 = LOW;
        }
        else
        {
          // Send program change for EFFECT - 6
          SendMIDI(PatchB2);
          state1 = LOW;
          state2 = HIGH;
          state3 = LOW;
          state4 = LOW;
        }
      }
      time = millis();
    }
    digitalWrite(outPin1, state1);
    digitalWrite(outPin2, state2);
    digitalWrite(outPin3, state3);
    digitalWrite(outPin4, state4);
    previous2 = reading2;
  }
  {
    if (reading3 == LOW && previous3 == LOW && millis() - time > debounce) {
      if (state3 == HIGH)
      {
        // Send program change for BYPASS / no effect
        SendMIDI(PatchOff);
        state3 = LOW;
      }
      else
      {
      //  if (reading5 == HIGH)
       if (buttonPushCounter % 2 == 0) 
        {
          // Send program change for EFFECT - 3
          SendMIDI(PatchC1);
          state1 = LOW;
          state2 = LOW;
          state3 = HIGH;
          state4 = LOW;
        }
        else
        {
          // Send program change for EFFECT - 7
          SendMIDI(PatchC2);
          state1 = LOW;
          state2 = LOW;
          state3 = HIGH;
          state4 = LOW;
        }
      }
      time = millis();
    }
    digitalWrite(outPin1, state1);
    digitalWrite(outPin2, state2);
    digitalWrite(outPin3, state3);
    digitalWrite(outPin4, state4);
    previous3 = reading3;
  }
  {
    if (reading4 == LOW && previous4 == LOW && millis() - time > debounce) {
      if (state4 == HIGH)
      {
        // Send program change for BYPASS / no effect
        SendMIDI(PatchOff);
        state4 = LOW;
      }
      else
      {
        //if (reading5 == HIGH)
         if (buttonPushCounter % 2 == 0) 
        {
          // Send program change for EFFECT - 4
          SendMIDI(PatchD1);
          state1 = LOW;
          state2 = LOW;
          state3 = LOW;
          state4 = HIGH;
        }
        else
        {
          // Send program change for EFFECT - 8
          SendMIDI(PatchD2);
          state1 = LOW;
          state2 = LOW;
          state3 = LOW;
          state4 = HIGH;
        }
      }
      time = millis();
    }
    digitalWrite(outPin1, state1);
    digitalWrite(outPin2, state2);
    digitalWrite(outPin3, state3);
    digitalWrite(outPin4, state4);
    previous4 = reading4;
  }
}

// Send "Program Change" MIDI Message

void SendMIDI(byte number)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[2];                 // Construct the midi message (2 bytes)
    Message[0]=0xC0;                 // 0xC0 is for Program Change 
    Message[1]=number;               // Number is the program/patch 
    Midi.SendData(Message);          // Send the message
    delay(10);
  }

  else
  {
    digitalWrite(outPinErr, HIGH);
    delay (500);
    digitalWrite(outPinErr, LOW);
    delay (500);
    digitalWrite(outPinErr, HIGH);
    delay (500);
    digitalWrite(outPinErr, LOW);
    delay (500);
    digitalWrite(outPinErr, HIGH);
    delay (500);
    digitalWrite(outPinErr, LOW);
  }

}

I've got a set of a few choices serial outputs being sent through a Keyes USB shield based on digital inputs on the arduino (various button presses). This works and works well BUT... it takes a bunch of button presses to get this thing to begin working. After it's online, it works perfectly. But... why is it that I have to press buttons when I first turn it on for 20 seconds or so until it becomes active? It can be on for 2 hours but if no buttons are pressed it doesn't start working. I'd prefer it work right away. Any tips would be appreciated!!

I don't know what you mean by "online", this sketch never goes online (on the Internet).
It doesn't do anything by design if no button is pressed, so I really don't know what you think goes wrong.

Describe in detail (step-by-step), what you do and what the reaction is as well as what you expected the system to do.

Did you write that sketch yourself?

Sorry for the confusion there. By 'online' I mean active. The code and hardware are inactive and takes several button presses until something actually sends serial (MIDI) data through the USB Shield. Once it's 'online', it runs as intended. Each button press sends the corresponding MIDI string and all is happy. It's just that for some reason it doesn't do anything initially. There are a bunch of dead button presses until it works as intended.

This sketch is a combination of two existing sketches and some of my own adaptation to better suit my needs. The original sketch also does not become active until several button presses. Not sure why....

What does “several button presses” mean? Does it have to be a strict combination or is any order OK? How many presses does it need?

I think your problem are located in the Usb.Task() method not being called in the loop().

I'm thinking it doesn't have any order to it. Button(s) just have to be pressed a few times and about 20-30 seconds must elapse thereafter before button presses do anything.

So this last section should be moved to the main loop?

void SendMIDI(byte number)
{
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
    byte Message[2];                 // Construct the midi message (2 bytes)
    Message[0]=0xC0;                 // 0xC0 is for Program Change 
    Message[1]=number;               // Number is the program/patch 
    Midi.SendData(Message);          // Send the message
    delay(10);
  }

  else
  {
    digitalWrite(outPinErr, HIGH);
    delay (500);
    digitalWrite(outPinErr, LOW);
    delay (500);
    digitalWrite(outPinErr, HIGH);
    delay (500);
    digitalWrite(outPinErr, LOW);
    delay (500);
    digitalWrite(outPinErr, HIGH);
    delay (500);
    digitalWrite(outPinErr, LOW);
  }

No, just Usb.Taks().

Ahhh! It works. Thank you for your expertise and a good eye!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.