text:
Integrating blinking light code and time on/off code
I'm trying to integrate code from one of my projects with another. One is code that blinks some Adafruit Neopixel LED strips at a specific rate and the other is a time on/off circuit here is the code for both of these projects, respectively:
NeoPixel LEDs

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define PIN        6
#define NUMPIXELS 7

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void NeoBlink(int num, int wait)
{
for (int i = 0; i < num; i++)
{
pixels.setPixelColor(i, 0, 0, 0);
}
pixels.show();
delay(8000);
for (int j = 0; j < num; j++)
{
pixels.setPixelColor(j, 255, 255, 255);
}
pixels.show();
delay(3);
}

void setup()
{
pixels.begin();
pixels.setBrightness(255);
}

void loop()
{
NeoBlink(7, 500);
}

AND

#include <EEPROM.h>
#include <RTClib.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>

hd44780_I2Cexp lcd;//0x3F is my lcd address, maybe not yours!
RTC_DS3231 RTC;

#define HD44780_LCDOBJECT

//-----------------------//
//------Variables--------//
//-----------------------//

//------First Timer
byte onhour1;
byte onmin1;
byte onsec1;

byte offhour1;
byte offmin1;
byte offsec1;
//------Pages or menus
int page_counter=1;
int subpage1_counter=0;
int subpage2_counter=0;

//-------To convert clock into single number
unsigned long Time;
unsigned long Hour;
unsigned long Min;
unsigned long Sec;
//------To convert first timer into Single number
unsigned long on_Time1;
unsigned long on_hour1;
unsigned long on_min1;
unsigned long on_sec1;

unsigned long off_Time1;
unsigned long off_hour1;
unsigned long off_min1;
unsigned long off_sec1;

//-------Push buttons current/last state
boolean current_up = LOW;
boolean last_up=LOW;
boolean current_sel = LOW;
boolean last_sel = LOW;
boolean last_down = LOW;
boolean current_down = LOW;
//-------Pins
int up=2;      //Up button to pin 2
int sel=3;     //Select button to pin 3
int down=4;   //Down button to pin 4

//Custom return char
byte back[8] = {
  0b00100,
  0b01000,
  0b11111,
  0b01001,
  0b00101,
  0b00001,
  0b00001,
  0b11111
};

//Custom arrow char
byte arrow[8] = {
  0b01000,
  0b00100,
  0b00010,
  0b11111,
  0b00010,
  0b00100,
  0b01000,
  0b00000
};

void setup() {
  pinMode(6, OUTPUT);

     Wire.begin();
     RTC.begin();
     lcd.init();
     lcd.backlight();
     lcd.clear();
  lcd.createChar(1, back);//Custom chars
  lcd.createChar(2, arrow);
//--------eePROM  read values-------//
//------First Timer
onhour1=EEPROM.read(0);
onmin1=EEPROM.read(1);
onsec1=EEPROM.read(2);

offhour1=EEPROM.read(3);
offmin1=EEPROM.read(4);
offsec1=EEPROM.read(5);

}

   //---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(10);
current = digitalRead(pin);
}
return current;
}

