body:
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

```Multiple Timer  RTC3231+LCD+Single Relay+Everyday+eeprom

#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 [![Schematic][1]][1]

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

  [1]: https://i.stack.imgur.com/Wa8vN.png

title: Integrating blinking light code and time on/off code

Answers: 0


body:
This is not about using a capacitive button to control an Arduino; it is the opposite. I would like to "touch" a capacitive button on another conventional device. There could be a way like actually moving a finger-like stick and touch the button, but that is too much work. Can't it be done non-mechanically?

According to this page ( https://scienceline.org/2012/01/okay-but-how-do-touch-screens-actually-work/ ), "Instead, they work with anything that holds an electrical charge – including human skin.". Then, can I emulate "touching" the button by sending some small electrical current?

If so, what module/parts do I need to send such small current?

title: Touching a capacitive button, non-mechanically

Answers: 1

body:
The simply way is making a little capacitor.
Cut 2 circle with aluminium from a can and put a paper between them, then solder one one to one circle and other to the other side. One wire goes to the positive and the other to the I/O. When you set to 1 it should create a capacitive charge and "touch" de button.


body:
I am developing a project based in Arduino Nano and 2 sensors. In this projects is very important the energy because of the prototype is going to be powered by batteries or solar power.
In order to save energy in the
```
void loop(){....}
```
I am only getting the value of a temperature sensor continuously in a method that returns true / false.
When the method returns true, one relay is activated by Arduino, and it provides energy to the ESP8266-01 module and other sensor.
At this moment I need to connect the ESP8266 to WiFi network, and after the WiFi connection is successfully, I need to read other sensor value 50 times and make a connection with
```
client.connect(server, 80)
```
and send sensor data with GET method to upload every sensor value to server.
In this way I am able to send the first read, but for further sensor reads the connection to server gives error

My code resumed:

```
void setup(){
  // Setup sensors...
}

void initWifi(){
  // Open ESP8266 connection to WiFi network
}

boolean tempetarure_read(){
  // read continuously the temp sensor...
}

void loop(){
  if(tempetarure_read()){
    digitalWrite(relayPin, HIGH); //Open relay to give energy to ESP8266 module
    read_other_sensor_and_send_to_server();
    digitalWrite(relayPin, LOW); // Switch off the relay
  }
}

void read_other_sensor_and_send_to_server(){
  for (int x = 0; x < 50; x++) {
    string sensor_data = get_sensor_data();

    Serial.println();
    Serial.println("Starting connection to server...");
    // if you get a connection, report back via serial
    if (client.connect(server, 80)) {
        Serial.println("Connected to server");
        // Make a HTTP request
        //client.println("GET /asciilogo.txt HTTP/1.1");
        client.print("GET /sensor/store?");
        client.print(sensor_data);
        client.println(" HTTP/1.1");
        client.println("Host: my.server.com");
        client.println("Connection: close");
        client.println();
    }

    String res="";
    while (client.available()) {
        char c = client.read();
        res += c;
    }

    client.flush();
    client.stop();
    delay(1000);

  } // end for
}

