message:
HTTPS GET request working on esp32 but not on esp8266

I'm trying to port my esp32 program to esp8266, and i've come across a problem where i can't get a response from a HTTPS GET request on esp8266, but on my esp32 the same code works fine.
The function i'm using looks like this:

    void GetHTTP()
    {
      if (WiFi.status() == WL_CONNECTED)
      {
        HTTPClient http;
        http.begin(requestURL);
        int httpCode = http.GET();
        if (httpCode > 0)
        {
          requestData = http.getString();
          GenerateTable();
          //GetDelimiterCount(requestData, delimiterStart);
        }
        http.end();
      }
    }
I've also tried running my request with the esp8266 "BasicHttpsClient" and "BasicHttpClient", and in both cases the program returns the error: "connection failed" from `https.errorToString(httpCode).s_str()`
or http code "-1" without any API specific error codes.

I'm requesting from Trafiklab's [realtime infromation v4 API][1] And
the request looks somewhat like this:
> https://api.sl.se/api2/realtimedeparturesV4.json?<apikeysandparams>

I've omitted the API key and parameters i use from this URL. The response is also correct when requested by any browser.

Could this be something to do with SSL? I'm completely out of clues as to what the differences between esp32's and esp8266's http-client libraries might be. I'm also using the latest version of the ESP8266 Boards libraries (2.7.4).

  [1]: https://www.trafiklab.se/node/15754/documentation

body:
I ended up using

> ESP8266WiFi.h

 instead of

> ESP8266WiFiMulti.h

This fixed both my original code and the basic HTTPS example. I still don't understand what difference it made though.


sender: user

message:
How to get 2 loop functions to cooperate?

I have a OLED SSD1306 & DS3231 RTC, 2 buttons to set the time & date. My project is to display a scrolling text at the top of the OLED, the RTC time in the middle, the day & date on the last line. My issue is I can't get the scrolling text & the time to run right when in the loop together, individually they work normal. When they are together, the scrolling text is fine, but the time is static, its not displaying the current RTC. Then after 1 loop cycle the time seconds text become jumbled, then after a 2nd cycle the minutes & seconds become jumbled. I have tried putting display.clearDisplay(); display.display(); at the end of the loop, doing this fixes the time from becoming jumbled by clearing the buffer before the next cycle, but does not fix the time from being static. How can I get the time to not be static anymore? Any help would be greatly appreciated. Here is my sketch:

```
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define button1    9                       // Button B1 is connected to Arduino pin 9
#define button2    8                       // Button B2 is connected to Arduino pin 8

void setup(void) {
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  delay(1000);

  // by default, the high voltage from the 3.3v line
  display.begin(SSD1306_SWITCHCAPVCC, 0x3c);  // initialize with the I2C address
  // init done

  // Clear the display buffer.
  display.clearDisplay();
  display.display();

  display.setTextColor(WHITE, BLACK);
}

char Time[]     = "  :  :  ";
char Calendar[] = "  /  /20  ";
byte i, second, minute, hour, day, month, date, year;

void display_day(){
  switch(day){
    case 1:  draw_text(0, 50, " SUNDAY  ", 1); break; //(Column,Row,Data to be displayed,Font size)
    case 2:  draw_text(0, 50, " MONDAY  ", 1); break; //(Column,Row,Data to be displayed,Font size)
    case 3:  draw_text(0, 50, " TUESDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
    case 4:  draw_text(0, 50, "WEDNESDAY", 1); break; //(Column,Row,Data to be displayed,Font size)
    case 5:  draw_text(0, 50, "THURSDAY ", 1); break; //(Column,Row,Data to be displayed,Font size)
    case 6:  draw_text(0, 50, " FRIDAY  ", 1); break; //(Column,Row,Data to be displayed,Font size)
    default: draw_text(0, 50, "SATURDAY ", 1); //(Column,Row,Data to be displayed,Font size)
  }
}

void DS3231_display(){
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour   = (hour >> 4)   * 10 + (hour & 0x0F);
  month  = (month >> 4)  * 10 + (month & 0x0F);
  date   = (date >> 4)   * 10 + (date & 0x0F);
  year   = (year >> 4)   * 10 + (year & 0x0F);
  // End conversion

  Time[7]     = second % 10 + 48;
  Time[6]     = second / 10 + 48;
  Time[4]     = minute % 10 + 48;
  Time[3]     = minute / 10 + 48;
  Time[1]     = hour   % 10 + 48;
  Time[0]     = hour   / 10 + 48;
  Calendar[9] = year   % 10 + 48;
  Calendar[8] = year   / 10 + 48;
  Calendar[4] = date   % 10 + 48;
  Calendar[3] = date   / 10 + 48;
  Calendar[1] = month  % 10 + 48;
  Calendar[0] = month  / 10 + 48;

//Print text
  draw_text(60, 50, Calendar, 1); // Display the date (format: mm/dd/yyyy)
  draw_text(15, 25, Time, 2); // Display the time
}

void blink_parameter(){
  byte j = 0;
  while(j < 10 && digitalRead(button1) && digitalRead(button2)){
    j++;
    delay(25);
  }
}

byte edit(byte x_pos, byte y_pos, byte parameter){
  char text[3];
  sprintf(text,"u", parameter);
  while(!digitalRead(button1));                      // Wait until button B1 released
  while(true){
    while(!digitalRead(button2)){                    // If button B2 is pressed
      parameter++;
      if(i == 0 && parameter > 12)                   // If month > 12 ==> month = 1
        parameter = 1;
      if(i == 1 && parameter > 31)                   // If date > 31 ==> date = 1
        parameter = 1;
      if(i == 2 && parameter > 99)                   // If year > 99 ==> year = 0
        parameter = 0;
      if(i == 3 && parameter > 23)                   // If hours > 23 ==> hours = 0
        parameter = 0;
      if(i == 4 && parameter > 59)                   // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text,"u", parameter);
      draw_text(x_pos, y_pos, text, 1);
      delay(200);                                    // Wait 200ms
    }
    draw_text(x_pos, y_pos, "  ", 1);
    blink_parameter();
    draw_text(x_pos, y_pos, text, 1);
    blink_parameter();
    if(!digitalRead(button1)){                       // If button B1 is pressed
      i++;                                           // Increment 'i' for the next parameter
      return parameter;                              // Return parameter value and exit
    }
  }
}

void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
  display.setCursor(x_pos, y_pos);
  display.setTextSize(text_size);
  display.print(text);
  display.display();
}

void scroll_text(){
  draw_text(0, 0, "The Pumpkin Express", 1);
  display.display();
  display.startscrollright(0x00, 0x00);
  delay(8500);
  display.stopscroll();
  delay(4000);
  }

void loop() {

  if(!digitalRead(button1)){                         // If button B1 is pressed
    i = 0;
    while(!digitalRead(button1));                    // Wait for button B1 release
    while(true){
      while(!digitalRead(button2)){                  // While button B2 pressed
        day++;                                       // Increment day
        if(day > 7) day = 1;
        display_day();                               // Call display_day function
        delay(200);                                  // Wait 200 ms
      }
      draw_text(0, 50, "         ", 1);
      blink_parameter();                             // Call blink_parameter function
      display_day();                                 // Call display_day function
      blink_parameter();                             // Call blink_parameter function
      if(!digitalRead(button1))                      // If button B1 is pressed
        break;
    }
    //set position of text when editing on button press
    month  = edit(60, 50, month);                    // Edit month
    date   = edit(80, 50, date);                      // Edit date
    year   = edit(110,50, year);                    // Edit year
    hour   = edit(14, 25, hour);                     // Edit hours
    minute = edit(50, 25, minute);                   // Edit minutes

    // Convert decimal to BCD
    minute = ((minute / 10) << 4) + (minute % 10);
    hour = ((hour / 10)  << 4) + (hour % 10);
    date = ((date / 10) <<  4) + (date % 10);
    month = ((month / 10)  << 4) + (month % 10);
    year = ((year / 10)  << 4) + (year % 10);
    // End conversion

    // Write data to DS3231 RTC
    Wire.beginTransmission(0x68);               // Start I2C protocol with DS3231 address
    Wire.write(0);                              // Send register address
    Wire.write(0);                              // Reset seconds and start oscillator
    Wire.write(minute);                         // Write minute
    Wire.write(hour);                           // Write hour
    Wire.write(day);                            // Write day
    Wire.write(month);                          // Write month
    Wire.write(date);                           // Write date
    Wire.write(year);                           // Write year
    Wire.endTransmission();                     // Stop transmission and release the I2C bus
    delay(200);                                 // Wait 200ms
  }

  Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
  Wire.write(0);                                // Send register address
  Wire.endTransmission(false);                  // I2C restart
  Wire.requestFrom(0x68, 7);                    // Request 7 bytes from DS3231 and release I2C bus at end of reading
  second = Wire.read();                         // Read seconds from register 0
  minute = Wire.read();                         // Read minutes from register 1
  hour   = Wire.read();                         // Read hour from register 2
  day    = Wire.read();                         // Read day from register 3
  month  = Wire.read();                         // Read month from register 4
  date   = Wire.read();                         // Read date from register 5
  year   = Wire.read();                         // Read year from register 6
  Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
  Wire.write(0x11);                             // Send register address
  Wire.endTransmission(false);                  // I2C restart
  Wire.requestFrom(0x68, 2);                    // Request 2 bytes from DS3231 and release I2C bus at end of reading

  DS3231_display();                             // Display time & calendar
  display_day();                                // Display date

  scroll_text();                                // Display scrolling text
              // If i dont use the clear buffers(next 2 line codes), on the
             //next loop cycle the seconds & minute text becomes jumbled
  //display.clearDisplay();
  //display.display();

  delay(50);                                    // Wait 50ms
}
```

sender: assistant

body:
The answer to your title question, "How to get 2 loop functions to cooperate?" is: You can't, because your program can't have two functions with the same name. What you'd need to do instead is redesign your program, keeping in mind the MCU can only *do one thing at a time*, although you could break up each of several jobs into pieces and interleave them fast enough that we slow humans won't notice.

My approach, when I have a question like this, is to temporarily put aside what I know about coding and about MCUs, and just focus on how to do the job. I list the sub-tasks my code needs to do but without thinking too much about *how* to do them. Write them down, in the order they required doing, in any note-taking style that suits you.

Now break down each one of those sub-tasks into *its* sub-tasks. Repeat, until you understand how to code each one. Then you'll know enough to start writing the code.

Update:

@NathanJiang is correct. The solution is not to make two loop() functions (because the language doesn't support that), but to decide how to interleave pieces of each job within 1 function, in such a way that they each appear to operate smoothly and don't interfere with each other. Especially, neither one must call delay(), which *stops your code doing anything* for the duration. If some piece isn't ready to be done yet, your code must move on to other pieces and do which ever of those *is* ready. This keeps it checking each piece over and over again, rapidly, doing what is ready and skipping what is not.


body:
The way to get functions to cooperate with each other is to re-code them so they don't waste time and pass control back and forth as quickly as possible.  You do this by using the [BlinkWithoutDelay trick][1] to re-write the "blocking" code to be non-blocking and trust in `loop()` to hand back control to your function in a reasonable amount of time.

For instance take this function that @jsotola identified as a performance killer:

```
void scroll_text(){
  draw_text(0, 0, "The Pumpkin Express", 1);
  display.display();
  display.startscrollright(0x00, 0x00);
  delay(8500);
  display.stopscroll();
  delay(4000);
  }
```
It really doesn't need to monopolize the processor for 12500 microseconds--Instead it could just check the time and turn scrolling on and off every so often, and quickly pass control back to the `loop()` for reading and updating the clock.

I don't have your hardware or setup, so here's some untested code:

```
void scroll_text(){
  // some local state variables to remember where we are
  static bool isInitialized = false; // maybe a global if re-initializing is needed.
  static bool isScrolling = false;
  static unsigned long interval = 1;
  static unsigned long last = -interval;
  unsigned long now = millis();
  if (now - last >= interval ) { // time to do something
    last = now;
    if( !isInitialized ){
      draw_text(0, 0, "The Pumpkin Express", 1);
      display.display();
      isIinitialized = true;
    }
    if ( !isScrolling ) {
        isScrolling = true;
        display.startscrollright(0x00, 0x00);
        // delay(8500);  // use BWOD trick instead
        interval = 8500;
     } else { // isScrolling
       isScrolling = false;
       display.stopscroll();
       //delay(4000);
       interval = 4000;
     }
  }
```

This drop-in `scroll_text()` function can be called many time times per millisecond and will mostly do nothing and return control immediately.  But when it realizes the time is right, it will update its own state variables and the output states.

By replacing the `scroll_text()` function with a non-blocking form, it speeds up `loop()` by 12.5 seconds per loop.  Doing similar replacement of processor-sapping `delay()`s could further improve responsiveness.  However it is a big mind shift to stop using serial, blocking code and shift to events.  Every time you see a `delay()`, a `while(...)`, or a `for()` loop, think about whether you really need to trap the processor inside of that loop, or what data you would need in order to skip it for now and come back to it next time through the main event `loop()`.

I think the next step would be to wrap the reading of the reading the the DS3231 with the BWOD trick -- you only need to read the clock once per 1000ms and you could save hundreds of instructions per `loop()`.

  [1]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay


message:
Turning off a LED

I am trying to make 2 alarms for 2 different times using 2 LED's which should turn on when the time corresponds to the set time and then if a pushbutton is pressed, the LED should turn off. For the first alarm, the first LED can be turn off with the pushbutton, instead for the second alarm, the second LED is turning on, but if the pushbutton is pressed is will not turn off, even though is the same code. What can I do to turn off the second LED?

    #include <RTClib.h>
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x27, 16, 2);
    int nowHr, nowMin, nowSec;
    RTC_DS3231 rtc;

    int h1 = 15;
    int m1 = 51;
    int h2 = 15;
    int m2 = 52 ;
    int pin_buton1 = 8;
    int stop_buton =9;
    int state_stop_buton = 0;

    int led1_pin = 6;
    int state_led = LOW;
    int pushpressed = 0;

    int led2_pin = 7;
    int state_led2 = LOW;

    void setup()
    {

      Wire.begin();
      //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      rtc.adjust(DateTime(2021, 03, 27, 15, 50, 50));

      lcd.backlight();
      lcd.begin(16, 2);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Welcome To Our");
      lcd.setCursor(0, 1);
      lcd.print("device");

      pinMode(pin_buton1, INPUT);
      pinMode(stop_buton, INPUT);
      pinMode(led1_pin, OUTPUT);
      pinMode(led2_pin, OUTPUT);
      delay(2000);
      Serial.begin(9600);
    }

    void loop() {
      timeScreen();
      first_alarm();
      stopPins();
      second_alarm();
      stopPins2();

      state_stop_buton = digitalRead(stop_buton);

    }

    void timeScreen() {

      DateTime now = rtc.now();
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Time:");
      lcd.setCursor(6, 0);
      lcd.print(nowHr = now.hour(), DEC);
      lcd.print(":");
      lcd.print(nowMin = now.minute(), DEC);
      lcd.print(":");
      lcd.print(nowSec = now.second(), DEC);
      lcd.setCursor(0, 1);
      lcd.print("Date: ");
      lcd.print(now.day(), DEC);
      lcd.print("/");
      lcd.print(now.month(), DEC);
      lcd.print("/");
      lcd.print(now.year(), DEC);
      delay(500);

    }

    void stopPins() {
      if (state_stop_buton == 1) {

        pushpressed =1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("first message ");
        lcd.setCursor(0, 1);
        lcd.print("was read");
        delay(1200);
        lcd.clear();
      }
    }

    void startBuzz() {

      if (pushpressed == 0) {

        if (state_led == LOW) {
          state_led = HIGH;
          digitalWrite(led1_pin, state_led);

        }
      }
      else if (pushpressed == 1) {

        state_led = LOW;
        digitalWrite(led1_pin, state_led);
      }
    }

    void first_alarm() {
      DateTime t = rtc.now();
      if (int(t.hour()) == h1 && int(t.minute()) == m1) {

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("first ");
        lcd.setCursor(0, 1);
        lcd.print("text");
        startBuzz();
        delay(5000);

      }
    }

    //

    void stopPins2() {
      if (state_stop_buton == 1) {

        pushpressed = 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("second message ");
        lcd.setCursor(0, 1);
        lcd.print("was read ");
        delay(1200);
        lcd.clear();
      }
    }

    void startBuzz2() {

      if (pushpressed == 1) {

        if (state_led2 == LOW) {
          state_led2 = HIGH;
          digitalWrite(led2_pin, state_led2);

        }
      }
      else  if (pushpressed == 0 ) {
        state_led2 = LOW;
       digitalWrite(led2_pin, state_led2);
     }
    }

    void second_alarm() {
      DateTime t = rtc.now();
      if (int(t.hour()) == h2 && int(t.minute()) == m2   ) {

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("second");
        lcd.setCursor(0, 1);
        lcd.print("text");
        startBuzz2();
        delay(5000);

      }
    }

body:
**1.** `pushpressed` gets set, but never reset.

It's set in `stopPins()` and `stopPins2()` if the input is `HIGH`. Since it's never reset back to zero, once it's been set, the logic in `startBuzz` and `startBuzz2` will follow a single pass. You've created a latched switch.

---

*General Stuff*

---

**2.** Inconsistent naming: makes reading code harder

Pick `snake_case` or `camelCase` or `smashitalltogether` (not recommended) and stick with it :) Same goes for the "types" of variables: some things are named `xxx pin xxx`, some are named `xxx state xxx`, some aren't. It's clearer when same-things are named-same.

**3.** Duplication: makes understanding code harder

Along with the naming, the (essentially) duplicated code makes tracking down problems harder, as you've noticed trying to debug this problem. There are a ton of ways to go about shrinking the code down to make it understandable. The nutshells are to identify the differences in similar code, and to do less at once.

(And if you want to take it to its logical conclusion, wrapping up each alarm in a class would eliminate all duplication and most function parameters :)

---

*Annoying Diversion of Explanation*

---

Let's look at `startBuzz` and `startBuzz2`.

```cpp
void startBuzz() {
  if (pushpressed == 0) {
    if (state_led == LOW) {
      state_led = HIGH;
      digitalWrite(led1_pin, state_led);
    }
  } else if (pushpressed == 1) {
    state_led = LOW;
    digitalWrite(led1_pin, state_led);
  }
}

void startBuzz2() {
  if (pushpressed == 1) {
    if (state_led2 == LOW) {
      state_led2 = HIGH;
      digitalWrite(led2_pin, state_led2);
    }
  } else if (pushpressed == 0) {
    state_led2 = LOW;
    digitalWrite(led2_pin, state_led2);
  }
}
```

The only things different here are the LED pin, and the LED state. Let's normalize our naming so things become clear, using `startBuzz` as the example. We'll also assume `pushPressed` can only be 0 or 1 (HIGH or LOW):

```cpp
void startBuzz() {
  if (pushPressed == LOW) {
    if (led1State == LOW) {
      led1State = HIGH;
      digitalWrite(led1Pin, led1State);
    }
  } else {
    led1State = LOW;
    digitalWrite(led1Pin, led1State);
  }
}
```

We can make this work for either LED by doing two things: taking in the pin and current state, and returning the new state. Why return the new state instead of setting it here? It makes the mainline code easier (and avoids passing a reference).

```cpp
void startBuzz(int ledPin, int ledState) {
  int newLedState = ledState;

  if (pushPressed == LOW) {
    if (ledState == LOW) {
      newLedState = HIGH;
      digitalWrite(ledPin, newLedState);
    }
  } else {
    newLedState = LOW;
    digitalWrite(ledPin, newLedState);
  }

  return newLedState;
}
```

Then when we call `startBuzz` or `startBuzz2` we replace the current code with:

```cpp
led1State = startBuzz(led1Pin, led1State);
```

We're not done.

Since we keep the original `ledState` we can remove the duplicated calls to `digitalWrite`; at worst we'll have a superfluous write when `pushPressed != LOW && ledState != HIGH`.

Since all conditions except one lead to a `LOW` value we don't even need to keep the original state. And since it's two conditions to flip it `HIGH` we can combine those. And if we pull out the digitalWrite we're really just calculating the next state--that doesn't rely on the LED pin.

```cpp
void getNextLedState(int ledState) {
  return (pushPressed == LOW && ledState == LOW) ? HIGH : LOW;
}
```

And the callsites look like this:

```cpp
led1State = getNextLedState(led1State);
digitalWrite(led1Pin, led1State);
```

Similarly for the alarms: create a function called `checkAlarm` that takes in hrs and mins and returns a boolean. In the loop call `checkAlarm(h1, m1)` and if true, call `runAlarm1()`. (Even that could be shrunk further, but you get the idea.) `stopPins` differs only in the strings written to the LCD. And so on.


message:
LED sometimes don't turn off when a button is pressed

I'm still very new to this but I've put together some code that when a button is pressed, my servo runs continuously, a second button rotates it the other way and a third cancels everything.

A red or green comes on depending on the rotation and this can be one using an IR receiver also.

Issue I'm having is that randomly, 1/5 of the time, the red or green LED does not turn off. I can manually kill it using the third cancel button or just press it a couple times until it turns off as it should on the next push of the button.

Cant work out where im going wrong.

I also find my IR remote works maybe 60% of the time. Any help would be greatly appreciated.