void loop() {

current_up = debounce(last_up, up);         //Debounce for Up button
current_sel = debounce(last_sel, sel);      //Debounce for Select  button
current_down = debounce(last_down, down);   //Debounce for Down button

DateTime now = RTC.now();        // Clock call
now = RTC.now();

//-----Up/Down functions to move main pages------///

if(subpage1_counter==0 && subpage2_counter==0){ //up/down buttons enabled if subpages counters are 0,Disabled if 1,2..etc to work on submenus

//Page Up
    if (last_up== LOW && current_up == HIGH){ //Up button pressed
      lcd.clear();                            //Clear lcd if page is changed to print new one
      if(page_counter <3){                   //Page counter never higher than 3(total of pages)
      page_counter ++;                       //Page up
      }
      else{
      page_counter= 1;                       //If higher than 3 (last page)go to main page
      }

}
last_up = current_up;                   //Save up button last state

//Page Down
    if (last_down== LOW && current_down == HIGH){//Down button pressed
      lcd.clear();                               //Clear lcd if page is changed to print new one
      if(page_counter >1){                      //Page counter never lower than 1
      page_counter --;                          //Page down

      }
      else{
      page_counter= 3;                 //If lower than 1(first page)go to last page
      }
  }
    last_down = current_down;         //Save down button last state
}
//------------Pages and submenus display and control----------//
  switch (page_counter){
    case 1:                      //Content of main page
     last_sel=current_sel;  //Save last state of select button when we jump from the save screen
      lcd.setCursor(0,0);
      lcd.print("ULTRA MEGA TIMER");
      lcd.setCursor(0,1);
      lcd.print("TIME");

//--------Show  Time On LCD

lcd.setCursor(7,1);
if(now.hour() < 10)
{
lcd.print("0");
}
lcd.print(now.hour(), DEC); //Print hour
lcd.print(':');
if(now.minute() < 10)
{
lcd.print("0");
}
lcd.print(now.minute(), DEC); //Print min
lcd.print(':');
if(now.second() < 10)
{
lcd.print("0");
}
lcd.print(now.second(), DEC); //Print sec
    //case 1
    break;

    case 2:                   //Content and functions of page 2
      lcd.setCursor(0,0);
      lcd.print("T1");
      lcd.setCursor(3,0);
      lcd.print("ON");
      lcd.setCursor(1,1);
      lcd.write(byte(1));
      lcd.setCursor(3,1);
      lcd.print("OFF");

            lcd.setCursor(7,0);    //Printing on/off values
            if(onhour1<10){
              lcd.print("0");
            }
            lcd.print(onhour1);
            lcd.setCursor(10,0);
            if(onmin1<10){
              lcd.print("0");
            }
            lcd.print(onmin1);
            lcd.setCursor(13,0);
            if(onsec1<10){
              lcd.print("0");
            }
            lcd.print(onsec1);
            lcd.setCursor(7,1);
            if(offhour1<10){
              lcd.print("0");
            }
            lcd.print(offhour1);
            lcd.setCursor(10,1);
            if(offmin1<10){
              lcd.print("0");
            }
            lcd.print(offmin1);
            lcd.setCursor(13,1);
            if(offsec1<10){
              lcd.print("0");
            }
            lcd.print(offsec1);

//--------------Modifying on/off values-------//
     // Sub counter control
     if (last_sel== LOW && current_sel == HIGH){ //select button pressed
      if(subpage1_counter <7){                    // subpage counter never higher than 7 (total of items)
     subpage1_counter ++;                         //subcounter to move beetwen submenu
     }
     else{                                       //If subpage higher than 7 (total of items) return to first item
      subpage1_counter=1;
     }
     }
     last_sel=current_sel;                      //Save last state of select button

     //First item control(subpage_counter =1) onhour1
     if(subpage1_counter==1){
     lcd.setCursor(0,1);         //Delete last arrow position (back)
     lcd.print(" ");
     lcd.setCursor(6,0);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      if(onhour1 < 23){
     onhour1 ++;
      }
      else{
     onhour1 =0;
      }
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
     if(onhour1 >0){
      onhour1 --;
     }
     else{
      onhour1=23;
     }
     }
     last_down=current_down;
    }//subpage1_counter 1

     //Second item control(subpage_counter =2) onmin1
     if(subpage1_counter==2){
     lcd.setCursor(6,0);         //Delete last arrow position (onhour1)
     lcd.print(" ");
     lcd.setCursor(9,0);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      if(onmin1 < 59){
     onmin1 ++;
      }
      else{
     onmin1 =0;
      }
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
     if(onmin1 >0){
      onmin1 --;
     }
     else{
      onmin1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 2

     //Thirth item control(subpage_counter =3) onsec1
     if(subpage1_counter==3){
     lcd.setCursor(9,0);         //Delete last arrow position (onmin1)
     lcd.print(" ");
     lcd.setCursor(12,0);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      if(onsec1 < 59){
     onsec1 ++;
      }
      else{
     onsec1 =0;
      }
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
     if(onsec1 >0){
      onsec1 --;
     }
     else{
      onsec1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 3

     //fourth item control(subpage_counter =4) offhour1
     if(subpage1_counter==4){
     lcd.setCursor(12,0);         //Delete last arrow position (onsec1)
     lcd.print(" ");
     lcd.setCursor(6,1);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      if(offhour1 < 23){
     offhour1 ++;
      }
      else{
     offhour1 =0;
      }
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
     if(offhour1 >0){
      offhour1 --;
     }
     else{
      offhour1=23;
     }
     }
     last_down=current_down;
    }//subpage1_counter 4

     //fifth item control(subpage_counter =5) offmin1
     if(subpage1_counter==5){
     lcd.setCursor(6,1);         //Delete last arrow position (offhour1)
     lcd.print(" ");
     lcd.setCursor(9,1);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      if(offmin1 < 59){
     offmin1 ++;
      }
      else{
     offmin1 =0;
      }
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
     if(offmin1 >0){
      offmin1 --;
     }
     else{
      offmin1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 5

     //sixth item control(subpage_counter =6) offsec1
     if(subpage1_counter==6){
     lcd.setCursor(9,1);         //Delete last arrow position (offmin1)
     lcd.print(" ");
     lcd.setCursor(12,1);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      if(offsec1 < 59){
     offsec1 ++;
      }
      else{
     offsec1 =0;
      }
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
     if(offsec1 >0){
      offsec1 --;
     }
     else{
      offsec1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 6

     //seventh item control(subpage_counter =7) back
     if(subpage1_counter==7){
     lcd.setCursor(12,1);         //Delete last arrow position (offsec1)
     lcd.print(" ");
     lcd.setCursor(0,1);          //Place arrow in front of selected item
     lcd.write(byte(2));
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      lcd.setCursor(0,1);         //Delete last arrow position (back) to exit
      lcd.print(" ");
     subpage1_counter=0;         //Exit submenu. Up/down butons enabled to move main pages
     }
     last_up=current_up;

     if(last_down== LOW && current_down == HIGH){//Down
      lcd.setCursor(0,1);         //Delete last arrow position (back)
      lcd.print(" ");
     subpage1_counter=1;         //Go to first item (onhour1)
     }
     last_down=current_down;
    }//subpage1_counter 7
    //case 2
    break;

    case 3:                //Page 3 display and functions
      lcd.setCursor(4,0);
      lcd.print("PRESS SEL");
      lcd.setCursor(5,1);
      lcd.print("TO SAVE");
     if (last_sel== LOW && current_sel == HIGH){  //select button pressed.Save settings to eeprom
  EEPROM.write(0, onhour1);
  EEPROM.write(1, onmin1);
  EEPROM.write(2, onsec1);
  EEPROM.write(3, offhour1);
  EEPROM.write(4, offmin1);
  EEPROM.write(5, offsec1);
  lcd.clear();                 //Print message "SAVED!"
  lcd.setCursor(5,1);
  lcd.print("SAVED!");
  delay(2000);
  lcd.clear();               //Clear lcd and go to main page
  page_counter=1;
     }
     last_sel=current_sel;  //Save last state of select button

    //Case 3
    break;
  }//switch

//-------------Conversion----------//

//---------Converting clock time into single number

Hour = now.hour();
Min = now.minute();
Sec = now.second();
Time = (Hour*10000+ Min*100 +Sec*1);

//--------Converting firt timer on/off into single number
on_hour1=onhour1;
on_min1=onmin1;
on_sec1=onsec1;
on_Time1=(on_hour1*10000 + on_min1*100 + on_sec1);

off_hour1=offhour1;
off_min1=offmin1;
off_sec1=offsec1;
off_Time1=(off_hour1*10000 + off_min1*100 + off_sec1);

//----Relay Function----//
if(onhour1 == offhour1 && onmin1==offmin1 && onsec1==offsec1){
   digitalWrite(Relay, LOW);
}

if(on_Time1 < off_Time1){

             if(Time >= on_Time1 && Time < off_Time1){  //Start
             digitalWrite(Relay, HIGH);
             }
             else if(Time >= off_Time1) {
             digitalWrite(Relay, LOW);
             }
             else{
             digitalWrite(Relay, LOW);
             }
}
if (on_Time1 > off_Time1){

            if(Time >= on_Time1 && Time <= 235959){     //Start
            digitalWrite(Relay, HIGH);
            }
            else if(Time < off_Time1 ){
            digitalWrite(Relay, HIGH);
            }
            else if(Time >= off_Time1 && Time < on_Time1){
            digitalWrite(Relay, LOW);
            }
}

}//void loop

And this is my attempt at integration:

void loop() {

  current_up = debounce(last_up, up);         //Debounce for Up button
  current_sel = debounce(last_sel, sel);      //Debounce for Select  button
  current_down = debounce(last_down, down);   //Debounce for Down button

  DateTime now = RTC.now();        // Clock call
  now = RTC.now();

  //-----Up/Down functions to move main pages------///

  if (subpage1_counter == 0 && subpage2_counter == 0) { //up/down buttons enabled if subpages counters are 0,Disabled if 1,2..etc to work on submenus

    //Page Up
    if (last_up == LOW && current_up == HIGH) { //Up button pressed
      lcd.clear();                            //Clear lcd if page is changed to print new one
      if (page_counter < 3) {                //Page counter never higher than 3(total of pages)
        page_counter ++;                       //Page up
      }
      else {
        page_counter = 1;                      //If higher than 3 (last page)go to main page
      }

    }
    last_up = current_up;                   //Save up button last state

    //Page Down
    if (last_down == LOW && current_down == HIGH) { //Down button pressed
      lcd.clear();                               //Clear lcd if page is changed to print new one
      if (page_counter > 1) {                   //Page counter never lower than 1
        page_counter --;                          //Page down

      }
      else {
        page_counter = 3;                //If lower than 1(first page)go to last page
      }
    }
    last_down = current_down;         //Save down button last state
  }
  //------------Pages and submenus display and control----------//
  switch (page_counter) {
    case 1:                      //Content of main page
      last_sel = current_sel; //Save last state of select button when we jump from the save screen
      lcd.setCursor(0, 0);
      lcd.print("ULTRA MEGA TIMER");
      lcd.setCursor(0, 1);
      lcd.print("TIME");

      //--------Show  Time On LCD

      lcd.setCursor(7, 1);
      if (now.hour() < 10)
      {
        lcd.print("0");
      }
      lcd.print(now.hour(), DEC); //Print hour
      lcd.print(':');
      if (now.minute() < 10)
      {
        lcd.print("0");
      }
      lcd.print(now.minute(), DEC); //Print min
      lcd.print(':');
      if (now.second() < 10)
      {
        lcd.print("0");
      }
      lcd.print(now.second(), DEC); //Print sec
      //case 1
      break;

    case 2:                   //Content and functions of page 2
      lcd.setCursor(0, 0);
      lcd.print("T1");
      lcd.setCursor(3, 0);
      lcd.print("ON");
      lcd.setCursor(1, 1);
      lcd.write(byte(1));
      lcd.setCursor(3, 1);
      lcd.print("OFF");

      lcd.setCursor(7, 0);   //Printing on/off values
      if (onhour1 < 10) {
        lcd.print("0");
      }
      lcd.print(onhour1);
      lcd.setCursor(10, 0);
      if (onmin1 < 10) {
        lcd.print("0");
      }
      lcd.print(onmin1);
      lcd.setCursor(13, 0);
      if (onsec1 < 10) {
        lcd.print("0");
      }
      lcd.print(onsec1);
      lcd.setCursor(7, 1);
      if (offhour1 < 10) {
        lcd.print("0");
      }
      lcd.print(offhour1);
      lcd.setCursor(10, 1);
      if (offmin1 < 10) {
        lcd.print("0");
      }
      lcd.print(offmin1);
      lcd.setCursor(13, 1);
      if (offsec1 < 10) {
        lcd.print("0");
      }
      lcd.print(offsec1);

      //--------------Modifying on/off values-------//
      // Sub counter control
      if (last_sel == LOW && current_sel == HIGH) { //select button pressed
        if (subpage1_counter < 7) {                 // subpage counter never higher than 7 (total of items)
          subpage1_counter ++;                         //subcounter to move beetwen submenu
        }
        else {                                      //If subpage higher than 7 (total of items) return to first item
          subpage1_counter = 1;
        }
      }
      last_sel = current_sel;                    //Save last state of select button

      //First item control(subpage_counter =1) onhour1
      if (subpage1_counter == 1) {
        lcd.setCursor(0, 1);        //Delete last arrow position (back)
        lcd.print(" ");
        lcd.setCursor(6, 0);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          if (onhour1 < 23) {
            onhour1 ++;
          }
          else {
            onhour1 = 0;
          }
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          if (onhour1 > 0) {
            onhour1 --;
          }
          else {
            onhour1 = 23;
          }
        }
        last_down = current_down;
      }//subpage1_counter 1

      //Second item control(subpage_counter =2) onmin1
      if (subpage1_counter == 2) {
        lcd.setCursor(6, 0);        //Delete last arrow position (onhour1)
        lcd.print(" ");
        lcd.setCursor(9, 0);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          if (onmin1 < 59) {
            onmin1 ++;
          }
          else {
            onmin1 = 0;
          }
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          if (onmin1 > 0) {
            onmin1 --;
          }
          else {
            onmin1 = 59;
          }
        }
        last_down = current_down;
      }//subpage1_counter 2

      //Thirth item control(subpage_counter =3) onsec1
      if (subpage1_counter == 3) {
        lcd.setCursor(9, 0);        //Delete last arrow position (onmin1)
        lcd.print(" ");
        lcd.setCursor(12, 0);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          if (onsec1 < 59) {
            onsec1 ++;
          }
          else {
            onsec1 = 0;
          }
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          if (onsec1 > 0) {
            onsec1 --;
          }
          else {
            onsec1 = 59;
          }
        }
        last_down = current_down;
      }//subpage1_counter 3

      //fourth item control(subpage_counter =4) offhour1
      if (subpage1_counter == 4) {
        lcd.setCursor(12, 0);        //Delete last arrow position (onsec1)
        lcd.print(" ");
        lcd.setCursor(6, 1);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          if (offhour1 < 23) {
            offhour1 ++;
          }
          else {
            offhour1 = 0;
          }
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          if (offhour1 > 0) {
            offhour1 --;
          }
          else {
            offhour1 = 23;
          }
        }
        last_down = current_down;
      }//subpage1_counter 4

      //fifth item control(subpage_counter =5) offmin1
      if (subpage1_counter == 5) {
        lcd.setCursor(6, 1);        //Delete last arrow position (offhour1)
        lcd.print(" ");
        lcd.setCursor(9, 1);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          if (offmin1 < 59) {
            offmin1 ++;
          }
          else {
            offmin1 = 0;
          }
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          if (offmin1 > 0) {
            offmin1 --;
          }
          else {
            offmin1 = 59;
          }
        }
        last_down = current_down;
      }//subpage1_counter 5

      //sixth item control(subpage_counter =6) offsec1
      if (subpage1_counter == 6) {
        lcd.setCursor(9, 1);        //Delete last arrow position (offmin1)
        lcd.print(" ");
        lcd.setCursor(12, 1);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          if (offsec1 < 59) {
            offsec1 ++;
          }
          else {
            offsec1 = 0;
          }
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          if (offsec1 > 0) {
            offsec1 --;
          }
          else {
            offsec1 = 59;
          }
        }
        last_down = current_down;
      }//subpage1_counter 6

      //seventh item control(subpage_counter =7) back
      if (subpage1_counter == 7) {
        lcd.setCursor(12, 1);        //Delete last arrow position (offsec1)
        lcd.print(" ");
        lcd.setCursor(0, 1);         //Place arrow in front of selected item
        lcd.write(byte(2));
        //Move item + or -
        if (last_up == LOW && current_up == HIGH) { //Up
          lcd.setCursor(0, 1);        //Delete last arrow position (back) to exit
          lcd.print(" ");
          subpage1_counter = 0;       //Exit submenu. Up/down butons enabled to move main pages
        }
        last_up = current_up;

        if (last_down == LOW && current_down == HIGH) { //Down
          lcd.setCursor(0, 1);        //Delete last arrow position (back)
          lcd.print(" ");
          subpage1_counter = 1;       //Go to first item (onhour1)
        }
        last_down = current_down;
      }//subpage1_counter 7
      //case 2
      break;

    case 3:                //Page 3 display and functions
      lcd.setCursor(4, 0);
      lcd.print("PRESS SEL");
      lcd.setCursor(5, 1);
      lcd.print("TO SAVE");
      if (last_sel == LOW && current_sel == HIGH) { //select button pressed.Save settings to eeprom
        EEPROM.write(0, onhour1);
        EEPROM.write(1, onmin1);
        EEPROM.write(2, onsec1);
        EEPROM.write(3, offhour1);
        EEPROM.write(4, offmin1);
        EEPROM.write(5, offsec1);
        lcd.clear();                 //Print message "SAVED!"
        lcd.setCursor(5, 1);
        lcd.print("SAVED!");
        delay(2000);
        lcd.clear();               //Clear lcd and go to main page
        page_counter = 1;
      }
      last_sel = current_sel; //Save last state of select button

      //Case 3
      break;
  }//switch

  //-------------Conversion----------//

  //---------Converting clock time into single number

  Hour = now.hour();
  Min = now.minute();
  Sec = now.second();
  Time = (Hour * 10000 + Min * 100 + Sec * 1);

  //--------Converting firt timer on/off into single number
  on_hour1 = onhour1;
  on_min1 = onmin1;
  on_sec1 = onsec1;
  on_Time1 = (on_hour1 * 10000 + on_min1 * 100 + on_sec1);

  off_hour1 = offhour1;
  off_min1 = offmin1;
  off_sec1 = offsec1;
  off_Time1 = (off_hour1 * 10000 + off_min1 * 100 + off_sec1);

 //----Relay Function----//
if(onhour1 == offhour1 && onmin1==offmin1 && onsec1==offsec1){
   NeoBlink(0, 0);
}