```

I get
```
[WiFiEsp] Connecting to my.server.com
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] Disconnecting  3
```
but the module is connected to wifi and my.serever.com is online. Can anybody help me to solve this issue?

Thanks in advance

title: ESP8266 HttpClient recursive connections to URL to send sensor data

Answers: 0


body:
I am trying to create a sinusoidal wave segmented in 64 **Frame**, each holding a **Duty cycle** precisely varying from 0x00 to 0xff. This is for an Arduino Nano.

I have trouble understanding the following:

 - Which Wave Generator Mode and Matches will cause an interrupt at the constant **Frame** as well as help do a phase correct/fast PWM for the varying **Duty Cycle**?
 - How to tell which pin to use? I guess OC0B means Pin5 [according to Pin Mapping](http://brittonkerin.com/cduino/pin_map.html) but I'm not sure I truly understand.

This is what I have for the moment.

    const byte waveFrame = 126;
    const byte wave[]    = {
        0x80,0x98,/*a total of 64 values*/,0x67
    };
    byte frame = 0;
    void setup(){
        pinMode(3,OUTPUT);
        noInterrupts();
        TCCR0A = (1<< WGM00)  // Phase correct PWM with top as OCR0A
               | (1<<COM0A0)  // Toggle OC0A on match
               | (1<<COM0B1); // Clear/Set OC0B on Compare Match when up/down-counting.
        TCCR0B = (1<<  CS01); // Prescaler of 8 (16MHz/8= 2MHz)
        TCNT0  = 0;           // Counter restarted
        OCR0A  = waveFrame;   // Constant frequency/64 for each frame
        OCR0B  = 0;           // Duty Cycle
        interrupts();
    }
    ISR(TIMER2_COMPA_vect){
        OCR0B = wave[frame & 0x3f]; //Rolls around
        frame++;
    }

Thank you! I've lost a little bit of hair on this.

title: Timer question: Phase Correct PWM at specific frequency

Answers: 1

body:
> pinMode(3,OUTPUT);

Pin 3 on the Nano is `OC2B`. It's PWM is controlled by Timer 2. You
want to use pin 5 (`OC0B`), since you are using Timer 0. Or
switch to Timer 2.

> Phase correct PWM with top as OCR0A

Note that this is the description of mode 5. If you want this mode, you
have to set both the bit `WGM00` in `TCCR0A` (which you did)
and the bit `WGM02` in `TCCR0B` (which you didn't). Here you have set
mode 1: phase correct PWM with top = 0xff.


body:
I'm reading a text file saved on my ESP8266 device (using `LittleFS`).

    while (myFile.available()) {
         Serial.write(myFile.read());
        }

My goal is to save file content ( each line ) to a `String` / `char` array.
`myFile.read()` returns a binary - and I'm looking for a quick and elegant way to do so ( as in `Serial.write` which converts it to text ).

Guy

title: Convert Binary to char

Answers: 1

body:
`myFile.read()` returns one character. That character can be represented as a number (such as 65 for 'A') or a character, or whatever you want. Everything is just a number.

Letters are just our personal representation of certain numbers as humans. You could think of it as the numbers represented in base 256, where each value between 0 and 255 is assigned a unique symbol.

`Serial.write()` just passes that number verbatim to the computer which then maps it in the serial monitor to the corresponding letter in the ASCII table.

Thanks to the object-oriented and polymorphic nature of the Arduino API (see [C++ Polymorphism](https://www.w3schools.com/cpp/cpp_polymorphism.asp)) there is no difference between reading from a file and reading from serial. They all inherit the same `Stream` class that gives you the same functions regardless of what you're reading.

So you could, like Serial, read each byte from the file one at a time until you reach the line ending character(s) (`\n` for a Unix file, or `\r\n` for a Windows file) and append each to the end of a string (either a `String` object, which is frowned upon, though less so on more capable MCUs like the ESP8266 and ESP32, or a `char` array).

Alternatively you could use one of the helper functions of the `Stream` class, such as `readStringUntil()`, which reads an entire string up to (and discarding) the specified terminating character and returns a `String`.

However both those have problems when it comes to building up an array of all the results, especially if you don't know beforehand how many lines there are in the file - since in C++ arrays have a fixed size.

A better solution, if you really *do* want it all in RAM (see below), might be instead to, at first, forget the idea of lines and just read the entire file into memory. Once it is in memory you can read through the entire block of data counting the number of `\n` bytes (and add one if it doesn't end with `\n`). That will give you the number of lines in the file.

You can then allocate an array of pointers with the same number of entries as there are lines.

From there you can use `strtok()` on the data to split it into chunks on the `\n` bytes and assign each chunk to one of the pointers in your array.  That array then becomes a kind of index to the data.

But one has to ask... why do you want to store this data in RAM anyway? You have it in flash, and that is quite fast to access (not as fast as internal flash in a traditional MCU, but still many times faster than an SD card for example). If ease of navigating the data is your goal, maybe you should be thinking of better ways of storing your data. Depending on what that data is maybe a fixed size record based file structure using a `struct` to manipulate the data would be a better solution - then you can just seek to multiples of the record (or struct) size to almost instantly get to different entries in the file.

If it's textual data then maybe reading through the file and recording the file offsets of the start of each line in an array (note: two passes - one to count the lines for allocating the array and one for recording the offsets into the array) similar to the indexing of the data block described above would be a better solution. That way you're only storing 4 bytes per entry in your array rather than all the data. Seeking is instant (just seek to the offset stored in the array for the line you want) and you're not having to store all the data in RAM.


body:
I am using a GY-521 accelerometer as well as BMP280 pressure sensors via I²C on an ESP8266.

When I analyze I²C data with the oscilloscope, I can see missing ACKs on both of them as shown in the pictures.

Is that something to worry about or is it just normal, considering I bought cheap Chinese sensors?

[![Missing ACK on GY-521][1]][1]

[![Missing ACK on BMP280][2]][2]

My BMP280 code is this:

    // https://github.com/mahfuz195/BMP280-arduino-library
    #include <BMP280.h>
    BMP280 bmp280;

    #include "Wire.h"
    TwoWire i2c = TwoWire();

    // Hardware setup
    #define CLOCK_PIN D1
    #define DATA_PIN D2
    #define I2C_SPEED 400000

    // I²C response codes
    #define FOUND 0
    #define NORESPONSE 2

    bool sensorAvailableAt(byte address)
    {
       i2c.beginTransmission(address);
       byte response = i2c.endTransmission();
       return response == FOUND;
    }

    void stop(char* message){
      Serial.println(message);
      while(true);
    }

    void setup() {
      Serial.begin(115200);
      while(!Serial){} // Waiting for serial connection

      i2c.begin(DATA_PIN, CLOCK_PIN, I2C_SPEED);
      if (!sensorAvailableAt(0x76))
      {
        stop("BMP280 sensor not found");
      }

      if (bmp280.begin())
      {
        Serial.println("BMP280 init success");
      }
      else
      {
        stop("BMP280 initialization failed.");
      }
    }

    void loop() {
      double temperature;
      double pressure;
      bmp280.getTemperatureAndPressure(temperature, pressure);
      double sealevel = bmp280.sealevel(pressure, 800);

      Serial.print("Temperature: ");
      Serial.print(temperature,1);
      Serial.println(" °C");

      Serial.print("Pressure: ");
      Serial.print(pressure, 1);
      Serial.println(" mbar (absolute)");

      Serial.print("Pressure: ");
      Serial.print(sealevel);
      Serial.println(" mbar (sealevel, compensated for 800 m height)");

      delay(50);
    }

  [1]: https://i.stack.imgur.com/n7kjX.png
  [2]: https://i.stack.imgur.com/Hwfrl.png

title: Missing ACKs on I²C

Answers: 1

body:
The NACK at the end of a master read/slave send transmission is normal expected behavior.

In I2C communication the acknowledgement is a possibility to react to send data. For example, when the slave sends a NACK while the master sends data to it, it might be, because it currently cannot process further data. Acknowledgement goes in both ways, depending on the direction of transmission. The reader always needs to acknowledge the data to mark a successful transmission. It is normal for the master to send a NACK on the end of it's reading cycle to mark, that it doesn't want to receive more data. While this isn't strictly logically needed (since the end of a transmission is marked by the master by a STOP or RESTART condition), it is done nonetheless.

I think I have also seen this behavior with the `Wire` library of Arduino. So it comes down to the implementation of the I2C protocol in your case. As your library simply uses the `Wire` library, the behavior is not part of it. The I2C protocol is implemented by `Wire`. You would see the same behavior in every sensor library, that uses the `Wire` library.

You can read more about the I2C protocol at [this site][1].

  [1]: https://i2c.info/i2c-bus-specification


body:
This is my code:

    int trigPin=13; //Sensor Trig pin connected to Arduino pin 13
    int echoPin=11;  //Sensor Echo pin connected to Arduino pin 11
    float pingTime;  //time for ping to travel from sensor to target and return
    float targetDistance; //Distance to Target in inches
    float speedOfSound=776.5; //Speed of sound in miles per hour when temp is 77 degrees.
    int trigPin1=2;
    int echoPin1=3;
    float pingTime1;  //time for ping to travel from sensor to target and return 1
    float targetDistance1; //Distance to Target in inches 1
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
      pinMode(trigPin1, OUTPUT);
      pinMode(echoPin1, INPUT);
    }

    void loop() {
      // put your main code here, to run repeatedly:

      digitalWrite(trigPin, LOW); //Set trigger pin low
      delayMicroseconds(2000); //Let signal settle
      digitalWrite(trigPin, HIGH); //Set trigPin high
      delayMicroseconds(15); //Delay in high state
      digitalWrite(trigPin, LOW); //ping has now been sent
      delayMicroseconds(10); //Delay in low state
      digitalWrite(trigPin1, LOW); //Set trigger pin low
      delayMicroseconds(2000); //Let signal settle
      digitalWrite(trigPin1, HIGH); //Set trigPin high
      delayMicroseconds(15); //Delay in high state
      digitalWrite(trigPin1, LOW); //ping has now been sent
      delayMicroseconds(10); //Delay in low state

      pingTime1 = pulseIn(echoPin1, HIGH);  //pingTime is presented in microceconds
      pingTime1=pingTime1/1000000; //convert pingTime to seconds by dividing by 1000000 (microseconds in a second)
      pingTime1=pingTime1/3600; //convert pingtime to hourse by dividing by 3600 (seconds in an hour)
      targetDistance1= speedOfSound * pingTime;  //This will be in miles, since speed of sound was miles per hour
      targetDistance1=targetDistance1/2; //Remember ping travels to target and back from target, so you must divide by 2 for actual target distance.
      targetDistance1= targetDistance*63360;    //Convert miles to inches by multipling by 63360 (inches per mile)
      pingTime = pulseIn(echoPin, HIGH);  //pingTime is presented in microceconds
      pingTime=pingTime/1000000; //convert pingTime to seconds by dividing by 1000000 (microseconds in a second)
      pingTime=pingTime/3600; //convert pingtime to hourse by dividing by 3600 (seconds in an hour)
      targetDistance= speedOfSound * pingTime;  //This will be in miles, since speed of sound was miles per hour
      targetDistance=targetDistance/2; //Remember ping travels to target and back from target, so you must divide by 2 for actual target distance.
      targetDistance= targetDistance*63360;    //Convert miles to inches by multipling by 63360 (inches per mile)

      Serial.println(targetDistance);

      Serial.println(targetDistance1);

      delay(100); //delay tenth of a  second to slow things down a little.
    }
Python code:

    import serial #Import Serial Library

    arduinoSerialData = serial.Serial('com3',9600) #Create Serial port object called arduinoSerialData

    while (1==1):
        if (arduinoSerialData.inWaiting()>0):
            myData = arduinoSerialData.readline()
            myData=str(myData)
            myData= myData.replace("b'",'')
            myData=myData.replace("\\r\\n'",'')
            if myData<"3":

                print( myData)

When I compile the sketch, it shows no error.But when I run the file in python, output=0.However, when they are run individually, python gives me a valid input.so is this code correct?Also, is there a way to call for the exact c++file in python?Thanks for the help!

title: Code for 2 ultrasonic sensors

Answers: 1

body:
You are trying to measure with 2 ultrasonic sensors at once. You cannot do that so easily. You need to measure sequentially for 2 reasons:

1. The ultrasonic sensors might get confused by the others signal
2. You will miss the pulse of the one sensor, while you are reading the pulse of the other via `pulseIn()`.

So the order of actions is like this:

1. Trigger sensor 1
2. Read sensor 1 with `pulseIn()`
3. Trigger sensor 2
4. Read sensor 2 with `pulseIn()`


body:
I working with Arduino Nano Every that has several analog PWM pins. I want to use one to control a small servo.

Do I need to put a resistor between PWM pin and the servo signal?

title: Do I need a resistor to control a servo with a PWM signal?

Answers: 1

body:
No, you don't.

Resistors are used to limit and control current (amongst other things) and you don't need to do that when sending a signal from one digital device to another.


body:
I'm new to this, so, please, don't crucify me.

I have a function that checks if an entry in multilevel array is in a certain range. Using FOR loop I check the whole array with this function, which gives me true/false value for each record.

And now the problem:
I need to check if ANY entry in that loop returns true and hold it until every result of that loop is false again.

Any tips?

Thanks a lot.

There is my for loop:

      for(int i = 0; i < arrayTop; i++){
    for(int j = 0; j < arrayDay; j++){
      for(int k = 0; k < arrayTime; k++){
        timeCompare(timeArray[i][j][k][0], timeArray[i][j][k][1], timeArray[i][j][k][2], timeArray[i][j][k][3], timeArray[i][j][k][4], timeArray[i][j][k][5], timeArray[i][j][k][6]);

        //Serial.print(i);Serial.print(j);Serial.print(k);Serial.print(" ");
        Serial.println(compareVar);

        if(i == 0){

          //set water switch
          if(compareVar == 1){
            waterOn = 1;
            Serial.println("Water ON");

            goto bailout;
          }
          else {
            waterOn = 0;
            Serial.println("water OFF");
          }
        }
        else if(i == 1){

          //set light switch
          if(compareVar == 1){
            lightOn = 1;
            Serial.println("Light ON");
            goto bailout;
          }
          else {
            lightOn = 0;
            Serial.println("light OFF");
          }
        }
      }
    }
  }
  bailout:

and this is the called function:

    //time compare with ON/OFF switch
    int timeCompare(int hrOn, int minOn, int secOn, int hrOff, int minOff, int secOff, int timerSwitch){
      unsigned long int onTime = (hrOn*10000UL) + (minOn*100UL) + secOn;
      unsigned long int offTime = (hrOff*10000UL) + (minOff*100UL) + secOff;
      unsigned long int currentTime = (dt.hour*10000UL) + (dt.minute*100UL) + dt.second;

      if(timerSwitch == 1){
        if(onTime < currentTime && offTime > currentTime){
          compareVar = 1;
        }
        else {
          compareVar = 0;
        }
      }
     else if(timerSwitch == 0) {
        compareVar = 0;
      }

      //Serial.print("compare: "); Serial.println(compareVar);

    }

title: Check if any of loop's insides returns 1 and hold it until the whole loop is 0 again

Answers: 1

body:
First, you should really not use a global variable to get the result of your comparison function. That is only confusion and unnecessary complicated code. For that we have return values. So instead of setting the `compareVar` variable inside the `timeCompare()` function, you should just return the corresponding value. In the `timeCompare()` function replace

    compareVar = 1;

with

    return 1;

and

    compareVar = 0;

with

    return 0;

Then in your main code: As I understood, you only need `compareVar` in the for loops, so you could delete the globally defined `compareVar` and declare it directly before the for loops:

    int compareVar = 0;

Now we can do the magic trick. We want to go through our for loops and get a result of `1`, if for any of the elements `timeCompare()` returns 1. For that we just doing an OR operation:

    compareVar = compareVar || timeCompare(timeArray[i][j][k][0], timeArray[i][j][k][1], timeArray[i][j][k][2], timeArray[i][j][k][3], timeArray[i][j][k][4], timeArray[i][j][k][5], timeArray[i][j][k][6]);

This is a boolean OR `||`. In C++ zero is treated as `false`, while any other number is treated as `true`. We are starting with `compareVar` begin zero. When `timeCompare()` for the element returns also zero, it stays zero. If it returns 1, `compareVar` will become 1. If it returns 1 again, it will stay one. If it returns zero, it will stay zero.

So now you can check for `compareVar` after the for loops. It will be 1, if any of the elements gave you 1.

Similarly you could check for all elements returning 1, if you replace the OR `||` by an AND `&&` operation.

---

Lastly I want to strongly discourage you from using `goto`. It ignores some important principles and you can easily create really bad code with it. Refer to questions like [this one][1] to read more about it. I would say, that in every case you have better ways than `goto`. Here it seems, that you simply want to go out of both loops. I would pack these loops into a function, so that you could simply use a `return` statement to get out of them.

  [1]: https://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto


body:
I am using 5 sensors out of which two have the same I2C address and are connected via TCA9548 multiplexer. The remaining 3 sensors are connected to the main arduino I2C bus. In example sketches online I see the following function to choose the specific port/channel on the multiplexer:

    #define MPLXADR 0x70 // Address of TCA9548A I2C Multiplexer
    void multiplexer (uint8_t ch) {
      if (ch > 7) return;
      Wire.beginTransmission(MPLXADR);
      Wire.write(1 << ch);
      Wire.endTransmission();
    }

I understand that this function should be called before executing instructions for the sensors with shared address but how would it still send the data to the right sensor when the last line "Wire.endTransmission();" just closes connection?

Since in my circuit there are sensors which are connected directly to the arduino I2C bus, I wonder if the code related to those sensors comes after the code for sensors with shared address, wouldn't those instructions also be sent to the ensors with shared I2C address? To me it makes more sense if the instructions for the shared address sensors are enclosed inside the above mentioned function as follows:

channel select -> execute instruction -> end transmission

But the usage I see in the tutorials baffles me. Could somebody please clarify these points? Thanks

Here is the complete sketch I am using:

    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BME280.h>
    #include <AHT10.h>
    #include <HDC2080.h>

    Adafruit_BME280 bme1; // on Arduino I2C bus
    Adafruit_BME280 bme2; // on multiplexer I2C bus
    Adafruit_BME280 bme3; // on mulitplexer I2C bus
    AHT10 AHT(AHT10_ADDRESS_0X38); // on Arduino I2C bus
    HDC2080 HDC2080(0x41);// on Arduino I2C bus

    #define MPLXADR 0x70 // Address of TCA9548A I2C Multiplexer
    void multiplexer (uint8_t ch) {
      if (ch > 7) return;
      Wire.beginTransmission(MPLXADR);
      Wire.write(1 << ch);
      Wire.endTransmission();
    }

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

      while (AHT.begin() != true)
      {
        Serial.println(F("AHT10 not connected or fail to load calibration coefficient"));
        delay(5000);
      }
      Serial.println(F("AHT10 OK"));

      HDC2080.begin();

      // Begin with a device reset
      HDC2080.reset();

      // Set up the comfort zone
      HDC2080.setHighTemp(28);         // High temperature of 28C
      HDC2080.setLowTemp(22);          // Low temperature of 22C
      HDC2080.setHighHumidity(55);     // High humidity of 55%
      HDC2080.setLowHumidity(40);      // Low humidity of 40%

      // Configure Measurements
      HDC2080.setMeasurementMode(TEMP_AND_HUMID);  // Set measurements to temperature and humidity
      HDC2080.setRate(ONE_HZ);                     // Set measurement frequency to 1 Hz
      HDC2080.setTempRes(FOURTEEN_BIT);
      HDC2080.setHumidRes(FOURTEEN_BIT);

      //begin measuring
      HDC2080.triggerMeasurement();
      Serial.println();

      Serial.println(F("BME280 test"));

      //BME280 sensor 1
      multiplexer(0);
      if (! bme1.begin(0x77, &Wire)) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
      }

      // weather monitoring
      Serial.println("-- Weather Station Scenario --");
      Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
      Serial.println("filter off");
      bme1.setSampling(Adafruit_BME280::MODE_FORCED,
                       Adafruit_BME280::SAMPLING_X1, // temperature
                       Adafruit_BME280::SAMPLING_X1, // pressure
                       Adafruit_BME280::SAMPLING_X1, // humidity
                       Adafruit_BME280::FILTER_OFF   );

      //BME280 sensor 2
      multiplexer(1);
      if (! bme2.begin(0x77, &Wire)) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
      }

      // weather monitoring
      Serial.println("-- Weather Station Scenario --");
      Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
      Serial.println("filter off");
      bme2.setSampling(Adafruit_BME280::MODE_FORCED,
                       Adafruit_BME280::SAMPLING_X1, // temperature
                       Adafruit_BME280::SAMPLING_X1, // pressure
                       Adafruit_BME280::SAMPLING_X1, // humidity
                       Adafruit_BME280::FILTER_OFF   );

      //BME280 sensor 3
      if (! bme3.begin(0x76, &Wire)) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
      }

      // weather monitoring
      Serial.println("-- Weather Station Scenario --");
      Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
      Serial.println("filter off");
      bme3.setSampling(Adafruit_BME280::MODE_FORCED,
                       Adafruit_BME280::SAMPLING_X1, // temperature
                       Adafruit_BME280::SAMPLING_X1, // pressure
                       Adafruit_BME280::SAMPLING_X1, // humidity
                       Adafruit_BME280::FILTER_OFF   );

      // suggested rate is 1/60Hz (1m)
     }

    void loop() {
      bme3.takeForcedMeasurement(); // has no effect in normal mode
      printValuesBME3();
      delay(5000);

      printValuesAHT();
      delay(5000);

      printValuesHDC2080();
      delay(5000);

      multiplexer(0);
      bme1.takeForcedMeasurement(); // has no effect in normal mode
      printValuesBME1();
      delay(5000);

      multiplexer(1);
      bme2.takeForcedMeasurement(); // has no effect in normal mode
      printValuesBME2();
      delay(10000);
    }

    void printValuesBME1() {

      Serial.println();
      Serial.print("BME1 Readings");

      Serial.print("Temperature = ");
      Serial.print(bme1.readTemperature());
      Serial.println(" *C");

      Serial.print("Humidity = ");
      Serial.print(bme1.readHumidity());
      Serial.println(" %");

      Serial.println();
    }

    void printValuesBME2() {

      Serial.println();
      Serial.print("BME2 Readings");

      Serial.print("Temperature = ");
      Serial.print(bme2.readTemperature());
      Serial.println(" *C");

      Serial.print("Humidity = ");
      Serial.print(bme2.readHumidity());
      Serial.println(" %");

      Serial.println();
    }

    void printValuesBME3() {

      Serial.println();
      Serial.print("BME3 Readings");

      Serial.print("Temperature = ");
      Serial.print(bme3.readTemperature());
      Serial.println(" *C");

      Serial.print("Humidity = ");
      Serial.print(bme3.readHumidity());
      Serial.println(" %");

      Serial.println();
    }

    void printValuesHDC2080() {
      Serial.println("HDC2080 Values");
      Serial.print("Temperature (C): "); Serial.print(HDC2080.readTemp());
      Serial.print("\t\tHumidity (%): "); Serial.println(HDC2080.readHumidity());
    }

    void printValuesAHT() {

      Serial.println(F("AHT10: read 12-bytes, show 255 if communication error is occurred"));
      Serial.print(F("Temperature: ")); Serial.print(AHT.readTemperature()); Serial.println(F(" +-0.3C")); //by default "AHT10_FORCE_READ_DATA"
      Serial.print(F("Humidity...: ")); Serial.print(AHT.readHumidity());    Serial.println(F(" +-2%"));   //by default "AHT10_FORCE_READ_DATA"
    }

title: Arduino I2C Multiplexing uisng TCA9548A

Answers: 1

body:
The TCA9548 is a switch.

You begin a transaction to it, change the channel that it allows through, and then end *that specific transaction.*

From that point on one and only one of the other two sensors are attached to your bus - the other doesn't exist.  When you communicate on the address of that sensor it passes through the TCA9548 as if it doesn't exist.

You can think of the TCA9548 as a controller that sits *next to* the switch:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/OjN94.png)

<!-- End schematic -->

Send channel 0 and it flips the switch one way. Send channel 1 and it flips the switch the other way. Once the switch is flipped it stays flipped until you tell it otherwise.

From your sketches perspective the two HDC2080s on the MUX are only one HDC2080. You just flip the switch to the right position to access the specific physical device you want at the time.


body:
I have Arduino IDE v. 1.8.13.
I bought an ESP8266-01 module which I want to use in my Arduino-UNO board to send fingerprint registration confirmation (ID) via HttpClient to a xampp server since I dont want to store the fingerprint image in the database.
My ESP connection is as below:
[![ESP8266-01 Wifi Module connection][1]][1]

In the serial monitor, my AT commands work well when I connect the module to my wifi using AT+CWJAP="ssid","password".

When I upload my code, which is supposed to connect to wifi, it says WiFi shield not present.
Im new to this, is there anything I am missing?
Thanks in advance.

Here is my code:

    #include <ArduinoHttpClient.h>
    #include <WiFi101.h>
    #include "arduino_secrets.h"
    char ssid[] = SECRET_SSID;
    char pass[] = SECRET_PASS;

    char serverAddress[] = "localhost/bel/arduino/scannerstatus/php";  // server address
    int port = 80;

    WiFiClient wifi;
    HttpClient client = HttpClient(wifi, serverAddress, port);
    int status = WL_IDLE_STATUS;

    void setup() {
      Serial.begin(9600);
      while ( status != WL_CONNECTED) {
        Serial.print("Attempting to connect to Network named: ");
        Serial.println(ssid);                   // print the network name (SSID);
        // Connect to WPA/WPA2 network:
        status = WiFi.begin(ssid, pass);
      }

Basically, my uploaded code does not go past the wifi connection stage. Even though the AT commands individually can connect to wifi.
I have tried different ESP8266 libraries and HttpClient libraries but they all seem to not connect to wifi.
Is there any other way to call a php script from arduino without using wifi?

  [1]: https://i.stack.imgur.com/TDNBY.png

title: ESP8266-01 Wifi module + Wifi shield not present + ESP8266-01 libraries not working?

Answers: 1

body:
Can you please include some explanation of how the Arduino Uno and ESP8266-01 are connected. You will need to program for the ESP8266 ESP-01 module like shown below,
[![enter image description here][1]][1]

You will need to write code for the ESP module to connect to the WIFI and listen to its Serial Com Port. The ESP will need to handle the message interpretation & WIFI updating.

The Arduino Uni will not be capable of directly using the ESP-01 module as a WIFI shield. It will need to communicate with the ESP via a serial coms link, you will need to send commands that include instructions & a Message to the ESP from the Arduino.

[![enter image description here][2]][2]

https://create.arduino.cc/projecthub/jeffpar0721/add-wifi-to-arduino-uno-663b9e - Link to the above image document, this should help explain my concept in more detail

I apologies if my comments above miss the point but with the amount of information provided I don't think I can help further.

  [1]: https://i.stack.imgur.com/8gut5.jpg
  [2]: https://i.stack.imgur.com/D1Ifg.png


body:
I encountered to me inexplicable behavior on an arduino uno.
I'm serial reading a string from the serial monitor/python serial. This string is the conditional on several if/else if statements.
The crazy thing is, some strings just get ignored, but if I print out the read string after reading it, the ignored statements then get executed and the script works the way it's supposed to.
This is the code:
```
// power outlet 1
# define OUT_1_1 2 // relay #4
# define OUT_1_2 3 // relay #3