```
#include <Servo.h>
Servo servo1;
int servoPin = 9;
#include "IRremote.h"

/*----- Variables, Pins -----*/

int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 6
int RledPin = 5;
int GledPin = 3;
int buttonApin = 7;
int buttonBpin = 8;
int buttonCpin = 4;
unsigned long elapsedTime;
unsigned long onTime;

/*-----( Declare objects )-----*/
// Setup of proper sequencing for Motor Driver Pins
// In1, In2, In3, In4 in the sequence 1-3-2-4

IRrecv irrecv(receiver);    // create instance of 'irrecv'
decode_results results;     // create instance of 'decode_results'

void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  servo1.attach(servoPin);
  servo1.write(90);
  pinMode(RledPin, OUTPUT);
  pinMode(GledPin, OUTPUT);
  pinMode(buttonApin, INPUT_PULLUP);
  pinMode(buttonBpin, INPUT_PULLUP);
  pinMode(buttonCpin, INPUT_PULLUP);

}

void loop(){

if (digitalRead(buttonApin) == LOW)   // Switch is closed to start LED timer
         {
          digitalWrite(RledPin, HIGH);  // Red LED comes On
          digitalWrite(GledPin, LOW);  // Green LED Goes Off
          servo1.attach(servoPin); //Servo is activated
          servo1.write(0);  //Servo turns on clockwise
            onTime = millis();  //time set
          }

      if(onTime > 0 && millis() - onTime > 1500)  //time limit target
            {
            servo1.write(90); //Servo stops
            servo1.detach(); //servo deactivated
            delay(500); //used to sync the servo stop with the LED off
            digitalWrite(RledPin, LOW);  // LED goes off
              onTime = 0;  //time reset
            }

if (digitalRead(buttonCpin) == LOW)   // Switch is closed to start LED timer
         {
          digitalWrite(GledPin, HIGH);  // Green LED comes On
          digitalWrite(RledPin, LOW);  // RED LED Goes Off
          servo1.attach(servoPin); //Servo is activated
          servo1.write(180);  //Servo turns on anti-clockwise
            onTime = millis();  //time set
          }

      if(onTime > 0 && millis() - onTime > 1500)  //time limit target
            {
            servo1.write(90); //Servo stops
            servo1.detach(); //servo deactivated
            delay(500);
            digitalWrite(GledPin, LOW);
              onTime = 0;  //time reset
            }

if (digitalRead(buttonBpin) == LOW) //Deactivation Sequence KILL SWITCH
  {
    digitalWrite(RledPin, LOW);
    digitalWrite(GledPin, LOW);
    servo1.write(90);
    servo1.detach();
      onTime = 0;  //time reset
  }

  if (irrecv.decode(&results)) // have we received an IR signal?

  {
    switch(results.value)

    {

      case 0xFFE01F: // DOWN button pressed
                      {
          digitalWrite(RledPin, HIGH);  // Red LED comes On
          digitalWrite(GledPin, LOW);  // Green LED Goes Off
          servo1.attach(servoPin); //Servo is activated
          servo1.write(0);  //Servo turns on clockwise
          onTime = millis();  //time set
          }

          if(onTime > 0 && millis() - onTime > 2000)  //time limit target
            {
            servo1.write(90); //Servo stops
            servo1.detach(); //servo deactivated
            digitalWrite(RledPin, LOW);  // LED goes off
             onTime = 0;  //time reset
            }
            break;

      case 0xFF906F: // UP button pressed
                      {
          digitalWrite(GledPin, HIGH);  // Green LED comes On
          digitalWrite(RledPin, LOW);  // RED LED Goes Off
          servo1.attach(servoPin); //Servo is activated
          servo1.write(180);  //Servo turns on anticlockwise
          onTime = millis();  //time set
          }

      if(onTime > 0 && millis() - onTime > 2000)  //time limit target
            {
            servo1.write(90); //Servo stops
            servo1.detach(); //servo deactivated
            digitalWrite(GledPin, LOW);  // LED goes off
             onTime = 0;  //time reset
            }
            break;

      case 0xFF02FD: // PAUSE button pressed
                      servo1.write(90);
                      servo1.detach();
                      digitalWrite(GledPin, LOW);
                      digitalWrite(GledPin, LOW);
                      break;

    }

      irrecv.resume(); // receive the next value

  }
}/* --end main loop -- */

```

body:
Found the answer!

I added serial print to every line and realised that my kill process after the time elapsed was switching between the red led and green led.

I didn't need the if time elapsed function many times, just once. Deleted that portion and it worked perfectly. Seems to have fixed the IR troubles too.

Working code:
```

#include <Servo.h>
Servo servo1;
int servoPin = 9;
#include "IRremote.h"

/*----- Variables, Pins -----*/

int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 6
int RledPin = 5;
int GledPin = 3;
int buttonApin = 7;
int buttonBpin = 8;
int buttonCpin = 4;
unsigned long elapsedTime;
unsigned long onTime;

/*-----( Declare objects )-----*/
// Setup of proper sequencing for Motor Driver Pins
// In1, In2, In3, In4 in the sequence 1-3-2-4

IRrecv irrecv(receiver);    // create instance of 'irrecv'
decode_results results;     // create instance of 'decode_results'

void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  servo1.attach(servoPin);
  servo1.write(90);
  pinMode(RledPin, OUTPUT);
  pinMode(GledPin, OUTPUT);
  pinMode(buttonApin, INPUT_PULLUP);
  pinMode(buttonBpin, INPUT_PULLUP);
  pinMode(buttonCpin, INPUT_PULLUP);
  Serial.begin(9600);
  pinMode(LED_BUILTIN, HIGH);

}

void loop(){

if (digitalRead(buttonApin) == LOW)   // Switch is closed to start LED timer
         {
          digitalWrite(RledPin, HIGH);  // Red LED comes On
          Serial.println("RED comes on");
          digitalWrite(GledPin, LOW);  // Green LED Goes Off
          Serial.println("green off");
          servo1.attach(servoPin); //Servo is activated
          Serial.println("red servo attach");
          servo1.write(0);  //Servo turns on clockwise
          Serial.println("red servo spins");
            onTime = millis();  //time set
         }

if(onTime > 0 && millis() - onTime > 1500)  //time limit target
            {
            servo1.write(90); //Servo stops
            Serial.println("servo stops spinning");
            digitalWrite(RledPin, LOW);  // LED goes off
            digitalWrite(GledPin, LOW);  // LED goes off
            Serial.println("red RED goes off");
            delay(500);
            Serial.println("delay");
            servo1.detach(); //servo deactivated
            Serial.println("servo Rled dettach");
              onTime = 0;  //time reset

         }
if (digitalRead(buttonCpin) == LOW)   // Switch is closed to start LED timer
         {
          digitalWrite(GledPin, HIGH);  // Green LED comes On
          Serial.println("green comes on");
          digitalWrite(RledPin, LOW);  // RED LED Goes Off
          Serial.println("RED goes off");
          servo1.attach(servoPin); //Servo is activated
          Serial.println("green servo attached");
          servo1.write(180);  //Servo turns on clockwise
          Serial.println("green servo spins");
            onTime = millis();  //time set
         }

if (digitalRead(buttonBpin) == LOW) //Dectivation Sequence KILL SWITCH
  {
    digitalWrite(RledPin, LOW);
    Serial.println("total red off");
    digitalWrite(GledPin, LOW);
    Serial.println("total green off");
    servo1.write(90);
    Serial.println("total servo off");
    servo1.detach();
    Serial.println("total detach");
      onTime = 0;  //time reset
  }

  if (irrecv.decode(&results)) // have we received an IR signal?

  {
    switch(results.value)

    {

      case 0xFFE01F: // DOWN button pressed
                      {
          digitalWrite(RledPin, HIGH);  // Red LED comes On
          digitalWrite(GledPin, LOW);  // Green LED Goes Off
          servo1.attach(servoPin); //Servo is activated
          servo1.write(0);  //Servo turns on clockwise
          onTime = millis();  //time set
          }
          break;

      case 0xFF906F: // UP button pressed
                      {
          digitalWrite(GledPin, HIGH);  // Green LED comes On
          digitalWrite(RledPin, LOW);  // RED LED Goes Off
          servo1.attach(servoPin); //Servo is activated
          servo1.write(180);  //Servo turns on clockwise
          onTime = millis();  //time set
          }
          break;

      case 0xFF02FD: // PAUSE button pressed
          servo1.write(90);
          digitalWrite(GledPin, LOW);
          digitalWrite(GledPin, LOW);
          delay(500);
          servo1.detach();
          break;
    }

      irrecv.resume(); // receive the next value

  }
}/* --end main loop -- */

```


message:
error: expected primary-expression before ',' token edit status 1

Im using tinkercad for my robotics class and I can't seem to figure out a solution for this problem.
Heres my codes:
```
#include <LiquidCrystal.h> //LCD library
#define echo 2
#define trig 3

// Gas Sensor
#define GREEN 4
#define Yellow 6
#define RED 7
#define Buzzer 5
#define Sensor A0

float duration;
float distance;

LiquidCrystal lcd(13,,12,11,10,9,8);

int sensor_Input;
float temp;

void setup()
{
  // Ultrasonic sensor
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
  lcd.begin(13, 2);

  //temp
  measure_Temp();
  display_Temp();

  // Gas Sensor
  for (int i = 0; i < 6; i++)
    pinMode(i, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  // Ultrasonic Sensor
  time_Measurement();
  distance = duration * (0.0343) /2;

  display_distance();

  // Gas Sensor
  for (int i = 0; i < 6; i++)
    digitalWrite(i, LOW);

  status_Indicator();
}

void status_Indicator()
{
  // Gas Sensor
  int sensor_In = analogRead(A0);
  Serial.println(sensor_In);

  if ( sensor_In>=40 )
  {
    digitalWrite(RED, HIGH);
    digitalWrite(Buzzer, HIGH);
  }
  else if (sensor_In >=25 )
  {
    digitalWrite(Yellow, HIGH);
  }
  else
  {
    digitalWrite(GREEN, HIGH);
  }
  delay(10);
}

void time_Measurement()
{
  // Ultrasonic Sensor
  digitalWrite(trig, LOW);
  delayMicroseconds(2);

  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);
}

void display_distance()
{
  lcd.clear();
    lcd.setCursor(0, 0);
  Serial.print("Distance in m: ");
  Serial.print(distance);
  Serial.println();
  lcd.print("distance in m: ");
  lcd.setCursor(5, 1);
  lcd.print(distance);
  delay(1000);
}

void measure_Temp()
{
  //Temp
  sensor_Input = analogRead(A0);
  temp = (float)sensor_Input / 1024;
  temp = temp *5;
  temp = temp - 0.5;
  temp = temp *100;
}

void display_Temp()
{
  //temp
  lcd.setCursor(0, 0);
  Serial.print("Temp. in Celcius: ");
  Serial.print(temp);
  Serial.println();
  lcd.print("Temp. in Celcius: ");
  lcd.setCursor(5, 1);
  lcd.print(temp);
  delay(500);
}
```

body:
You have two commas in the command when making the `lcd` object:
```cpp
LiquidCrystal lcd(13,,12,11,10,9,8);
```
Probably just a typo, delete the comma and you should be good to go.
```cpp
LiquidCrystal lcd(13,12,11,10,9,8);
```


message:
How to attempt connection to WiFi only once?

I am working on a garden timer project, I connect to WiFi once and if its successful show time from NTPClient or else show time from RTC.