if(on_Time1 < off_Time1){

             if(Time >= on_Time1 && Time < off_Time1){  //Start
             NeoBlink(7, 500);
             }
             else if(Time >= off_Time1) {
             NeoBlink(0, 0);
             }
             else{
            NeoBlink(0, 0);
             }
}
if (on_Time1 > off_Time1){

            if(Time >= on_Time1 && Time <= 235959){     //Start
            NeoBlink(7, 500);
            }
            else if(Time < off_Time1 ){
            NeoBlink(7, 500);
            }
            else if(Time >= off_Time1 && Time < on_Time1){
            NeoBlink(0, 0);
            }
}

}//void

(I had to cut this last one down a bit^ -too many characters, the most important stuff is there though)
This actually has no apparent errors BUT when I run it-it messes with my RTC, LCD and I cannot access the serial display (referring to a Time On/Off Circuit minus the 5v relay I made
Also the lights don't run like they do when I run the first string of code I posted.
The majority of the changes are at the end where I subbed in NeoBlink() for digitalwrite(). I also made the correct changes to voidsetup() and voidloop().
Of course I can think of some reasons why this code wouldn't run but I have a specific question.
My question is would it even be possible to integrate the first string of code into the second or will it have to be completely re-formatted for integration? If re-formatting is required-where should I start?
Thanks

try merging the code before posting ... that way you can ask an actual question about a problem you are having

You're right-I've actually already tried. I don't know why I didn't do that.


text:
How can I pause serial transfer and then un-pause it?
So I am running a USB (UART) connection from my Arduino UNO (using the serialtransfer.h library) to my pc (using the pyserial transfer library).
This how the INTENDED cycle of code goes:
I receive the list_ packet and save it to a list on the Arduino . Then the elements in the list are checked and used to control parameters of motor a using GPIO pins. Finally a return message is sent to acknowledge each transfer.
I was hoping to make the return message from Arduino as sort of a flag ; whether to wait or move onto the next transfer, this is on the python side of things.
However this is not the case as the sending of packets from Arduino is almost instantaneous even with delay functions and before the Arduino can process the information the transfer is done.
1)Why doesn't delay() work ?
2) Why isn't code sequential ?
This is the Arduino side of things
#include "SerialTransfer.h"

SerialTransfer myTransfer;
int motor1 = 13;
int motor2 = 10;

int obj_cordinates[9];
char reply [16] = {"Packet Recieved"};
void setup()
{
  Serial.begin(115200);
  pinMode(motor1,OUTPUT);
  pinMode(motor2,OUTPUT);

  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    // use this variable to keep track of how many
    // bytes we've processed from the receive buffer
    uint16_t recSize = 0;
    uint16_t sendSize = 0;

    recSize = myTransfer.rxObj(obj_cordinates, recSize);
    sendSize = myTransfer.txObj(reply, sendSize);

     if( obj_cordinates[4] == 15)
    {
      digitalWrite(motor1, HIGH);
      digitalWrite(motor2, LOW);

      delay(5000);

      digitalWrite(motor1, LOW);
      digitalWrite(motor2, HIGH);
      delay(5000);
    }

    myTransfer.sendData(sendSize);
  }

}

The python side of things
import time
from pySerialTransfer import pySerialTransfer as txfer

def Ser_tran_list (list_):

    try:
        link = txfer.SerialTransfer('COM6')
        link.open()
        time.sleep(2) # allow some time for the Arduino to completely reset

        to_transfer = True
        while to_transfer:
            send_size = 0

            # Send a list

            list_size = link.tx_obj(list_)
            send_size += list_size

            # send a character
            str_ = 'Sending data Packet'
            str_size = link.tx_obj(str_, send_size) - send_size
            send_size += str_size
            link.send(send_size)

            while not link.available():
                if link.status < 0:
                    if link.status == txfer.CRC_ERROR:
                        print('ERROR: CRC_ERROR')
                    elif link.status == txfer.PAYLOAD_ERROR:
                        print('ERROR: PAYLOAD_ERROR')
                    elif link.status == txfer.STOP_BYTE_ERROR:
                        print('ERROR: STOP_BYTE_ERROR')
                    else:
                        print('ERROR: {}'.format(link.status))

            # Parse response string

            rec_str_   = link.rx_obj(obj_type=type(str_),
                                     obj_byte_size=16,
                                     start_pos=0)

            # Display the received data

            print('SENT: {} {}'.format(list_,str_))
            print('Recieved: {}'.format(rec_str_))

            to_transfer = False

Probably because obj_cordinates[4] != 15 You can't use delay() for something that needs  eventually some unpausing ...

The delay() function uses the milliseconds interrupt. Inside an interrupt handler, all other interrupts are suspended so the millis() counter doesn't count and delay() never ends. delayMicroseconds() will work in the interrupt routine because it just sits in a busy loop. Rewrite the code to eliminate the delay function, you can use millis if you want. This is telling you while in the delay function just about everything stops until it is finished.

There are several protocols that will do what you want. There is hardware handshaking and serial handshaking.  This link explains a lot about both and how flow control works. https://stackoverflow.com/questions/7578812/serial-port-handshake-what-the-difference-between-hardware-and-none-handshaking

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
CAN Bus Shield Initialization Failed
The Problem
I've been working on a project that requires the use of a CAN Bus Shield v2 on an Arduino. For most of the time it has worked great, completely as intended. But recently, I was trying to hookup a 24V heater to a MOSFET to be controlled by the Arduino. I had hooked it up the pin 2 which later I found out was a bad idea because pin 2 is for the interrupt signal. I uploaded the code and the heater did not turn on.
A while later I tried to upload code to the Arduino and it would not upload, citing a not in sync error. So, switched the Arduino board out for another one of the same model and the code uploaded just fine. But, the CAN Shield was throwing a "CAN Bus Shield Init FAILED" error over and over again. And the INT light was staying permanently on. And the Rx light would stay on if I tried to send a message on the bus from another node.
My question is, will I have to purchase a new shield or is there a way to fix this?
What I have tried

Turning it off and on again
Using the shield on the old Arduino
Wiping the Arduino and adding the code again
Reverting to an older piece of code
Setting pin 2 HIGH (this turned off the INT light but did not fix the init problem)
Sending various messages on the CAN Bus
Flipping the OBD switch on/off
Trying different resistors

simulate this circuit – Schematic created using CircuitLab

Sounds like maybe a bad wiring issue where you fried the Arduino? Can you post a wiring diagram? You can use the "Schematic" button in the editor when editing your question.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Detecting an incoming 7.875 kHz pulse to use as trigger
I have written a code that detects an incoming pulse (square) of 7.875 kHz to trigger the output High for the entire duration of pulse, and trigger the output low if the pulse is off or not detected.
CODE
// Define pins
volatile int pulse1 = 2;    //incoming pulse 1 on pin 2

const int ledPin = 13;   //output to trigger LED

void setup() {

  pinMode(pulse1, INPUT);

  pinMode(ledPin, OUTPUT);

  // Timer Setup

  TCCR1A = 0;               // set entire TCCR1A register to 0
  TCCR1B = 0;               // same for TCCR1B
  TCNT1  = 65282;           // initialize counter value
  TCCR1B |= (1<<CS10);      // set prescaler to 8 bit
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt

}
ISR(TIMER1_OVF_Vect){
  TCNT1 = 65282;
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV2, FALLING);
  }

void loop() {
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV1, RISING);

}

// Interrupt routines

void ISR_UV1(){
  digitalWrite(ledPin, HIGH);      // Send high signal
}

void ISR_UV2(){
  digitalWrite(ledPin, LOW);      // Send low signal
}

Is it the correct approach, or am I doing it wrong. One last thing that is bothering me is, every time I connect a wire (not connected to anything) to the input pin 2, it sends a high signal, and keeps the signal high until the Arduino is reset.
The pulse is a square wave 50% duty cycle generated by a device. I dont need to measure it or count it. I am just using it as a trigger to send a HIGH signal when it occurs. So it stays on (occurs) for 25ms & turns off during which its freq. is 7.875MHz & then it is repeated by the device according to the device parameters. I am aware it is a very short pulse but for the purpose of project nothing else can be used as the trigger
Any help will be appreciated.

If you don't connect the wire to anything, the pin is still floating. It can have any value, even rapidly changing, depending on which noise it is currently picking up. The pin itself can already pick up noise. With an attached wire you are basically creating an antenna.

Why are you attaching the interrupts again and again? You never detach the interrupts, so why attaching them over and over again?

Also it does not make sense to me, where you are attaching the interrupts. I don't think it works, that you attach 2 interrupts to one pin. Then you are just changing the interrupt for a very short time, when the timer overflows. Instead you could just use 1 interrupt with CHANGE instead of RISING or FALLING. Inside it you can read the pin to check, which one happended. Have you tried, if that code is working? Or are you just asking in advance?

Can you describe the pulse waveform more in detail? This is such a high freq that there's no way you can do anything in that time except maybe see if it occurred. Example of a detailed description: it is a 200ns HIGH pulse occurring once per second. Or, it is a 200ns HIGH followed by 200ns LOW, repeating.

What does it mean for the pulse to be "off" or "not detected"? Is OFF when the signal is LOW? Or is it when you haven't seen a HIGH pulse for X ns, or something else?

Also, take a look at my answer here: https://arduino.stackexchange.com/a/76981/7727. digitalWrite alone takes 5us, a whole order of magnitude longer than this pulse you are trying to measure. We can reduce that digitalWrite to 125ns, but have to use direct register access to write to the pins.

maybe you can use a simple demodulator to extract the pulse from the 7.875 MHz signal

@chrisl Thank you for your feedback.

@chrisl I am using this code inside another program, & these routines have to be on priority which is why i thought this approach will work. The control has to be precise i.e. as soon as the pulse starts the high signal should be sent vice versa. Which is why i am using a timer interrupt as well. I will try what you suggested. & finally regarding the floating problem, I just solved it by keeping it on LOW & turns on when the signal is connected.

@GabrielStaples Thank you for your input, The pulse is a square wave 50% duty cycle generated by a device. I dont need to measure it or count it. I am just using it as a trigger to send a HIGH signal when it occurs. So it stays on (occurs) for 25ms & turns off during which its freq. is 7.875MHz & then it is repeated by the device according to the device parameters. I am aware it is a very short pulse but for the purpose of project nothing else can be used as the trigger.

@jsotola i will try that as well. But the goal is to keep the whole thing as simple as possible. since this is part of a bigger project.

@chrisl after troubleshooting it, I think it gets stuck with in the timer interrupt, The main reason for timer is to use it as double check so that after the pulse is over, it sends low signal. If you have any suggestions on how to do it otherwise. that will be helpful.

Also, i am unsure if it matters or not, but the high signal of pulse is 3.3V. I dont think it is an issue because as far as i am aware if the voltage is higher than 0.6x5Vcc it should be fine.. but do let me know if that has an effect

3.3V is fine. It is high enough, as you state.

I'm very curious, if your willing to share: what's the application of this whole pulse thing and trigger?

@GabrielStaples well the short version is, the trigger will be used to control UV LEDs (which has its own controller) & i guess you can speculate on where the UV LED is bieng used =)