// power outlet 2
# define OUT_2_1 4 // relay #2
# define OUT_2_2 5 // relay #1

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

  // power outlet 1
  pinMode(OUT_1_1, OUTPUT);
  pinMode(OUT_1_2, OUTPUT);

  // power outlet 2
  pinMode(OUT_2_1, OUTPUT);
  pinMode(OUT_2_2, OUTPUT);

  // init outputs to HIGH
  digitalWrite(OUT_1_1, HIGH);
  digitalWrite(OUT_1_2, HIGH);
  digitalWrite(OUT_2_1, HIGH);
  digitalWrite(OUT_2_2, HIGH);

  Serial.begin(9600);
}

void loop() {
  String str = "";

  // checking for bytes in the buffer
  if (Serial.available() > 0) {
    str = Serial.readStringUntil("\n");
  }
  // Serial.println(str); // if this line is uncommented serial input "2_ON\n" and "2_OFF\n" is recognized and outled 2 is successfully switched

  // identity
  if (str == "IDN\n") {
    Serial.println("Serial Power Outlet");
  }

  // controlling power outlet 1
  else if (str == "1_ON\n") {
    digitalWrite(OUT_1_1, LOW);
    digitalWrite(OUT_1_2, LOW);
  }
  else if (str == "1_OFF\n") {
    digitalWrite(OUT_1_1, HIGH);
    digitalWrite(OUT_1_2, HIGH);
  }

  // controlling power outlet 2
  else if (str == "2_ON\n") {
    digitalWrite(OUT_2_1, LOW);
    digitalWrite(OUT_2_2, LOW);
  }
  else if (str == "2_OFF\n") {
    digitalWrite(OUT_2_1, HIGH);
    digitalWrite(OUT_2_2, HIGH);
  }
  delay(1000);
}
```
If I serial input `2_ON\n` or `2_OFF\n` the according else if blocks are just ignored (all other inputs work correctly).

But after I've uncommented `// Serial.println(str);` these blocks are executed the way they are supposed to and all works just fine.