I have been done the above, and it works in the sense that if I turn off the WiFi **while the program is running**, it switches to the RTC and back to NTPClient when  WiFi is available again.

**PROBLEM-** If the WiFi is not available **when the board boots**, the program just waits for WiFi where I want it to use RTC.

Hardware-ESP8266 based NodeMCU, I2C RTC, I2C 16x2 LCD.

Software-Blynk

My code:-

```
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <DS3231.h>
#include <Wire.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"

#define BLYNK_PRINT Serial
#define DHT_PIN_DATA  12
// LCD definitions
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22

// Auth code and wifi credentials here
char auth[] = "ymri80lFL9_xjZppphf6WIRHtQ1kqEWOt9zBy";
char ssid[] = "Hotspot-82DB";
char pass[] = "qqnbkbbbk";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int postNoon;
int eveTime;
int schTime;
int minStep;
int interval;
int count;
int flag = 0;
int soilHum = A0;
int waterItr;
int checkRun;
int waterItr1;
int oneTime;
bool h12Flag;
bool pmFlag;

unsigned long previousMillis = 0;
byte wifi[] = {
  B00001,
  B00001,
  B00101,
  B00101,
  B00101,
  B10101,
  B10101,
  B10101,

};

DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
DS3231 Clock;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);

BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V0)
{
  autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V1)
{
  morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V2)
{
  afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V6)
{
  postNoon = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V3)
{
  eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V10)
{
  waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V4)
{
  schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V7)
{
  minStep = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  Wire.begin();
  dht.begin();
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  digitalWrite(14, LOW);
  digitalWrite(15, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  pinMode(0, INPUT_PULLUP);
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
      timeClient.begin();
  /*
    while ( WiFi.status() != WL_CONNECTED ) {
      delay ( 500 );
      Serial.print ( "." );
    }
  */

  Blynk.syncAll();
  lcdI2C.createChar(0, wifi);
}

void loop()
{
  Blynk.run();
  time_run();
  lcd();
  butPress();
  butCheck();
  /*if (waterNow != 1) {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, minStep * 60);
    }*/
  if (waterNow == 1) {
    if (waterItr < minStep * 60) {
      waterOn();
      waterItr++;
      delay(500);
    }
    else {
      waterOff();
    }

  } else if (autoSch == 0) {
    auto_run1();
    waterItr = 0;
  } else if (autoSch == 1) {
    sch_run2();
    waterItr = 0;
  } else {
    //Blynk.virtualWrite(V10, 0);
    waterItr = 0;
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
  }
  Blynk.syncAll();

}

void butPress() {
  if (digitalRead(0) == LOW) {
    delay (100);
    if (flag == 0) {
      flag = 1;
    }
    else if (flag == 1) {
      flag = 0;
      waterItr1 = 0;
      digitalWrite(15, LOW);
      Blynk.virtualWrite(V5, 0);
    }
  }
}

void butCheck() {
  if (flag == 1) {
    digitalWrite(15, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr B Now :  ");
    lcdI2C.print(600 - waterItr1);
    if (waterItr1 < 600) {
      waterItr1++;
      delay(500);
    }
    else {
      waterItr1 = 0;
      flag = 0;
      digitalWrite(15, LOW);
      Blynk.virtualWrite(V5, 0);
    }
  }
}

void lcd() {
  if (oneTime == 0){

    oneTime=0;
    }
  //lcdI2C.clear();
  lcdI2C.setCursor(0, 0);

  if (WiFi.status() == WL_CONNECTED) {
    timeClient.update();
    lcdI2C.print("T:");
    lcdI2C.print(timeClient.getFormattedTime());
    Clock.setHour(timeClient.getHours());
    Clock.setMinute(timeClient.getMinutes());
    Clock.setSecond(timeClient.getSeconds());
  } else {
lcdI2C.print("R:");
lcdI2C.print(Clock.getHour(h12Flag, pmFlag)); lcdI2C.print(":"); lcdI2C.print(Clock.getMinute()); lcdI2C.print(":"); lcdI2C.print(Clock.getSecond());
  }
  if (autoSch == 0) {
    lcdI2C.setCursor(10, 0);
    lcdI2C.print(" Auto   ");
  } else {
    lcdI2C.print(" Sch   ");
  }

  if (WiFi.status() == WL_CONNECTED) {
    lcdI2C.setCursor(15, 0);
    lcdI2C.write(0);
  }

  if (digitalRead(14) == 1) {
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now           ");
  }
  else
  {
    if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12n ");
    } else if (int(timeClient.getHours()) < 14 && postNoon == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at:14pn ");
    } else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18e ");
    } else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) >= 6 && morTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) >= 12 && afterTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12a ");
    }   else if (int(timeClient.getHours()) >= 14 && postNoon == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 14a ");
    }  else if (int(timeClient.getHours()) >= 18 && eveTime == 1 && autoSch == 0) {
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18a ");
    } else {
      if (autoSch == 0) {
        lcdI2C.selectLine(2);
        lcdI2C.print("  Switch to Sch  ");
      } else {
        lcdI2C.selectLine(2);
        lcdI2C.print("  Schedule mode ");
      }
    }
  }
}

void waterOn() {
  lcdI2C.setCursor(0, 0);
  digitalWrite(14, HIGH);
  Blynk.virtualWrite(V5, 255);
  lcdI2C.selectLine(2);
  lcdI2C.print("Wtr Now :");
  lcdI2C.print((minStep * 60)  - waterItr);
  Blynk.virtualWrite(V8, (minStep * 60)  - waterItr);
  Blynk.syncAll();
}

void waterOff() {
  Blynk.virtualWrite(V10, 0);
  digitalWrite(14, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  waterItr = 0;
  Blynk.syncAll();
}

void sch_run2() {
  if (schTime == 1) {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
    Blynk.syncAll();
  } else if (schTime == 0) {
    checkRun = 0;
    if (checkRun == 0) {
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.syncAll();
    }
  }
}

void time_run() {
  Blynk.virtualWrite(V11, int(timeClient.getHours()));
  Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
  Blynk.virtualWrite(V13, float(dht.readTempC()));
  Blynk.virtualWrite(V14, float(dht.readHumidity()));
}

void auto_run1() {
  if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else if (postNoon == 1 && String(timeClient.getFormattedTime()) > "14:00:00" && String(timeClient.getFormattedTime()) < "14:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "11:49:00" && String(timeClient.getFormattedTime()) < "11:50:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    checkRun = 1;
  }
  else  {
    //(String(timeClient.getFormattedTime() == "06:20:00" || "12:20:00" || "14:20:00" || "13:48:00"))
    //waterNowrun();
    checkRun = 0;
    if (checkRun == 0) {
      //Blynk.virtualWrite(V10, 0);
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.virtualWrite(V8, 0);
      Blynk.syncAll();
    }
  }
}
```

body:
Instead of using ```blynk.begin()``` use ```WiFi.begin()``` and ```blynk.config()``` to achieve non-blocking code
```
void setup(){
//  Blynk.begin(auth, ssid, pass); don't use this
  WiFi.begin(ssid, pass);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  Blynk.config(auth);
}
```


message:
AT 09 BLE module not transmitting data

I have recently started working with the Arduino Pro Mini 5v/16Mhz and an AT 09 BLE module for an IoT project. I am controlling the BLE module using Software Serial and am leaving the hardware serial for for my laptop. I am using an app called "Serial Bluetooth Terminal" on Android to send/receive messages. The BLE module is able to receive messages and the "AT" command is also working. But when I try to get the BLE module to send a message, I get no response in the app. Any idea why this is happening and how can I resolve it?

My connections are:
> Laptop -> Arduino UNO, MB-102(USB to breadboard power adapter)

> Arduino UNO(without IC) Rx -> Pro mini Tx0

> Arduino UNO(without IC) Tx -> Pro mini Rx1

> Arduino UNO(without IC) RESET -> Pro mini Rst

> MB-102 5V -> Pro Mini Pin RAW

> MB-102 GND -> Pro Mini Pin GND

> Pro Mini Pin 2 -> AT 09 TXD

> Pro Mini Pin 3 -> AT 09 RXD

> Pro Mini Pin VCC -> AT 09 VCC

> Pro Mini Pin GND -> AT 09 GND

This is my code:
```cpp
#include<SoftwareSerial.h>

SoftwareSerial ble(2, 3);

int statePin = 4;
char c;
void setup()
{
  Serial.begin(9600);
  ble.begin(9600);
  ble.print("AT\r\n");
  delay(100);
  while(!ble.available())
    Serial.print(".");
  while(ble.available())
  {
    Serial.print(char(ble.read()));
  }
}

void loop()
{
  while(ble.available() > 0)
  {
    c = char(ble.read());
    delay(10);
    Serial.print(c);
    ble.print(c);
  }
}
```

This is the first time I am posting here so please tell me if I missed out on any information.

body:
So my AT 09 module is most likely faulty. I got a new HM 10 and connected it without changing any connections or code and it worked like a charm.
I do not know the exact nature of the defect but since the chip was responding to commands, I think the PCB might have been damaged.


message:
Message is sent multiple times from one arduino to another, using nRF24L01

I am trying to build a bidirectional communication channel, using nRF24L01 and two arduinos. The message is introduced using a button (but) in Morse code, decoded and then sent when another button (but_send) is pressed.
Although everything seems to work fine, the message is sent multiple times even though I added delays. I am a beginner in Arduino and I have no idea what else i could do. I even tried deleting the string right after radio.write, but it doesn't seem to work either. If anyone has an idea, please help!

[![enter image description here][1]][1]

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

