Serial Interrupt for switch

Hi, i was working on a simple project with a led strip, a bluetooth module (HC-06), and one arduino uno, the thing is i want to be able to interrupt the code when i send a serial command, i just wat to change the ledstrip animation on the fly via the command and not wait till the animation does the loop to de function calling the serial.read() if that posible, ill attach the code right here:

SoftwareSerial btMod(2,3);

void mainAnimation() {

  serialBTRead();
  
  if (debugEn == true) {
    
    btMod.println("------------" + String(millis()) + "-------------");
    btMod.println("Serial Available");
    btMod.println(String(btMod.available()));
    btMod.println("btRead");
    btMod.println(btRead);
    btMod.println("AniSel");
    btMod.println(aniSel);
    btMod.println("Actual Serial Read");
    btMod.println(String(btMod.read()));
    btMod.println("--------------------------------------------------");

    pauseLED(3000);
    
  }
  
  
  switch(aniSel) {
    case 'a':
      solidLED();
      break;
    case 'e':
      edgeLED();
      break;
    default:
      testLED();
      break;
  }
  
}

void serialBTRead() {

  delay(50);
  if(btMod.available() > 0) {
    btRead = btMod.read();
    //btMod.write(btRead);
    newData = true;
  }

  //btMod.println(btRead);
  
  if (newData == true) {
    if(btMod.read() != -1) {
      aniSel = btRead;
      EEPROM.write(0, aniSel);
      newData = false;
    } else {
      newData = false;
    }
  }
}

aniSel is declared globaly

I tried to put only the relevant code for the serial BT thing, the code itself if doing what it supposed to do, ill send the command via my phone and change the animation but if the animation is too long ill have to wait till its end, thats why i want to now if there's any way to change it immediately

As an allday analogon:

You can do eating a meal this way:

while (some rice is left on the plate) {
  put fork into rice
  put fork into mouth
  // stops when no more rice is on the plate
}

while (some meat is left on the plate) {
  put fork into meat
  cut a piece of meat with knife
  put fork into mouth
  // stops when no more meat is on the plate
}

while (some limo is left in the glas) {
  take glas to the mouth
  take a sip
  put glas on the table
  // stops when glas is empty
}

But that's not the way you eat

you are doing it like calling functions repeatedly


void some_rice() {
  put fork into rice;
  put fork into mouth;
}

void a_piece_of_meat() {
  put fork into meat
  cut a piece of meat with knife
  put fork into mouth
}

void Take_a_sip() {
  take glas to the mouth
  take a sip
  put glas on the table
}

void loop {
  some_rice();
  a_piece_of_meat();
  Take_a_sip();
}

That is what you can do in coding too

repetated calling of functions
and the 100 times repeated call of a function does the same
as a for-loop

for (int I = 0; i< 100 i++)

only difference the 100 times looping is not done inside a for-loop the

looping is done by function loop itself

That's why it is called "loop"

But this needs a fundamental re-design of the animations

The functions a_piece_of_meat() etc.
do one step per call
= just one piece of meat per call

So your animations must do just one step per call
and after each call you can execute if something was received over the serial interface

So to help you re-designing your code do what you always should do
posting your complete sketch.

Without seeing your functions edgeLED(); etc. it is not possible to give advice how to re-design it.

There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

best regards Stefan

1 Like

Oh thanks didn't know about that option for copying the code, i have little experience with the Arduino IDE and that kind of stuff, so here is the whole code, but i get what your mean with that pretty good, still i attached the code, there's some leftovers because im still testing some stuffs

#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>


const byte ledPin = 9;
const byte stripLeds = 150;
unsigned long time_now = 0;

int globalRed = 0;
int globalGreen = 0;
int globalBlue = 0;

bool iniAni = false;
bool debugEn = false;
bool newData = false;
char aniSel = 'a';
char btRead;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(stripLeds, ledPin, NEO_GRB);
SoftwareSerial btMod(2, 3); //RX-TX

void setup() {

  systemINI();
  offLEDS(0, 149);
  if (iniAni == true) {
    iniAnimation();
    offLEDS(0, 149);
  }

}

void loop() {

  mainAnimation();

}