Where is my mistake, what am I getting wrong here?
These blocks also get executed if I `Serial.println` any random output.
Why do I have to Serial.println something first so my script works according to plan? What am I missing?

EDIT: added all of the code.

title: else if is ignored if not Serial.println anything before

Answers: 1

body:
Even though you read until \n, that just controls the ending of your buffered string.  It does not control it's start.  There may be some garbage before the command that you have not cut out.  In other words, I suggest you check if the string endsWith as opposed to == the command string.

As for what noise could be causing garbage or why activity on the tx side of the serial cleaned it up, i do not know.  Heck something might just be weird enough in the wiring that '2' is just the set of bits needed to aggravate it.


body:
There's actually another post with this very same topic but no answers on that post. Back in January of 2020, the last commenter said he had sample code and then he went dark without posting the actually code. The thread is here:

https://arduino.stackexchange.com/questions/25593/want-to-create-bluetooth-audio-control-volume-up-down-play-pause-etc-for-s/71423#71423?newreg=f9eaf7e88f3c4c3b90e72b4e070f9e5a

My problem is the exactly the same as the original post. Amazon and Aliexpress have literally hundreds of these "media buttons" that you can buy and pair via bluetooth with your Android or iOS. You can then playback media on iOS/Android and the "media buttons" can control the playback. Pretty common controls are volume up/down, next, previous, play and pause.