These are the two codes. They are quite similar, but i added them both just in case:
```
#include <LiquidCrystal.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
struct record
{
  char mesaj[10];
  boolean state = 1;
};

typedef struct record Record;
Record  button_state, button_state1 ;
RF24 radio(9, 10); // CE, CSN(pini nrf01)
const byte addresses [][6] = {"00001", "00002"};  //Setting the two addresses. One for transmitting and one for receiving
String code = "";
int len = 0;
char ch;
int ok;
char new_char;
int i1 = 0;
int i2 = 1;
const int but_send = 8;
const int but = 5;
const int led = 4;
const int del = 3;
String a = "";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
int buttonState = 0;

char MakeString()
{
  if (pres_len < (unit_delay * 3) && pres_len > 50)
  {
    return '.';                        //if button press less than 0.6sec, it is a dot
  }
  else if (pres_len > (unit_delay * 3))
  {
    return '-';                        //if button press more than 0.6sec, it is a dash
  }
}

void Morse_decod()
{
  static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
                           "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                           ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
                          };
  int i = 0;
  while (morse[i] != "!")
  {
    if (morse[i] == code)
    {
      Serial.print(char('A' + i));
      a = a + char('A' + i);
      Serial.print(" ");
  }
  if (morse[i] == "!")
  {
    Serial.println("");
    Serial.println("This code is not exist!");
  }

  code = "";
}
void sendText()
{
  // Aici trebuie sa fe codul pentru trimiterea efectiva a msj
  if (ok == 1) {
    Serial.println("Lavinia:" + a);
  }
  ok = 0;

  delay(100);
}
void setup() {
  Serial.begin(9600);
  pinMode(but, INPUT_PULLUP);
  pinMode(but_send, INPUT_PULLUP);
  pinMode(del, INPUT_PULLUP);

  pinMode(led, OUTPUT);
  radio.begin();                           //Starting the radio communication
  radio.openWritingPipe(addresses[0]);     //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[1]);  //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MIN); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.

}
void loop() {

label:
  while (digitalRead(but) == HIGH) {
    delay(5);
    radio.startListening();

    if (radio.available())                     //Looking for incoming data
    {
      radio.read(&button_state, sizeof(button_state));
      if (button_state.state == 0)
      {

        ok = 1;
        sendText();
        String final = "";

        for (int i = 0; i < strlen(button_state.mesaj); i++)
        {
          final += String(button_state.mesaj[i]);
        }
        ok = 1;
        Serial.println("Iulia: " + final);
        button_state.state = 1;
        radio.stopListening();
      }
      else
      {
        //nu se intampla nimic daca eu nu am trimis mesaj

      }
      delay(5);

      radio.stopListening();                           //This sets the module as transmitter
      button_state1.state = digitalRead(but_send);
      int n = a.length();
      char char_array[n + 1];
      strcpy(char_array, a.c_str());
      strcpy(button_state1.mesaj, char_array);
      radio.write(&button_state1, sizeof(button_state1));   //Sending the data
    }

    if (digitalRead(del) == LOW && a[0] != '\0' ) {
      Serial.println("Deleted string");
      a = "\0";
      Serial.println(a);
    }

  }
  old_pres = rel_time;
  pres_time = millis();
  digitalWrite(led, HIGH);
  while (digitalRead(but) == LOW) {}
  rel_time = millis();
  digitalWrite(led, LOW);
  pres_len = rel_time - pres_time;
  space = pres_time - old_pres;
  if (pres_len > min_delay)
  {
    code += MakeString();
  }
  while ((millis() - rel_time) < (unit_delay * 3))
  {
    if (digitalRead(but) == LOW)
    {
      goto label;
    }

  }

  Morse_decod();
  delay(1000);

}
```
```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN(pini nrf01)
#include <LiquidCrystal.h>
struct record
{
  char mesaj[10];
  boolean state = 1;
};

typedef struct record Record;
const byte addresses [][6] = {"00001", "00002"};  //Setting the two addresses. One for transmitting and one for receiving
String code = "";
int len = 0;
char ch;
int ok;
int ok2;
char new_char;
int i1 = 0;
int i2 = 1;
const int but_send = 8;
const int but = 5;
const int led = 4;
const int del = 3;
String a = "";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
Record  button_state, button_state1 ;

char MakeString()
{
  if (pres_len < (unit_delay * 3) && pres_len > 50)
  {
    return '.';                        //if button press less than 0.6sec, it is a dot
  }
  else if (pres_len > (unit_delay * 3))
  {
    return '-';                        //if button press more than 0.6sec, it is a dash
  }
}

void Morse_decod()
{
  static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
                           "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                           ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
                          };
  int i = 0;
  while (morse[i] != "!")
  {
    if (morse[i] == code)
    {
      Serial.print(char('A' + i));
      a = a + char('A' + i);
      Serial.print(" ");
  }
  if (morse[i] == "!")
  {
    Serial.println("");
    Serial.println("This code is not exist!");
  }

  code = "";
}
void sendText()
{
  // Aici trebuie sa fe codul pentru trimiterea efectiva a msj
  if (ok == 1) {
    Serial.println("Iulia:" + a);
  }
  ok = 0;

  delay(100);
}
void setup() {
  Serial.begin(9600);
  pinMode(but, INPUT_PULLUP);
  pinMode(but_send, INPUT_PULLUP);
  pinMode(del, INPUT_PULLUP);

  pinMode(led, OUTPUT);
  radio.begin();                           //Starting the radio communication
  radio.openWritingPipe(addresses[1]);     //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[0]);  //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MIN); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.

}
void loop() {
label:
  while (digitalRead(but) == HIGH) {

    delay(5);
    radio.stopListening();                             //This sets the module as transmitter
    button_state.state = digitalRead(but_send);

    int n = a.length();
    char char_array[n + 1];
    strcpy(char_array, a.c_str());
    strcpy(button_state.mesaj, char_array);
    radio.write(&button_state, sizeof(button_state));  //Sending the data
    delay(5);

    radio.startListening();                            //This sets the module as receiver
    if (radio.available())
    {
      radio.read(&button_state1, sizeof(button_state1)); //Reading the data
      String final = "";
      if (button_state1.state == 0)      {
        ok = 1;

        sendText();
        for (int i = 0; i < strlen(button_state1.mesaj); i++)
        {
          final += String(button_state1.mesaj[i]);
        }
        Serial.println("Lavinia: " + final);
        button_state1.state = 1;
      }

    }

    if (digitalRead(del) == LOW && a[0] != '\0' ) {
      Serial.println("Deleted string");
      a = "\0";
      Serial.println(a);
    }

  }
  old_pres = rel_time;
  pres_time = millis();
  digitalWrite(led, HIGH);
  while (digitalRead(but) == LOW) {}
  rel_time = millis();
  digitalWrite(led, LOW);
  pres_len = rel_time - pres_time;
  space = pres_time - old_pres;
  if (pres_len > min_delay)
  {
    code += MakeString();
  }
  while ((millis() - rel_time) < (unit_delay * 3))
  {

    if (digitalRead(but) == LOW)
    {
      goto label;

    }

  }

  Morse_decod();
  delay(1000);

}
```

I believe the relevant part would be:
```
    int n = a.length();
    char char_array[n + 1];
    strcpy(char_array, a.c_str());
    strcpy(button_state.mesaj, char_array);
    radio.write(&button_state, sizeof(button_state));  //Sending the data
    delay(5);

```
where a is the message to be sent.

body:
(Too few characters in comments, so writing as answer instead)

It's a bit hard to figure out without having the setup here and I don't think I have any of the radio modules in my box.

What I think is happening is this.

It seems like the first code will not send anything unless it receives a message from the second code, because the radio.write is inside the radio.available if-block. But when it receives a message, the message to send back must be present, so you start by entering a message on Arduino1.

Then you enter a message on Arduino2. You press the button, it skips the while loop below the label. When you release the button, it will enter the while loop and send the message. For both versions, the message will be sent as soon as 'but' is released. but_send is copied to the record that is sent, but the sending does not depend on the state of this button. You need an if statement that checks but_send to do this. The effect is, that you can only send '.' or '-' because the message is sent right away, before you get to enter more dots or dashes.

Anyways, the message from Arduino2 is received by Arduino1. If the state field of the message is 1, the message is written to Serial. Then the message from Arduino1 is send to Arduino2. Since we are not pressing any buttons, the message from Arduino 2 is send again and again and again. The state field will be 0, because but_send is not pressed, but the message is sent anyway. This triggers a new send on Arduino 1, because it receives something from Arduino 2 and gets into the radio.available part.

It seems like the messages will bounce back and forth. The only reason you don't see your Serial console filled with letters is that state is 0 for most of the messages, because you release btn_send. But as long as you hold down btn_send, it will set state=1 and print the message at the receiving end.

To prevent this, you should not call radio.write unless btn_send is released. That is going from LOW to HIGH. To test this, have a variable called old_btn_send and do something like this:
Initialize old_btn_send to HIGH in setup()

    if (old_btn_send == LOW && digitalRead(btn_send) == HIGH {
        [do the sending thing]
    }
    old_btn_send = digitalRead(btn_send);

That is, you press btn_send. We will not enter the if block, but old_btn_send will be LOW. When you release, the condition will be true, but only once, because old_btn_send will be HIGH after the if block.

Please note, that what I write is from reading the code and not doing any testing, so I might be completely wrong :)


message:
How do I wire a ground rail to a VEROboard?

I’m looking to move my project from a breadboard to a vero board. However, I’m not sure how to go about soldering in my ground and power connections as the veroboard doesn't seem to have dedicated ground and power rails like the breadboard.

I’ve also attached a photo of my schematic in its current state.