So i figured out what the problem was, I had to detach interrupts in the interrupt routines not in my main code. So basically these changes:
void loop() {
  digitalWrite(ledPin, LOW);
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV1, CHANGING);

}

& in the Interrupt routines:
digitalWrite(ledPin, HIGH);      // Send high or Low dpending on the routine
detachInterrupt(digitalPinToInterrupt(pulse1));

& basically this works like a charm, & there are still issues with the timer, but that will be solved in my main code with another sensor.

I don't think, that your current approach will work. The logic seems flawed to me (though I cannot know, how exactly this code is embedded in your actual code) and the frequency is that high, that it will be difficult for the microcontroller to do much between the different interrupt triggers.
I would suggest 2 different approaches, based on the actual needs:

You can build a demodulator, which just gives you a high value, when your signal is there, and a low one, if it is not. Here you would need extra components.

You could feed the signal into one of the timers as clock source. Then the timer counts the pulses (actually twice the pulses, since the timer increments on every edge, rising or falling). You can use the overflow interrupt to get the value out of it. Lets say you use Timer 1 for the signal and still have Timer 0 for doing the Arduino time stuff (delay(), millis(), micros()). Then you can write an ISR for the Timer1 overflow interrupt. In there you take the current time and subtract the time of the last interrupt. Then you get the time, that it took the timer to overflow. Since you know, how many pulses are needed to overflow the timer, you now know the average frequency. If it is in the needed range, you set a simple single byte flag variable (be sure to declare it as volatile). You can tune the time for the average for example with the prescaler.
In your main code you can then check for the flag being set and do stuff accordingly. Reset the flag, if you have done stuff, and save a timestamp. Check in your main code, if a specific time has passed since your last timestamp. If yes, that means, that the signal is lost. There you can act accordingly

Thank you so much once again for your suggestions, I will try those out & let you know if it works. I do suspect that in the end i would have to go to the de-modulator approach.

My apologies!!! The frequency is in KHz not MHz. I double checked it with a scope. Nonetheless.. i will try out your suggestions.

@MalikElahi, this new frequency changes everything! :) Also, the details you have provided us in your comments everywhere need to be in your question. Please update your question with all your new details and I'll see if I can provide an answer today. What you want to do is certainly doable.

@GabrielStaples Thank you so much, Yes certainly i will update the question. I tried my the code as suggested by chrisl to change the 'rising' to 'change' & it is working, but there is still few bugs & i am 90% sure that it gets stuck in timer interrupt or since the timer count is not a whole number the timer is off by couple of micro seconds

@MalikElahi you should consider to use direct port manipulation instead of calls to digitalWrite(). From my experience the highest frequency you can achieve with digitalWrite() is ~500Hz on an arduno uno. Actually, I wonder how you get this working at 7kHz.


text:
Which Arduinos support ATOMIC_BLOCK?
Is there a definitive list of which Arduino architectures support the ATOMIC_BLOCK() macro, and a list of #defines for each architecture?
I've tried searching through the Arduino cores on GitHub to see where ATOMIC_BLOCK is used. If it's not used in a core, I've assumed it's not supported. I generated this list based upon that assumption, but how accurate is it?
ArduinoCore         Supported       Archived    #define
-------------------------------------------------------
  samd
  avr                  Yes                      __AVR__
  arc32
  sam                  Yes
  primo                               Yes
  megaavr              Yes
  API
  nRF528x-mbedos
  mbed

I would like to write some code, something like this (edited in response to comments):
#define ATOMIC_BLOCK_SUPPORTED (__AVR__ || __MEGAAVR__ || __SAM__)
.
.
.
#if ATOMIC_BLOCK_SUPPORTED
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
#endif

        // Do not disturb.

#if ATOMIC_BLOCK_SUPPORTED
    }
#endif

For architectures that don't support ATOMIC_BLOCK, I would like to write my own code to save, disable and restore the global interrupt flag, something like this.
    asm
    {
        // Save interrupt flag.
    }
    // Clear interrupt flag.
    // Do not disturb.
    // Restore interrupt flag.

Potential Solution?
#ifdef __AVR__
#include <util/atomic.h>
#elif defined(__ARCH2__)
#define ATOMIC_BLOCK(/* for architecture 2 */)
#elif defined(__ARCH3__)
#define ATOMIC_BLOCK(/* for architecture 3 */)
// etc
#endif
.
.
.
#ifdef ATOMIC_BLOCK
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
#endif

        // Do not disturb.

#ifdef ATOMIC_BLOCK
    }
#endif

Is there a definitive list of code that saves, disables and restores the global interrupt flag for every Arduino architecture that could be dropped into each #elif branch?

Have you tried #ifdef ATOMIC_BLOCK?

Or even: #ifndef ATOMIC_BLOCK /* define your own ATOMIC_BLOCK here */ #endif

Have you found any one that doesn't support it?

Have you actually tried it on all those architectures?

Note that, on AVR, ATOMIC_BLOCK is not provided by the Arduino core, but by the avr-libc.

Please note that your idea of concatenating #defined symbols and use #ifdef on that will not work. Better try to #define X (defined(A) | defined(B) | defined(C)) and check with #if X.

Thanks @edgar-bonet and @the-busybee. I'm currently reading Identifying... and Platform Specification. Seems to be a perennial issue that no-one has yet holistically addressed. Thinking I might have to data-scrape all the Arduino forums for #defines...

@tim, see if my answer provides what you need. This is a topic I've studied a lot about.

This answer covers: Which Arduinos support ATOMIC_BLOCK? And how can I duplicate this concept in C with __attribute__((__cleanup__(func_to_call_when_x_exits_scope))) and in C++ with class constructors and destructors?.
Which Arduino's support the ATOMIC_BLOCK macros?

Which Arduinos support ATOMIC_BLOCK?

Only AVR (ATmel AVR architecture) microcontrollers support the ATOMIC_BLOCK macros, because these macros are part of the avr-libc library, which, you guessed it!, supports only AVR microcontrollers.
AVR-based Arduinos include those based on the ATmega328 microcontroller (Arduino Uno, Nano, Mini, etc.), ATmega2560 (Arduino Mega 2560), ATmega32U4 (Arduino Leonardo, Pro Micro), etc.
How are the ATOMIC_BLOCK macros implemented in C with the gcc compiler, and where can I see their source code?
avr-libc is available for download here: https://www.nongnu.org/avr-libc/ --> "source code and documentation" link under the "Downloads" section. Ex: here is the tarball for v 2.0.0: http://download.savannah.gnu.org/releases/avr-libc/avr-libc-2.0.0.tar.bz2.
The entire source code for the ATOMIC_BLOCK macros is contained in avr-libc-2.0.0/include/util/atomic.h.
ATOMIC_BLOCK is an ingenious macro written in C and relying upon the gcc "cleanup" attribute C extension which can call a function you define when a variable goes out of scope. Essentially, this is identical to a C++ class destructor which gets called when an instance of a class in C++ goes out of scope. The gcc "cleanup" attribute extension is a way to get C++-like behavior in C.
Here is the official gcc documentation: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html. It states:

cleanup (cleanup_function)
The cleanup attribute runs a function when the variable goes out of scope. This attribute can only be applied to auto function scope variables; it may not be applied to parameters or variables with static storage duration. The function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
If -fexceptions is enabled, then cleanup_function is run during the stack unwinding that happens during the processing of the exception. Note that the cleanup attribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.

Its format is like this:
int x __attribute__((__cleanup__(func_to_call_when_x_exits_scope))) = 0;

You use it like this:
RUN A REAL EXAMPLE OF THIS CODE IN C ONLINE HERE.
static __inline__ void cleanup_my_byte(uint8_t *my_byte_p)
{
    Serial.print("my_byte is going out of scope! Its value is ");
    Serial.println(*my_byte_p);
}

void setup()
{
    uint8_t my_byte __attribute__((__cleanup__(cleanup_my_byte))) = 7;
} // The following function call occurs automatically here as `my_byte`
  // exits its scope!:
  //    `cleanup_my_byte(&my_byte);`

Studying the avr-libc-2.0.0/include/util/atomic.h file referenced above, you can see how the ATOMIC_RESTORESTATE macro is implemented, using this attribute. I've put just the relevant pieces from that file here:
#include <avr/io.h>
#include <avr/interrupt.h>

#define ATOMIC_BLOCK(type) for ( type, __ToDo = __iCliRetVal(); \
                           __ToDo ; __ToDo = 0 )

static __inline__ uint8_t __iCliRetVal(void)
{
    cli();
    return 1;
}

#define ATOMIC_RESTORESTATE uint8_t sreg_save \
    __attribute__((__cleanup__(__iRestore))) = SREG

static __inline__ void __iRestore(const  uint8_t *__s)
{
    SREG = *__s;
    __asm__ volatile ("" ::: "memory");
}

Note that cli() clears (turns off) interrupts, and sei() sets (turns on) interrupts.
So, you can see that ATOMIC_RESTORE_STATE gets replaced by uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG, which backs up the global interrupt state from the AVR SREG 8-bit register into sreg_save, then calls this function call when sreg_save exits its scope: __iRestore(&sreg_save);. That function call to __iRestore() then sets the SREG register back to where it was, restoring the interrupt state (turning it ON if it was ON before, or OFF if it was OFF before).
The official documentation for ATOMIC_BLOCK is here: https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html. An example usage is this:
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
    my_var_copy = my_var;
}

