Lightning on a magic book

Hello everyone.
This is my first post so I hope to respect the forum rules.
I discovered Arduino while creating a sound book project. I press a button, it makes a sound, I press another button, it makes another sound track. So far all was well...
but I would like to add a lighting atmosphere using an RGB LED which would change at the same time as the audio tracks.
As long as the lighting is "steady" (either red or green...), not too much of a problem. However, I would like to create a light variation" (for example changes from red to pink, in a loop) BUT which interrupts instantly when I press another button.
I can't seem to find a solution to this. either the light dimming runs non-stop, or you have to wait for it to complete a loop before you can move on to something else. Does anyone have a suggestion to suggest to me?
THANKS.

#include "SoftwareSerial.h"
#include <RGBLed.h>
SoftwareSerial mySerial(10, 11);
#define Start_Byte 0x7E
#define Version_Byte 0xFF
#define Command_Length 0x06
#define End_Byte 0xEF
#define Acknowledge 0x00  //Returns info with command 0x41 [0x01: info, 0x00: no info]
#define ACTIVATED LOW
int b2tton = 2;
int b3tton = 3;
int b4tton = 4;
int L6D = 6;
int L7D = 7;
int L8D = 8;

boolean isPlay2 = false;
boolean isPlay3 = false;
boolean isPlay4 = false;

boolean isLed2 = false;
boolean isLed3 = false;
boolean isLed4 = false;

RGBLed led(6, 7, 8, RGBLed::COMMON_CATHODE);

void setup() {
  // put your setup code here, to run once:

pinMode(b2tton, INPUT_PULLUP);
  digitalWrite(b2tton, HIGH);
pinMode(b3tton, INPUT_PULLUP);
  digitalWrite(b3tton, HIGH);
pinMode(b4tton, INPUT_PULLUP);
digitalWrite(b4tton, HIGH);

pinMode(L6D, OUTPUT);
pinMode(L7D, OUTPUT);
pinMode(L8D, OUTPUT);

  mySerial.begin(9600);
  delay(1000);

}


void loop() { // put your main code here, to run repeatedly:
 if (digitalRead(b2tton) == LOW) {
 
play2();
light2();

}

 if (digitalRead(b3tton) == LOW) {

play3();
light3();
}


  if (digitalRead(b4tton) == LOW) {

play4();
light4();

}
}

void play2 (){
 
     execute_CMD(0x03, 0, 003);
      delay(50);
     setVolume(30);
}

void play3 (){
 
     execute_CMD(0x03, 0, 002);
      delay(50);
     setVolume(30);
}

void play4 (){
 
     execute_CMD(0x03, 0, 001);
      delay(50);
     setVolume(30);
}

void light2 (){

digitalWrite(6, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
}

void light3 (){

digitalWrite(6, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
}

void light4 (){
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
}


void execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
                            Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++) {
    mySerial.write(Command_line[k]);
  }
}

void setVolume(int volume) {
  execute_CMD(0x06, 0, volume);  // Set the volume (0x00~0x30)
  delay(1);
}

or

#include "SoftwareSerial.h"
#include <RGBLed.h>
SoftwareSerial mySerial(10, 11);
#define Start_Byte 0x7E
#define Version_Byte 0xFF
#define Command_Length 0x06
#define End_Byte 0xEF
#define Acknowledge 0x00  
#define ACTIVATED LOW
int b2tton = 2;
int b3tton = 3;
int b4tton = 4;
int L6D = 6;
int L7D = 7;
int L8D = 8;


boolean isPlay2 = false;
boolean isPlay3 = false;
boolean isPlay4 = false;

boolean isLed2 = false;
boolean isLed3 = false;
boolean isLed4 = false;

RGBLed led(6, 7, 8, RGBLed::COMMON_CATHODE);

void setup() {
  // put your setup code here, to run once:
Serial.println("isPlay4");
pinMode(b2tton, INPUT_PULLUP);
  digitalWrite(b2tton, HIGH);
pinMode(b3tton, INPUT_PULLUP);
  digitalWrite(b3tton, HIGH);
pinMode(b4tton, INPUT_PULLUP);
digitalWrite(b4tton, HIGH);

pinMode(L6D, OUTPUT);
pinMode(L7D, OUTPUT);
pinMode(L8D, OUTPUT);

mySerial.begin(9600);
delay(1000);
Serial.begin(9600);

}