Also, I’m using an Arduino Nano Board as opposed to the UNO featured in the schematic. (I’ve just used it as a placeholder as I could find a component for the nano.

Any help would be greatly appreciated.

[![Project Schematic][1]][1]

Here’s a photo of the type of veroboard I have:

[![veroboard][2]][2]

  [1]: https://i.stack.imgur.com/YC3Nq.jpg
  [2]: https://i.stack.imgur.com/bGsfW.jpg

body:
There's nothing special about ground. It's just a wire like any other.

You *could* designate a row of holes as ground then link them all together, but you don't need to. Just wire your grounds together as you would any other connection.


message:
Serial communication between Arduinos

I'm trying to send data from Arduino Mega to UNO.
The master code sends characters 'x' and 'a' every half second to the slave Arduino UNO.
Slave receives the characters and switches the state of the onboard LED.
Here I'm trying to print some text in the beginning of the loop and the characters received.
Instead of the letters it is printing numbers as given below.
Why this line `Serial.println('Soft serial avaialble')` prints numbers?
How to print real text received from the master?

    > 27749
    > 97
    > 27749
    > 120
    > 27749

**Master code:**

 // Include the Software Serial library
 #include <SoftwareSerial.h>
 // Define a Software Serial object and the used pins
 SoftwareSerial softSerial(8, 9);  // RX, TX
 void setup()  {
  Serial.begin(9600);
  softSerial.begin(9600);
 }
 void loop()  {
  // Sends characters 'x' and 'a' every half second.
  if (Serial.available())  {
   softSerial.write('x');
   delay(500);
   digitalWrite(LED, LOW);
   delay(500);
  }
 }

**Slave code:**

    // Include the Software Serial library
 #include <SoftwareSerial.h>
 // Define a Software Serial object and the used pins
 SoftwareSerial softSerial(8, 9);
 // LED Pin
 int LED = 13;

 void setup()  {
  softSerial.begin(9600);
  Serial.begin(9600);
  pinMode(LED, OUTPUT);

 }
 void loop()  {
  Serial.println('Soft serial avaialble');
  if (softSerial.available())  {
   int com = softSerial.read();
   if (com == 'x')  {
    Serial.println(com);
    digitalWrite(LED, LOW);
   } else if (com == 'a'){
    Serial.println(com);
    digitalWrite(LED, HIGH);
   }
  }
 }

body:
In your slave, you've declared `com` as an int, so Serial.println() interprets it that way. If you want to keep it as int except for printing, cast Serial.println()'s argument to char:

    Serial.println((char)com);


body:
In addition to JRobert's remark, note that strings in C++ are delimited by _double_ quotes, thus:

```c++
Serial.println("Soft serial avaialble");
```


message:
Global array doesn't get assigned the space it would take up in memory

I have this sketch:

```c++
const uint32_t len = 65536;
uint8_t arr[len];

void setup() {}

void loop() {}
```

The length of the array should fit into the dynamic memory. However, when I compile the sketch it says this in the output window:

    Sketch uses 10528 bytes (0%) of program storage space. Maximum is 2031616 bytes.
    Global variables use 13504 bytes (1%) of dynamic memory, leaving 1034224 bytes for local variables. Maximum is 1048576 bytes.

If I change `len` to 10, that doesn't change. The compiler is set to "Debug", so it should not get optimized away. This indicates, that the memory isn't actually being allocated. What seems to be the problem here?

I am compiling for the Teensy 4.0, but the output is the same in essence for the Arduino Uno and other boards (with lower memory sizes).

body:
There is no problem here. Only the compiler is a bit smarter than you anticipated. It sees, that you are not using `arr` anywhere, so it just optimizes it out.

There are two ways to prevent that, if you really want to:
 - I think you can use flags to tell the compiler, that this shouldn't be optimized out. I'm no expert in this, others might know more about this and add their own answer
- You can just start using it.


message:
Send packet of multiple sensors data to Bluetooth module

In my project I am using 3 sensors. I am sending a regular stream of sensors data to Bluetooth module  but now I want to send data in form of packet (which may be 30 bytes or 40 bytes of size) in which first 10 bytes contain the first sensor data while next 10 bytes contain second sensor data and so on. But problem here is I am not finding something relevant to my approach. Can any one suggest me some link or some way to do this.

Thanks in advance.

body:
There are many ways to transmit binary data over a byte-stream based interface like `Serial` (which is used by common bluetooth modules like the HC-05/HC-06). I will only describe one here.

First we need to define a start byte, which marks the start of a new packet. That can be any arbitrary value, for example `0xFF`. It is also possible to use a specific byte sequence as start marker. This start byte/sequence is what we send first when transmitting a packet.

Then we want to transmit the size of the following data. With small to normal packet sizes a single byte is enough here (giving room for up to 255 bytes).

Sometimes you might want to compute a CRC hash value to check for data corruption. That could also be send here. But unless you have a system, which really is loosing/corrupting data, you don't need it. I suggest you first try it without and check, if corrupted data is really a thing for your setup.

And then we are sending the actual data. How exactly you are doing this depends on how the data is stored in your code. Though you will use `Serial.write()` in some way. If you want a more specific answer in this regard, you need to include your code, so that we can see how you are storing your sensor data.

On the receiving side you would then wait for the start marker, read the size byte and then read bytes until you have received as many, as the size byte said. As you have multiple sensors, you could send the sensor data of each sensor in it's own packet. The data could then be formatted like: 1 byte sensor ID, X byte sensor data.


message:
Why does Adafruit guide for motors use transistors on ground rather than modulating the power source

I'm going through the Adafruit Motors guide for Arduino, found [here][1], and I'm struggling to understand how each of these parts play in. From what I understood, pulse width modulation is basically a way to send varying levels of power through a digital output source. Additionally, it seems that the guide is using a transistor with the PWM signal as the gate, so it can allow the percentage given by the PWM signal to control how much flow is given to the motor. However, what I'm confused here is that both the power and ground are interfacing with this transistor/diode setup.

This is more specifically what I mean, on the bottom seems really simple: the PWM signal comes on the yellow wire, fed through the resistor so that it doesn't fry the transistor into the gate.

After this though, there's a ground signal being passed into the source leg of the transistor, and the sink leg is connected to both a diode for power AND the ground of the motor? I might be misunderstanding how a diode works but this doesn't seem to make sense as to why the ground signal is being modulated.

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

My initial thought for this would be a system where only the power of the motor is varied by the PWM signal, sorta like in this way (apologies for the terrible drawing style, I haven't gotten used to some of the Arduino sketching software online):

[![enter image description here][3]][3]

I've not gotten to try this yet, but I assume it wouldn't work or would destroy components somehow since this does seem to be a simpler solution, and it's not being used. I was sorta trying to figure out 1) why my solution would be bad and 2) how the official solution works, as they haven't really given any actual schematic (not that I would understand it, haha) Any help would be appreciated! Thanks!

  [1]: https://learn.adafruit.com/adafruit-arduino-lesson-13-dc-motors/breadboard-layout
  [2]: https://i.stack.imgur.com/CTRI8.png
  [3]: https://i.stack.imgur.com/kdDv8.png

body:
**Your schematic**

The blue line in your first schematic "going up" that you marked GND, is not really GND but one of the motor connections. If you look at the Adafruit schematic you can see this.

The motor in the Adafruit schematic in the link you provided is connected between 5V and the diode's Anode (and the transistor's collector).

**Flyback diode**

The diode is a so-called "flyback diode", connected between the motor connections to "soak up" back-EMF that occurs when the motor is turned off and its magnetic field collapses. If the diode would not be there, there would be a voltage spike on the transistor's collector, possibly damaging it.

**Low-side switching**

The "Adafruit" solution uses an NPN transistor as a switch on the low side of the motor when the I/O pin is high, like the schematic on the right. This is a very common setup as it has almost no disadvantages.

**High-side switching**

Your own suggestion (called high-side switching, shown on the right) would work as well (with the addition of a flyback diode) but it would need a different type of transistor, a PNP transistor. Also, the I/O inputs would work in an inverted way: when the I/O pin is low, the motor will be on and when the I/O pin is high, it will be off.

Note that high-side switching will only work when the supply voltage is lower or equal to the voltage that's on the I/O pins. You can't turn on a 12V motor this way, for example. With low side switching, you will not have this problem and you can switch higher voltages.

<!-- 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/usl6G.png)

<!-- End schematic -->


body:
I think your confusion does indeed stem from the diode. You can forget the diode, it doesn't feature in the switching of the motor. When a motor runs it can generate large negative voltages caused by the repeatedly collapsing magnetic field. The diode, which is *connected backwards*, exists to take those negative voltages and prevent them damaging the rest of the circuit.

The transistor arrangement in use is called *common emitter*, and is also known as a *low-side switch* when used in *saaturation* between the load and GND, as in this situation.  It doesn't matter to the motor if you have the switch between the motor and GND (using an N-channel MOSFET or NPN bipolar transistor) or between power and the motor (using a P-channel MOSFET or PNP bipolar transistor), but it does matter to the Arduino.

It is harder to switch a "high side switch" from an Arduino, especially if your power supply is *higher* than the voltage the Arduino runs at. Since the switching is controlled by the difference in voltage between the "common" point (emitter [BJT] / source [MOSFET]) and the switching signal (Arduino), which is limited to 5V, any "common" point voltage that is higher than that is unreachable by the switching signal, so ends up in being always on and the switching fails.

It *is* possible to switch the high side, but you need an extra driving stage to allow the higher voltage switching.

For this *specific* circuit where the power is 5V it's not as susceptible to the problem, but this is a rare case. Normally you will be driving motors at a higher voltage, such as 12V, and there you *will* need an extra driving stage, or just use the far simpler low-side switch arrangement this circuit teaches you.


message:
First Arduino Project - Need Advice (powering WS2812B LEDs)

I'm making a long LED display made up of 3 (8x32) LED matrices to go inside of a car. I can't seem to find any in-depth guides on this sort of thing. If anybody has examples that they would like to share please do!

The major issue I'm having is power. I'm extremely new to electronics, and I don't understand how these lights can be powered separately, and still be addressably lit by the Arduino?

Parts:
3* LED matrices (8x32)

https://www.amazon.com/gp/product/B088BTXHRG/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1

1* Mega 2560

Here's the mock-up schema:

[![enter image description here][1]][1]

I forgot to draw in a switch, and a power line leading to the Arduino. But let's assume there will be a switch before the resistor and a line that feeds power to the MEGA 2560.

What in this schematic doesn't look or sound right?

Thank you all in advance for your help. This is probably not at all how to go about building circuits, and I'm trying my best to learn. All advice is wanted!

  [1]: https://i.stack.imgur.com/c8mgD.jpg

body:
**Powering the LED panels**

Powering your panels will be your greatest challenge!

These LED panels are powered by a single +5V power input per panel and *do not need a resistor in the power supply path* (they actually need a very low resitance path). You do need a good quality +12V DC -> +5V DC power supply (or multiple, as explained below).

Since 3 x 256 RGB LEDs require a large amount of power when they're all lighted at the same time (something like 60mA * 768 =~ 46A), the power supply should be able to accomodate that. It might be better to use three individual, smaller (~15A) power supplies. You could opt for power supplies smaller than 15A, but you should ensure that all LEDs will never light up at full intensity at the same time.