The ATOMIC_RESTORESTATE part backs up the SREG register and sets up the call for __iRestore(&sreg_save); to occur when sreg_save exits this block scope, as we've already discussed, and the ATOMIC_BLOCK part gets converted into this: for ( ATOMIC_RESTORESTATE, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ). This means that the entire block is now an ingenious for loop which runs only once! Prior to entering the for loop block, __iCliRetVal() is called once, clearing (turning OFF) interrupts, and __ToDo is set to 1, or true, so the for loop runs at least once, and then at the end of the first run it is set to 0, or false, to stop the for loop after one single run! As we've already gone over, the sreg_save variable now goes out-of-scope at the closing brace and the call to __iRestore(&sreg_save); is made, via the gcc extension, to restore the interrupt state! Ingenious!
How could you implement the ATOMIC_BLOCK functionality in Arduino in C++ (as opposed to avrlibc's gcc C version)?
In C++ (Arduino is C++, so we don't have to be limited to just C plus gcc extensions, as was the constraint in the avrlibc ATOMIC_BLOCK macros), you can get a similar effect using destructors in structs or classes (or, just use the avrlibc pattern shown above if you like, as that gcc C code is also perfectly valid gcc C++ code!).
Option 1: example to create a usage style similar to C++'s std::lock_guard
This, for example, would implement a form of ATOMIC_BLOCK(ATOMIC_FORCEON) {}, using a simple class in C++:
It relies on Arduino's built-in functions interrupts() (same as avrlibc's sei() function) and noInterrupts() (same as avrlibc's cli() function). I wish that Arduino also had built-in saveInterrupts() and restoreInterrupts() functions, but unfortunatley they don't. Someone will have to go file a feature request and request them, or implement them themselves and do a Pull Request (PR) on GitHub to try to get them back into the main Arduino branches.
RUN A REAL EXAMPLE OF THIS CODE IN C++17 ONLINE HERE.
#define ATOMIC_BLOCK_FORCEON AtomicBlockForceOn atomicBlockForceOn_

class AtomicBlockForceOn
{
public:
    // Constructor: called when the object is created
    inline AtomicBlockForceOn()
    {
        noInterrupts(); // turn interrupts OFF
    }

    // Destructor: called when the object is destroyed (ex: goes
    // out-of-scope)
    inline ~AtomicBlockForceOn()
    {
        interrupts(); // turn interrupts ON
    }
};

That's it! Now use it like this:
uint16_t my_var_copy;
{
    ATOMIC_BLOCK_FORCEON;
    // now do whatever you want here, with interrupts disabled; ex:
    my_var_copy = my_var;
} // the `atomicBlockForceOn_` object's destructor is called here
  // and interrupts are automatically turned back ON!

Pretty cool!
This, I imagine, is probably exactly how C++'s std::lock_guard is implemented! Its usage is very similar:
void safe_increment()
{
    const std::lock_guard<std::mutex> lock(g_i_mutex);
    ++g_i;

    std::cout << std::this_thread::get_id() << ": " << g_i << '\n';

    // g_i_mutex is automatically released when lock
    // goes out of scope
}

Option 2: example to create a usage style similar to avrlibc's ATOMIC_BLOCK macros
To obtain a usage style of ATOMIC_BLOCK(ATOMIC_FORCEON) { } in C++ one can definitely use the gcc C style which avrlibc uses, since that is also valid C++, but let's continue with the C++ class style shown just above instead, with just a few tweaks. We will add a couple more helper macros and a couple more functions to the class to make this work. Here it is, with a usage example shown at the end which is identical to how avrlibc's ATOMIC_BLOCK can be used! I think this is pretty cool too.
RUN A REAL EXAMPLE OF THIS CODE IN C++17 ONLINE HERE.
#define ATOMIC_BLOCK(type) for(type; type##_OBJECT_NAME.run(); \
    type##_OBJECT_NAME.stop())
#define ATOMIC_FORCEON_OBJECT_NAME atomicBlockForceOn_
#define ATOMIC_FORCEON AtomicBlockForceOn ATOMIC_FORCEON_OBJECT_NAME

class AtomicBlockForceOn
{
public:
    // Constructor: called when the object is created
    inline AtomicBlockForceOn()
    {
        noInterrupts(); // turn interrupts OFF
    }

    // Destructor: called when the object is destroyed (ex: goes
    // out-of-scope)
    inline ~AtomicBlockForceOn()
    {
        interrupts(); // turn interrupts ON
    }

    // Can we run? Returns true to run the `for` loop or
    // `false` to stop it.
    inline bool run()
    {
        return run_now;
    }

    // Tell the `for` loop to stop
    inline void stop()
    {
        run_now = false;
    }

private:
    bool run_now = true;
};

Use it like avrlibc's ATOMIC_BLOCK() { } macro!
Usage example:
uint16_t my_var_copy;
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
    // now do whatever you want here, with interrupts disabled; ex:
    my_var_copy = my_var;
} // the `ATOMIC_FORCEON_OBJECT_NAME` (`atomicBlockForceOn_`) object's
  // destructor is called here and interrupts are automatically
  // turned back ON!

Further reading:

Nick Gammon's excellent "Interrupts" page, which is how I first got started learning about interrupts in 2012~2014 or so: https://gammon.com.au/interrupts.
Other answer's I've done about interrupts, locks/guards, and things:

global volatile variable not being updated in ISR
My own race condition problem: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why
My own race condition solution, demonstrating 3 (or 4, depending on how you look at it) ways to enforce "atomic access guards" on AVR-based 8-bit Arduinos: https://stackoverflow.com/questions/36381932/c-decrementing-an-element-of-a-single-byte-volatile-array-is-not-atomic-why/39693278#39693278

What's that weird type##_OBJECT_NAME thing I did in the macro anyway? Read more about macro token concatenation using the ## preprocessor operator in the official gcc C++ user manual here: https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html. Note: this also works in C of course.
gcc inline or __inline__, and static inline or static __inline__ rules:
https://gcc.gnu.org/onlinedocs/gcc/Inline.html

Thanks. That's a great answer. I'd previously read some of your Further Reading (points 1 & 2i-iii) while researching the issue. I was about to collate it, but you've saved me the job by creating an excellent reference post. The macro with the for  loop and Option 1 & 2 with the class are what I was looking at implementing, so thanks for a clear explanation of them. Now need to figure out what to put in the macro __iRestore and the class constructure/destructor to save/restore the global interrupt flag for each architecture.

Correct. You have to figure out how to disable/enable interrupts now for each architecture, then put the appropriate code into the constructor/destructor. Here's how to do it on STM32, for instance, which is used in the Arduino "professional" line such as the $103 Portenta H7, based on the STM32H7 microcontroller: prim = __get_PRIMASK();, __disable_irq();, if (!prim) { __enable_irq(); }. That's using the low-level CMSIS libraries.

You can also use a half dozen other techniques, including the STM32 core libraries and the FreeRTOS libraries (if using the FreeRTOS real time operating system). I have personal notes on it all that I need to publish on my website someday. 32-bit microcontrollers are beasts. I have no idea how to do it on Atmel/Microchip 32-bit SAM or SAMD microcontrollers, such as the Zero or Due, but there are ways for all chips, you just have to figure them out.


text:
A9G GSM not connecting to teensy 4.0
Below is my current code for connecting to the A9G. As far as I can tell, it never actually opens a connection as HWSERIAL.println("AT"); does not return anything. Any ideas would be appreciated.
The TX and RX pins of the A9G connected to the 0 and 1 pins on the teensy
    #include <SoftwareSerial.h>

    #define HWSERIAL Serial1

    void setup()
    {
      //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
      Serial.begin(115200);

      //Begin serial communication with Arduino and A6
      HWSERIAL.begin(115200);

      Serial.println("Initializing...");
      delay(1000);

      HWSERIAL.println("AT"); //Once the handshake test is successful, it will back to OK
      updateSerial();
    }

    void loop()
    {
      updateSerial();
    }

    void updateSerial()
    {
      delay(500);
      while (Serial.available())
      {
        HWSERIAL.write(Serial.read());//Forward what Serial received to Software Serial Port
      }
      while(HWSERIAL.available())
      {
        Serial.write(HWSERIAL.read());//Forward what Software Serial received to Serial Port
      }
    }

you said nothing about the connections, so there may be none

I've got the TX and RX pins of the A9G connected to the 0 and 1 pins on the teensy

What voltage did you use to power the A9G module? Most GSM modules need something higher than 3.5V for their radio stage. Doublecheck the module datasheet.

@ChrisH its running on 5v


text:
timing changes once DC motors are connected to power
I'm using an arduino uno with two DC motors. I'm also using the built in LED to tell me when the motors should be on as a debug tool. The code is a simple while loop that turns both the motors and the LED on for 10 seconds, and off for 5, and repeat, while a witch is on. This works fine when the motors are not connected to power (when the switch is on, the LED turns on for 10 secs, off for 5 and repeat), but when the motor driver is connected to the power the timing is changed. The motors and the LED are on for less than a second, and off for 5. the "on" period changes a bit, once it even reached the intended 10 seconds.
Why is that and how do I fix that? I tried changing batteries (though i don't know how that might change things, as the led is also working incorrectly and it works of a seperate power source).
the Arduino is connected to a 9V battery and the motors are connected to 4 AA batteries through a L298N motor driver.
this is my code:
#include <Arduino.h>
int RightSpeedPin = 5;
int Rdir2 = 6;
int Rdir1 = 7;
int led = 13;
int LeftSpeedPin = 10;
int Ldir2 = 8;
int Ldir1 = 9;
int SwitchPin = 4;
int ReadVal;
void setup() {
  // put your setup code here, to run once:
  pinMode(Rdir1, OUTPUT);
  pinMode(Rdir2, OUTPUT);
  pinMode(RightSpeedPin, OUTPUT);
  pinMode(LeftSpeedPin, OUTPUT);
  pinMode(Ldir1, OUTPUT);
  pinMode(Ldir2, OUTPUT);
  pinMode(SwitchPin, INPUT);
  pinMode(led, OUTPUT);
}

void loop() {
  ReadVal = digitalRead(SwitchPin);
  while (ReadVal == 1)
  {
    digitalWrite(led, HIGH);
  // starting situation- both motors heading forward
    // running for 10 secs
    digitalWrite(Rdir1, HIGH);
    digitalWrite(Ldir1, HIGH);
    digitalWrite(Rdir2, LOW);
    digitalWrite(Ldir2, LOW);
    analogWrite(RightSpeedPin, 255);
    analogWrite(LeftSpeedPin, 255);
    delay(10000);
    // off for 5
    analogWrite(RightSpeedPin, 0);
    analogWrite(LeftSpeedPin, 0);
    digitalWrite(led, LOW);
    ReadVal = digitalRead(SwitchPin);
    delay(5000);
  }
}

link to the schematics. its rough, I'm not very experienced at drawing schematics. Note that all the ground wires are connected to a breadboard ground rail other that the 9V that powers the arduino. its connected with a round plug, so i don't have individual wires.
EDIT: fixed the schematic

A schematic of your setup would help.  Maybe a picture if all wires can be clearly seen.  Also your sentence: "...and it works of a seperate power source)." sounds important but is confusing.  I'd write an ANSWER, but I am only guessing w/o a schematic... did you connected the 5V power between the Arduino and L298N motor board?

my first guess is that the state of the switch is not being detected correctly ... use a pullup resistor ... second guess is that the arduino is resetting ... you have no code to tell you when setup() executes ... use Serial.print() for debugging messages ... or blink the led twice inside setup()

added schematics.
what would blinking inside of the setup tell me?

think about when setup() executes ... read all of my comment again

Please embed the schematic in your question, do not use external resources, as they can disappear.

the battery symbols are drawn backwards

After debugging by printing:
sTime = millis();
analogWrite(RightSpeedPin, 255);
analogWrite(LeftSpeedPin, 255);
delay(5000);
analogWrite(RightSpeedPin, 0);
analogWrite(LeftSpeedPin, 0);
Serial.print(millis() - stime);

I got times that are less than 300 ms, and no reset (added print to setup). I still have no idea why.
after that, I just replaced delay with while (millis() < Stime + t) { which solved my problem.


text:
Arduino resets or stuck during run, only when DC motors are connected
I'm using an arduino connected to 2 DC motors through L298N. the arduino is powered by a 9V battery, and the L298N is powered by 4 AA batteries. there's also a switch that starts the movement.
I've added print statements to debug, one in the setup, one in the start of the loop, and two before and after running so i know when the motors start and how long they run. I also print the state of the switch. this is what i get:
1                          // switch state. 1  means off.
loop                       // start of loop statement
1
loop
0                          // switch state changed to on
0                          // added another switch check after the if
Forward for: 5 seconds     // motors on
setup                      // reset for some reason
loop                       // start of loop
0                          // switch still on
setup                      // another reset
loop
0
0
Forward for: 5 seconds     // motor starts again
setup                      // another reset
loop
0
0
Forward for: 5 seconds     // stuck with the motors on, no more resets

its not always this bad, sometimes it runs once or twice correctly (for five seconds) and then off. some times it gets stuck on without reseting. also, sometimes it starts reading the switch value as 1 after a few seconds of reading the correct value, even though the switch wasen't moved. also, when I remove one of the motor batteries so they don't get power everything works great.
What causes the reset and the freezing? How can I fix that?
this is my code:
#include <Arduino.h>
int RightSpeedPin = 5;
int Rdir2 = 6;
int Rdir1 = 7;
int led = 13;
int LeftSpeedPin = 10;
int Ldir2 = 8;
int Ldir1 = 9;
int SwitchPin = 4;
int ReadVal;
int baseSpeed = 230;
int Stime;
int Etime;

void go(int d) { // d = 1 will move, d = 0 will stop
  analogWrite(RightSpeedPin, (d == 1 ? 230 : 0));
  analogWrite(LeftSpeedPin, (d == 1 ? 255 : 0));
}

void forward(int t) {
  Serial.print("Forward for: ");
  Serial.print(t / 1000);
  Serial.println(" seconds");
  digitalWrite(Rdir1, HIGH);
  digitalWrite(Ldir1, HIGH);
  digitalWrite(Rdir2, LOW);
  digitalWrite(Ldir2, LOW);
  digitalWrite(led, HIGH);
  Stime = millis();
  while (millis() < Stime + t) {
    go(1);
  }
  go(0);
  Etime = millis();
  Serial.print("ran for ");
  Serial.println(Etime - Stime);
  digitalWrite(led, LOW);
}

void spin() {
  digitalWrite(Rdir1, LOW);
  digitalWrite(Rdir2, HIGH);
  digitalWrite(Ldir1, HIGH);
  digitalWrite(Ldir2, LOW);
  Stime = millis();
  while (millis() < Stime + 100) {
    go(1);
  }
  go(0);
}

void setup() {
  // put your setup code here, to run once:
  pinMode(Rdir1, OUTPUT);
  pinMode(Rdir2, OUTPUT);
  pinMode(RightSpeedPin, OUTPUT);
  pinMode(LeftSpeedPin, OUTPUT);
  pinMode(Ldir1, OUTPUT);
  pinMode(Ldir2, OUTPUT);
  pinMode(SwitchPin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  Serial.println("setup");
}

void loop() {
  Serial.println("loop");
  ReadVal = digitalRead(SwitchPin);
  Serial.println(ReadVal);
  if (!ReadVal) {
    delay(500);
    Serial.println(ReadVal);
  // starting situation- both motors heading forward
    // running for 5 secs
    forward(5000);
    delay(1000);
    spin();
  }
}

and this is my scheme:

Does it also freeze if you remove the motors (not their batteries)?

didn't try since it doesn't freeze when i remove the battery. i didn't think removing them completely might have a different result.

Micro processor pull up resistors can vary greatly.  If pulling the motors improves the expected behavior, consider adding a 1K (1K/3V = 3mA) pull up resistor to the enable / disable switch.  If that improves things, try increasing it to 10K (10K/3V = 0.3mA).  As you want to draw as small a current as possible to extend battery life.  Also, avoid routing 9V and 6V battery wires in parallel as much as possible.

@st2000 the problem is that the Arduino is resetting and freezing mid run when the motors are connected, why do you think the pull up resistor is the cause here? I don't get any problems when the motors aren't powered, and the resistor is still in use.
the 9V is connected to the Arduino barrel jack, the 6V is connected to the L298N and the negative rail. there's no crossing.

This looks a bit like the motor driver is causing a voltage drop for the microcontroller, causing it to freeze or reboot. Probably one of the digital lines is drawing to much power, which could be caused by a defective motor driver board.

Brush DC motors (assumed what is being used) are making and breaking contact with inductive loads with each revolution.  That is a lot of noise!  Most small motors come with small capacitors across their input terminals to mitigate problems.  The schematic looks correct. And the code has activated the internal pull up resistor on the enable input.  But if the internal pull up resistor was large, noise could induce a high enough voltage to unexpectedly disable the motors.  Or, perhaps, with enough noise, the processor may see enough supply voltage variation that it unexpectedly resets.

The L298 has a pair of darlington bipolar transistors in each motor lead. This will cause a voltage drop of at least 1.4V or 2.8V to the motor, starving it of power. This is burnt up as heat which your battery is supplying. Also a 9V smoke alarm battery is a bad choice for powering an Arduino even though many place show using it as a power source.

The L298 has a pair of darlington bipolar transistors in each motor lead. This will cause a voltage drop of at least 1.4V on each lead or 2.8V to the motor, starving it of power. This voltage drop is burnt up as heat which your battery is supplying. A 9V smoke alarm battery is a bad choice for powering an Arduino even though many place show using it as a power source. Take a look at this link, it has some nice graphs showing just how much the voltage drop will be.
https://www.powerstream.com/9V-Alkaline-tests.htm The maximum current draw of the Arduino R3 is in the range of 200mA. Try connecting several 9V batteries in parallel and if the problem disappears should the 9V battery.

When brushed motors are involved I usually think of arc suppression caps across the motor terminals, 100 mF or larger cap across the motor power supply, solid common (GND) connections. Sparking motor commutators can cause all sorts of problems.

I've tried with a 4700uF 16V cap  across the motor driver and the common ground, its the highest F i could get and it did nothing. should i order a stronger cap online?


text:
Program work when used Delay() but same program doesn't work with millis()
I'm running a dc motor using esp32 and mosfet by taking readings of IR.
Program works fine when used delay() but same program doesn't work when uploaded using millis().
//This uses fixed delay()

// Pin definitions
const int irSensorPin = 34;  // IR sensor connected to GPIO 2
const int motorPin = 32;     // DC motor connected to GPIO 4

// Variables
bool isObjectDetected = false;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Set pin modes
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  // Check if object is detected
  if (digitalRead(irSensorPin) == LOW) {
    if (!isObjectDetected) {
      // Object detected for the first time
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Stop the motor
      delay(500);                   // Wait for 500ms
      Serial.println("Resuming motor.");
      digitalWrite(motorPin, HIGH); // Start the motor
    }
  } else {
    if (isObjectDetected) {
      // Object is no longer detected
      isObjectDetected = false;
    }
  }
}

//This uses millis()

// Pin definitions
const int irSensorPin = 34;  // IR sensor connected to GPIO 34
const int motorPin = 32;     // DC motor connected to GPIO 32

// Variables
bool isObjectDetected = false;
unsigned long motorStopTime = 0;
const unsigned long motorDelayTime = 500;  // Delay time in milliseconds

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Set pin modes
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);

  // Initialize motor state
  digitalWrite(motorPin, HIGH);  // Start the motor
}

void loop() {
  // Check if object is detected
  if (digitalRead(irSensorPin) == HIGH) {
    if (!isObjectDetected) {
      // Object detected for the first time
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Stop the motor
      motorStopTime = millis();     // Record the stop time
    }
  } else {
    if (isObjectDetected) {
      // Object is no longer detected
      isObjectDetected = false;
      unsigned long currentTime = millis();
      if (currentTime - motorStopTime >= motorDelayTime) {
        Serial.println("Resuming motor.");
        digitalWrite(motorPin, HIGH); // Start the motor
      }
    }
  }
}

“doesn't work” is not a useful description of the problem. What is the expected behavior? What is the actual behavior?

@EdgarBonet Sorry for my bad clarification. I have made a program where IR sensor detects object and the dc motor has to turn off for 1 sec or 500ms. In first of my program it works fine. motor starts normally, ir detects object and tell motor to wait for 1 sec and then motor starts again after 1 second even if ir sensor is detecting object ahead. In my second program, I'm using millis() with 500ms delay but that program doesn't start the motor normally.

I posted a code example to a similar question at https://arduino.stackexchange.com/questions/93115/arduino-dc-motor-control-over-ir-sensor-input ... it includes a link to a simulation

@jsotola switch?

What print statements are you seeing? Could be that the input in "chattering" since you are not debouncing it at all, and so motorStopTime is continuing to get reset to the current time.

switch? ... I have no idea what that means

I am not sure I quite understand what the requirements are for this
program. However, they do not do the same thing. I tried to represent
their behavior as state diagrams, and here is what I got:
Version using delay():

Version using millis():

In the above diagrams, states with a gray background are those where the
motor is off. As can be seen here, the first version never keeps the
motor off for more than 0.5 s, where the second one can keep the
motor indefinitely off if the sensor remains HIGH.
I suggest you start by drawing the state diagram corresponding to the
behavior you actually want. Then, use the technique outlined in this
tutorial on finite state machines to turn the diagram into code.
Note that finite state machines work well with millis()-based timing.


text:
MHZ19B Sensor - Library not found- Please Help!
I can't seem to figure out what the problem is here. I am trying to upload this code to Arduino Uno but it keeps telling me that the library is not found. I did download the library for the MHZ sensors but it doesn't like it.
I am somewhat new to Arduino.
Please help!
This is the code:
// Libraries
#include <DHT.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <MHZ19B.h>

// Constants
const int chipSelect = 10;   // SD card chip select pin
#define DHTPIN 7             // DHT sensor pin
#define DHTTYPE DHT22        // DHT sensor type
#define MHZ19B_TX_PIN 8      // MHZ19B sensor TX pin
#define MHZ19B_RX_PIN 9      // MHZ19B sensor RX pin

// Variables
DHT dht(DHTPIN, DHTTYPE);
File dataFile;

MHZ19B mhz19b;
float hum;      // Humidity value
float temp;     // Temperature value
int lightVal;   // Light sensor value
int co2;        // CO2 concentration

void setup()
{
  Serial.begin(9600);
  dht.begin();

  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  Serial.println("card initialized.");

  Serial.print("Initializing MHZ19B sensor...");
  mhz19b.begin(MHZ19B_TX_PIN, MHZ19B_RX_PIN);
  Serial.println("MHZ19B sensor initialized.");
}

void loop()
{
  lightVal = analogRead(A1);
  Serial.print("Light Value: ");
  Serial.println(lightVal);
  delay(50);

  hum = dht.readHumidity();
  temp = dht.readTemperature();
  Serial.print("Humidity: ");
  Serial.print(hum);
  Serial.print(" %, Temp: ");
  Serial.print(temp);
  Serial.println(" Celsius");
  delay(5);

  co2 = mhz19b.getCO2();
  Serial.print("CO2 Concentration: ");
  Serial.print(co2);
  Serial.println(" ppm");

  dataFile = SD.open("datalog.txt", FILE_WRITE);

  if (dataFile) {
    dataFile.println("Light Value: ");
    dataFile.println(lightVal);
    delay(50);

    hum = dht.readHumidity();
    temp = dht.readTemperature();
    dataFile.print("Humidity: ");
    dataFile.println(hum);
    dataFile.print(" %, Temp: ");
    dataFile.println(temp);
    dataFile.println(" Celsius");

    co2 = mhz19b.getCO2();
    dataFile.print("CO2 Concentration: ");
    dataFile.print(co2);
    dataFile.println(" ppm");

    delay(5000);
    dataFile.close();
  }
  else {
    Serial.println("Error opening datalog.txt");
  }

  delay(1000);
}

look at the example code in the library

That's because it should be either #include <MHZ.h> for the MH-Z CO2 Sensors library or #include <MHZCO2.h> for the MHZCO2 one.
How do you typically include the libraries you download? Thru the library manager? The way you can do it in Arduino IDE 2.0 is going  thru Sketch -> Include Library -> the library you want to include -- that should include the correct header.

Yes. The library manager. Thank you for your help. I will try this.

@Maria you're welcome! As jsotola mentions above, take a look at the example in the library (if you're going to use the MH-Z CO2 Sensors one) - the way the sensor is initialized is a bit different than how you've done it in the sketch you've provided.