I've written a lot of Arduino code for Nano, Uno and even MKR. I've written a bunch of ESP8266 and ESP32 code as well. Usually when I try and learn something, a few google searches will find an example that I can figure out. For this, I've been able to find nothing.

Every tutorial or sample code is about how to send commands to the ESP32 via Bluetooth or pair an ESP32 with a bluetooth joystick, etc. None of those examples help me understand what's needed for an ESP32 to pair with my Android and act as media buttons, sending volume up, down and play/pause commands via bluetooth.

Can anyone help with example code for doing this with an ESP32? (by the way, this forum would not let me comment on the original post or I would have. it said I didn't have enough karma points or something)

title: Anyone have example code for ESP32 as media controller for Android/iPhone Media Apps

Answers: 1

body:
Well after I posted this question, I kept googling. Literally hours of googling at this point. Then I stumbled across this example:

https://github.com/T-vK/ESP32-BLE-Keyboard

I wrote that sketch to my ESP32, paired my iPhone and it immediately starting controlling music playback on my phone. After looking at the code, it's so simple that I'm embarrassed I couldn't figure this out on my own. In case the link goes dead, I'll paste the code here:

<pre>
#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
}

void loop() {
  if(bleKeyboard.isConnected()) {
    Serial.println("Sending 'Hello world'...");
    bleKeyboard.print("Hello world");

    delay(1000);

    Serial.println("Sending Enter key...");
    bleKeyboard.write(KEY_RETURN);

    delay(1000);

    Serial.println("Sending Play/Pause media key...");
    bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);

    delay(1000);

    Serial.println("Sending Ctrl+Alt+Delete...");
    bleKeyboard.press(KEY_LEFT_CTRL);
    bleKeyboard.press(KEY_LEFT_ALT);
    bleKeyboard.press(KEY_DELETE);
    delay(100);
    bleKeyboard.releaseAll();

  }
  Serial.println("Waiting 5 seconds...");
  delay(5000);
}
</pre>


