message:
HTTP POST request error on esp8266 to my localhost (error:-1)

I've looked around for solutions and tried but can't get this to work. I'm trying to send a  POST request to a localapi. My code:
```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include "ArduinoJson.h"
#include <WiFiClient.h>

const char* ssid = "VIOT";
const char* password = "********";
const char* sensor_0 = "1234";
const char* sensor_1 = "5678";
const char* sensor_2 = "3678";
String postMessage;

void setup()

 {
Serial.begin(115200);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
Serial.println(WiFi.localIP());
}

void loop()
{
  WiFiClient client;
  HTTPClient http;
  StaticJsonDocument<256> doc;
  doc["batteryCharge"] = sensor_0;
  doc["powerUsage"] = sensor_1;
  doc["powerProduced"] = sensor_2;

  serializeJson(doc, postMessage);

  Serial.print("[HTTP] begin...\n");
  http.begin(client,"http://192.168.1.190/",3000);
  http.addHeader("Content-Type", "application/json");
  Serial.print("[HTTP] POST...\n");
  int httpCode = http.POST(postMessage);
  Serial.print(httpCode);
  if (httpCode > 0) {
    if (httpCode == HTTP_CODE_OK) {
      String payload = http.getString();
      Serial.println("HTTP POST request successful");
      Serial.println("Response: " + payload);
}
}

else {

 Serial.println("HTTP POST request failed");

 }

http.end(); delay(10000); // Wait for 10 seconds before sending the next request

 }
```
Both devices are connected to the same network and my computer ip is 192.168.1.190.
Tested my api on postman and it ran successfully.
Here is the error:
```
15:45:26.469 -> Connecting to WiFi...
15:45:27.469 -> Connecting to WiFi...
15:45:29.207 -> Connecting to WiFi...
15:45:30.208 -> Connecting to WiFi...
15:45:30.208 -> Connected to WiFi
15:45:30.208 -> 192.168.1.180
15:45:30.208 -> [HTTP] begin...
15:45:30.208 -> [HTTP] POST...
15:45:30.208 -> -1HTTP POST request failed
```

body:
I found the problem. I changed
```
http.begin(client,"http://192.168.1.190/",3000);
```
to
```
http.begin(client,"http://192.168.1.190:3000");
```


sender: user

message:
How to make 2 lidar lite v3 work with 1 Arduino?

I'm using the code below, but I had no success.

I'm using this connection wire:
The photo of the Arduino doesn't show the SCL and SDA pins, but please consider that it has 2 SCL pins and 2 SDA pins in the places where I marked them in the image.

Both sensors are working, however they are mirroring each other's measurements.

That link is from the datasheet:
https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf

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

    #include <Wire.h>
    #include <LIDARLite.h>

    #define LIDAR1_ADDRESS 0x62 // Endereço I2C do LIDAR Lite 1
    #define LIDAR2_ADDRESS 0x63 // Endereço I2C do LIDAR Lite 2

    LIDARLite lidar1; // Objeto para o LIDAR Lite 1
    LIDARLite lidar2; // Objeto para o LIDAR Lite 2

    void setup() {
      Wire.begin();        // Inicializa a biblioteca Wire (I2C)
      Serial.begin(115200);  // Inicializa a comunicação serial

      // Inicializa os objetos dos LIDARs
      lidar1.begin(LIDAR1_ADDRESS); // Inicialização do LIDAR Lite 1
      lidar2.begin(LIDAR2_ADDRESS); // Inicialização do LIDAR Lite 2
    }

    void loop() {
      int distance1 = lidar1.distance();
      int distance2 = lidar2.distance();

      // Exibe as medições dos LIDARs no Monitor Serial
      Serial.print("LIDAR 1: ");
      Serial.print(distance1);
      Serial.print(" cm | LIDAR 2: ");
      Serial.print(distance2);
      Serial.println(" cm");

      delay(500); // Intervalo entre as leituras
    }

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

sender: assistant

body:
If these are the Garmin Lidar Lite V3, here is a [link to their data sheet.][1] On page 5 of the datasheet you'll find instructions for configuring their I2C addresses. If you haven't already done that, it's quite likely that both devices are replying at once to the same query.

If you have done that already, please update your question with that and any other relevant data - such as the manufacturer, if I got that wrong, add any configuration changes you've made.

  [1]: https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf


message:
Read binary file on SD card

Why I can't read the last byte in the file when I use the Arduino ide code?
The code in cpp is work without any mistakes.
This is my code on Arduino ide:

      vector<unsigned char> text;
      unsigned char textseg;
      in_file.read(&textseg,1);
      while (in_file.available()){
          text.push_back(textseg);
          in_file.read(&textseg,1);
      }

And this is cpp code:

    vector<unsigned char> text;
    unsigned char textseg;
    in_file.read(reinterpret_cast<char*>(&textseg), 1);
    while (!in_file.eof())
    { text.push_back(textseg);
     in_file.read(reinterpret_cast<char*>(&textseg), 1);
    }

body:
Your loop seems to be out-by-one. I would prefer:

<!-- language: lang-c++ -->

      vector<unsigned char> text;
      unsigned char textseg;
      while (in_file.available()){
          in_file.read(&textseg,1);
          text.push_back(textseg);
      }

Why read a byte, as you did, before you know if it is available?

In the Standard C++ library, `eof()` is true if a read fails, however in the Arduino `available()` means a byte is available to be read. They are not directly swappable.


message:
communicating esp 32 with arduino uno

I made a spider robot using arduino and from esp. I made an audio output device which is linked to python program which writes a particular data (when we speak a command) to esp board and accordingly the voice would be activated. Now I want to link them together.

If the esp32 sends a particular data the function in arduino is executed.  Therefore I want to connect esp32 to arduino uno though Serial monitor and send data from esp 32 to arduino. I have only analog pins vacant as all digital pins are used for the servos. how can I achieve this?.

In the main arduino file there are 2 more flexitimer and flexitimer2.cpp files but there is no need of editing them and hence I am giving the code of main file.