Ok. I will take a look. I am not fluent with Arduino code but I will check and see if I can modify and make it work.


text:
LED doesn't completely turn off with digitalWrite(led, LOW);
When I was testing out a program I found a strange behavior of ESP8266.
LEDs don't turn off completely in the first digitalWrite(led, LOW), just the brightness of the LED goes down, but it does turn off in the second digitalWrite(led, LOW).
I don't know if it's related to the code or the circuit, so here are both (the program is just two different visual patterns of LEDs toggled by a button)
#define led1 D0
#define led2 D1
#define led3 D2
#define led4 D3
#define button D7

unsigned long pressedButton;
bool change = 0;
unsigned long previousTime = millis();
unsigned int difference;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop(){
  if (!digitalRead(button) && millis()-pressedButton>200){       //check if button was pressed to change visual pattern of leds
      pressedButton = millis();
      change = !change;
      digitalWrite(led1, LOW);         //here led completely turn off
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      previousTime = millis();
  }

  difference = millis()-previousTime;

  if (!change){                                     //default visual pattern of leds
    if (!digitalRead(led1) && difference>=200){
      digitalWrite(led1, HIGH);
    }
    if (!digitalRead(led2) && difference>=400){
      digitalWrite(led2, HIGH);
    }
    if (!digitalRead(led3) && difference>=600){
      digitalWrite(led3, HIGH);
    }
    if (!digitalRead(led4) && difference>=800){
      digitalWrite(led4, HIGH);
    }
    if (difference>=1000){
      digitalWrite(led4, LOW);           //the leds just shrink here
    }
    if (difference>=1200){
      digitalWrite(led3, LOW);
    }
    if (difference>=1400){
      digitalWrite(led2, LOW);
    }
    if (difference>=1600){
      digitalWrite(led1, LOW);
      previousTime = millis();
    }
  }

  if (change){                    //alternative pattern
     if (!digitalRead(led1) && difference>=200 && change){
       digitalWrite(led1, HIGH);
       digitalWrite(led4, HIGH);
       digitalWrite(led2, LOW);
       digitalWrite(led3, LOW);
    }
    if (digitalRead(led1) && difference>=400 && change){
       digitalWrite(led1, LOW);
       digitalWrite(led4, LOW);
       digitalWrite(led2, HIGH);
       digitalWrite(led3, HIGH);
       previousTime = millis();
    }
  }
}

