body:
For a university Lab course i have to realize a UPS unit with a internal LiPo battery . The unit uses as battery charger a buck converter

I have only a problem with the battery charger (buck converter). Few weeks before i verify the code and it works without problem. Now i can notice that the analog value that i read are floating too much and this represents a problem for the Constant Current (CC) and Constant Voltage (CV) phases of the battery charge process.

I found that this problem happens when plug arduino  after i have started the PC, while it doesn't happen when i plug the USB cable of arduino and then start the PC. It seems to be a problem with the ground of arduino.

the circuit scheme is the following one:
[![enter image description here][1]][1]

and what i obtain is that:

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

  [1]: https://i.stack.imgur.com/Aapkf.png
  [2]: https://i.stack.imgur.com/6tDYL.png

as you can see i have a strange increase of all the voltage that i read with the analog pin of arduino. The code is correct since before this week it works well, but if necessary i will upload it.

the 10Ohm resistor is placed in the buck converter only to measure the chargin current that i calculate as:

charging_current=(analogRead(A1)-analogRead(A2))*5.00/1023.00

The battery must be charged at constant current equal to 50mA until the battery voltage became equal to 4.10V, after that value the battery must be charged at constant voltage equal to 4.20V until the charging current became smaller than 10/5mA.

Notice that i try also to make more acquisition for each voltage: i made 8 measurement and then i calculate the average value, but the result doesn't change.

title: Problem with floating of AnalogRead

Answers: 0


body:
I am trying to reach the webserver running in my Wemos D1 Mini compatible board.

I am trying one esp8266 example using Arduino examples "WifiManualServer" code below.
I have replaced the SSI and password for my wifi network in the lines
```cpp
#define STASSID "my wifi ssid"
#define STAPSK  "my secret"
```

```cpp
/*
    This sketch demonstrates how to set up a simple HTTP-like server.
    The server will set a GPIO pin depending on the request
      http://server_ip/gpio/0 will set the GPIO2 low,
      http://server_ip/gpio/1 will set the GPIO2 high
    server_ip is the IP address of the ESP8266 module, will be
    printed to Serial when the module is connected.
*/

#include <ESP8266WiFi.h>

#ifndef STASSID
#define STASSID "my wifi ssid"
#define STAPSK  "my secret"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

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

  // prepare LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println();
  Serial.println(F("WiFi connected"));

  // Start the server
  server.begin();
  Serial.println(F("Server started"));

  // Print the IP address
  Serial.println(WiFi.localIP());
  server = WiFiServer(80);
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  Serial.println(F("new client"));

  client.setTimeout(5000); // default is 1000

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(F("request: "));
  Serial.println(req);

  // Match the request
  int val;
  if (req.indexOf(F("/gpio/0")) != -1) {
    val = 0;
  } else if (req.indexOf(F("/gpio/1")) != -1) {
    val = 1;
  } else {
    Serial.println(F("invalid request"));
    val = digitalRead(LED_BUILTIN);
  }

  // Set LED according to the request
  digitalWrite(LED_BUILTIN, val);

  // read/ignore the rest of the request
  // do not client.flush(): it is for output only, see below
  while (client.available()) {
    // byte by byte is not very efficient
    client.read();
  }

  // Send the response to the client
  // it is OK for multiple small client.print/write,
  // because nagle algorithm will group them into one single packet
  client.print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now "));
  client.print((val) ? F("high") : F("low"));
  client.print(F("<br><br>Click <a href='http://"));
  client.print(WiFi.localIP());
  client.print(F("/gpio/1'>here</a> to switch LED GPIO on, or <a href='http://"));
  client.print(WiFi.localIP());
  client.print(F("/gpio/0'>here</a> to switch LED GPIO off.</html>"));

  // The client will actually be *flushed* then disconnected
  // when the function returns and 'client' object is destroyed (out-of-scope)
  // flush = ensure written data are received by the other side
  Serial.println(F("Disconnecting from client"));
}
```