```c++
    #include <Servo.h>    //to define and control servos
    #include "FlexiTimer2.h"//to set a timer to manage all servos
    /* Servos --------------------------------------------------------------------*/
    //define 12 servos for 4 legs
    char data = 0;
    Servo servo[4][3];
    //define servos' ports
    const int servo_pin[4][3] = { {2, 3, 4}, {5, 6, 7}, {8, 9, 10}, {11, 12, 13} };
    /* Size of the robot ---------------------------------------------------------*/
    const float length_a = 55;
    const float length_b = 77.5;
    const float length_c = 27.5;
    const float length_side = 71;
    const float z_absolute = -28;
    /* Constants for movement ----------------------------------------------------*/
    const float z_default = -50, z_up = -30, z_boot = z_absolute;
    const float x_default = 62, x_offset = 0;
    const float y_start = 0, y_step = 40;
    const float y_default = x_default;
    /* variables for movement ----------------------------------------------------*/
    volatile float site_now[4][3];    //real-time coordinates of the end of each leg
    volatile float site_expect[4][3]; //expected coordinates of the end of each leg
    float temp_speed[4][3];   //each axis' speed, needs to be recalculated before each movement
    float move_speed;     //movement speed
    float speed_multiple = 1; //movement speed multiple
    const float spot_turn_speed = 4;
    const float leg_move_speed = 8;
    const float body_move_speed = 3;
    const float stand_seat_speed = 1;
    volatile int rest_counter;      //+1/0.02s, for automatic rest
    //functions' parameter
    const float KEEP = 255;
    //define PI for calculation
    const float pi = 3.1415926;
    /* Constants for turn --------------------------------------------------------*/
    //temp length
    const float temp_a = sqrt(pow(2 * x_default + length_side, 2) + pow(y_step, 2));
    const float temp_b = 2 * (y_start + y_step) + length_side;
    const float temp_c = sqrt(pow(2 * x_default + length_side, 2) + pow(2 * y_start + y_step + length_side, 2));
    const float temp_alpha = acos((pow(temp_a, 2) + pow(temp_b, 2) - pow(temp_c, 2)) / 2 / temp_a / temp_b);
    //site for turn
    const float turn_x1 = (temp_a - length_side) / 2;
    const float turn_y1 = y_start + y_step / 2;
    const float turn_x0 = turn_x1 - temp_b * cos(temp_alpha);
    const float turn_y0 = temp_b * sin(temp_alpha) - turn_y1 - length_side;
    /* ---------------------------------------------------------------------------*/

      - setup function
       ---------------------------------------------------------------------------*/
    void setup()
    {
      //start serial for debug
      Serial.begin(9600);
      Serial.println("Robot starts initialization");

      //initialize default parameter
      pinMode(14, OUTPUT);
      set_site(0, x_default - x_offset, y_start + y_step, z_boot);
      set_site(1, x_default - x_offset, y_start + y_step, z_boot);
      set_site(2, x_default + x_offset, y_start, z_boot);
      set_site(3, x_default + x_offset, y_start, z_boot);
      for (int i = 0; i < 4; i++)
      {
        for (int j = 0; j < 3; j++)
        {
          site_now[i][j] = site_expect[i][j];
        }
      }
      //start servo service
      FlexiTimer2::set(20, servo_service);
      FlexiTimer2::start();
      Serial.println("Servo service started");
      //initialize servos
      servo_attach();
      Serial.println("Servos initialized");
      Serial.println("Robot initialization Complete");
    //   stand();
    //   delay(1000);
    //   hand_shake(2);
    //   Serial.println("hihihihihi");
    //   delay(1000);
    //   step_forward();
    //   step_forward();
    //   step_forward();
    //   step_forward();
    //   step_forward();
    //   step_forward();
    //   delay(1000);
    //   step_back();
    //   step_back();
    //   step_back();
    //   step_back();
    //   step_back();
    //   step_back();
    //   delay(1000);

    //   turn_left();
    //   turn_left();
    //   turn_left();
    //   turn_left();
    //   delay(1000);
    //   turn_right();
    //   turn_right();
    //   turn_right();
    //   turn_right();
    //   delay(1000);
    //   hand_wave(4);
    //   delay(1000);
    //   hand_shake(4);
    //   delay(1000);
    //   sit();
    //   delay(1000);
    }

    void servo_attach(void)
    {
      for (int i = 0; i < 4; i++)
      {
        for (int j = 0; j < 3; j++)
        {
          servo[i][j].attach(servo_pin[i][j]);
          delay(100);
        }
      }
    }

    void servo_detach(void)
    {
      for (int i = 0; i < 4; i++)
      {
        for (int j = 0; j < 3; j++)
        {
          servo[i][j].detach();
          delay(100);
        }
      }
    }

    /*
      - loop function
       ---------------------------------------------------------------------------*/
    void loop()
    {

      if(Serial.available() > 0)
       {
          data = Serial.read();
          Serial.print(data);
          Serial.print("\n");

          if(data == 'F')
            {
             Serial.println("Step forward");
             step_forward();
            }
          else if(data == 'B')
             {
              Serial.println("Step back");
              step_back();
            }
          else if(data == 'L')
             {
             Serial.println("Turn left");
             turn_left();

            }
          else if(data == 'R')
            {
              Serial.println("Turn right");
              turn_right();

            }
            else if(data == 'X')
            {
             Serial.println("Stand");
             stand();
            }
             else if(data == 'x')
            {
              Serial.println("Sit");
              sit();
            }
           else if(data == 'S' ||data == 'D' )

            {

            }

             else if(data == 'W')
            {
              digitalWrite(14, HIGH);
            }
              else if(data == 'w')
            {
             digitalWrite(14, LOW);
            }
            else if(data == 'V')
            {
              Serial.println("Hand wave");
              hand_wave(3);
            }
              else if(data == 'v')
            {
             Serial.println("Hand wave");
             hand_shake(3);
            }
             else if(data == 'U')
            {
              Serial.println("Body dance");
              body_dance(10);
            }
              else if(data == 'u')
            {
              Serial.println("Body dance");
              body_dance(10);
            }
            while(Serial.available()) {Serial.read();}
       }

    }

    /*
      - sit
      - blocking function
       ---------------------------------------------------------------------------*/
    /*
      - spot turn to right
      - blocking function
      - parameter step steps wanted to turn
       ---------------------------------------------------------------------------*/
    void turn_right()
    {
        move_speed = spot_turn_speed;

        if (site_now[2][1] == y_start)
        {
          //leg 2&0 move
          set_site(2, x_default + x_offset, y_start, z_up);
          wait_all_reach();

          set_site(0, turn_x0 - x_offset, turn_y0, z_default);
          set_site(1, turn_x1 - x_offset, turn_y1, z_default);
          set_site(2, turn_x0 + x_offset, turn_y0, z_up);
          set_site(3, turn_x1 + x_offset, turn_y1, z_default);
          wait_all_reach();

          set_site(2, turn_x0 + x_offset, turn_y0, z_default);
          wait_all_reach();

          set_site(0, turn_x0 + x_offset, turn_y0, z_default);
          set_site(1, turn_x1 + x_offset, turn_y1, z_default);
          set_site(2, turn_x0 - x_offset, turn_y0, z_default);
          set_site(3, turn_x1 - x_offset, turn_y1, z_default);
          wait_all_reach();

          set_site(0, turn_x0 + x_offset, turn_y0, z_up);
          wait_all_reach();

          set_site(0, x_default + x_offset, y_start, z_up);
          set_site(1, x_default + x_offset, y_start, z_default);
          set_site(2, x_default - x_offset, y_start + y_step, z_default);
          set_site(3, x_default - x_offset, y_start + y_step, z_default);
          wait_all_reach();

          set_site(0, x_default + x_offset, y_start, z_default);
          wait_all_reach();
        }
        else
        {
          //leg 1&3 move
          set_site(1, x_default + x_offset, y_start, z_up);
          wait_all_reach();

          set_site(0, turn_x1 + x_offset, turn_y1, z_default);
          set_site(1, turn_x0 + x_offset, turn_y0, z_up);
          set_site(2, turn_x1 - x_offset, turn_y1, z_default);
          set_site(3, turn_x0 - x_offset, turn_y0, z_default);
          wait_all_reach();

          set_site(1, turn_x0 + x_offset, turn_y0, z_default);
          wait_all_reach();

          set_site(0, turn_x1 - x_offset, turn_y1, z_default);
          set_site(1, turn_x0 - x_offset, turn_y0, z_default);
          set_site(2, turn_x1 + x_offset, turn_y1, z_default);
          set_site(3, turn_x0 + x_offset, turn_y0, z_default);
          wait_all_reach();

          set_site(3, turn_x0 + x_offset, turn_y0, z_up);
          wait_all_reach();

          set_site(0, x_default - x_offset, y_start + y_step, z_default);
          set_site(1, x_default - x_offset, y_start + y_step, z_default);
          set_site(2, x_default + x_offset, y_start, z_default);
          set_site(3, x_default + x_offset, y_start, z_up);
          wait_all_reach();

          set_site(3, x_default + x_offset, y_start, z_default);
          wait_all_reach();
        }
    }

    /*
      - go forward
      - blocking function
      - parameter step steps wanted to go
       ---------------------------------------------------------------------------*/
    void step_forward()
    {
        move_speed = leg_move_speed;

        if (site_now[2][1] == y_start)
        {
          //leg 2&1 move
          set_site(2, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(2, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(2, x_default + x_offset, y_start + 2 * y_step, z_default);
          wait_all_reach();

          move_speed = body_move_speed;

          set_site(0, x_default + x_offset, y_start, z_default);
          set_site(1, x_default + x_offset, y_start + 2 * y_step, z_default);
          set_site(2, x_default - x_offset, y_start + y_step, z_default);
          set_site(3, x_default - x_offset, y_start + y_step, z_default);
          wait_all_reach();

          move_speed = leg_move_speed;

          set_site(1, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(1, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(1, x_default + x_offset, y_start, z_default);
          wait_all_reach();
        }
        else
        {
          //leg 0&3 move
          set_site(0, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(0, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(0, x_default + x_offset, y_start + 2 * y_step, z_default);
          wait_all_reach();

          move_speed = body_move_speed;

          set_site(0, x_default - x_offset, y_start + y_step, z_default);
          set_site(1, x_default - x_offset, y_start + y_step, z_default);
          set_site(2, x_default + x_offset, y_start, z_default);
          set_site(3, x_default + x_offset, y_start + 2 * y_step, z_default);
          wait_all_reach();

          move_speed = leg_move_speed;

          set_site(3, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(3, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(3, x_default + x_offset, y_start, z_default);
          wait_all_reach();
        }
    }

    /*
      - go back
      - blocking function
      - parameter step steps wanted to go
       ---------------------------------------------------------------------------*/
    void step_back()
    {
        move_speed = leg_move_speed;
        if (site_now[3][1] == y_start)
        {
          //leg 3&0 move
          set_site(3, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(3, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(3, x_default + x_offset, y_start + 2 * y_step, z_default);
          wait_all_reach();

          move_speed = body_move_speed;

          set_site(0, x_default + x_offset, y_start + 2 * y_step, z_default);
          set_site(1, x_default + x_offset, y_start, z_default);
          set_site(2, x_default - x_offset, y_start + y_step, z_default);
          set_site(3, x_default - x_offset, y_start + y_step, z_default);
          wait_all_reach();

          move_speed = leg_move_speed;

          set_site(0, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(0, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(0, x_default + x_offset, y_start, z_default);
          wait_all_reach();
        }
        else
        {
          //leg 1&2 move
          set_site(1, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(1, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(1, x_default + x_offset, y_start + 2 * y_step, z_default);
          wait_all_reach();

          move_speed = body_move_speed;

          set_site(0, x_default - x_offset, y_start + y_step, z_default);
          set_site(1, x_default - x_offset, y_start + y_step, z_default);
          set_site(2, x_default + x_offset, y_start + 2 * y_step, z_default);
          set_site(3, x_default + x_offset, y_start, z_default);
          wait_all_reach();

          move_speed = leg_move_speed;

          set_site(2, x_default + x_offset, y_start + 2 * y_step, z_up);
          wait_all_reach();
          set_site(2, x_default + x_offset, y_start, z_up);
          wait_all_reach();
          set_site(2, x_default + x_offset, y_start, z_default);
          wait_all_reach();
        }
    }

    // add by RegisHsu

    void body_left(int i)
    {
      set_site(0, site_now[0][0] + i, KEEP, KEEP);
      set_site(1, site_now[1][0] + i, KEEP, KEEP);
      set_site(2, site_now[2][0] - i, KEEP, KEEP);
      set_site(3, site_now[3][0] - i, KEEP, KEEP);
      wait_all_reach();
    }

    void body_right(int i)
    {
      set_site(0, site_now[0][0] - i, KEEP, KEEP);
      set_site(1, site_now[1][0] - i, KEEP, KEEP);
      set_site(2, site_now[2][0] + i, KEEP, KEEP);
      set_site(3, site_now[3][0] + i, KEEP, KEEP);
      wait_all_reach();
    }

    void hand_wave(int i)
    {
      float x_tmp;
      float y_tmp;
      float z_tmp;
      move_speed = 1;
      if (site_now[3][1] == y_start)
      {
        body_right(15);
        x_tmp = site_now[2][0];
        y_tmp = site_now[2][1];
        z_tmp = site_now[2][2];
        move_speed = body_move_speed;
        for (int j = 0; j < i; j++)
        {
          set_site(2, turn_x1, turn_y1, 50);
          wait_all_reach();
          set_site(2, turn_x0, turn_y0, 50);
          wait_all_reach();
        }
        set_site(2, x_tmp, y_tmp, z_tmp);
        wait_all_reach();
        move_speed = 1;
        body_left(15);
      }
      else
      {
        body_left(15);
        x_tmp = site_now[0][0];
        y_tmp = site_now[0][1];
        z_tmp = site_now[0][2];
        move_speed = body_move_speed;
        for (int j = 0; j < i; j++)
        {
          set_site(0, turn_x1, turn_y1, 50);
          wait_all_reach();
          set_site(0, turn_x0, turn_y0, 50);
          wait_all_reach();
        }
        set_site(0, x_tmp, y_tmp, z_tmp);
        wait_all_reach();
        move_speed = 1;
        body_right(15);
      }
    }

    void hand_shake(int i)
    {
      float x_tmp;
      float y_tmp;
      float z_tmp;
      move_speed = 1;
      if (site_now[3][1] == y_start)
      {
        body_right(15);
        x_tmp = site_now[2][0];
        y_tmp = site_now[2][1];
        z_tmp = site_now[2][2];
        move_speed = body_move_speed;
        for (int j = 0; j < i; j++)
        {
          set_site(2, x_default - 30, y_start + 2 * y_step, 55);
          wait_all_reach();
          set_site(2, x_default - 30, y_start + 2 * y_step, 10);
          wait_all_reach();
        }
        set_site(2, x_tmp, y_tmp, z_tmp);
        wait_all_reach();
        move_speed = 1;
        body_left(15);
      }
      else
      {
        body_left(15);
        x_tmp = site_now[0][0];
        y_tmp = site_now[0][1];
        z_tmp = site_now[0][2];
        move_speed = body_move_speed;
        for (int j = 0; j < i; j++)
        {
          set_site(0, x_default - 30, y_start + 2 * y_step, 55);
          wait_all_reach();
          set_site(0, x_default - 30, y_start + 2 * y_step, 10);
          wait_all_reach();
        }
        set_site(0, x_tmp, y_tmp, z_tmp);
        wait_all_reach();
        move_speed = 1;
        body_right(15);
      }
    }

    void head_up(int i)
    {
      set_site(0, KEEP, KEEP, site_now[0][2] - i);
      set_site(1, KEEP, KEEP, site_now[1][2] + i);
      set_site(2, KEEP, KEEP, site_now[2][2] - i);
      set_site(3, KEEP, KEEP, site_now[3][2] + i);
      wait_all_reach();
    }

    void head_down(int i)
    {
      set_site(0, KEEP, KEEP, site_now[0][2] + i);
      set_site(1, KEEP, KEEP, site_now[1][2] - i);
      set_site(2, KEEP, KEEP, site_now[2][2] + i);
      set_site(3, KEEP, KEEP, site_now[3][2] - i);
      wait_all_reach();
    }

    void body_dance(int i)
    {
      float x_tmp;
      float y_tmp;
      float z_tmp;
      float body_dance_speed = 2;
      sit();
      move_speed = 1;
      set_site(0, x_default, y_default, KEEP);
      set_site(1, x_default, y_default, KEEP);
      set_site(2, x_default, y_default, KEEP);
      set_site(3, x_default, y_default, KEEP);
      wait_all_reach();
      //stand();
      set_site(0, x_default, y_default, z_default - 20);
      set_site(1, x_default, y_default, z_default - 20);
      set_site(2, x_default, y_default, z_default - 20);
      set_site(3, x_default, y_default, z_default - 20);
      wait_all_reach();
      move_speed = body_dance_speed;
      head_up(30);
      for (int j = 0; j < i; j++)
      {
        if (j > i / 4)
          move_speed = body_dance_speed * 2;
        if (j > i / 2)
          move_speed = body_dance_speed * 3;
        set_site(0, KEEP, y_default - 20, KEEP);
        set_site(1, KEEP, y_default + 20, KEEP);
        set_site(2, KEEP, y_default - 20, KEEP);
        set_site(3, KEEP, y_default + 20, KEEP);
        wait_all_reach();
        set_site(0, KEEP, y_default + 20, KEEP);
        set_site(1, KEEP, y_default - 20, KEEP);
        set_site(2, KEEP, y_default + 20, KEEP);
        set_site(3, KEEP, y_default - 20, KEEP);
        wait_all_reach();
      }
      move_speed = body_dance_speed;
      head_down(30);
    }

    /*
      - microservos service /timer interrupt function/50Hz
      - when set site expected,this function move the end point to it in a straight line
      - temp_speed[4][3] should be set before set expect site,it make sure the end point
       move in a straight line,and decide move speed.
       ---------------------------------------------------------------------------*/
    void servo_service(void)
    {
      sei();
      static float alpha, beta, gamma;

      for (int i = 0; i < 4; i++)
      {
        for (int j = 0; j < 3; j++)
        {
          if (abs(site_now[i][j] - site_expect[i][j]) >= abs(temp_speed[i][j]))
            site_now[i][j] += temp_speed[i][j];
          else
            site_now[i][j] = site_expect[i][j];
        }

        cartesian_to_polar(alpha, beta, gamma, site_now[i][0], site_now[i][1], site_now[i][2]);
        polar_to_servo(i, alpha, beta, gamma);
      }

      rest_counter++;
    }

    /*
      - set one of end points' expect site
      - this founction will set temp_speed[4][3] at same time
      - non - blocking function
       ---------------------------------------------------------------------------*/
    void set_site(int leg, float x, float y, float z)
    {
      float length_x = 0, length_y = 0, length_z = 0;

      if (x != KEEP)
        length_x = x - site_now[leg][0];
      if (y != KEEP)
        length_y = y - site_now[leg][1];
      if (z != KEEP)
        length_z = z - site_now[leg][2];

      float length = sqrt(pow(length_x, 2) + pow(length_y, 2) + pow(length_z, 2));

      temp_speed[leg][0] = length_x / length * move_speed * speed_multiple;
      temp_speed[leg][1] = length_y / length * move_speed * speed_multiple;
      temp_speed[leg][2] = length_z / length * move_speed * speed_multiple;

      if (x != KEEP)
        site_expect[leg][0] = x;
      if (y != KEEP)
        site_expect[leg][1] = y;
      if (z != KEEP)
        site_expect[leg][2] = z;
    }

    /*
      - wait one of end points move to expect site
      - blocking function
       ---------------------------------------------------------------------------*/
    void wait_reach(int leg)
    {
      while (1)
        if (site_now[leg][0] == site_expect[leg][0])
          if (site_now[leg][1] == site_expect[leg][1])
            if (site_now[leg][2] == site_expect[leg][2])
              break;
    }

    /*
      - wait all of end points move to expect site
      - blocking function
       ---------------------------------------------------------------------------*/
    void wait_all_reach(void)
    {
      for (int i = 0; i < 4; i++)
        wait_reach(i);
    }

    /*
      - trans site from cartesian to polar
      - mathematical model 2/2
       ---------------------------------------------------------------------------*/
    void cartesian_to_polar(volatile float &alpha, volatile float &beta, volatile float &gamma, volatile float x, volatile float y, volatile float z)
    {
      //calculate w-z degree
      float v, w;
      w = (x >= 0 ? 1 : -1) * (sqrt(pow(x, 2) + pow(y, 2)));
      v = w - length_c;
      alpha = atan2(z, v) + acos((pow(length_a, 2) - pow(length_b, 2) + pow(v, 2) + pow(z, 2)) / 2 / length_a / sqrt(pow(v, 2) + pow(z, 2)));
      beta = acos((pow(length_a, 2) + pow(length_b, 2) - pow(v, 2) - pow(z, 2)) / 2 / length_a / length_b);
      //calculate x-y-z degree
      gamma = (w >= 0) ? atan2(y, x) : atan2(-y, -x);
      //trans degree pi->180
      alpha = alpha / pi * 180;
      beta = beta / pi * 180;
      gamma = gamma / pi * 180;
    }

    /*
      - trans site from polar to microservos
      - mathematical model map to fact
      - the errors saved in eeprom will be add
       ---------------------------------------------------------------------------*/
    void polar_to_servo(int leg, float alpha, float beta, float gamma)
    {
      if (leg == 0)
      {
        alpha = 90 - alpha;
        beta = beta;
        gamma += 90;
      }
      else if (leg == 1)
      {
        alpha += 90;
        beta = 180 - beta;
        gamma = 90 - gamma;
      }
      else if (leg == 2)
      {
        alpha += 90;
        beta = 180 - beta;
        gamma = 90 - gamma;
      }
      else if (leg == 3)
      {
        alpha = 90 - alpha;
        beta = beta;
        gamma += 90;
      }

      servo[leg][0].write(alpha);
      servo[leg][1].write(beta);
      servo[leg][2].write(gamma);
    }
```