void loop() { // put your main code here, to run repeatedly:
 
 if (digitalRead(b2tton) == LOW) {
  delay(10);

isPlay2 = true;
 isPlay3 = false;
  isPlay4 = false;

if (isPlay2 == true and isPlay3 == false and isPlay4 == false){
Serial.println("isPlay2");
  execute_CMD(0x03, 0, 003);
    delay(50);
    setVolume(30);
digitalWrite(6, HIGH);
 digitalWrite(7, LOW);
  digitalWrite(8, LOW);  

}
}

if (digitalRead(b3tton) == LOW) {
  delay(10);
 
 isPlay3 = true;
 
if (isPlay2 == true and isPlay3 == false and isPlay4 == false){
  Serial.println("isPlay3");
     execute_CMD(0x03, 0, 002);
      delay(50);
      setVolume(30);
digitalWrite(6, LOW);
 digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
}
}

if (digitalRead(b4tton) == LOW) {
      delay(10);
   
    isPlay4 = true;

if (isPlay4 == true){
   Serial.println("isPlay4");
       execute_CMD(0x03, 0, 001);
        delay(50);
       setVolume(30);
digitalWrite(6, LOW);
 digitalWrite(7, LOW);
  digitalWrite(8, HIGH);
}
}
}

void execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
  // Calculate the checksum (2 bytes)
  word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
  // Build the command line
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
                            Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte };
  //Send the command line to the module
  for (byte k = 0; k < 10; k++) {
    mySerial.write(Command_line[k]);
  }
}

void setVolume(int volume) {
  execute_CMD(0x06, 0, volume);  // Set the volume (0x00~0x30)
  delay(1);
}

Are you able to post your code?
Please remember to use code tags. To get them, press ENTER to start a new line, then press the backquote key (to the left of the number 1 on your keyboard) three times, then press ENTER again. Then paste your code. Then, after your code, press ENTER again, and press the backquote key three more times.

1 Like

The search-term you are looking for is "non-blocking". As in:

https://forum.arduino.cc/t/fastled-neopixel-examples-that-are-non-blocking

It takes re-writing an animation to not use delay() or long for() loops and use the Blink-Without-Delay trick.

Here is a simulation of an interrupt with a blocking function call. I tried to explain what was happening.

the sketch
// Demonstrates one method of interrupt - FALLING

// This does not allow for LONG PRESS, which generates TWO interrupts when held longer than debounce

volatile bool buttonPressed; // using type "volatile" for variables INSIDE interrupt service routeine (ISR)
int buttonPin = 2; // interrupt pin INT0... also available is INT1, pin 3
int ledPin3 = 3; // red LED
int ledPin5 = 5; // white LED
int count; // a counter

void setup() {
  Serial.begin(9600); // start the serial monitor for text (for this demonstration)

  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin5, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); // button is wired to ground and signal pin, pulled HIGH internally

  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, FALLING); // PIN#, ISR, TRIGGER
  // digitalPinToInterrupt(buttonPin) - use the Arduino pin number, not the ATMega328 pin number
  // buttonISR - the function (also Interrupt Service Routine/Interrupt Handler) to be called
  // TRIGGER - run the ISR when the pin senses RISING, FALLING, ONCHANGE

  welcome(); // Send an introduction to the Serial Monitor (for this demonstration)
}

void loop() {
  // calling functions
  blockingCode(); // blink LED and delay
  checkButton();
}

int buttonISR() { // Interrupt Service Routine called on a button press
  noInterrupts(); // disable interrupts while in the ISR
  buttonPressed = true; // set the flag that the button was pressed
  interrupts(); // enable interrupts when leaving the ISR
}

void blockingCode() { // set both LEDs ON
  digitalWrite(ledPin5, !(digitalRead(ledPin5))); // read and toggle LED pin
  delay(250); // wait
}

void checkButton() {
  if (buttonPressed) { // check the buttonPressed flag always
    delay(150); // debounce the button press noise if the buttonPressed flag was set
    buttonPressed = false; // reset buttonPressed flag to prepare for the next interrupt
    digitalWrite(ledPin3, !(digitalRead(ledPin3))); // toggle LED pin
    count++; // increment the counter...
    Serial.print(" "); Serial.print(count); // ... show the number of button presses
  }
}

void welcome() {
  // a place to display instructions
  Serial.print("Button Press count: 0");
}

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