body:
Is it possible to connect arduino uno to call a php script using ONLY an arduino uno board, and an esp8266-01 wifi module.? That is, I lack wifi shield such as node MCU.
I just need the setup to call a php script on my localhost server.
I'm using arduino IDE 1.8.13.
Gracias

title: Calling a localhost php script from arduino

Answers: 1

body:
You can program the ESP-01 module using the arduino IDE. There are instructions in the README here: https://github.com/esp8266/Arduino

You can program the ESP-01 to connect to WiFi and communicate with your arduino sketch using the serial port. Don't forget the ESP-01 runs at 3.3V while the arduino runs at 5V. You'll need to shift the voltages somehow, otherwise you'll burn the arduino uno.

Here's an example of code you can run on the ESP-01 to connect to WiFi and start a TCP connection: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino

All that's missing is making an HTTP request instead of a "raw" TCP connection. You can probably find that in the examples. Then, add code for serial communication back to your arduino uno.

Good luck!


body:
I'm trying to program an Arduino Uno (atmega328p) using only the serial Tx/Rx lines (no DTR, so no automatic reset). This is so I can upload code via WiFi/TCP using an ESP-01.

To achieve this, I need to Arduino sketch/application to reset itself (and run the bootloader) whenever it sees avrdude trying to upload code (e.g. when `0 0 ` appears in the serial port).

I've tried a few approaches to jumping to the bootloader from application code but had no success so far.

 1. **Using the watchdog timer**
```
void reset_to_bootloader() {
 // see 11.2.2 MCUCR – MCU Control Register
 // Enable change of interrupt vectors
 MCUCR = (1<<IVCE);
 // Move interrupts to Boot Flash section
 MCUCR = (1<<IVSEL);

 // enable watchdog timer
 wdt_enable(WDTO_30MS);

    // block waiting for the watchdog to timeout and jump to the bootloader
 while(1);
}
```
Unfortunately, the datasheet[1] mentions the `IVSEL` bit is not available in atmega328p, so even though this compiles, it simple resets the MCU and the bootloader does not run.

2. **Jumping to the bootloader address directly**

There is a table in the datasheet (Table 26-7. Boot Size Configuration, ATmega328P) that specifies the bootloader start address for the 4 supported bootloader section sizes, which are configured by the BOOTSZ fuse.

I have read the fuses and confirmed the bootloader section is 512-bytes (256 words) long.
Therefore, according to the datasheet, the Boot Loader Flash Section is `0x3F00 - 0x3FFF`. So, the start of the bootloader should be at word-address 0x3F00.

I have even dumped the whole 32768-byte flash off the MCU and confirmed the bootloader is at byte-address `0x7e00`, which matches the expected word-address `0x3F00` (`0x7e00 / 2 = 0x3F00`).

I have tried a couple methods of jumping to address 0x3F00. Here's a few. None of them seem to work. They just reset the MCU and the bootloader doesn't seem to run.

```
void jump_to_bootloader() {
 size_t bootloader_addr = 0x3F00;

 void (*bootloader_ptr)() = (void (*)())(bootloader_addr);

 SREG = 0;
 wdt_disable();
 bootloader_ptr();
}

void jump_to_bootloader2() {
 asm volatile ("ijmp" ::"z" (0x3F00));
}
```

3. **Jumping and updating the value of `MCUSR`**

I then realised the bootloader[4] checks the reset source and only runs on an external reset:

```
ch = MCUSR;
if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
    pp_start();  // skip bootloader
```

So I tried faking it before jumping, but it didn't work either:

```void jump_to_bootloader2() {
    MCUSR = _BV(EXTRF);
 asm volatile ("ijmp" ::"z" (0x3F00));
}
```

Any help is appreciated. Thanks in advance!