For supplying power from a 12V car battery, you could use high quality 12V DC to 5V DC buck converters (they're efficient). Use good quality cable with a diameter large enough for transporting the large currents necessary. If you need connections in the path of the power supply, make sure they are good quality as well. To reduce losses in long stretches of wire, you should place the buck converter(s) near the LED panels.

**Connecting the data lines**

The color and intensity of Individual LEDs is controlled via the data input coming from your Arduino and it only needs one input to control all 768 LEDs. The first panel's "data out" should be connected to the next panel's "data in" and so on, like your drawing.

**Software**

I recommend you look up the [*FastLED library*](https://github.com/FastLED/FastLED) and some of its examples to get familiar with controlling large amounts of addressable RGB LEDs. There are many good examples and interesting projects out there.


message:
Error in I2C Communication Between Arduino and Raspberry Pi

The code below sends data to Raspberry Pi every 20 millisecond. The code works fine but sometimes python throws an error. Why this is happening? Should I give more time between `writeData`?

**Error:**

    > Traceback (most recent call last):   File "rpi-I2C.py", line 33, in
    > <module>
    > writeData("360")   File "rpi-I2C.py", line 12, in writeData
    > bus.write_i2c_block_data(address,0x00,byteValue) OSError: [Errno 121] Remote I/O error

**Python code:**

    import smbus
    import time
    # for RPI version 1, use bus = smbus.SMBus(0)
    bus = smbus.SMBus(1)

    # This is the address we setup in the Arduino Program
    address = 0x04

    #http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2
    def writeData(value):
        byteValue = StringToBytes(value)
        bus.write_i2c_block_data(address,0x00,byteValue)
        #first byte is 0=command byte.. just is.
        return -1

    def StringToBytes(val):
            retVal = []
            for c in val:
                    retVal.append(ord(c))
            return retVal

    while True:
        print("sending test")
        writeData("left")
        time.sleep(0.02)

        #print('Sending OPEN-00-00');
        writeData("right")
        time.sleep(0.02)

        #print('Sending WIN-12-200');
        writeData("360")
        time.sleep(0.02)

**Arduino code**:

    #include <Wire.h>
    #define SLAVE_ADDRESS 0x04

    volatile boolean receiveFlag = false;
    char temp[32];
    String command;

    void setup() {
      Wire.begin(SLAVE_ADDRESS);
      // define callbacks for i2c communication
      Wire.onReceive(receiveEvent);
      Serial.begin(115200);
      Serial.println("Ready!");
    }

    void loop() {
      if (receiveFlag == true) {
        Serial.println(temp);
        receiveFlag = false;
      }
    }

    void receiveEvent(int howMany) {
      for (int i = 0; i < howMany; i++) {
        temp[i] = Wire.read();
        temp[i + 1] = '\0';  //add null after ea. char
      }

      //RPi first byte is cmd byte so shift everything to the left 1 pos so temp contains our string
      for (int i = 0; i < howMany; ++i)
        temp[i] = temp[i + 1];
        receiveFlag = true;
      }

body: A RPI uses 3.3v logic while an arduino uses 5v logic you can use a logic converter but by now it's probly to late and maybe your arduino or RPI is broken (_**Sorry!**_)


message:
How to get version of Arduino board remotely

I have multiple Arduino WeMos D1 boards, with a mix of versions bought months apart.  One of these boards is working but I need to update it and I am not sure if it is R1 or R2 (the pinouts are different).  I do not have physical access to it (it is 200+ miles away in an area that is locked down) but I can connect through another device over WiFi.

It has the following included:

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>

    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>

So, I can even browse to a Webserver to run commands.  How can I add to the code (or even replace it) to return a value that tells me which version the board is?  According to [this][1] you can do it with an AT command, but I am not sure how to pass an AT command from the WebServer interface (or any other way).

EDIT: I guess I may have confused the issue with my phrasing.  I can connect to the board and upload a new sketch (using OTA).  My question is, can I put something in a new sketch to determine the board details and upload it.  Once I get that, I can then put in a the actual sketch that I want.

  [1]: https://arduino.stackexchange.com/q/47321/26515

body:
There's nothing you can do with your currently loaded sketch. The board can *only* do exactly what you have programmed it to do and nothing more.

* There *are* no "AT" commands. They only exist if you load the AT firmware instead of your own firmware
* You can't magically make your code do things it wasn't programmed to do1

However the only real differences between the two boards is the version of the ESP8266 module in use: ESP-12E vs ESP-12F, (and the *only* difference between those modules is the layout of the PCB antenna in order to achieve FCC certification) and the addition of some unpopulated serial and I2C pins.

<s>Aside from that the only other differences are purely cosmetic or of no consequence to your software.

So it really doesn't matter which board you have or which you compile your code for.</s>

----
1: Unless you can cause some buffer overflow and inject new code into memory to execute, but to do that you'd need to be a l33t h4x0r.

----
**Addendum:**

It appears they have two boards, named the same, with different pin arrangements (both sadly very stupidly designed, but there you are).  All I can suggest is compile for one, install it, and see if it works. If it doesn't, then compile for the other and see if that works.

Or compile some special firmware that will probe what you have attached and work out what is attached where - then install and run that.


message:
I2S read() is which channel?

The Arduino I2S [reference][1] describes the I2S standard and functions available with the standard I2S library, (Bizarrely it doesn't reference the existing `read()` function which is used in the [examples][2] but that is beside the point). There also exists an [ArduinoSound][3] library, however I have the same issue with this.

I would like to record audio from WM8731 connected up to Arduino. I am using an SAMD arduino part.

But, I have a tremendous issue with the `I2S.read()` function. The `I2S.read()` function only returns a singular value, however the I2S standard is *intrinsically* stereo.

This is particularly important for my project as I am only interested in the LEFT channel as the RIGHT channel is muted.

I would expect this to either:

 - return a pair of values (i.e left /right) samples for that particular point in time , OR
 - return a singular sample with extra information telling me which channel that is was retrieved from.

However it seems this is not the case. ([Github][4])

I also assume that the I2S is buffered making it impossible to simply read the WS pin state, as I will probably be popping a sample from the buffer that was push into the buffer at some point in the past.

So, is it possible to know *which* channel the sample was returned from the `I2S.read()` function or does this mean that the library needs to be modified?

I am more interested in using the samd library as other libraries such as AudioLibrary is limited to 16-bit - I need 32-bit resolution.

  [1]: https://www.arduino.cc/en/Reference/I2S
  [2]: https://www.arduino.cc/en/Tutorial/LibraryExamples/I2SInputSerialPlotter
  [3]: https://www.arduino.cc/en/Reference/ArduinoSound
  [4]: https://github.com/arduino/ArduinoCore-samd/blob/master/libraries/I2S/src/I2S.cpp

body:
From my understanding it's just retrieving subsequent samples from the DMA buffer, which means you will alternately get left and right samples from each read. It would be more normal to use the `read(buffer, len)` variant to read two (or more) samples at once.

```c++
int16_t pair[2]; // change to int32_t for 32 bit samples
I2S.read(pair, sizeof(pair));
```


message:
2 way switch with Arduino?

Hey I'm working on a home automation system where I can replace one of my 2 way switches to an Arduino Or node MCU controlled one but I want to avoid normal relays because as of what I know they can be unreliable and tend to fail. So is there any way I can replace my switch with an Arduino controlled switch and also I cannot use solid state relay as it has only two terminals and it cannot replace my two way switch.

body:
Like Gil said, it sounds like what you are calling a two-way switch is actually a three-way switch. These are typically wired like this (but not always, make sure to double check!):

[![three-way switch][1]][1]

To replace one of the two switches with a relay, you can simply connect a SPDT relay with the load/hot wire (depending on which side you're adding the relay from) to the common contact, and then the two traveler wires to the normally open and normally closed contacts. This effectively takes your existing wiring and directly swaps in a relay -- after all, the relay is literally a switch, just electrically activated instead of manually.

I can't speak to the reliability or lack thereof of a specific model of relay, but a normal power relay is more than adequate for home automation in almost all cases; you don't need anything too fancy. Yes, there will be a mechanical point of failure, but they are typically rated for 100,000+ actuations minimum on a decent relay (like [this one][2] from SparkFun, for example) which will take quite some time to reach. Avoid the super cheap relays both for safety and reliability, and you should be fine.

  [1]: https://i.stack.imgur.com/PkvpB.png
  [2]: https://www.sparkfun.com/products/15093


body: I have not had good luck with these relays, the modules themselves are OK I just solder in a new relay. Try looking for: "solid state 3 way switch"  I found this on my first try. DPST 1NO 1NC 8Amp Power Relay Module. It was labeled "OONO". Consider what happens when the power fails in just the controls, light circuit or both. What will you have then, and then when the power comes back on. I use larger relays and have not have any failures, they are rated at 20A 277V with 24VDC coile.


message:
How to program and arduino UNO via NodeMCU ESP8266?

I don't have my USB type A cable to program my UNO, I would like to program it via a NodeMCU ESP8266.

Maybe with the TX and Rx pins, I've seen people program certain versions of ESP with a UNO board.

How do I do this and is it possible?

body:
The UNO's USB connection is little more than a USB to UART converter.  The NodeMCU's USB connection is *also* little more than a USB to UART converter.

With a little *jiggery pokery* (yes, that's a technical term) you can replace one with the other.

By keeping the NodeMCU in RESET mode (tie the EN pin low, or hold the RESET button) you can use the TX and RX pins as the output to the onboard USB to UART converter to connect to the TX and RX pins of the Arduino.

The tricky part is getting the Arduino to reset at the right time: you have to press the Arduino's RESET button at just the right time. Normally this is done by a small capacitor between the DTR signal of the USB to UART converter and the RESET pin, but you don't have access to the DTR signal, so you will have to do it manually. Timing here is everything. Press upload, and *just as AVRDude starts to execute* you press RESET. Having verbose compilation turned on in the IDE can help.

It may take a few attempts to get it right.


message:
HX711 Ridiculous speeds

I'm using a SparkFun HX711 board and an Adafruit AdaLogger (M0) Featherboard. I have cut the trace on the back of the HX711 to get a faster data rate (should be about 80 sps). I did this by reviewing the spec sheet and confirming with this post ([Github link for faster rates][1]).

Before I read from the board I get startTime from micros() and immediately after I get get the scale data, I call micros() again and record the endTime. I then write this data along with the load cell data to an SD card. Then to check the time, after the experiment is over in excel I take 1/((endTime - startTime)*10^-6) to get the approximate number of samples per second.

My issue is that apparently, I'm recording at a max of around 6000 SPS but commonly around 600 SPS. Which, would be awesome if I wasn't so sure that it was a lie. I was hoping someone could take a look and see what I'm doing wrong? I used this same code on a different M0 with an unmodified HX711 and was getting around 10 SPS. The only thing different (I thought) was cutting the trace on the back of the board to enable the higher rate.

In the GitHub link above, they do mention that you can get a faster rate if you splice in a faster crystal with a cap to bridge pins 13 and 14. I have not done this, but perhaps the faster processor on the Feather might be playing some of a role in this?

VCC and VDD are both connected to 3.3V and GND is connected to the ground pin on the Feather. Pin 11 is connected to DAT and Pin 10 is connected to CLK

    #include <SPI.h>
    #include <SD.h>
    #include "HX711.h"

    #define FILE_BASE_NAME "FAST" // max six characters
    #define DOUT_one 11   // Red
    #define CLK_one  10   // Orange

    const uint8_t CS_PIN = 4;
    const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;

    char fileName[] = FILE_BASE_NAME "00.csv";

    float calibration_factor_one = -7050; // needs to be calibrated still

    File file;

    long startTime=0;
    long endTime =0;

    String dataString = "";

    double scale_one_value = 0.0;

    HX711 scale_one;

    void SetUpSDCard(){
      if (!SD.begin(CS_PIN)) {
        Serial.println(F("begin failed"));
        return;
        }
       while (SD.exists(fileName)) {
        if (fileName[BASE_NAME_SIZE + 1] != '9') {
          fileName[BASE_NAME_SIZE + 1]++;
        } else if (fileName[BASE_NAME_SIZE] != '9') {
          fileName[BASE_NAME_SIZE + 1] = '0';
          fileName[BASE_NAME_SIZE]++;
        } else {
          Serial.println(F("Can't create file name"));
          return;
        }
      }
       file = SD.open(fileName, FILE_WRITE);
      if (!file) {
        Serial.println(F("open failed"));
        return;
      }
      Serial.print(F("opened: "));
      Serial.println(fileName);
      }

    void SetUpLoadCell(){
      Serial.println("Remove all weight from scale");
      scale_one.begin(DOUT_one, CLK_one);
      scale_one.set_scale();
      scale_one.tare();

      long zero_factor_one = scale_one.read_average(); //Get a baseline reading
      Serial.print("Zero factor: ");
      Serial.println(zero_factor_one);
      Serial.println("Load cell one initialized");
      scale_one.set_scale(calibration_factor_one); //Adjust to this calibration factor
      }

    void LogData(){
      startTime= micros();
      scale_one_value = scale_one.get_units();
      endTime = micros();

      dataString = String(startTime) + "," + String(scale_one_value) + "," + String(endTime);
      file.println(dataString);
      file.flush();
      }

    void setup() {
      Serial.begin(9600);
      SetUpSDCard();
      Serial.println("Remove all weight from scale");
      SetUpLoadCell();
    }

    void loop() {
      LogData();
    }

Then the saved data that is on the SD card is as follows, this is just the first 20 lines.

    3383895, 0,      3384049
    3401786, 0,      3401938
    3411851, 0,      3412004
    3421850, -0.02, 3422004
    3432012, -0.03, 3432164
    3442074, 0.01,   3442226
    3452118, 0,      3452269
    3462299, 0,      3462450
    3472441, 0.03,   3473497
    3483434, 0.03,   3485070
    3495011, 0.02,   3496638
    3506580, 0.01, 3508211
    3518576, 0.03, 3519785
    3529783, 0.02, 3531353
    3541282,    0,     3542924
    3552831, 0,     3554495
    3564476, 0,     3566070
    3575900, 0.01, 3577638
    3587476, -0.01, 3589209
    3599068, -0.03, 3600782

  [1]: https://github.com/olkal/HX711_ADC/issues/29

body:
You're not measuring how many samples you do in a second, instead you're measuring the amount of time it takes to retrieve one sample from the HX711.

You store the time, retrieve the next sample, then store the time again. Then you spend a comparative age storing that data to the SD card, during which time the HX711 is taking any number of other samples.  By the time you eventually get around to reading from the HX711 again it's already ready to give you a sample.

You need to factor in the amount of time it takes to write to the SD card to have any kind of meaningful results - that is, the total amount of time that it takes to execute a loop(), or more simply: how long since the last time your logData() function has been run.

The actual sampling time of the HX711 will probably pale into insignificance compared to all the rest of your sequential code.


message:
How to test custom cables?

I'm trying to make a cable checker to help me make custom cables for my computer. I'm thinking I plug the cable ends into sockets on the device, then the Arduino checks between different pins to make sure that no wires are in the wrong spot or unplugged.

So I'm thinking it runs through like this:

I plug the cable into connectors on the device. The Arduino has the PSU pinouts saved. Pin 1 represents one end of the cable, pin 2 represents the opposite end. Same with 3-4/5-6 etc. If the cable is assembled correctly, it should act as a connection between pins 1-2, pins 3-4, 5-6 etc.

tests pin 1 - 2 to see if they're connected, if yes, light up a green LED, if not, light up a red LED

tests pin 3 - 4, does the same thing

Repeats this  for every wire in the cable

Am I on the right track? How would I do this? I've seen people talking about pullup resistors but I'm also seeing people say that shorting can damage the board

body:
The scope of your question is too wide for a simple answer so let us constrain it to slow signals (audio frequencies or less) over short cables (not more than several meters) in a electrically clean environment (such as found in most homes).

That said, it is likely most looking for similar solutions reading your question will have different specific requirements.  So to make this question and answer useful to others let us consider the most generic, economical and Arduino based solution.

 1. Most cables worth automatically testing will have far more individual connections than common Arduino boards, such as the Arduino Uno, have GPIO pins.  Consider using a GPIO expander or multiple Arduinos which communicate with each other to coordinate efforts.
 2. When testing a cable that will be used for low frequencies, short distance and low immunity to noise it is likely the only faults that are of concern are OPENS and SHORTS.
 3. As this design uses GPIO pins we have the following options at any given GPIO pin: Drive High, Drive Low and Input With Pull Ups.
 4. Build a cable test rig where one end (the near end) of the cable under test is connected to GPIO pins designated as the driver side and the other end of the cable under test (the far end) is connected to GPIO pins designated as the sensing side.
 5. For a SHORTS and OPENS test set all the sensing  and driving GPIO pins to Input With Pull Ups.  Verify that all sensing GPIO pins report a 1.  Next change one and only one of the driver GPIO pins to an output and send a 0.  Record that state of all sensing GPIO pins.  Return the driver GPIO pin to Input with NO PULL UPS and repeat these steps for the next GPIO driver pin.
 6. If this is a STRAIGHT THROUGH cable only 1 sensing GPIO pin should report a 0 in each testing pattern recorded.  If more than 1 sensing GPIO pin reports a 0 then there is a short between the 0 reporting pins.  If none of the GPIO pins reports a 0 then there is an open for that GPIO pin.
 7. Use the same test for cables containing intentional SHORTS (perhaps multiple ground pins are shorted together) expecting to see the associated GPIO pins to all change to 0 at the same time.
 8. For even more complex cables containing loop backs at both ends consider only the "GPIO pin set to an output sending 0" as the driver and record the state of ALL OTHER GPIO pins as they are now all possible outputs.


message:
LED Blink in assembly with timer1 output compare interrupt not working

I was trying to have some fun with avr-assembly on my arduino and I tried the following codes to blink my LED

first I tried the ISR approach and when It didn't work I tried the CTC mode one,
both codes are listed respectively. on the first one the LED lightsup and stay that way (no blinking) on the second one it just stays off

one more thing to note is on trying to load OCR1AL first The led would blink nicely if my hand got near PORTD pins for some reason,

I guessed it's some grounding problem and It's fixed when I pulled high all PORTD pins and it disappeared completely when I figured out that I need to load (the high byte) OCR1AH first

```
.nolist
.include "m328Pdef.inc"
.list

.org  0x0000
jmp  Init

.org  0x0016
jmp  TIMER1_COMPA

.EQU LED_PIN = PB1

Init:
 ;ldi  r16, 255
 ;out  DDRD, r16
 ;out  PORTD, r16

 ;First configure The led pin as output and initilize it to high
 sbi  DDRB, LED_PIN
 sbi  PORTB, LED_PIN

 ;Second Enable Global Interrupts
 sei

 ;Enable the Output compare Interrupt in the TIMSK1 Register
 ldi  r16, 0b00000010
 sts  TIMSK1, r16

 ; Reset the TCCR1A
 ldi  r16, 0b00000000
 sts  TCCR1A, r16

 ; Set the prescalar to 256 in the Timer Control 1B register
 ldi  r16, 0b00000111
 sts  TCCR1B, r16

 ;Now load the value for Output compare register 31250 or   01111011 00100000  or 15625 =  00111101 00001001
 ldi  r16, 0b00111101
 ldi  r17, 0b00001001
 sts  OCR1AH, r16
 sts  OCR1AL, r17

LOOP:

 rjmp  LOOP

TIMER1_COMPA:
 ;First Reset the coutner
 ldi  r16, 0
 sts  TCNT1H, r16
 sts  TCNT1L, r16

 ;Second Toggle the Pin (LED) state
 sbi  PINB, LED_PIN

 reti

```

**CTC:**
```
.nolist
.include "m328Pdef.inc"
.list

.org  0x0000
jmp  Init

.org  0x0016
jmp  TIMER1_COMPA

.EQU LED_PIN = PB1

Init:
 ;ldi  r16, 255
 ;out  DDRD, r16
 ;out  PORTD, r16

 ;First configure The led pin as output and initilize it to high
 sbi  DDRB, LED_PIN
 sbi  PORTB, LED_PIN

 ;Second Enable Global Interrupts
 sei

 ;Enable the Output compare Interrupt in the TIMSK1 Register
 ldi  r16, 0b00000010
 sts  TIMSK1, r16

 ; Reset the TCCR1A
 ldi  r16, 0b01000000
 sts  TCCR1A, r16

 ; Set the prescalar to 256 in the Timer Control 1 registers
 ldi  r16, 0b00001111
 sts  TCCR1B, r16

 ;Now load the value for Output compare register 31250 or   01111011 00100000  or 15625 =  00111101 00001001
 ldi  r16, 0b00111101
 ldi  r17, 0b00001001
 sts  OCR1AH, r16
 sts  OCR1AL, r17

LOOP:
 rjmp  LOOP

TIMER1_COMPA:
 ;First Reset the coutner
 ;ldi  r16, 0
    ;sts  TCNT1H, r16
 ;sts  TCNT1L, r16

 ;;Second Toggle the Pin (LED) state
 ;sbi  PINB, LED_PIN

 reti

```

body:
I am not set up to test your code right now, perhaps later.  But:

```none
    ; Set the prescalar to 256 in the Timer Control 1B register
    ldi     r16, 0b00000111
    sts     TCCR1B, r16
```

When set to ones, the low order three bits of TCCR1B, select an external clock source at the T1 pin, for clocking on a rising edge.  Probably what's happening is that when you finger is near enough the T1 pin you are capacitively coupling mains frequency to it causing it to tick.

/256 prescaler would have `100` in the lower three bits.

If I manage to get a proper environment up to test your code, I'll look into it a bit more thoroughly.


message:
How can I use attached interrupt on my project?

Hi I have a coinslot project and connected with a fingerprint sensor it was stated in the ardiuno forum that it will work on pin 2 and 3 , but it is already used pins of the finger print sensor .

Coinslot signal is in pin 9 and the in2,3 is for the rx and tx of the fingerprint sensor.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/WRDQz.jpg

body:
If you can't rearrange the pins like Majenko suggests in the their comment, something you can do is is use pin change interrupts rather than the regular "external" interrupts.  On the UNO, these are available on all of the "digital" capable pins, which also includes most of the "analog" pins if you have an SMT UNO, or all of them if you have a DIP model.

[NiceHood's PinChangeInterrupt library][1] is modeled after the regular `attachInterrupt` function, so it should be [familiar looking to you][2].  It's in the library manager; you don't need to get it from github.

NOTE: The O.P. opened a another [question][3] which seems to be this same thing, only with different context and specific code.  There I've given **more details on what's outlined above but in relation to that that specific code in an [answer there][4]**.

  [1]: https://github.com/NicoHood/PinChangeInterrupt
  [2]: https://github.com/NicoHood/PinChangeInterrupt/blob/1.2.9/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino#L50
  [3]: https://arduino.stackexchange.com/q/84325/70020
  [4]: https://arduino.stackexchange.com/a/84326/70020


message:
Is there a way to make the RESET pin work in the inverse?

Is there a way for me to have this work the opposite way?

I have one cable with an alligator clip hooked up to the reset pin and another hooked up to ground.

When I clip them both together, the board resets.

However, I would like for this to work in the opposite way such that they’re already clipped together and when you detach the cables, the board resets.

body:
The easiest way to do that would be to use an external pulldown resistor (a resistor from the reset pin to ground) and connect to Vcc (5V on the Nano) via your alligator cables.

As long as the alligator cables are connected, the reset pin is held HIGH through them. When you disconnect them, the pulldown resistor pulls the reset pin to LOW. That holds the Nano in reset until you again connect the alligator clips.

If you want the Nano to reset and then directly work again without the alligator clips reconnected, it gets more difficult. One way I can think of is building a monostable vibrator circuit, which gets in the excited state, when your alligator clips are disconnected, resets the Arduino and then goes back into the stable stable, letting the Arduino execute its code. Though that is more an electrical question, than an Arduino one.


body:
My personal preference would be to attach a NOT gate to the RESET pin.  This can be constructed very simply from a single NPN transistor (or N-channel MOSFET) and a resistor.

<!-- 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/XgkOA.png)

<!-- End schematic -->

With the wire disconnected R1 turns on Q1 which pulls the RESET pin LOW.  With the wire connected Q1 is turned off, allowing RESET to be pulled back up by the pullup resistor that's built into the Arduino.

This method also won't interfere with the programming reset action of the Arduino.