NOTE: I am deleting some functions like `void sit(void)` stand as the maximum limit of characters was reached.

This is my esp32 code

```c++
    #include "Arduino.h"
    #include "WiFi.h"
    #include "Audio.h"

    #define I2S_DOUT      25
    #define I2S_BCLK      27
    #define I2S_LRC       26

    Audio audio;

    char data = 0;
    void setup()
    {

      Serial.begin(115200);

      WiFi.disconnect();
      WiFi.mode(WIFI_STA);
      WiFi.begin( "Physics", "299792458");

      while (WiFi.status() != WL_CONNECTED)
        delay(1500);

      audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
      audio.setVolume(100);
      audio.connecttospeech("Hello From akshit singh,,welcome to tapovan international school's project day ,,i am a smart walking robot ,you can also call me astra bot ", "en");

    }

    void loop(){
    if(Serial.available() > 0)
       {
          data = Serial.read();
          Serial.print(data);
          if(data == 'A')
            {
             audio.connecttospeech("hello everyone ,welcome to tapovan international school's project day ", "en");
             Serial.println("done");
            }

          else if(data == 'B')
            {
             audio.connecttospeech("BYE Bye everyone", "hi");
             Serial.println("done 2");
            }
          else if(data == 'C')
            {
             audio.connecttospeech("i am a smart walking robot ,you can also call me astra bot ", "hi");
             Serial.println("done 2");
            }

          else if(data == 'F')
            {
             audio.connecttospeech("going forward ,sir", "hi");
             Serial.println("done 2");
            }

          else if(data == 'b')
            {
             audio.connecttospeech("going backward ,sir", "hi");
             Serial.println("done 2");

            }
          else if(data == 'L')
            {
             audio.connecttospeech("moving left, sir", "hi");
             Serial.println("done 2");

            }
          else if(data == 'R')
            {
             audio.connecttospeech("moving right ,sir", "hi");
             Serial.println("done 2");

            }

       }

    {
      audio.loop();
    }

      }

    void audio_info(const char *info) {
      Serial.print("audio_info: "); Serial.println(info);
    }

```

body:
Well first of all you need to be aware that the UNO runs at 5V, and the ESP32 at 3V3, so you will need a level shifter in between the UNO and ESP32 unless you want to possibly damage your ESP32.

You can [create a bidirectional level shifter with an N-Channel mosfet and 2 resistors,][1]
or [buy a breakout board,][2] or use a chip like the GTL2010. Just note that not all bidirectional level shifters are the same, some require changing the direction with a pin(usually DIR), the GTL2010 is not one of those.

#### [Bitbanged UART][3]

Can be done on any pin.

Either a uni or bi directional level shifter will work just fine.

#### [SPI][4]
 Since your servos aren't being run by PWM/Timer hardware you could use the analog pins for a couple of your servos, and use the SPI peripheral which uses pins 10, 11, 12, and 13.

Your ESP32 is sending the commands, so you'd want to set up the ESP32 as the master, and the UNO as the slave.

Just like the BBUART option, either a uni or bi directional level shifter will work.

#### [I2C][5]

This uses the SDA and SCL pins next to VREF, which are really just A4 and A5. And again, you'd set the ESP32 to be the master, and the UNO to be the slave.

Be aware that you will need a **bidirectional** level shifter, a unidirectional will not work.

Although I don't recommend, there is a chance you may be able to get away without using a level shifter by attaching your pull-up resistors to 3V3. Just note, [for the atmega328P to register a high logic level, the input voltage needs to be 60% of VCC.][6] So if its running at 5V, it will take 3V to read high, which does have a chance at working. But if its running at 5V5, it will require 3V3 to register high and probably wont function properly if at all.