Once I compile and upload the sketch, the sketch is able to connect to my wifi network.
The following is the output in the serial monitor.
```cpp
20:45:12.633 -> Connecting to <text replaced xxxxxxx>
20:45:13.247 -> ........
20:45:17.551 -> WiFi connected
20:45:17.551 -> Server started
20:45:17.551 -> 192.168.0.39
```

I am able to verify the client connection in my wifi routers network management UI.
The espboard is connected and assigned the IP as in the output (`192.168.0.39`).

When I launch browser and try to get `http://192.168.0.39/gpio/0`, the request times out.
from my windows 10 pc, tried ping on `192.168.0.39`, the Request timed out.

From the sketch I see the following lines in the `loop()` function:

```cpp
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  Serial.println(F("new client"));
```

The execution never reached the line `Serial.println(F("new client"));`.

I had tried inserting the line `server = WiFiServer(80);` after the wifi connection is established.

Please share your thoughts on why the `server.available()` is not successful?

title: ESP8266 Webserver does not respond

Answers: 0


body:
I was supposed to first create a 4x1 MUX using AND and NOT gates. The 4 input data lines (io,i1,i2,i3) were 4 PWM pins from the arduino (3,5,6,9), with analogWrite() values as 100,150,200,250 respectively, and the selection lines were taken from two slide switches.
[![enter image description here][1]][1]

    int i0=100;
    int i1=150;
    int i2=200;
    int i3=250;

    void setup()
    {
      pinMode(5, OUTPUT);
      pinMode(6,OUTPUT);
      pinMode(9,OUTPUT);
      pinMode(3,OUTPUT);

      analogWrite(3,i0);
      analogWrite(5,i1);
      analogWrite(6,i2);
      analogWrite(9,i3);

      Serial.begin(9600);
    }

    void loop()
    {

    }

Simulation link: https://www.tinkercad.com/things/cRZNvuwhZYV

The voltmeter + is connected to the output of the MUX. Both selection lines are HIGH, so the output is i3, which has the pWM value 250. So the voltage should be (250/255)*5, i.e about 4.9 V, which is what the meter shows. (The servo is present but not connected.)

The voltmeter values are in accordance for all the 4 possible combinations. **In short, the 4x1 MUX is working perfectly.**

**(it was important for me to clarify this as otherwise people might have thought of the MUX implementation as the problem with my lsubsequent circuit , and with the messy wiring, it would've been impossible to confirm whether or not this is the case. However, as I have clearly shown, the problem is NOT with the MUX).**

Next, I tried to control the servo using this MUX. I connected the servo control pin to the MUX output:
[![enter image description here][2]][2]

    #include<Servo.h>
    Servo s1;
    Servo s2;
    Servo s3;
    Servo s4;

    int i0=100;
    int i1=150;
    int i2=200;
    int i3=250;

    void setup()
    {
      pinMode(3,OUTPUT);
      pinMode(5,OUTPUT);
      pinMode(6,OUTPUT);
      pinMode(9,OUTPUT);

      analogWrite(3,i0);
      analogWrite(5,i1);
      analogWrite(6,i2);
      analogWrite(9,i3);

      s1.attach(3);
      s2.attach(5);
      s3.attach(6);
      s4.attach(9);

      Serial.begin(9600);
    }

    void loop()
    {

     s1.write((i0*180)/255);
     s2.write((i1*180)/255);
     s3.write((i2*180)/255);
     s4.write((i3*180)/255);
    }

For instance, I thought if both switches were on, then the output is i3,(which was coming from pin 9), so
only `s4.attach(9);` and `s4.write((i3*180)/255);` will work. (As, it is apparent that the control pin is connected to pin 9 in this case).

The servo does move around when I change the switches to on off combinations, **however,something drastic has happened to the voltmeter values, which tells me that my code is messing with the MUX output. The output voltages fluctuate rapidly between 97 and 180 mV.**

**What exactly have I done wrong, and how exactly am I supposed to control the Servo, then?**

  [1]: https://i.stack.imgur.com/6m2dX.jpg
  [2]: https://i.stack.imgur.com/e8QCk.jpg

title: Using 4x1 MUX to control a servo

Answers: 0


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

title: How to get 2 loop functions to cooperate?

Answers: 2

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


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

      }
    }