Actually, it's a NodeMCU Esp8266, with the pins defined on the code and a 470 ohms resistor.  (obs: resistor is not shorted, in my breadboard those rows are separated)

That resistor won't do anything with the conductor running underneath it in parallel.

Leds doesn't turn off completely ... how do you know this? ... maybe they are turning on and off very fast ... reduce your code to turn on led, delay 1 second, turn off led, delay 1 second, and repeat

have you checked the connection between wires and tried a new led?

@timemage Sorry, I forgot to mention that in my breadboard the bottom row is separated for some reason

if (!digitalRead(led3) && difference>=600){
  digitalWrite(led3, HIGH);
}
if (!digitalRead(led4) && difference>=800){
  digitalWrite(led4, HIGH);
}
if (difference>=1000){
  digitalWrite(led4, LOW);           //the leds just shrink here
}
if (difference>=1200){
  digitalWrite(led3, LOW);
}

Consider what will happen when the difference is >= 1000.
If the LED is off you turn it on (because it passes the first test, the difference is >= 600), and a moment later you turn it off. So the LEDs are being turned on and off in quick succession, which makes them look dim.
Try re-ordering the tests, and add else for each subsequent one. That seems to work for me:
  if (!change){                                     //default visual pattern of leds
    if (difference>=1600){
      digitalWrite(led1, LOW);
      previousTime = millis();
    }
    else if (difference>=1400){
      digitalWrite(led2, LOW);
    }
    else if (difference>=1200){
      digitalWrite(led3, LOW);
    }
    else if (difference>=1000){
      digitalWrite(led4, LOW);
    }
    else if (!digitalRead(led4) && difference>=800){
      digitalWrite(led4, HIGH);
    }
    else if (!digitalRead(led3) && difference>=600){
      digitalWrite(led3, HIGH);
    }
    else if (!digitalRead(led2) && difference>=400){
      digitalWrite(led2, HIGH);
    }
    else if (!digitalRead(led1) && difference>=200){
      digitalWrite(led1, HIGH);
    }
  }

Also, that resistor on the bottom row isn't achieving anything because all the pins on the bottom row are connected together so it is just shorted out. Not good for the LEDs or the processor.

Thank you! I didnt see that problem on code. And sorry, I forgot to mention that my breadboard have the bottom row separated so it's not shorted.


text:
ESP8266 seems to be killing a while loop
When i was testing out a program I found a strange behavior of esp8266
It seems to get out of a while loop even when there's no option of getting out on code
I don't know if these are related but here's the code
(the program is just two different visual patterns of leds toggled by a button)
#define led1 D0
#define led2 D1
#define led3 D2
#define led4 D3
#define button D7

unsigned long pressedButton;
bool change = 0;
unsigned long previousTime;
unsigned int difference;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop(){
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);         //when the while loop change, this should delete interference
  digitalWrite(led4, LOW);
  previousTime = millis();

  while (!change){                                      //default visual pattern of leds
    difference = millis()-previousTime;

    if (!digitalRead(led1) && difference>=200){
      digitalWrite(led1, HIGH);
    }
    if (!digitalRead(led2) && difference>=400){
      digitalWrite(led2, HIGH);
    }
    if (!digitalRead(led3) && difference>=600){
      digitalWrite(led3, HIGH);
    }
    if (!digitalRead(led4) && difference>=800){         //after here, all the leds should be HIGH
      digitalWrite(led4, HIGH);
    }
    if (digitalRead(led4) && difference>=1000){
      digitalWrite(led4, LOW);
    }
    if (digitalRead(led3) && difference>=1200){
      digitalWrite(led3, LOW);
    }
    if (digitalRead(led2) && difference>=1400){
      digitalWrite(led2, LOW);
    }
    if (digitalRead(led1) && difference>=1600){        //after here, all the leds should be LOW
      digitalWrite(led1, LOW);
      previousTime = millis();
    }

    if (!digitalRead(button) && millis()-pressedButton>200){       //check if button was pressed to break while loop
      pressedButton = millis();
      break;
    }
  }

  while (change){                                         //alternative of visual pattern of leds
    difference = millis()-previousTime;

    if (!digitalRead(led1) && difference>=200){
      digitalWrite(led1, HIGH);
      digitalWrite(led4, HIGH);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
    }
    if (digitalRead(led1) && difference>=400){
      digitalWrite(led1, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, HIGH);
      previousTime = millis();
    }

    //if (!digitalRead(button) && millis()-pressedButton>=200){     //check if button was pressed to break while loop
    //  pressedButton = millis();
    //  break;
    //}
  }

  change = !change;         //after a break in one of the while loops, this will make the program go to the other while loop
 }

Is there something wrong with the code?
Here is a link of a video of the behavior for more details
https://drive.google.com/file/d/1822MHNGQn-A2-HGHhRXz_8xydz-wM4Ha/view?usp=sharing

You can't trap an ESP in a while loop like that.  There are things it needs to get back to main and do between loops.  Instead, let the loop function be your loop.  Make the while statements if statements and where you have break, that's where you change the change variable.  Put the code at the top in an if statement that checks to see if change has changed.

@Delta_G Please make an answer and not a comment.

Concerning your LED issue: Even if it happens with your current sketch, please post a separate question for it. When you do, please add a schematic of your circuit.

@NickGammon.  Done.

@the busybee all right I didn't know the problems were not related. Like that? https://arduino.stackexchange.com/questions/93807/led-doesnt-completely-turn-off-with-digitalwriteled-low

Exactly. And you have already an answer.

You can't trap an ESP in a while loop like that. There are things it needs to get back to main and do between loops. Instead, let the loop function be your loop. Make the while statements if statements and where you have break, that's where you change the change variable. Put the code at the top in an if statement that checks to see if change has changed.
#define led1 D0
#define led2 D1
#define led3 D2
#define led4 D3
#define button D7

unsigned long pressedButton;
bool change = 0;
bool oldChange = 1;
unsigned long previousTime;
unsigned int difference;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(button, INPUT_PULLUP);
}

void loop() {
  if (change != oldChange) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);  //when the while loop change, this should delete interference
    digitalWrite(led4, LOW);
    previousTime = millis();
    oldChange = change;
  }

  if (!change) {  //default visual pattern of leds
    difference = millis() - previousTime;

    if (!digitalRead(led1) && difference >= 200) {
      digitalWrite(led1, HIGH);
    }
    if (!digitalRead(led2) && difference >= 400) {
      digitalWrite(led2, HIGH);
    }
    if (!digitalRead(led3) && difference >= 600) {
      digitalWrite(led3, HIGH);
    }
    if (!digitalRead(led4) && difference >= 800) {  //after here, all the leds should be HIGH
      digitalWrite(led4, HIGH);
    }
    if (digitalRead(led4) && difference >= 1000) {
      digitalWrite(led4, LOW);
    }
    if (digitalRead(led3) && difference >= 1200) {
      digitalWrite(led3, LOW);
    }
    if (digitalRead(led2) && difference >= 1400) {
      digitalWrite(led2, LOW);
    }
    if (digitalRead(led1) && difference >= 1600) {  //after here, all the leds should be LOW
      digitalWrite(led1, LOW);
      previousTime = millis();
    }

    if (!digitalRead(button) && millis() - pressedButton > 200) {  //check if button was pressed to break while loop
      pressedButton = millis();
      change = true;
    }
  }

  if (change) {  //alternative of visual pattern of leds
    difference = millis() - previousTime;

    if (!digitalRead(led1) && difference >= 200) {
      digitalWrite(led1, HIGH);
      digitalWrite(led4, HIGH);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
    }
    if (digitalRead(led1) && difference >= 400) {
      digitalWrite(led1, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, HIGH);
      previousTime = millis();
    }
  }

  change = false
}

Thank you! That resolved the unwanted break on the second pattern. But what is the reason for the while loop not working inside another loop?