Another reason to use a level shifter is apparently the Arduino I2C library uses the internal pull-up resistors, so you would have to modify the library to disable them, so your ESP32 pins aren't pulled to 5V.

*BBUART is probably your best bet, it uses the least pins, and easiest to work with in code. All you need is a level shifter and you're good to go. But if you feel confident enough coding wise, you could try I2C without a level shifter, and if it doesn't work then purchase one.*

  [1]: https://cdn.sparkfun.com/r/400-400/assets/f/3/3/4/4/526842ae757b7f1b128b456f.png
  [2]: https://www.sparkfun.com/products/12009
  [3]: https://docs.arduino.cc/learn/built-in-libraries/software-serial
  [4]: https://www.arduino.cc/reference/en/language/functions/communication/spi/
  [5]: https://docs.arduino.cc/learn/communication/wire
  [6]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf#nameddest=28.2 DC Characteristics


message:
When I use AnalogueWrite the voltage doesn't vary properly

I have a project where I want to control a pump, I use an Arduino, connected to a driver L298N and I will connect the pin 5, 6, 7 of the arduino to the pin IN2, IN1, ENA of the driver respectively and the motor will be connected to the output

My materiel :
- Arduino Uno R3
- Multimeter
- Arduino IDE 2.1.1

The issue :
When I use the function analogWrite the voltage vary only between two value (0v or 5.5v).
The pin used was the Digital pin n°7, noted in the code 7.

The code :

```c++
#define PUMP_DIR_1 5
#define PUMP_DIR_2 6
#define PUMP_PWM 7
#define INVERTED 0

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

void set_pump_speed(int speed){
  Serial.print("Set speed ");
  Serial.print(speed);
  Serial.print("\r\n");
  analogWrite(PUMP_PWM, speed);
}

void loop() {
  set_pump_speed(255);
  delay(3000);
  set_pump_speed(0);
  delay(3000);
  set_pump_speed(125);
  delay(3000);
}

```

As output I obtained :

>00:32:17.184 -> Set speed 0\
00:32:20.175 -> Set speed 125\
00:32:23.178 -> Set speed 255\
00:32:26.182 -> Set speed 0\
00:32:29.197 -> Set speed 125\
00:32:32.201 -> Set speed 255

From the mutlimeter I obtained :
>0v when speed = 0\
0v when speed = 125\
5.5v when speed = 255

The arduino is not wired to anything

body: Pin 7 isn't a PWM pin. Use, say, pin 6 and you will get correct results. The PWM pins are marked with a "~" on the board.


message:
Updating the firmware of Arduino Mega2560

I wanted to connect my Arduino board to MATLAB although it recognized the Arduino board, I kept receiving the error that said:

"Internal error: The initialization of the server code is incorrect."

I got the recommendation of updating my Arduino board's firmware;
So I connected my board to my pc and opened Arduino IDE; It said that the Arduino Mega or Mega 2560 on com6 is connected.

I even uploaded the blink example to my board to make sure that it was connected and fully functioning. Which it was.

But in the above bar in Arduino IDE, "Tools" menu, when I select the "WIFI101/ Firmware Updater" It says that no supported board connected.
What should I do now?

*P.S:
I'm currently using Arduino IDE version 2.1.1 and MATLAB 2023a on Windows 11.*

I'm sorry, I'm really new to this and would appreciate your help.

body:
https://www.mathworks.com/help/supportpkg/arduinoio/ug/configure-setup-for-arduino-hardware.html

This link has the instructions for connecting the Arduino board.  Look right at the first where it talks about the USB connection. Step 2 where you click program is the step where you are loading the server firmware onto the Mega.  That's the bit it sounds like you're missing.


message:
Can arduino be used in industrial projects?

I'm developing an industrial project and my programming knowledge is limited to arduino.

I'm planning to use either Atmega328 or STM32F103C8T6 chip in my pcb and to program it using arduino IDE. My plan is just to use Arduino IDE to create sketches and programming the chip after burning arduino bootloader.

Is this concept viable for industrial environments? Are there any problems/challenges using this method?

body:
The chips should work fine, however it depends on how things are assembled, what parts are used, ambient temperature, cooling and electronic protection. For reference here is what I use:
Hobby: 0°C to 50°C
Commercial: 0 ° to 70 °C.
Industrial: −40 ° to 85 °C.
Military: −55 ° to 125 °C.
Automotive: -40°C to 175°C, location dependent.
Without a complete set of specifications, schematic, and component information I cannot give you a yes or no answer.

At this point you should realize it will not be a slam dunk simple project.


body:
Industrial environments can be hostile to electronics that aren't "hardened" against the potential hazards. There is no one answer to this without knowing the specific environment. Will it be controlling heavy electrical machinery (even if not switching the power). You'll need to know more about the intended environment to know whether and how you can harden your electronics to it.

But if nothing else, Arduino is terrific for prototyping things that, once the concept is proven, might then have to be re-built to a higher standard for production use.


body:
You don't talk about Arduino hardware. Your concern is the Arduino IDE.

Which is a lawyer's licensing topic. Might depend on the libraries you plan to use. And whether you want to hide the fact you're using (selling ?) open source software.


body:
I don't think there are any major problems with your proposal. The chips themselves will have documented limitations (specifications) that you would need to be aware of. I think you would find that most manufacturers of washing machines, toasters, TVs etc. do not also manufacture processor chips, so they too would be relying on commercially-available chips such as the ones you mentioned.

This brings us to the IDE. It is basically a "wrapper" around a C++ compiler which is available for anyone to use in any project. The Arduino libraries themselves may have licensing you would need to be aware of, the same as if you used a library not associated with the Arduino.