title: Turning off a LED

Answers: 1

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.


body:
I specifically had saved code for the purpose of checking the connection, but it doesn't seem to work anymore.

All the examples from this [simple tutorial][1] work, so it can't be a hardware issue.

Maybe someone can find a reason why the code wouldn't work? It returns radio.available() as false

    //Transmitter
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>

    RF24 radio(7, 8); // CE, CSN
    const byte addresses[][6] = {"00001", "00002"};
    float valueTransmit;
    float valueRecieved;

    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.openWritingPipe(addresses[1]); // 00002
      radio.openReadingPipe(1, addresses[0]); // 00001
      radio.setPALevel(RF24_PA_LOW);
      valueTransmit = 0
    }
    void loop() {
      radio.stopListening();
      radio.write(&valueTransmit, sizeof(valueTransmit));
      delay(5);

      radio.startListening();
      if (radio.available() ) {
          radio.read( &valueRecieved, sizeof(valueRecieved) );
      Serial.print(valueRecieved);
      valueTransmit = valueRecieved + 0.01;
      }
    }

    //Reciever
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>

    RF24 radio(7, 8); // CE, CSN
    const byte addresses[][6] = {"00001", "00002"};
    float valueTransmit;
    float valueRecieved;

    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.openWritingPipe(addresses[0]); // 00001
      radio.openReadingPipe(1, addresses[1]); // 00002
      radio.setPALevel(RF24_PA_LOW);
    }
    void loop() {
      radio.startListening();
      if (radio.available() ) {
        radio.read( &valueRecieved, sizeof(valueRecieved) );
        Serial.print(valueRecieved);
        valueTransmit = valueRecieved + 1;
      }

      radio.stopListening();
      radio.write(&valueTransmit, sizeof(valueTransmit));
      delay(5);

    }

  [1]: https://forum.arduino.cc/t/simple-nrf24l01-2-4ghz-transceiver-demo/405123/4

title: Communication code between nrf24l01's suddenly not working. Hardware is fine

Answers: 0


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

```

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

Answers: 1

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 -- */

```


body:
Hi good day to all I have a project that , it will lock the solenoid using the fingerprint then I have hook up a coinslot that will count the coins inside the vault its like a secured piggybank.

Project objective
1. it must display the coin total :
2. If fingerprint is access it will unlock the solenoid
3. then goes back to total of coins

The problem is its just showing total of coins inserte but the fingerprint wont detect any image id taken from enrrol code