---
edit:

4. **Jumping to after the bootloader checks the reset source**

Following @Edgar Bonet's suggestion, avoiding the `if (!(ch & _BV(EXTRF))) appStart();` check in the bootloader by jumping to the instruction that follows it:
```
void jump_to_bootloader2() {
 // the bootloader assumes these are true:
 cli();
 SP = RAMEND;
 SREG = 0;
 MCUSR = 0;
 asm volatile ("eor __zero_reg__, __zero_reg__");
 asm volatile ("eor r1, r1");
 // jump to after the bootloader checks the reset source
 asm volatile ("ijmp" ::"z" (0x7e0au / 2));
 while(1);
}
```

I could see it entered the bootloader (LEDs flashed a couple times), but avrdude was not able to upload code.

The bootloader sets up a watchdog timer (WDT), so I'm suspecting avrdude waits for to long after sending the initial `0 0 0 ` and since the bootloader does not see anything on the serial port the WDT resets it.

---

References:

  - [1] AVR Instruction Set Manual: http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf
  - [2] atmega328p datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
  - [3] random forum thread I have also read: https://www.avrfreaks.net/forum/jump-bootloader-app-help-needed
  - [4] bootloader code: https://github.com/sparkfun/Arduino_Boards/blob/805def002e815509032fde37a674d2916af8aecc/sparkfun/avr/bootloaders/atmega/ATmegaBOOT_168.c#L299-L307

title: Jumping to bootloader from application code in atmega328p

Answers: 2

body:
The source of Optiboot on Uno is [here][1].

I would prefer a simple watchdog reset with
```
  wdt_enable(WDTO_15MS);
  while (true);
```
But I am not sure now if it runs sketch upload detection in bootloader.

For direct jump to Optiboot on Uno (one flash page) this should work
```
typedef void (*bootloader_jump_t)();
const bootloader_jump_t bootloader_jump = (bootloader_jump_t)((FLASHEND-511)>>1);
```
and then you can call `bootloader_jump();`

EDIT:
while the Optiboot 4 on Uno from factory doesn't check for new upload after watchdog reset or direct jump, Optiboot 8 has checks to handle this right

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/optiboot/optiboot.c

body:
Maybe you could jump to right after the line

```c
if (!(ch & _BV(EXTRF))) appStart();
```

Here is an [excerpt of the disassembly][disasm]:

```c
  if (!(ch & _BV(EXTRF))) appStart();
    7e06: 81 ff        sbrs r24, 1
    7e08: f0 d0        rcall .+480     ; 0x7fea <appStart>

#if LED_START_FLASHES > 0
  // Set up Timer 1 for timeout counter
  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
    7e0a: 85 e0        ldi r24, 0x05 ; 5
    7e0c: 80 93 81 00  sts 0x0081, r24
```

The conditional call to `appStart()` is made by the instructions `sbrs`
and `rcall`. The instruction right after that is the `ldi` at byte
address 0x7e0c (word address 0x3f05). I would try jumping right there.
You won't miss much:

 * `eor r1, r1` is not needed when jumping from C++, as the value of r1
   is already enforced by the compiler as per the ABI.
 * `in r24, 0x34` reads `MCUSR` into a register that is clobbered right
   away
 * `out 0x34, r1` clears `MCUSR`; if this turns out to be useful, you
   could do it right before jumping to the bootloader.

You may want to check that the bootloader you have matches the
disassembly I linked to.

[disasm]: https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/optiboot/optiboot_atmega328.lst#L48-L56


body:
A weird is happening which i can't figure out why. First I had issue communicating with SIM800L.
So i tried checking the USART Hardware to see what UNO sends to SIM800 using small piece attached below.
The sketch is to compares what i send from serial monitor with strings "Hello", "heLLo" and "Hello" expecting to get Found .... or No match found.
each line string i send, the serial monitor prints twice WHY?,
The first says not found and the second say Received == ........ WHY?

**See the output of serial terminal
when i typed "Hello" with quotes.

    12:03:46.536 -> Buffer Received= " No match found
    12:03:46.569 ->
    12:03:46.569 -> Buffer Received= Hello"
    12:03:46.603 ->  Found Hello
    when i typed "HELLO" with quotes.
    12:03:55.855 -> Buffer Received= " No match found
    12:03:55.888 ->
    12:03:55.888 -> Buffer Received= HELLO"
    12:03:55.921 ->  Found HELLO**

****when i typed "heLLo" with quotes.

    12:04:04.016 -> Buffer Received= " No match found
    12:04:04.049 ->
    12:04:04.049 -> Buffer Received= heLLo"
    12:04:04.082 ->  Found heLLo
    12:04:04.115 ->****

When i typed without quotes, all i get No match found

    char buffer[100];
    uint8_t index=0;

    void setup()
    {
      Serial.begin(9600);
      _delay_ms(4000);
    }

    void loop()
    {
      if(Serial.available()>0)
      {
        index=0;
        while(Serial.available())
        {
          buffer[index++]=Serial.read();
        }

        buffer[index]='\0';
        Serial.println(' ');
        Serial.print("Buffer Received");
        Serial.print(buffer);
        Serial.print('\t');
        if(strstr(buffer, "Hello")!=NULL) Serial.println("Found Hello");
        else if(strstr(buffer, "HELLO")!=NULL) Serial.println("Found HELLO");
        else if(strstr(buffer, "heLLo")!=NULL) Serial.println("Found heLLo");
        else Serial.println("No match found");
        Serial.flush();
      }
    }

Note: Suspecting my PC hardware and serial driver,
so I tried it in my Ubuntu 20.04 and window 10 installed with Arduino IDE 1.8.13
suspecting it may be crystal, i tried two different boards and used even Atmega328P core.
I also suspected my keyboard "ENTER" key, so i tried the serial monitor "send" button. \
with no difference.

I seems to run short is ideas so i am posting to the community. Let me have your advice and experience too.

Thanks.

title: Issues with Arduino UNO printing repeated "double" on serial monitor

Answers: 1

body:
As Majenko and DataFiddler already stated in the comments, you are reading the Serial interface in the wrong way, because you seem to misunderstand a specific point involving the interface.

The Serial (UART) interface knows only of individual bytes, which are send asynchronously over the lines. It does not have any context of a full packet or message. When you type in some data into the Serial Monitor and then press "Send", the data will be send, but not as one big bunch of data. The individual bytes are delayed.

The first delay comes with the nature of the interface itself, as you send with a limited baudrate. With a baudrate of 9600 the Arduino is way faster, than the bytes can arrive. So when you first get a result higher than zero from `Serial.available()`, the rest of the message is not yet received. Thus with your current code you would only process only the first part of the message.