void systemINI() {

  pinMode(2, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  Serial.begin(9600);
  btMod.begin(9600);
  randomSeed(analogRead(0));
  pixels.begin();
  char rValue = char(EEPROM.read(0));
  if (rValue != ' ') {
    aniSel = rValue;
  }
  //attachInterrupt(digitalPinToInterrupt(2), serialBTRead, CHANGE);

}

void offLEDS(int firstLed, int lastLed) {

  for (int i = firstLed; i <= lastLed; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
  }
  pixels.show();

}

void iniAnimation() {
  int a = 10;
  int b = 9;
  int c = 64;
  int d = 63;
  int ie = 121;
  int f = 122;
  for (int frame = 0; frame <= 60; frame++) {
    if (a > 0) {
      pixels.setPixelColor(a, pixels.Color(25, 25, 25));
    }
    if (b > 0) {
      pixels.setPixelColor(b, pixels.Color(25, 25, 25));
    }
    if (c > 0) {
      pixels.setPixelColor(c, pixels.Color(25, 25, 25));
    }
    if (d > 0) {
      pixels.setPixelColor(d, pixels.Color(25, 25, 25));
    }
    if (ie > 0) {
      pixels.setPixelColor(ie, pixels.Color(25, 25, 25));
    }
    if (f > 0) {
      pixels.setPixelColor(f, pixels.Color(25, 25, 25));
    }
    pixels.show();
    a++;
    c++;
    b--;
    d--;
    ie--;
    f++;

    delay(30);
  }

  int r = 25;
  int g = 25;
  int cb = 25;

  for (int frame = 0; frame <= 60; frame++) {
    for (int i = 0; i <= stripLeds; i++) {
      pixels.setPixelColor(i, pixels.Color(r, g, cb));
    }
    pixels.show();
    if (r > 0) {
      r--;
    }
    if (g > 0) {
      g--;
    }
    if (cb > 0) {
      cb--;
    }
    delay(10);
  }
}

void pauseLED(long stopTime) {
  time_now = millis();
  while (millis() - time_now <= stopTime) {
    serialBTRead();
  }
}

void mainAnimation() {

  serialBTRead();

  if (debugEn == true) {

    btMod.println("------------" + String(millis()) + "-------------");
    btMod.println("Serial Available");
    btMod.println(String(btMod.available()));
    btMod.println("btRead");
    btMod.println(btRead);
    btMod.println("AniSel");
    btMod.println(aniSel);
    btMod.println("Actual Serial Read");
    btMod.println(String(btMod.read()));
    btMod.println("--------------------------------------------------");

    pauseLED(3000);

  }


  switch (aniSel) {
    case 'a':
      solidLED();
      break;
    case 'e':
      edgeLED();
      break;
    default:
      testLED();
      break;
  }

}

void serialBTRead() {

  delay(50);
  if (btMod.available() > 0) {
    btRead = btMod.read();
    //btMod.write(btRead);
    newData = true;
  }

  //btMod.println(btRead);

  if (newData == true) {
    if (btMod.read() != -1) {
      aniSel = btRead;
      EEPROM.write(0, aniSel);
      newData = false;
    } else {
      newData = false;
      //aniSel = 'a';
    }
  }
}

void solidLED() {

  for (int ledN = 0; ledN <= 149; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(100, 20, 0));
  }

  pixels.show();

}

void testLED() {

  for (int ledN = 0; ledN <= 149; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);

  offLEDS(0, 149);
  pauseLED(1000);

  for (int ledN = 0; ledN <= 36; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);

  for (int ledN = 37; ledN <= 92; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);

  for (int ledN = 93; ledN <= 149; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);

  offLEDS(0, 149);
  pauseLED(1000);

  for (int ledN = 0; ledN <= 36; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);
  offLEDS(0, 149);
  pauseLED(1000);

  for (int ledN = 37; ledN <= 92; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);
  offLEDS(0, 149);
  pauseLED(1000);

  for (int ledN = 93; ledN <= 149; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(50, 50, 50));
  }

  pixels.show();
  pauseLED(1000);
  offLEDS(0, 149);
  pauseLED(1000);

}

void edgeLED() {

  for (int ledN = 0; ledN <= 149; ledN++) {
    pixels.setPixelColor(ledN, pixels.Color(15, 15, 15));
  }
  pixels.show();

  int rLed1 = random(150);
  int rLed2 = random(150);
  int rLed3 = random(150);
  int rLed4 = random(150);
  int rLed5 = random(150);
  int rLed6 = random(150);
  int rLed7 = random(150);
  int rLed8 = random(150);

  pixels.setPixelColor(rLed1, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed2, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed3, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed4, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed5, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed6, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed7, pixels.Color(125, 125, 125));
  pixels.setPixelColor(rLed8, pixels.Color(125, 125, 125));
  pixels.show();
  pauseLED(5);
  pixels.setPixelColor(rLed1, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed2, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed3, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed4, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed5, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed6, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed7, pixels.Color(5, 5, 5));
  pixels.setPixelColor(rLed8, pixels.Color(5, 5, 5));
  pixels.show();
  pauseLED(5);

}

Check out my tutorial on Multi-tasking in Arduino and rewrite your code a tasks each of which take a short time.
For timers, check out my How to write Timers and Delays in Arduino
multitaskingDiagramSmall

1 Like

Awesome i thought that wasn't posible on arduino, going to take a look thanks!!!

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