```
#include <Adafruit_Fingerprint.h>    //Libraries needed
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#include <EEPROM.h>
#define coinSlot 9 // different pin!!! untested!!!

#define I2C_ADDR 0x27          //LCD i2c stuff
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

int in2 = 4;

String Names[] = { "RAVEN", "Surtr", "Tech",}; //Those are the names affected to the fingertemplates IDs
                                                 //The first on which is Names[0] : Yassine has the ID 1 in the fingerprint sensor

SoftwareSerial mySerial(2, 3);                  //Fingerprint sensor wiring RX 3, TX 2
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); //LCD declaring

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);                    //Fingerprint sensor declaring

int coinCount = 0;
int coinSlotSignal;
int requiredCoins = 1;
boolean coinInserted = false;

void setup()
{
  pinMode(in2, OUTPUT);
  digitalWrite(in2, HIGH);
  pinMode(coinSlot, INPUT_PULLUP);
  lcd.write(EEPROM.read(5));

  Serial.begin(9600);               //Serial begin incase you need to see something on the serial monitor
  finger.begin(57600);              //Sensor baude rate
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home();
  finger.getTemplateCount();        //Counts the number of templates stored in the sensor flash memory
  delay(2000);
}

void loop()
{
  int result = getFingerprintIDez();  //This function keeps looping and waiting for a fingerprint to be put on the sensor
    OpenDoor();

  // Coinslot
  while(!coinInserted){
    coinSlotSignal = digitalRead(coinSlot);

    if(coinSlotSignal < 1) {
      coinCount += 1;
      coinInserted = true;
      EEPROM.write(0,coinCount);
      Serial.println(EEPROM.read(0));

      lcd.setCursor(0,0);
      lcd.print("TOTAL:");
      lcd.setCursor(0,1);
      lcd.print(coinCount);
    } // if
  } // while

  while(coinInserted) {
   coinSlotSignal = digitalRead(coinSlot);
    if(coinSlotSignal >0) {
      coinInserted = false;
    }
  }

  if(coinCount >= requiredCoins) {
    delay(1500);
  }
}

//Main function taken from the "fingerprint" example and modified
//Only the modifications are commented
int getFingerprintIDez() {
  uint8_t p = finger.getImage();        //Image scanning
  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();               //Converting
  if (p != FINGERPRINT_OK)  return -1;

  lcd.clear();                     //And here we write a message or take an action for the denied template
  p = finger.fingerFastSearch();     //Looking for matches in the internal memory
  if (p != FINGERPRINT_OK){          //if the searching fails it means that the template isn't registered
    lcd.print("Access denied");
    delay(2000);
    return -1;
  }
            //If we found a match we proceed in the function

  lcd.print("Welcome");                  //Printing a message for the recognized template
  lcd.setCursor(2,1);
  lcd.print(Names[finger.fingerID-1]); //Then print the name we gave it and the -1 is to remove the shift as the ID starts from "1" but the array from "0"
  return finger.fingerID;
}

/*The two following functions depends on your locking system
 *mine has a DC motor that should turn in both ways for opening and closing
 *that's why I'm using H bridge, you could have a solenoid with a transistor
 *then you'll need only opening sequence but controlling the transistor
 *as the closing is spring loaded...
 */

void OpenDoor(){
  digitalWrite(in2, LOW); // turn on motor
  delay(5000);
  digitalWrite(in2, HIGH); // turn off motor
}
```

title: FingerPrint Scanner wont detect any input (fingerprint image)

Answers: 0


body:
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);
}
```

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

Answers: 1

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);
```


body:
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();
    }
  }
}
```

title: How to attempt connection to WiFi only once?

Answers: 1

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);
}
```


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

title: AT 09 BLE module not transmitting data

Answers: 1

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.


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

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

Answers: 1

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


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

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

Answers: 1

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.


body:
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);
   }
  }
 }

title: Serial communication between Arduinos