The second delay comes with the fact, that you and the Serial program on your PC cannot control, when exactly each byte is send. Thats done by the driver. So it might happen, that there is a small gap between 2 bytes somewhere in your message. You cannot mitigate this without writing your own driver and you cannot predict this.

**So, what to do now?** You should read data, when it is available, and put it into a buffer. And only, when a full message was received, you should process the data. Now you need to know, where the end of a message is. Mostly a delimiting character (like the newline character `\n`) at the end of the message is used. So you read, if available, and only process the message, when you have read the delimiting character. Something like this:

    unsigned int buffer_pos = 0;
    char buffer[50]="";

    void loop(){
        if(Serial.available()){
            char c = Serial.read();
            if(c == '\n'){
                buffer[buffer_pos] = '\0'; // End the message as C string with a null character
                // process the message here
                buffer_pos = 0;
            } else {
                buffer[buffer_pos] = c;
                buffer_pos++;
            }
        }
    }

`buffer` holds the message. `buffer_pos` is the current position in the buffer. We terminate the message with the null character, to get a valid C string in the buffer. After processing the message, we set the position back to zero, to receive the next message. When you send data from your PC, you need to make sure, that the message is ended with the newline character.

Now you are independent on when exactly the data is send.

---

DataFiddler stated in the comments, that without a delimiting character you can simply delay for enough time, so that the data has enough time to arrive. He also stated, that it is ugly. It is a bad coding style. A long delay will impact the responsiveness of your program, while a short delay may give you problems with longer messages. So I suggest, that you directly use the correct way to read the Serial interface. Then you don't have such pitfalls.


body:
I know this question has been asked a thousand times, but I can't find a solution for my case.

I what to get the length of a string array in a given function. This is for an arduino board.

```cpp
#define LEN(x) sizeof(x)/sizeof(x[0])
const char* mainMenu[] = {"FirstWord", "SecondWord", " "};

void myFunction(const char** m) {
  int a = LEN(m);

  /* Do something */
};

void setup(){
   myFunction(mainMenu);
};
```

The `LEN(m)` works fine in the `setup()` function. But in `myFunction()` it either gives me 1 (i guess the length of the pointer) or 9 (length of the 0th element of the array)

title: String array length in function

Answers: 1

body:
The problem is that LEN is evaluated locally for each usage replacing it with the content. In `myFunction` the parameter being passed to it is a pointer, not the array.

You need to evaluate the size once and once only in the context where the array hasn't collapsed into a pointer. That is usually done immediately where the array is defined:

```
const char* mainMenu[] = {"FirstWord", "SecondWord", " "};
#define MAINMENU_LEN (sizeof(mainMenu) / sizeof(mainMenu[0]))
```

Because `mainMenu` is a global it's always available, and when you require the length you get the length of the global array.

If you want to keep things local you will have to pass the number of elements in the array as a parameter to the function that uses that information.

    myFunction(mainMenu, MAINMENU_LEN);

Another common alternative is to have some "end of array" marker and you loop through your array until you find that marker (that's how strings work - with `\0` for the end of array marker):

    const char* mainMenu[] = {"FirstWord", "SecondWord", " ", 0};

Then:

    for (int i = 0; m[i] != 0; i++) {
        ...
    }


body:
I am a newbie C programmer and I just started with Arduino **web editor** (Win10-Firefox)to code for a **Raspberry Pi** (3B) board. RPi is on line via ethernet connection.

I tried to compile an example from Garmin Lidar_lite v3HP for I2C, as available in the library collections for Arduino.
When compiling the example I get after a while this error message:

*Using library Wire in folder: /home/builder/.arduino15/packages/arduino/hardware/mraa/1.0.8/libraries/Wire (legacy)*

*Using library lidar_lite_3_0_3 at version 3.0.3 in folder: /home/builder/opt/libraries/latest/lidar_lite_3_0_3*

*/tmp/967842743/v3HP_I2C/v3HP_I2C.ino: In function 'void setup()':*

*/tmp/967842743/v3HP_I2C/v3HP_I2C.ino:51:18: error: 'class TwoWire' has no member named 'setClock'*

*Wire.setClock(400000UL); // Set I2C frequency to 400kHz (for Arduino Due)*

^
*exit status 1*

Checking the arduino forum I find some similar question, but of many years ago and likely not applicable any longer.

I appreciate your expert inputs on how to resolve in simple terms.
Thanks a lot! Greetz, Ivan

title: error at compiling : 'class TwoWire' has no member named 'setClock'

Answers: 1

body: Thanks for the reply. I tried again with the arduino on PC with RasPiDuino librarie and had no further problem. The resulting executable does work on a RPi3 with Buster OS. Apparently the arduino webeditor lacks some libraries to succesfully compile for raspberry . I continue this road. Item can be closed.


body:
I have the attached script that reads data from a socket server (it is PHP at the server end).

My problem (I think) is that the `readStringUntil()` needs a test above it, so that it "reads up to \r" **only if there is any data** being received, otherwise it seems to keep trying to read forever, because when I DO send data, it is received with 1-2 seconds delay.

If I constantly send (properly \r delimited) data without any pause, then it seems to be received instantly (10-20ms or so).

I tried: `if (client.available()) { String received_message = client.readStringUntil('\r'); }` but it doesn't seem to be the right function, doesn't do anything.

This is ESP32 board, compiler mentioned it found **two wifi libraries**, one in arduino folder and one in ESP32, it used the second one. This might be relevant to what functions are available.

```
#include <WiFi.h>

const char* ssid = "MyWiFi";
const char* password =  "1234";

const uint16_t port = 8080;
const char * host = "myserver.example.com";

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

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("...");
  }

  Serial.print("wifi connected with IP: ");
  Serial.println(WiFi.localIP());
}

void loop() {

  WiFiClient client;

  if (!client.connect(host, port)) {
    Serial.println("connection to host failed");
    delay(500);
    return;
  }

  Serial.println("connected to server");

  // I assume this is where I need a test like "if any received data exists" >>>

  String received_message = client.readStringUntil('\r');
  Serial.println(received_message);

  // intentional delay doesn't seem to do much
  // when it constantly tries to read for data that is not always there
  delay(100);

  // do I need to disconnect here ?!
  // client.stop();
}
```

**EDIT:** my PHP loop looks like this:

```
do{
 $accept = socket_accept($socket) or die("Could not accept incomming connection");

 // $message_to_send = 'hi there '.microtime(true)."\r";
 // OR
 // get message from memcached variables

 if($message_to_send!=''){

  echo "\nsending: ".$message_to_send;

  socket_send($accept, $message_to_send, strlen($message_to_send), MSG_OOB);
 }

} while (true);
```

title: TCP client readStringUntil only when data exists

Answers: 0