The loop function is called repeatedly from main().  There are other things in main() that have to happen in between calls to loop.  You can't trap execution inside loop.  You have to let loop exit once in a while or call yield or delay(0).  In your case, you didn't need a while loop since loop is already a loop.


text:
Is there a way to use ESP8266 in promiscuous(monitor) mode and see the the wifi packets?
I didn't find much documentation about ESP promiscuous mode (just from the espressif sdk although I'm using ArduinoIDE https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/api-reference/wifi/esp_wifi.html )
So from seeing some sample codes ( https://github.com/spacehuhn/ArduinoPcap/blob/master/examples/esp8266_pcap_serial/esp8266_pcap_serial.ino and https://www.youtube.com/watch?v=3Ac6X6ZBQ0g ) the esp8266 doesn't work properly for some people but for others (https://www.esp8266.com/viewtopic.php?t=12127) it seems to work properly, so I don't know if it's a hardware limitation.
I tried making a simple sketch to try it for my NodeMCU 0.9 and compared the packets from wireshark and I saw the majority of the packets come incomplete or with anomalies
#include <ESP8266WiFi.h>
#include <Arduino.h>

extern "C" {
#include <user_interface.h>
}

static void ICACHE_FLASH_ATTR handlePacket(unsigned char* buf, uint16_t len) {
  for (int c=0; c < len; c++){
    Serial.printf("%d:%d  ", c, (int)buf[c]);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  Serial. println();

  wifi_set_opmode(STATION_MODE);
  wifi_promiscuous_enable(0);
  WiFi.disconnect();
  wifi_set_promiscuous_rx_cb(handlePacket);
  wifi_set_channel(6);
  wifi_promiscuous_enable(1);
}

void loop(){}

From the example code that works, the guy seems to use esp8266 sdk, is the ArduinoIDE a limitation for this monitor mode thing?
https://bbs.espressif.com/viewtopic.php?t=3072
https://github.com/kieransimkin/esp8266-freedom

Printing to serial from an interrupt is a very bad idea. Real time capture and output of network packets to serial is bound to run into the speed limits of the serial port, so incomplete and/or anomalous output is not unexpected.

Other than what @StarCat mentioned, I think you use the wrong macro ICACEH_FLASH_ATTR, it is supported to be ICACHE_RAM_ATTR.

@hcheung I was just following an example, I didnt really know what that mean, but from here ( https://stackoverflow.com/questions/58113937/esp8266-arduino-why-is-it-necessary-to-add-the-icache-ram-attr-macro-to-isrs-an ) it seems that the best for often called functions is to not have any cache at all

You must have come across this, right? https://github.com/RicardoOliveira/ESPProLib


text:
Stack Mega Shield
I need to support 18 push buttons and 66 IR sensors on my Arduino Mega (model railway). I have a Mega Sensor Shield, but won't have enough pins for all the sensors. Can I get a second sensor shield and nest it some way?
https://www.aliexpress.com/item/1005004554959620.html?spm=a2g0o.order_list.order_list_main.31.1cda18022wJnOM

Can you give a link to the shield in question please? There is almost certainly more than one.

https://www.aliexpress.com/item/1005004554959620.html?spm=a2g0o.order_list.order_list_main.31.1cda18022wJnOM

No, Nick is talking about a schematic @PaulN.  At the very least some sort of specifications.  Honestly, if I were going this route, most model railway setups I have seen are room sized.  Like way over 10 feet from end to end.  With runs like that, you will likely have problems keeping noise out of longer wire runs to/from sensor. I would use multiple Arduinos w/shorter runs.  And pick communication protocols more immune to noise to mitigate any problems.

If I see it right on aliexpress the entire shield essentially consists only of wiring individual pins together, along with power, to form groups of (pin, VCC, GND) couples for each pin. There is no logic, no electronics, nothing, just connectors.
(And reset and LED)

Hi st2000 - sorry, thought Tom was asking what shield I was using. For complete transparency, I already have the Mega set up with the board, and I have 9 AdaFruit PWM Servo boards which drive 23 servos for turnouts, 106 LEDs for the mimic panel indicating turnout routes and block occupancy. The push buttons for the mimic panel are in the sensor shield. Although I can chain more servo boards on, the pins are output pins only, not input, eg, I can't read an IR sensor on them. Therefore I need them on the shield. But I don't have enough pins on the original shield to add the 66 IR sensors.

I may be interpreting your question wrong, but it seems that you're asking if you can somehow get more input pins for your sensor (general-purpose input/output), with which your sensor shield will not help with that. If you want to get more inputs for your sensors, you'll need to use shift registers.
Link to understanding how to add more digital GPIO pins

Thank you - yes that sounds about right. I will get some. Assuming as I have a number of spare GPIO ports on my shield, I can put these to multiple shift registers, if each register supports 8 addresses, I can put 8 chips on a breadboard.

For a model railway, this may not work as well as you are expecting. Sending 66 sensors values and 18 push-buttons along long cable lengths, as may be expected for a model railway, could introduce noise which would give bogus readings. The noise in long, adjacent, cables could be from one cable inducing a voltage in its neighbour, or simply from the railway operations themselves.
It may be better to use something like RS485 which is a balanced protocol. That is, of the two data wires connecting nodes, one is positive and one is negative simultaneously, for a signal to be considered genuine. Noise would tend to influence the cables in the same direction (eg. both positive) and would thus be discarded.
As described in the Wikipedia article, RS485 is used in aircraft for reliability. The wiring is minimal: two wires for data, plus an earth wire. You would also need 5V power available at the nodes.
What I would suggest here is a series of nodes, spread around your railway layout. Each node could be an inexpensive Atmeg328P processor (around $3 on eBay) with a couple of supporting resistors and capacitors. You would use 3 pins for the RS485 (transmit, receive and enable) which would leave 17 inputs for your sensors and switches per node. Thus, around 5 nodes.
You would keep the cabling for the sensors running to each node as short as possible, to reduce noise. Maybe use shielded cable.
I wrote an RS485 non-blocking library - available on Github.
There are some explanations about using it on my website most of which is also on the Github page.
Basically what you would do is give each node an address (stored in EEPROM) and then have a master query each node in turn for the values on its sensors or switches. The node would reply, and then the master could move onto the next one.

I realise this isn't directly answering the question about the Mega shield, but I am trying to answer the underlying problem of how to connect 84 sensors and switches to one Arduino reliably.

Amazing Nick - thank you for the comprehensive write up. I have heard about RS485, and will now look in to this much more. Appreciate your assistance.


text:
How to Connect Two CQRobot Ocean Non-Contact Water/Liquid Level Sensors (CQRSENYW001) to Arduino UNO REV3 (A000066)?
I am a complete beginner trying my hand at a home automation project.
Part of my setup includes using an Arduino UNO REV3 (A000066), and connecting two CQRobot Ocean Non-Contact Water/Liquid Level Sensors (CQRSENYW001).
There is great documentation for the sensor:
http://www.cqrobot.wiki/index.php/Non-Contact_Water/Liquid_Level_Sensor_SKU:_CQRSENYW001
And setting up one sensor is a breeze (see setup in image below):

Red Wire to 5V
Black Wire to GND
Green Wire (Output) to 7

Since there is only one 5V on the Arduino (and since the project could expand), it sounds like I need to use a breadboard to allow for expansion.
I used the following video to connect the Arduino to the breadboard for power:
https://www.youtube.com/watch?v=Ia7gkgSor78
Now to connect the two sensors, do I just need to put the Black and Red Dupont Wires from the sensors anywhere in the - and + columns on the breadboard and connect the green wires back to the Arduino for the output in 6 and 7?
In other words, does the setup look correct below?

I have noticed that doing this seems to work for the most part (there is power) for the sensor, but I just want to make sure I am doing this right. Thanks!

if it works correctly, then you are doing it right

See my answer to your post in the arduino forum.

My answer to this question is there. I am curious why are you using the same question on two forums.


text:
Lilypad sends corrupted data on Serial
I have an Arduino Lilypad with this simple code where I try to write a simple message to the serial console. The baud rate is set to 9600 both in the code as well as in the serial console and I'm using the FTDI UART tool.
However, the output I'm receiving is corrupted and I'm not sure what could be the cause. Any ideas or suggestions are welcome. Thanks!

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(3000);
  Serial.write("Hello World");
}

Arduino is connected to the FTDI tool as shown here

@jsotola I have it connected as shown on the picture here https://i.sstatic.net/axOsO.png

@jsotola updated, but that doesn't really answer my question

Just as an experiment, try changing the code to make the serial port 4800 and if that doesn't work, try 119200. Alternatively, change the speed in the Terminal Monitor window to double or halve the speed.

I say that because it looks like the baud rate is wrong. Don't change both settings at once.

Does the LED blink with the 3-second delay?

@NickGammon changing the baud rate to 4800 while keeping 9600 in the terminal solved this. Now I can see properly written "Hello World" in the console. Can you post it as an answer here and I'll mark it as solved? Also, could you please explain why is that? Thanks a lot

He shouldn't. The answer should follow from the question. What he offered you was perfectly good diagnostic advice. At least he realized that and put it in a comment this time. What you've put in your comment is information that can be integrated into the question. A real answer as to why (or "what" following from what you asked) is still unknown.

What we have now is just an unexplained work-around. We still need to find out the underling reason, why you need different baudrates for your Lilypad and the PC. Is it possible that the IDE thinks that the Lilypad has a 16 MHz clock?

@timemage My answer (now posted) did follow from the question. What else would it follow from?

All three Lilypad boards are 8 Mhz. Of the two non-USB versions that take an FTDI style header, only the matching board definition will upload successfully because they have different bootloader baud rates. As the busybee said, what you have is a workaround. The actual cause and potential problem is still there. Incorrect fuses, wrong bootloader, boards.txt has been altered, core altered to set CLKPR, who knows? And we and future readers not going to know as things stand. I appreciate that you're happy to see your message printing though.

@timemage I agree we haven't solved the underlying problem, but without knowing exactly what board they selected, whether or not boards.txt was altered, the fuses on the Lilypad, etc. then the solution remains as a work-around. However quite possibly no-one else will have this exact problem. Even if they did, how would we know for sure it was the same problem?

It looks like the wrong baud rate. That often results in garbage characters. You said in a comment that halving the baud rate on the Arduino end seemed to synchronize the baud rates, and you could see proper characters.
I'm a bit puzzled by that because you were evidently able to upload the sketch in the first place. Therefore the baud rate was correct during the uploading process.
Looking in the file boards.txt which you should find somewhere in your Arduino installation, there appear to be a number of Lilypad variants. Perhaps you inadvertently chose the wrong one in the "Board" menu in the IDE?
It looks like the correct baud rate was used for the uploading, but the code generated by the compiler (because of settings passed by the IDE) thought that the board was running at half the speed it actually was (so it set the baud rate clocks to run faster), so by reducing the baud rate in the Serial.begin they became in sync.
You could just live with the difference, or try experimenting with choosing different Lilypad board types.
If the baud rate is wrong, probably the delays will be wrong too, whether or not that matters is up to you.