Answers: 2

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");
```


body:
I have three nema 23 steppers with one 8 channel relay(all the pins used) powering two dc motors and 4 IR sensors for feedback on the machine.

The problem is my machine is working fine for only 2 to 3 minutes until it just resets itself in the middle of the routine and crashes my whole system.

I am using 1/2 step microstepping with TB6600 stepper driver.
Also my arduino is mega 2560, maybe thats the problem I don't know about.

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

Here I am attaching the code

    const int dirPin1=2;
    const int stepPin1=3;
    const int dirPin2=4;
    const int stepPin2=5;
    const int dirPin3=6;
    const int stepPin3=7;
    int del=1;
    void setup() {
     pinMode(2,OUTPUT);
     pinMode(3,OUTPUT);
     pinMode(4,OUTPUT);
     pinMode(5,OUTPUT);
     pinMode(6,OUTPUT);
     pinMode(7,OUTPUT);
     pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);
    pinMode(13,OUTPUT);
    pinMode(14,OUTPUT);
    pinMode(15,OUTPUT);
    pinMode(16,INPUT);
    pinMode(17,INPUT);
    pinMode(18,INPUT);
    pinMode(19,INPUT);
    digitalWrite(8,HIGH);
    digitalWrite(9,HIGH);
    digitalWrite(10,HIGH);
    digitalWrite(11,HIGH);
    digitalWrite(12,HIGH);
    digitalWrite(13,HIGH);
    digitalWrite(14,HIGH);
    digitalWrite(15,HIGH);

    }
    void picker_up(){
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(10,LOW);
      digitalWrite(11,LOW);
      delay(570);
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(11,HIGH);
      delay(100);
    }
    void picker_down(){
      digitalWrite(8,LOW);
      digitalWrite(8,LOW);
      digitalWrite(10,HIGH);
      digitalWrite(11,HIGH);
      delay(320);
      digitalWrite(8,HIGH);
      digitalWrite(9,HIGH);
      digitalWrite(10,HIGH);
      digitalWrite(11,HIGH);
      delay(100);
    }
    void claw_close(){
      digitalWrite(12,LOW);
      digitalWrite(13,LOW);
      digitalWrite(14,HIGH);
      digitalWrite(15,HIGH);
      delay(100);
      digitalWrite(12,HIGH);
      digitalWrite(13,HIGH);
      digitalWrite(14,HIGH);
      digitalWrite(15,HIGH);
      delay(100);
    }
    void claw_open(){
      digitalWrite(12,HIGH);
      digitalWrite(13,HIGH);
      digitalWrite(14,LOW);
      digitalWrite(15,LOW);
      delay(100);
      digitalWrite(12,HIGH);
      digitalWrite(13,HIGH);
      digitalWrite(14,HIGH);
      digitalWrite(15,HIGH);
      delay(100);
    }

    void loop() {
      // put your main code here, to run repeatedly:
    digitalWrite(dirPin1,HIGH);
    digitalWrite(dirPin2,HIGH);
    digitalWrite(dirPin3,LOW);
    for(int i=0;i<=1200;i++){
      digitalWrite(stepPin1,HIGH);
      digitalWrite(stepPin2,HIGH);
      digitalWrite(stepPin3,HIGH);
      delay(del);
      digitalWrite(stepPin1,LOW);
      digitalWrite(stepPin2,LOW);
      digitalWrite(stepPin3,LOW);
      delay(del);
    }
    for(int i=1;i<=400;i++){
      digitalWrite(stepPin1,HIGH);
      delay(del);
      digitalWrite(stepPin1,LOW);
      delay(del);
    }
    delay(1000);
    picker_down();
    claw_open();
    claw_close();
    picker_up();
    delay(2000);
    digitalWrite(dirPin1,LOW);
    digitalWrite(dirPin2,LOW);
    digitalWrite(dirPin3,HIGH);
    for(int i=1;i<=400;i++){
      digitalWrite(stepPin1,HIGH);
      delay(del);
      digitalWrite(stepPin1,LOW);
      delay(del);
    }
    for(int i=0;i<=1200;i++){
      digitalWrite(stepPin1,HIGH);
      digitalWrite(stepPin2,HIGH);
      digitalWrite(stepPin3,HIGH);
      delay(del);
      digitalWrite(stepPin1,LOW);
      digitalWrite(stepPin2,LOW);
      digitalWrite(stepPin3,LOW);
      delay(del);
    }
    delay(2000);
    }

I am not getting why this is happening. Or do I need some more electronic components  included in the machine and I know I could have used mosfets to control the motors but I am just way too lazy.

I used uno before this and it used to work fine, so should I just go back to using it?

Also I have modified the code to be compatible with the uno again so please bare with the pin numbers.

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

title: Using arduino mega is making my cnc claw buggy. Help

Answers: 0


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

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

Answers: 1

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.


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

title: Send packet of multiple sensors data to Bluetooth module

Answers: 1

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.


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

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

Answers: 2

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.