See this page: [Licensing for products based on Arduino](https://support.arduino.cc/hc/en-us/articles/4415094490770-Licensing-for-products-based-on-Arduino):

> ## Note:
>
> * You can freely use Arduino hardware and software for your personal purposes, or within your company or organization, with no restrictions. The rules described in this document apply only when you distribute products based on Arduino to third parties or you make them public in any form.
> * If you comply with the open-source licenses of Arduino, you can distribute your software/hardware products for free or commercially. This document provides a summary of such rules for your convenience and does not waive the need to get professional legal advice.

---

I am not a  lawyer, and if you are worried about the legal aspects I suggest you get legal advice. However I doubt that a small-scale project would warrant anyone getting their lawyers involved. For one thing, it would be hard to prove that the 0s and 1s on your chip were produced using the Arduino IDE, or any of its libraries.


message:
Using Soft UART - how include library

I want to use the soft serial communication example.

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

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

But when I compile it, it sais:

    /home/xxx/Arduino/SoftwareSerialExample/aa/aa.ino:28:28: schwerwiegender Fehler: SoftwareSerial.h: Datei oder Verzeichnis nicht gefunden
    Kompilierung beendet.
    exit status 1
    Fehler beim Kompilieren für das Board Arduino Uno.

What is going there?
I  have a directory also with AFSoftSerial.h at /Arduino/libraries/AFSoftSerial/AFSoftSerial

body:
Check to make sure you have the line:

    #include <SoftwareSerial.h>

... at the top of your Sketch.

Also, compare your code with that found on the [Arduino Software Serial Library web page here][1].

Finally, make sure your Arduino Application and all your Arduino Libraries are up to date.

  [1]: https://docs.arduino.cc/learn/built-in-libraries/software-serial


body:
> I have a directory also with AFSoftSerial.h at /Arduino/libraries/AFSoftSerial/AFSoftSerial

The code is looking for the "SoftwareSerial" library and that is the library you need include and call, not "AFSoftSerial". Or, if you intend to use AFSoftSerial, then change your code to say that instead.


message:
Problem with reading MIFARE 13.5Mhz with MFRC522 lib

I'm trying to read the UID of MIFARE 13.5Mhz cards with MFRC522 lib and I have defined the following function for it.
```
void getUID() {
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
  Serial.println("Scanned PICC's UID:");
  tag = "";
  for (byte i = 0; i < mfrc522.uid.size; i++)
   {
    tag.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    tag.concat(String(mfrc522.uid.uidByte[i], HEX));
   }
  tag.toUpperCase();
  Serial.println(tag);
  mfrc522.PICC_HaltA(); // Stop reading
}
}

```
this function works perfectly fine in void loop() but when I call it in the following web request my esp8266 crashes.

```
controlserver.on("/searchuid", HTTP_POST, [](AsyncWebServerRequest *request){

    transmit = request->arg("idcode");
    if (request->hasArg("configmodule")) {
    File file = SPIFFS.open("/inputString.txt", "r");
    if (!file) {
    Serial.println("Failed to open file");
    return;
    }
    getID();
    delay(500);
    Serial.println(tag);
    String content = file.readString();
    if (content.indexOf(tag) >= 0) {
    Serial.println("Found search string");
  } else {
    Serial.println("Did not find search string");
  }

    }
  });
```
and I cannot understand why, any help will be appreciated.

body:
Under ["Important Things To Remember"][1] in the ESPAsyncWebServer README:

> You can not use yield or delay or any function that uses them inside
> the callbacks

Your code calls `delay()` in the callback, and calls functions that you cannot know do not call `delay()` or `yield()`.

You need to rewrite your code to follow the instructions in the web server's documentation.

  [1]: https://github.com/me-no-dev/ESPAsyncWebServer#important-things-to-remember


message:
Using SPI on Pi Pico, Arduino IDE

Beginner with the Pi Pico here, but I studied electronics engineering and am reasonably hardware literate. I've used mbed online for a project prior to covid.

I want to use SPI to connect to a display using the ILI9488, (480 x 320 TFT panel), however, I cannot see how or where I would define SPI pins, and my understanding is that using SPI.h would default to Arduino pinouts - the uno etc being pin incompatible with the pi pico.

Do I need to trudge through the SPI.h file to try to work out how I set the pins manually? Or am I barking up the wrong tree?

I am using macOS, Arduino IDE 2.1.1 and have no issues connecting to the pico W. Please ask for any other clarification, I can provide a schematic of my design if it makes things easier. Love the pico but am finding it hard to use with C/C++.

Thanks,
KL

body:
You can read the actual SPI pins with the following sketch

```c++
    void setup() {
      Serial.begin(115200);
    }

    void loop() {
      Serial.print("MOSI: ");
      Serial.println(MOSI);
      Serial.print("MISO: ");
      Serial.println(MISO);
      Serial.print(" SCK: ");
      Serial.println(SCK);
      Serial.print("  SS: ");
      Serial.println(SS);
      Serial.println();
      delay(5000);
    }
```
As Juraj wrote, they are defined in the board files.

I have no experience with your ILI9488 display and the corresponding library. Many libraries allow you to use software defined pins. I would not recommend that, especially for a display with 480 x 320 pixels. You really need the speed of the hardware SPI.


message:
ArduinoJson library: how much space to allocate for serialized buffer?

I am using the fantastic `ArduinoJson` library for working with JSON data on my ESP8266. I have been facing issues with **random software wdt resets** and have been investigating memory leaks wherever I can. I want to trim down my use of `Strings` and `DynamicJsonDocument`s as much as possible. So I thought of using automatic variables: char buffers: `char[N]` and `StatitcJsonDocument`s instead.

I am using the ArduinoJson assitant service to help me figure out how many bytes I should reserve. The following is one response payload, I am expecting to receive:

```
// char input[MAX_INPUT_LENGTH];

StaticJsonDocument<128> doc;

DeserializationError error = deserializeJson(doc, input, MAX_INPUT_LENGTH);

if (error) {
  Serial.print(F("deserializeJson() failed: "));
  Serial.println(error.f_str());
  return;
}

int statusCode = doc["statusCode"]; // 200
bool needUpdate = doc["needUpdate"]; // true
const char* message = doc["message"]; // "update required"

JsonObject data = doc["data"];
const char* data_deviceId = data["deviceId"]; // "DLD00005"
const char* data_user_fw_version = data["user_fw_version"]; // "0.0.0"
const char* data_new_fw_version = data["new_fw_version"]; // "0.0.5"

```

As you can see I am using a `char [N]` type as the input, which is in fact being copied using `strncpy()` from the `https.getString().c_str()` from the response of a previous `https.POST()` request. My issue is that **I do not know how much memory I should reserve for the `char[N]` array**, ie what should be the value of `N`? The reasons I ask is that I am getting a `deserialization() failed: IncompleteInput` error, which I'm pretty sure is because the `char[N]` buffer is not large enough. So my question is if the StaticJsonDocument object is `128` bytes, then how big should I make the `char[N]` buffer (is there any relation between the sizes)? Or should I just go with an arbitrarily large value like `char[512]` which I want to avoid to avoid stack overflows?
```
StaticJsonDocument<128> payload;
char payloadSerial[???];
...
int status = https.POST(payloadSerial);
strncpy(payloadSerial, https.getString().c_str(), sizeof(payloadSerial));
DeserializationError error = deserializeJson(payload, payloadSerial, sizeof(payloadSerial));
if (error) {
    Monitor.print(F("DeserializeJson() failed: "));
    Monitor.println(error.f_str());
}
```

body:
You're asking about code that looks like this:
```
StaticJsonDocument<128> payload;
char payloadSerial[???];
...
int status = https.POST(payloadSerial);
strncpy(payloadSerial, https.getString().c_str(), sizeof(payloadSerial));
DeserializationError error = deserializeJson(payload, payloadSerial, sizeof(payloadSerial));
```

The documentation for [`deserializeJson()`](https://arduinojson.org/v6/api/json/deserializejson/?cmdf=deserializeJson) shows that it can accept a `String` directly:
```
DeserializationError deserializeJson(JsonDocument& doc, const String& input);
```

So there's no need to copy `https.getString().c_str()` into `payloadSerial`. You can just pass the `String` that `https.getString()` returns:

```
StaticJsonDocument<128> payload;

int status = https.POST(request_body);

DeserializationError error = deserializeJson(payload, https.getString());
```

You were using the same character array here for both the body of the request that you passed to `POST()` and for deserializing the JSON response. While this is okay, for clarity I changed the `POST` call to use something else as the character array is completely unnecessary for processing the response.

Even if `deserializeJson()` didn't accept a `String` type as an argument, you still wouldn't need to copy the response into a buffer. You could just pass `https.getString().c_str()`:
```
StaticJsonDocument<128> payload;

int status = https.POST(request_body);

DeserializationError error = deserializeJson(payload, https.getString().c_str());
```

You **really** should check the value of `status`. It indicates whether the POST succeeded or not. If it failed, you should report that and the reason for the failure, and not attempt to process the returned payload as there is no returned payload.


message:
Timer interrupt setup for one second is too slow (~ 4 seconds)

I am trying to use the timer interrupt on an Arduion Uno.

Here is a imple example code for displaying a progressive digit on a lcd display, which is updated with timer interupt every second:

```
#include <LCD_I2C.h>

LCD_I2C lcd(0x27);
volatile bool timerFlag = false; // Timer-Flag (timer-Interrupt)
int displayWidth = 16; // display width
int digit = 0; // current digit

void setup() {
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Initializing...");

  noInterrupts();
  TCCR1A = 0;
  TCCR1B = (1 << CS12) | (1 << CS10); // set Prescaler to 1024
  TCNT1 = 0;
  OCR1A = 15624; // should be 1 second with a prescaler of 102
  TIMSK1 |= (1 << OCIE1A); // Enable timer interrupt
  interrupts();
}

ISR(TIMER1_COMPA_vect) {
  timerFlag = true;
}

void loop() {
  static int position = 0;
  char displayString[17]; // +1 null termination

  if (timerFlag) {
    lcd.clear(); // clear display

    // update digit and progress
    digit = (digit + 1) % 10;
    position = (position + 1) % (displayWidth + 1);
    memset(displayString, ' ', displayWidth);
    displayString[displayWidth] = '\0'; add null termination
    displayString[position] = '0' + digit; // Character for the current digit

    // Show updated progress on the display
    lcd.setCursor(0, 1);
    lcd.print(displayString);

    timerFlag = false;
  }
}
```
The values for setting up he inteupt timer 1 for 1 second is arround everywhere.
BUt the updates generated by this code is clearly much slower than 1 second, it's more about 4 seconds.
So i did a comparison with a delay based version of the same example:
```
#include <LCD_I2C.h>

LCD_I2C lcd(0x27);
int displayWidth = 16; // display width

void setup() {
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Initializing...");
}

void loop() {
  for (int digit = 0; digit < 10; digit++) {
    char displayString[17]; // +1 null termination
    int position = digit % (displayWidth + 1);

    // Update progression
    memset(displayString, ' ', displayWidth);
    displayString[displayWidth] = '\0'; // add null termination
    displayString[position] = '0' + digit; // Character for the current digit

    // Show updated progress on the display
    lcd.clear(); // Clear display
    lcd.setCursor(0, 1);
    lcd.print(displayString);

    delay(1000);
  }
}
```
This one works as expected and updates every second.

So what is wrong with my interrupt settings?

body: It is ignoring this `OCR1A = 15624;` and simply rolling over at 65535 instead., hence the error factor of 4. You have to set the wave generation mode as CTC in registers TCCR1A/B.


body:
There is a flag in `TCCR1A/B` called `WGM12` which sets the `wave generation mode (WGM)` to `Clear Timer on Compare Match (CTC)`.
This causes the timer to count up to the value in OCR1A and then automatically reset to 0.

This flag was forgotten, so the interrupt simply ignores the setting `OCR1A = 15624;` and counts through to 65535, which corresponds to the observed factor of about 4.
Therefore the setting line for TCCR1B must be changed to
```
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
// Set CTC mode and set Prescaler to 1024
```
Now the interrupt is triggered correctly every second.


message:
How to use Interrupt in Arduino to receive the data from Serial Input

Currently i have a project that forced me to make a program that receives several data from Serial Input using Interrupt in Arduino. I use Arduino as the receiver and ESP32 as the sender through Hardware Serial. The program i have written for Arduino is as posted at [Serial Input Basics][1] with a few changes as written below :
```
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

// variables to hold the parsed data
char messageFromPC[numChars] = {0};
unsigned long sendDataPrevMillis = 0;
int controlCondition = 0;
int droneCondition = 0;
int gasValue = 0;
int pitchValue = 0;
int rollValue = 0;
int yawValue = 0;

boolean newData = false;

void setup() {
  attachInterrupt(digitalPinToInterrupt(1), handleInterrupt, RISING);
  Serial.begin(57600);
}

void loop() {

  Serial.print("Control Condition :");
  Serial.print(controlCondition);
  Serial.print(" Drone Condition :");
  Serial.print(droneCondition);
  Serial.print(" Roll:");
  if(rollValue < 1500)Serial.print("<<<");
  else if(rollValue > 1500)Serial.print(">>>");
  else Serial.print("-+-");
  Serial.print(rollValue);
  Serial.print("  Pitch:");
  if(pitchValue > 1500)Serial.print("^^^");
  else if(pitchValue < 1500)Serial.print("vvv");
  else Serial.print("-+-");
  Serial.print(pitchValue);

  Serial.print("  Gas:");
  if(gasValue < 1500)Serial.print("vvv");
  else if(gasValue > 1500)Serial.print("^^^");
  else Serial.print("-+-");
  Serial.print(gasValue);

  Serial.print("  Yaw:");
  if(yawValue < 1500)Serial.print("<<<");
  else if(yawValue > 1500)Serial.print(">>>");
  else Serial.print("-+-");
  Serial.println(yawValue);
}

void handleInterrupt(){
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
    if (newData == true) {

    strcpy(tempChars, receivedChars);
    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars, ",");
    controlCondition = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ",");
    droneCondition = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ",");
    gasValue = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ",");
    pitchValue = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ",");
    rollValue = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ",");
    yawValue = atoi(strtokIndx);

    newData = false;
    }
}
```
The data will be sent from ESP32 to change the values of `controlCondition`, `droneCondition`, `gasValue`, `pitchValue`, `rollValue`, and `yawValue`.

I have tried it and the Interrupt cannot be triggered. The Interrupt should be triggered whenever the `controlCondition`, `droneCondition`, `gasValue`, `pitchValue`, `rollValue`, or `yawValue` change its value. Any idea what should I do? or is there something wrong with my code?

Note that the code that i showed in the `void loop()` is just an example code. The real code is more complex with so many calculations involved. The variables that I mentioned are the important variables for the calculations.

 [1]: https://forum.arduino.cc/t/serial-input-basics-updated/382007

body:
Why do you want to use an interrupt anyway? The serial hardware already generates an interrupt, and inside that ISR the incoming byte is placed into a buffer.

I presume you have a main loop where you are doing other stuff, and you want to react when some interesting serial data arrives.

I have an example of processing serial data without blocking on [my page about serial processing](http://www.gammon.com.au/serial) which I reproduce below:

<!-- language: c++ -->

    /*
    Example of processing incoming serial data without blocking.

    Author:   Nick Gammon
    Date:     13 November 2011.
    Modified: 31 August 2013.

    Released for public use.
    */

    // how much serial data we expect before a newline
    const unsigned int MAX_INPUT = 50;

    void setup ()
      {
      Serial.begin (115200);
      } // end of setup

    // here to process incoming serial data after a terminator received
    void process_data (const char * data)
      {
      // for now just display it
      // (but you could compare it to some value, convert to an integer, etc.)
      Serial.println (data);
      }  // end of process_data

    void processIncomingByte (const byte inByte)
      {
      static char input_line [MAX_INPUT];
      static unsigned int input_pos = 0;

      switch (inByte)
        {

        case '\n':   // end of text
          input_line [input_pos] = 0;  // terminating null byte

          // terminator reached! process input_line here ...
          process_data (input_line);

          // reset buffer for next time
          input_pos = 0;
          break;

        case '\r':   // discard carriage return
          break;

        default:
          // keep adding if not full ... allow for terminating null byte
          if (input_pos < (MAX_INPUT - 1))
            input_line [input_pos++] = inByte;
          break;

        }  // end of switch

      } // end of processIncomingByte

    void loop()
      {
      // if serial data available, process it
      while (Serial.available () > 0)
        processIncomingByte (Serial.read ());

      // do other stuff here like testing digital input (button presses) ...

      }  // end of loop

It looks to me like you are looking for an "end marker" which is when you want to react to what you have received earlier. Like in my example above, you could just pick up individual bytes in the main loop, and when the end marker arrives the whole line can be processed. I used a newline for and end marker, but you could change that to '>'.

---

The problems with an interrupt like you are doing are:

* The interrupt will fire on the first bit (out of 10) and so there won't be any serial data yet, and your program will uselessly look for serial data which won't be there.

* You are calling Serial.read() which won't return anything because while you are in **your** ISR the main serial ISR won't be able to fire.

* Your ISR is doing too much.

* Serial line is normally HIGH, and transitions to LOW (the start bit) when the byte starts, so you should be looking for FALLING and not RISING.

---

I strongly suggest you rework to just check for serial available in the main loop, as I have done, and process it when the end delimiter arrives.


body:
Don't do anything in your `loop()` function *except* calling other functions, each of which decides - for one part of your process - whether or not it is time to do that part. If so, do that part; if not, return immediately to the loop function.

Read [my answer to a similar question][1] that talks more about how to do this. This technique is called non-blocking programming. Your code should poll rapidly for whatever it might need to respond to, but should not wait for any of those things to occur. If you do that, you will likely not need the kind of response that would require interrupts.

Also, the print statements in your `loop()` will slow down (block) execution and may keep your PID from responding adequately. If you need them for debugging your calculations, you can wrap them in `#if DEBUG` ... `#endif` statements so one `#define DEBUG` can easily include them them when you need to (knowing that your device control will be affected) and remove them for operational tests. If you must keep some print statements live, make only as few as necessary live at one time, make sure to use the highest baud-rate possible, and keep them as brief as possible.

  [1]: https://arduino.stackexchange.com/questions/60759/how-to-rotate-two-or-more-steppers-simultaneously-by-giving-array-of-angles/66380#66380


message:
Arduino Nano TX and RX LEDs Not Lighting Up During Upload

I'm encountering a problem with my Arduino Nano board. When I attempt to upload sketches to the board using the Arduino IDE, only the Power LED lights up, and the TX and RX LEDs remain inactive. I've tried several troubleshooting steps, including reinstalling drivers, using different USB cables, and trying different USB ports on my computer. Despite these efforts, I haven't been able to resolve the issue.

Board Details:
- Arduino Nano with ATmega microcontroller
- Power LED is lit when the board is connected
- "L" LED blinks rapidly during upload
- TX and RX LEDs are not lighting up during upload

Troubleshooting Steps Taken:
- Reinstalled Arduino IDE and drivers
- Tried multiple USB cables and ports
- Verified COM port selection in Arduino IDE
- Checked USB-Serial converter chip for damage

I'm reaching out to the community for help and guidance. Has anyone else encountered this issue? What further steps should I take to diagnose and resolve this problem? Any insights or suggestions would be greatly appreciated.

body: They many times will not light because of the bit pattern being sent and the short time the bit is active to light the LED. If it is uploading code without errors you are good to go.  Quick test, If not try another Arduino and see if it uploads or not. If not it is your computer or a bad cable otherwise it is a bad Arduino.


message:
DS18B20 Error in Proteus 8.13

I am using the below code to check temperatures from 36 DS18B20 sensors using Arduino Mega 2560.  If any one of them go above 50 deg. celsius, then it sets the output pin to HIGH.

I am trying to run the code on Proteus 8.13, but during the same run, sometimes the virtual terminal prints -127 deg. celsius for all, sometimes right for some sensors and wrong for the other ones (usually the wrong value is also 85 deg. celsius). Is it something wrong with the simulator, or my code?

```c++
    #include <OneWire.h>
    #include <DallasTemperature.h>

    #define NUM_SENSORS 36
    #define START_PIN 14
    #define OUTPUT_PIN 2

    OneWire oneWire[NUM_SENSORS];
    DallasTemperature sensors[NUM_SENSORS];

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

      for (int i = 0; i < NUM_SENSORS; i++) {
        oneWire[i] = OneWire(START_PIN + i);
        sensors[i] = DallasTemperature(&oneWire[i]);
        sensors[i].begin();
      }

      pinMode(OUTPUT_PIN, OUTPUT);
      digitalWrite(OUTPUT_PIN, LOW);
    }

    void loop() {
      float celsius[NUM_SENSORS];

      for (int i = 0; i < NUM_SENSORS; i++) {
        sensors[i].requestTemperatures();
        celsius[i] = sensors[i].getTempCByIndex(0);
      }

      bool aboveThreshold = false;

      for (int i = 0; i < NUM_SENSORS; i++) {
        if (celsius[i] > 50.0) {
          aboveThreshold = true;
          break;
        }
      }

      digitalWrite(OUTPUT_PIN, aboveThreshold);

      printSensorData(celsius);

      delay(1000);
    }

    void printSensorData(float celsius[]) {
      for (int i = 0; i < NUM_SENSORS; i++) {
        Serial.print("Sensor ");
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(celsius[i]);
        Serial.print(" C  ");
        Serial.print(sensors[i].toFahrenheit(celsius[i]));
        Serial.println(" F");
      }
    }
```

body: The -127 indicates a fault on the hardware side, generally an open circuit. Also it sounds like your pull up resistor is not installed or way out of range.For the Mega. UNO and other 5V units 4.7K is a good size and 3.3K for the 3V3 systems. Note the resistor goes from VCC to the sensor output.


message:
Make my Arduino (Mega or whatever is better for the task) to be able to read and write `Serial` data to a **rj45** port

I have a Chinese hybrid solar inverter that exposes an **rj45 input** which talks the serial protocol (Baud rate 2400, no parity, 8 bits, 1 stop bit). I need my Arduino (say, Mega or whatever, does not really matter) to talk to it. What would be the best option to connect an Arduino board to the rj45 input such that it would be available as `Serial` in the code?

Basically, I'd like the following piece to code to "just work":

```
 uint8_t query[] = {81, 80, 73, 71, 83, 183, 169, 13};
 Serial.write(query, sizeof(query)); // Write some bytes to a device, i.e. send a request.
 Serial.flush();

 while (!Serial.available()); // Wait for device to reply.
 String str = Serial.readString();
    // do someting with `str`...
```

In other words, I am looking for a hardware solution to connect my Arduino board to the rj45 input without introducing an unnecessary complication (if any).

body: Look up the data sheet for the max232. It is an old chip that does what you need.  ARDUINOs serial work at 0 to 5v and the old fashioned standard for serial data works at +-12v.  Also, there will be a high low inversion.


message:
Error while trying to connect CH341 driver

I'm trying to connect an Arduino board to IDE on Ubuntu, and I have the following driver log:

    [  543.412356] usb 1-2: USB disconnect, device number 3
    [  549.593729] usb 1-2: new full-speed USB device number 7 using xhci_hcd
    [  549.748438] usb 1-2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.54
    [  549.748449] usb 1-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
    [  549.748454] usb 1-2: Product: USB2.0-Serial
    [  549.750234] ch341 1-2:1.0: ch341-uart converter detected
    [  549.750859] usb 1-2: ch341-uart converter now attached to ttyUSB0
    [  550.347356] input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input20
    [  550.462814] usb 1-2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
    [  550.463418] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
    [  550.463437] ch341 1-2:1.0: device disconnected
As a result no ports are found, any suggestion?

body:
Solved, thanks to this [article][1]

    sudo apt autoremove brltty

remove the conflict and now the board is visible
  [1]: https://0xsuk.github.io/posts/2022-07-19-how-to-install-ch340-on-ubuntu-22.04/


message:
Control esp32 via keyboard keys

I'm making a project in which I have to control a mini car and get sensor information via bluetooth. I'd like to be able to control the mini car with the computers keyboard (w,a,s,d), but I was not able to find a library that could help with that, like the "keyboard" library does in python for example

Ex.

```
import keyboard

# when w is pressed, the car goes forward

If (keyboard.is_pressed("w"):

    Forward()
```

The "keyboard" library in arduino does not seem to work the same way. And I didn't find any other libraries nor tutorials about it online.

How to make it work?

body:
In case someone is trying to do the same, I came up with a way to make it work. In ArduinoIDE, after the setup, the loop checks if the bluetooth serial is available and has received anything, if it receives the right variables for movement, it passes the instruction to the motors connected to the Arduino through an l298n module.

The code is as follows:
```
// variáveis para conexão bluetooth // variables for bluetooth connection
#include <SoftwareSerial.h>

SoftwareSerial SerialBT(8, 9);
char valorDoBluetooth;

//variáveis para o uso dos motores // variables for the use of motors
// motor 1
const byte in1 = 2;
const byte in2 = 4;
const byte enA = 3;
//motor 2
const byte in3 = 5;
const byte in4 = 7;
const byte enB = 6;

int velocidade = 100; // motor speed (up to 255)

int componentesOut[6] = { in1, in2, enA, in3, in4, enB }; // list created to setup the variables more easily

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

  // loop to set pins to Output
  for (int n = 0; n < 6; n++) {
    pinMode(componentesOut[n], OUTPUT);
  }
}

void loop() {
  // Read data from the Bluetooth module
  if (SerialBT.available()) {
    valorDoBluetooth = SerialBT.read(); // bluetooth Value

    if (valorDoBluetooth == 'F' || valorDoBluetooth == 'T' || valorDoBluetooth == 'D' || valorDoBluetooth == 'E' || valorDoBluetooth == 'P')  // if SerialBt recieved movement value
    {
      movimento(); // movement
    }
  }
}

void movimento() {
  if (valorDoBluetooth == 'F') {
    Serial.println("Frente");  // Forward
    frente();
  } else if (valorDoBluetooth == 'T') {
    Serial.println("Trás");  // Backwards
    tras();
  } else if (valorDoBluetooth == 'D') {
    Serial.println("Direita");  // Right
    direita();
  } else if (valorDoBluetooth == 'E') {
    Serial.println("Esquerda");  // Left
    esquerda();
  } else if (valorDoBluetooth == 'P') {
    Serial.println("Parar");  // Stop
    parar();
  }
  delay(1);
}

void frente() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, velocidade);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  digitalWrite(enB, velocidade);
}
void tras() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(enA, velocidade);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(enB, velocidade);
}
void direita() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(enA, velocidade);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
  digitalWrite(enB, velocidade);
}
void esquerda() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, velocidade);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(enB, velocidade);
}
void parar() {
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(enA, velocidade);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(enB, velocidade);
}
```

To be able to control it via the PC keyboards, I connected the PC to the device through bluetooth, then see which COM it is connected to in bluetooth configurations of control panel, and use this the COM number on a Python code that's able to communicate with the device.

The Python code is as follows:
```
import serial
import time
import keyboard

# Replace 'COMX' with the actual COM port assigned to the HC-05 module / Esp device on your PC. More info at https://pyserial.readthedocs.io/en/latest/shortintro.html
ser = serial.Serial('COM8', 9600, timeout=1)

flagMovido = True # flag that checks if the motors are finished moving before changing directions

def controle(event):
    global flagMovido

    if event.event_type == keyboard.KEY_DOWN: # if a key is pressed:
        if (event.name == "w" or event.name == "a" or event.name == "s" or event.name == "d") and flagMovido: # if movement keys are pressed and motors are finished moving to any other direction:
            flagMovido = False # motors started moving

            if event.name == "w" and not flagMovido:
                ser.write(b'F')

                print('frente') # Forward

            elif event.name == "a" and not flagMovido:
                ser.write(b'E')

                print('esquerda') # Left

            elif event.name == "s" and not flagMovido:
                ser.write(b'T')

                print('trás') # Backwards

            elif event.name == "d" and not flagMovido:
                ser.write(b'D')

                print('direita') # Right

    elif event.event_type == keyboard.KEY_UP: # if a key is released:
        if (event.name == "w" or event.name == "a" or event.name == "s" or event.name == "d") and not flagMovido: # if movement keys are released and motors are moving to some direction

            flagMovido = True # motors are finished moving

            ser.write(b'P')

            print('parado') # Stop

print('START')

def main():
    while True:
        data = ser.readline().decode().strip()

        keyboard.hook(controle)
        time.sleep(.001)

        if data:
            print(f"Recebido: {data}") # prints data if any received. Used to print the sensor values received.

if __name__ == "__main__":
    main()
```
obs:
* The code runs fine, but may present some problems if you press to many keys at a time, since it was made to handle one direction at a time. But the movement bools will help with that and prevents it from happening to certain extent. Though in specific cases is should be improved.
* I ended up using a HC05 module with Arduino, but the code also woks for Esp. But if connecting to an Esp, the ```ser = serial.Serial('COM8', 9600, timeout=1)``` line should be changed to the way it connects to the Esp. More info at the link provided.


message:
Lilypad sends corrupted data on Serial

I have an Arduino Lilypad with this simple code where I try to write a simple message to the serial console. The baud rate is set to 9600 both in the code as well as in the serial console and I'm using the [FTDI UART tool](https://www.sparkfun.com/products/10275).
However, the output I'm receiving is corrupted and I'm not sure what could be the cause. Any ideas or suggestions are welcome. Thanks!

```

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

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

```

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

Arduino is connected to the FTDI tool as shown here [![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/erAtj.png
  [2]: https://i.stack.imgur.com/axOsO.png

body:
It looks like the wrong baud rate. That often results in garbage characters. You said in a comment that halving the baud rate on the Arduino end seemed to synchronize the baud rates, and you could see proper characters.

I'm a bit puzzled by that because you were evidently able to upload the sketch in the first place. Therefore the baud rate was correct during the uploading process.

Looking in the file `boards.txt` which you should find somewhere in your Arduino installation, there appear to be a number of Lilypad variants. Perhaps you inadvertently chose the wrong one in the "Board" menu in the IDE?

It looks like the correct baud rate was used for the uploading, but the code generated by the compiler (because of settings passed by the IDE) thought that the board was running at half the speed it actually was (so it set the baud rate clocks to run faster), so by reducing the baud rate in the Serial.begin they became in sync.

You could just live with the difference, or try experimenting with choosing different Lilypad board types.

If the baud rate is wrong, probably the delays will be wrong too, whether or not that matters is up to you.


message:
Addressable LEDs using SM16704

I've been asked to interface with some LED strips that use SM16704 pixel chips.

A site search here doesn't show any mentions of this chip, so I wonder if anyone knows if they're compatible with the more common ones like WS281x and can be addressed using FastLED or other library?

Edit:

**[Here's][1]** the datasheet for the -PB version of the chip. I can't find one for a plain 16704 but I don't think the protocol is any different.

  [1]: http://www.jad-leds.com/web/userfiles/download/SM16704PB-Datasheet.pdf

body: The best data I can find says that this chip / protocol is compatible with the WS2813 and should require only a minor tweak, if any.


message:
How to detect, if Serial is really connected to listening PC program? (on atmega32u4)

How to detect, if **Serial** is really connected to listening PC program? (on **atmega32u4**)

I need to connect from PC to **Arduino Micro Pro** over USB `Serial` and disconnect again and not slow down the Arduino with timeouting on all `Serial.print`.

## Difference from other ##
Not same as https://arduino.stackexchange.com/questions/42977/arduino-leonardoatmega32u4-detecting-if-usb-is-connected-to-a-computer
* difference is what should happen after disconnecting PC program
    * "it is still connected to PC" (so it is **OK**, solved there)
    * "it is not listend to" and timeouting (so it is **BAD**, asked **here**)
* I tried the both solutions mentioned there (UDADDR & _BV(ADDEN)) and (USBSTA & _BV(VBUS)) as well as (Serial) - it behave the same from my point of view
    * fast before `screen` connects, fast when `screen` connected, **slow** after `screen` ends, fast when `screen` reconnected

## Details ##
I have **Arduino Micro Pro** managing a lot of things at its own, but I want sometimes connect to it via USB from my computer. I open `screen /dev/ttyACM0 115200` and get a lot of debugging info and so on. Then I close the `screen` and let it work in peace. But there is problem with timeouts - when I stop listening, it waits for me and everything is terribly slow, until I connect there again.

Here is my loop
```c++
 void loop() {
  DoSomethingImportant(); // it works
  StatusOff(); // Green LED off, Yellow On
  if (displayTime()) {  // print debug only on new second
   if (Serial) {   // ######## If there is somebody listening ... #########
    Serial.print(F("Ctrl: "));Serial.print(W00.Used());
    Serial.print(F("); R1/W1: "));Serial.print(R01.Used());Serial.print(F("/"));Serial.print(W01.Used());Serial.print(F(" ("));Serial.print(R01.Total_Count());Serial.print(F("/"));Serial.print(W01.Total_Count());
    Serial.print(F("); R2/W2: "));Serial.print(R02.Used());Serial.print(F("/"));Serial.print(W02.Used());Serial.print(F(" ("));Serial.print(R02.Total_Count());Serial.print(F("/"));Serial.print(W02.Total_Count());
    Serial.print(F("); R3/W3: "));Serial.print(R03.Used());Serial.print(F("/"));Serial.print(W03.Used());Serial.print(F(" ("));Serial.print(R03.Total_Count());Serial.print(F("/"));Serial.print(W03.Total_Count());
    Serial.println(F("); "));
   };
  };
  StatusOn(); // Green LED on, Yellow Off
 }
```
## Problem ##
When I connect the Arduino to PC (so it gets powered, I do not have much of the rest HW completed yet), it starts to do Something Important as fast as it can and every second the yellow LED blinks too fast to see that Green was off. It is OK.

Then I connect with `screen /dev/ttyACM0 115200` and it gets new long line every second. Still the Green looks all time on and Yellow can be seen just blink. Still OK.

Then I end `screen` and it went **slow** - Yellow is on for like 7 second, while Green is on for 1 sec. And it is BAD.

Then I connect with `screen /dev/ttyACM0 115200` and it gets new long line every second. The Green looks all time on and Yellow can be seen just blink. Again OK.

## Question ##
How to detect, if I am connected or not?

Or maybe better, how to prevent the terrible slowdown, when I am not connected?

body:
I can reproduce this on Ubuntu, however it seems to be an anomaly of the screen program. If I use this small Python program to listen to the port, the Micro doesn't seem to slow down.

<!-- language: lang-python -->

    import serial

    ser = serial.Serial('/dev/ttyACM0', 115200)  # Adjust the serial port accordingly

    while True:
        if ser.readable():
            line = ser.readline().decode().strip()
            print (line)

You may need to import pyserial into Python, for example:

<!-- language: lang-bash -->

    python -m pip install pyserial

My Arduino test code was:

<!-- language: lang-c++ -->

    const byte LED_PIN = 5;  // some pin for an LED

    void setup() {
      Serial.begin (115200);
      pinMode (LED_PIN, OUTPUT);

    }

    void loop() {
      digitalWrite (LED_PIN, HIGH);
      delay (250);
      digitalWrite (LED_PIN, LOW);
      delay (250);

      Serial.println(F("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
       "Ut molestie quam cursus, feugiat massa eget, lobortis ante.\n"
       "Nulla semper nisi a pretium finibus. Proin rutrum accumsan massa sit amet gravida.\n"
       "Etiam mollis, ipsum ac sagittis aliquam, sem urna euismod ipsum,\n"
       "eget accumsan orci sapien ornare felis. Nulla ex felis, facilisis in tincidunt at,\n"
       "dignissim vitae ligula. Aliquam facilisis tristique velit,\n"
       "a scelerisque turpis mollis quis. Nulla porta, mi vel ornare feugiat,\n"
       "mauris ligula commodo felis, in congue orci neque a est. "));

    }

By looking at the rate of flashes of the LED I can see that it doesn't slow down when running the Python program, or if you Ctrl+C to exit the Python program.

However it does slow down if you attach to the USB using `screen` and then kill it.

---

I don't think the Arduino can per se know whether or not a program on the PC happens to be listening to the USB port or not. That is a function of what is happening in the operating system, not a function of the USB hardware.

---

Another approach which I haven't tested might be to get your Python program to periodically (eg. for each line) send a character, and get the Arduino to check for serial input. If no serial input (ie. not prompting character) then don't echo the debugging data.

---

Another approach (and possibly the simplest) is just to have a switch on the micro on a spare port, and close the switch if you want debugging information, and open it if you don't. Then you have total control over the debugging.


body:
Thanks to Nick Gammon for his answer, the problem is really in the `screen` program.

There is detailed explanation from Majenko in
https://arduino.stackexchange.com/questions/20836/ifserial-not-working-correctly-on-micro-or-pro-micro

The problem is, that some programs (like `screen`) or some systems, or drivers, or so do not pull down `RTS` and `DTR` signals for Micro. (The `DTR` down is supposed to restart Uno and other non-USB arduinos).

It could be solved by running some small program to `close` the USB Serial properly after the `screen` is done with it - here are two which works for me

C program

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>

    int main(int argc, char *argv[]) {
            // Check if the correct number of command-line arguments is provided
            if (argc != 2 ) {
                    fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
                    fprintf(stderr, "  %s /dev/ttyACM0 - close USB Serial for Arduino on the port\n", argv[0]);
                    return 1; // Return an error code
            }
            int fd;
            fd = open(argv[1],O_RDWR | O_NOCTTY );//Open Serial Port

            int RTS_flag;
            RTS_flag = TIOCM_RTS;

            int DTR_flag;
            DTR_flag = TIOCM_DTR;

    //      ioctl(fd,TIOCMBIS,&RTS_flag);//Set RTS pin
    //      ioctl(fd,TIOCMBIS,&DTR_flag);//Set DTR pin

            ioctl(fd,TIOCMBIC,&RTS_flag);//Clear RTS pin
            ioctl(fd,TIOCMBIC,&DTR_flag);//Clear DTR pin
            close(fd);
    }

Python

    #!/usr/bin/python -u

    import serial
    import sys

    # Check if the correct number of command-line arguments is provided
    if not len(sys.argv) in {2,3}:
            print("Usage: {} <filename> [baudrate]".format(sys.argv[0]))
            print(" {} /dev/ttyACM0 - close USB Serial for Arduino on the port".format(sys.argv[0]))
            sys.exit(1)  # Exit with a non-zero error code

    # Get the filename from the command-line argument
    baudrate=115200
    filename = sys.argv[1]
    if len(sys.argv) > 2:
            baudrate=sys.argv[2]

    # Open the serial port
    ser = serial.Serial(filename, baudrate, xonxoff=False , rtscts=True , dsrdtr=True )
    ser.rts=False
    ser.dtr=False


message:
Arduino pulls i2c bus down

I am building an airplane. As a controller I am using a Raspberry pi 4. There are 3 sensors (MPU6050, QMC5883L, BME280) and arduino pro mini connected to the raspberry via i2c. When sending requests to the arduino it pulls the bus to 0 and shuts down(?).

- First screenshot. On the first search for all devices on the bus, the arduino responds and shuts down, but does not pull the bus to 0. On the second search It responds and pulls the bus to 0.

- Second screenshot. Rebooting the arduino, the SDA line goes up. Repeated runs of the search leads to what is shown in the first screenshot.

- Third screenshot. The arduino generates a PWM signal that is interrupted after a request to i2c.

As a test request I use the i2cdetect command on the Raspberry.
Raspberry is connected to the sensor bus through a level converter, because the level of signals from Raspberry is 3.3V, and sensors accept 5 volt logic.

There is no bus pull-up to the upper level, it is on the schematic of all sensors used (will it be enough?).

The arduino has a simple slave i2c device code, writing to registers the value arrived and output it to other elements (servo drives, motor controller, stepper motor drivers). The Arduino acts as a port expander because the Raspberry has only 2 buses and too few outputs for all the necessary devices

Why is the bus falling and how can I fix it?

arduino code
```c++
    #include <Wire.h>
    #include <Servo.h>
    #include <Stepper.h>

    uint16_t servoAngle1 = 90;
    uint16_t servoAngle2 = 90;
    uint16_t servoAngle3 = 90;
    uint16_t servoAngle4 = 90;

    bool zoomIn = false;
    bool zoomOut = false;

    bool focusIn = false;
    bool focusOut = false;

    Servo servo1;
    Servo servo2;
    Servo servo3;
    Servo servo4;

    Servo ESC;

    Stepper zoomMotor(100, 2, 4, 7, 8);
    Stepper focusMotor(100, 10, 11, 12, 13);

    void setup() {
      Wire.begin(0x23);
      Wire.onReceive(receiveEvent);

      servo1.attach(3);
      servo2.attach(5);
      servo3.attach(6);
      servo4.attach(9);
      ESC.attach(11, 1000, 2000);
    }

    void loop() {
      servo1.write(servoAngle1);
      servo2.write(servoAngle2);
      servo3.write(servoAngle3);
      servo4.write(servoAngle4);
      ESC.write(0);
      if (zoomIn) {
        zoomMotor.step(100);
        zoomIn = false;
      }
      if (zoomOut) {
        zoomMotor.step(-100);
        zoomOut = false;
      }

      if (focusIn) {
        focusMotor.step(100);
        focusIn = false;
      }
      if (focusOut) {
        focusMotor.step(-100);
        focusOut = false;
      }
    }

    void receiveEvent(int howMany) {
      if (howMany == 2) {
        uint8_t action = Wire.read();
        uint8_t value = Wire.read();

        if (action == 1) { servoAngle1 = value; }
        if (action == 2) { servoAngle2 = value; }
        if (action == 3) { servoAngle3 = value; }
        if (action == 4) { servoAngle4 = value; }

        if (action == 10) {
          if (value == 1) { zoomIn = true; }
          if (value == 2) { zoomOut = true; }
        }

        if (action == 11) {
          if (value == 1) { focusIn = true; }
          if (value == 2) { focusOut = true; }
        }
      } else {
        while (true) {
          Wire.read();
        }
      }
    }
```

**Screenshot 1**
[![screenshot 1][2]][2]

**Screenshot 2**
[![screenshot 2][3]][3]

**Screenshot 3**
[![screenshot 3][4]][4]

**and wiring diagram**
[![wiring diagram][1]][1]

  [1]: https://i.stack.imgur.com/Frk6W.jpg
  [2]: https://i.imgur.com/bqCf4FN.png
  [3]: https://i.imgur.com/n0wGO3m.png
  [4]: https://i.imgur.com/ADLoDgB.png

body:
For I2C to work there needs to be pull-ups on SDA and SCL somewhere (not one for each device). Typically 4.7k resistors or thereabouts would be used.

Also you need a bi-directional voltage level translator. An example schematic is:

[![Bi-directional level shifter][1]][1]

Image credit: [Sparkfun: Bi-Directional Logic Level Converter Hookup Guide ](https://learn.sparkfun.com/tutorials/bi-directional-logic-level-converter-hookup-guide/all)

This is because I2C devices actively pull SDA and SCL low, however they rely on the pull-up resistors to pull them high. Also this won't work unless the voltage level shifter is bi-directional.

For more information see the [Philips Application Note AN97055 - Bi-directional level shifter for I²C-bus and other systems.](https://cdn.sparkfun.com/tutorialimages/BD-LogicLevelConverter/an97055.pdf)

If you use the level shifter you need pull-up resistors on both the 3.3V part and the 5V part of the circuit (shown as Rp below).

[![Philips Application Note AN97055][2]][2]

  [1]: https://i.stack.imgur.com/3fEFX.png
  [2]: https://i.stack.imgur.com/EpUxY.png


message:
Code not Executing Reliably on Push Button Activation

I have put together the following code to activate a motor using an Arduino Uno via  push buttons.
- Two push buttons should be pressed simultaneously to activate the motor for a specified number of steps,
- then when both buttons are pressed again the motor will spin in reverse, returning the motor to its original position.

The code works, but not every time the button is pressed. I've gone through every line of the code and can't seem to find the issue. I know that the connections are correct since the code executes sometimes, but I don't know if there is an error in the code causing the unreliable response or if I have faulty/cheap push buttons with bad connections.

```c++
    #include <Bounce2.h> // Include the Bounce2 library

    // Define stepper motor connections:
    #define dirPin 3
    #define stepPin 2
    #define motorEnablePin 4 // Motor driver's enable pin
    #define buttonPin 8 // Push button connected to pin 8
    #define buttonPin2 9 // Push button connected to pin 8

    boolean motorRunning = false; // Flag to track motor rotation
    boolean oddRotation = true; // Flag to track odd/even rotations

    // Create a Bounce object for the button
    Bounce debouncer1 = Bounce();
    Bounce debouncer2 = Bounce();

    void setup() {
      // Declare pins as output or input:
      pinMode(stepPin, OUTPUT);
      pinMode(dirPin, OUTPUT);
      pinMode(motorEnablePin, OUTPUT); // Enable pin as output
      pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor for the button
      pinMode(buttonPin2, INPUT_PULLUP); // Use internal pull-up resistor for the button
      digitalWrite(dirPin, LOW); // Set the spinning direction CW/CCW
      digitalWrite(motorEnablePin, HIGH); // Disable motor driver initially

      // Attach the debouncer to the button pin
      debouncer1.attach(buttonPin);
      debouncer2.attach(buttonPin2);
      debouncer1.interval(50); // Set debounce time
      debouncer2.interval(50);
    }

    void loop() {
      // Update the debouncer
      debouncer1.update();
      debouncer2.update();

      if (debouncer1.fell() && debouncer2.fell()) {
        // Button pressed and motor is not running, initiate motor rotation
        motorRunning = true;
        oddRotation = !oddRotation; // Toggle the rotation direction

        int stepsPerRevolution = 200; // Number of steps for one full revolution
        int desiredRevolutions = 10;  // Number of desired revolutions
        int totalSteps = stepsPerRevolution * desiredRevolutions;
        int stepCount = 0; // Counter for the steps taken

        // Set the motor rotation direction
        digitalWrite(dirPin, oddRotation ? LOW : HIGH);

        // Enable the motor driver
        digitalWrite(motorEnablePin, LOW);

        while (stepCount < totalSteps) {
          // Rotate the motor
          digitalWrite(stepPin, HIGH);
          delayMicroseconds(600);
          digitalWrite(stepPin, LOW);
          delayMicroseconds(600);

          stepCount++;

          // If the desired number of rotations is reached, stop the motor
          if (stepCount >= totalSteps) {
            // Disable the motor driver
            digitalWrite(stepPin, LOW);
            digitalWrite(motorEnablePin, HIGH);

            // Reset the flag to stop motor rotation
            motorRunning = false;
          }
        }

        // Disable the motor driver when idle
        digitalWrite(motorEnablePin, HIGH);
      }
    }
```

body:
Bounce.fell() returns true only if the input fell since the last update(). So your code will only work if both buttons are pressed at exactly the same time.

I suggest that you record the time at which each button is pressed and execute your code if the press times are less than 100ms apart. That should give reliable operation.

You can test if this is the problem simply by removing the debouncer2.fell() call. The code should then work reliably when only button 1 is pressed.