message:
Custom LED toggling function: one out of three LEDs misbehave

I connected three LEDs to an Arduino Uno and wrote a simple LED class. I toggle all the leds the main loop, but for some reason **one led (connected to pin7) always misbehaves**, skips one toggle or stays on all the time. Initially all leds are off (in begin() function). What could cause this problem?

**main.cpp**
```
#include "led.h"
#include <Arduino.h>

Led leds[] = {
    Led(2),
    Led(3),
    Led(7)
};

void setup()
{
    Serial.begin(9600);
    for (Led& l : leds) l.begin();
}

void loop()
{
    for (Led &l : leds) l.toggle();
    delay(500);
}
```

**Led.h**
```
class Led {
public:
    Led(int pin);
    void begin();
    void toggle();

private:
    const int _pin;
};
```
**Led.cpp**
```
#include "led.h"
#include "Arduino.h"

Led::Led(int pin) : _pin(pin)
{}

void Led::begin()
{
    pinMode(_pin, OUTPUT);
    digitalWrite(_pin, LOW);
}

void Led::toggle()
{
    digitalWrite(_pin, !digitalRead(_pin));
}
```

body:
It seems to be a hardware fault, as others have suggested:
I connected the LED to another pin(8) and it works perfectly, everytime.
Looks like something got fried internally on that specific pin


sender: user

message:
Help to set vertical dcroll on SSD1306

I am trying to set the text to scroll vertically. I have a big chunk of text (example in the code below) to be set to scroll vertically. What I want is to display the complete text on the screen. Presently it scrolls the complete chunk of text. Any help or guidance is heartily welcome.

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

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

    // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
    // The pins for I2C are defined by the Wire-library.
    // On an arduino UNO:       A4(SDA), A5(SCL)
    // On an arduino MEGA 2560: 20(SDA), 21(SCL)
    // On an arduino LEONARDO:   2(SDA),  3(SCL), ...
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    void setup() {
      Serial.begin(9600);
      display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
      display.clearDisplay();

      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0, 0);
      display.println("Sometimes we dont want to scroll entire display. ");
      display.startscrollright(0x00, 0x0F);

      display.display();

      delay(1000);
    }
    void loop(){

    }

The link to the project is here: https://wokwi.com/arduino/projects/302023407584674313

**3rd edit**

My question:

My goal is to display the text in the window. The text should not go out of the window.  If the text is too long, it should scroll vertically.

Thanks again, everyone.

sender: assistant

body:
This line achieved it for me. I stole it from here: [Adafruit Forum][1]

```
display.startscrolldiagright(0x0F, 0x0F);
```
It sets diagonal scroll, but start and stop positions are multiples of the display width so that in total, it scrolls vertically up.

Alternatively, you edit the display buffer; by removing your content from the current position, deleting the first line of pixels, adding a new last line of pixels, writing it all back to the display buffer and then call ```display.display()```.

This is not exactly saving your microcontroller time but it works, too. I asked ChatGpt to do the coding for the second solution, it delivered. I won't post the code here though, as it is against the rules.

  [1]: https://forums.adafruit.com/viewtopic.php?f=47&t=133759


message:
How do I read from a correct data address of LIDAR using Arduino in I2C?

I need to read the distance data from a lidar in I2C using an Arduino Nano. Currently, this is the code I've written.

    unsigned int readDistance()
    {
      unsigned int dist = 0 ; // LiDAR actually measured distance value. static so we can return previous dist

      // step 1: instruct sensor to read echoes
      Wire.beginTransmission(0x10) ; // transmit to device 0x10
      Wire.write(2) ; // sets distance data address (addr)
      Wire.write(3) ; // sets distance data address (addr)
      Wire.endTransmission() ; // stop transmitting

      // step 2: wait for readings to happen
      delay(100) ; // datasheet suggests at least 100ms

      // step 3: request reading from sensor
      Wire.requestFrom(0x10, 2) ; // request 2 bytes (DIST_L, DIST_H) from slave device #0x10
      dist = Wire.read() ; dist += Wire.read() << 8; // calculate distance value, bit shift high distance
      return dist ; // return updated dist
    }

But I have a feeling I'm requesting from the wrong data address', since I'm not getting the results I expect (ie. varying distance data). Furthermore, I used an I2C scanner which 100% confirms the lidar is on the (default address) of 0x10.

Datasheet of (TF02 Pro): https://www.unmannedtechshop.co.uk/wp-content/uploads/2020/01/TF02-Pro-Product-Manual-Alpha.pdf

**Question: am i reading from the right data address**
Any help would be appreciated.

body:
Long story short, some i2c devices are configured such that data is only present in said registers after continually issuing 'read commands'.

In this case, the read command was: 5A 05 00 01 60

Amended code:

    unsigned int readDistance()
    {
      unsigned int dist = 0 ; // LiDAR actually measured distance value

      // step 1: instruct sensor to read echoes
      Wire.beginTransmission(0x10) ; // transmit to device 0x10
      Wire.write(0x5A) ; // some read command.
      Wire.write(0x05) ;
      Wire.write(0x00) ;
      Wire.write(0x01) ;
      Wire.write(0x60) ;
      Wire.endTransmission() ; // stop transmitting

      // step 2: wait for readings to happen
      delay(100) ; // datasheet suggests at least 100ms

      // step 3: request reading from sensor
      Wire.requestFrom(0x10, 4) ; // request first 4 bytes from slave device #0x10
      Wire.read() ; Wire.read() ; //ignore header bytes
      // remaining two bytes for distance (DIST_L, DIST_H)
      dist = Wire.read() ; dist += Wire.read() << 8 ; // calculate distance value, bit shift high distance
      return dist ; // return updated dist
    }


message:
My Arduino UNO works, but 2 smd overheats. Why?

I can use my Arduino with the usb plug, but 2 smd overheating when I plug into the computer, But when I use the DC plug, the leds on the Arduino barely visible (for example the "ON" led), so the arduino is only works with the USB plug.

[![These are the 2 sms-s which overheats.][1]][1]

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

body:
These look like C2 and C3 in the [Arduino UNO R3 schematic][1]. It *sounds* like both are internally shorted.

Assuming that's true, why it would work (partially anyway) on USB but not external power would depend in part on what external voltage had been applied.  The voltage seen on the board, and therefore the brightness of your LEDs, depends on the voltage being dropped above their source.  That is, it depends on what's happening to the PTC fuse and in the USB host port and cable etc for USB.  And in the linear regulator and similar current limiting in series with it.  Probably the thermal overload protection in your regulator is shutting it down so hard that the LEDs don't even light.  Or whatever event cause this problem happened while you were externally powering it and there's now an open somewhere on the side external powering.

For now it's probably better if you're not continuing to plug it into a PC.  If you're going to do that, it's probably better that you have a powered hub that you don't care about in between.

This seems to be the 3.3V regulator.  If you're not using 3.3V, you may be able to get a soldering iron and through-heat the capacitors and scrape them off the board and see whether or not the rest of the board, the 5V section, works fine.  Before you do that you may want to measure the 5V and 3.3V lines and write down what you get.  One or both are probably low.  Take note of the USB source you're using.  Try taking off the capacitor off the output side of the regulator first, see how things go.  Then go for the input side one.  From the sounds of it both are bad though.  But it can't hurt to go methodically.

  [1]: https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf


message:
How to write nonblocking code, for polling sensor at 100 Hz

I'm using this piece of code to try to poll an IMU sensor at 100 Hz (for a AHRS sensor fusion library).

    void loop(void)
    {
      // nonblocking code variables
      static uint32_t last_ms;
      uint32_t ms;
      // delay between samples
      ms = millis();
      if (ms - last_ms < 10) return;
      last_ms = ms;

      sensor_data (); //...

My 1st question is should I be declaring `last_ms` as a global variable instead of static?

Also, should this code be at the beginning or end of loop? My understanding is we are basically checking how long the previous loop took. And if it took less than 10 ms (100 Hz) we do nothing. But doesn't that mean that we might still get deviation from 100 Hz due to the time it takes to complete loop (about 2-5ms in my case), so effectively it's 10 ms + loop complete time?

Sorry if this is a stupid question.

body:
The time range your sensor code will be executed is 10ms to 10ms + the execution time of the first part of the loop (until the return) and the execution time outside of `loop()`. These additional times don't always apply, but in the worst case you can have up to that additional delay (because it means you are checking the `millis()` value only so often).

The mentioned additional delay is rather short (microseconds realm). Your sensor code is only executed, when the time is reached. As long as you don't disable interrupts, the Timer0 interrupt will continue to count further for `millis()`, so its value will increase independently from the execution time of your sensor code.

That is as long as the sensor code also doesn't take longer than 10ms (or a bit less, accounting for some overhead). As your sensor code only takes up to 5ms (according to your question), you should be safe here.

If `millis()` is accurate enough for you I cannot say. Thats up to your exact requirements. For more accurate timing an own timer interrupt would be better, though that also limits you with what you can do. Inside an interrupt you cannot execute code, that relies on interrupts (like communication over Serial or I2C). Depending on your sensors using your above code is already enough and should work good.

> should I be declaring last_ms as a global variable instead of static?

There is no definitive answer to that, but generally it is good to limit the scope of variables to the minimum needed (to avoid possible conflicts). `last_ms` is not needed anywhere else, so creating it locally and static is a good way to do it. Memory wise it doesn't really make a difference.


body:
> should I be declaring `last_ms` as a global variable instead of
> static?

Local static is better, as it limits the scope of the variable to just
where it is needed. Consider making it global only if the code is part
of a tutorial meant for beginners which may be confused by the keyword
`static`.

> should this code be at the beginning or end of loop?

The conditional early return only makes sense if `loop()` has nothing
more to do once the sensor data is handled, thus this should go at the
very end of `loop()`. However, if `loop()` does more than just handle
this data, I think it would be cleaner to avoid the early return: either
put this in a separate function (which can return early), or condition
the handling of the sensor on `ms - last_ms >= 10`.

> My understanding is we are basically checking how long the previous
> loop took.

No. The test is looking at how much time has elapsed since the previous
time `last_ms` was updated, which could be many `loop()` iterations ago.

> But doesn't that mean that we might still get deviation from 100 Hz
> due to the time it takes to complete loop (about 2-5ms in my case), so
> effectively it's 10 ms + loop complete time?

Indeed. With this logic, 10 ms is the _minimum_ time between calls
to `sensor_data()`. If you want to ensure an accurate _average_ polling
time, you should update `last_ms` by adding 10. You will still have
sole jitter though.

A small note about `millis()`: since the value is updated every
1.024 ms, it occasionally has to jump by two units at once, and has
therefore 1 ms of jitter. For a period as short as 10 ms, I
would rather use `micros()`. For example:

```c++
const uint32_t POLLING_PERIOD = 10000;  // 1e4 us = 10 ms

// Call this from loop()
void handle_sensor()
{
    static uint32_t last_us;
    if (micros() - last_us < POLLING_PERIOD) return;
    last_us += POLLING_PERIOD;
    sensor_data();
    // ...
}
```

**Edit**: About why `last_us` has to be incremented by a constant
amount, consider this alternative:

```c++
void handle_sensor()
{
    static uint32_t last_us;
    uint32_t now = micros()
    if (now - last_us < POLLING_PERIOD) return;
    last_us = now;
    sensor_data();
    // ...
}
```

The code following the `if ... return;` line will be executed when the
tested condition is false, i.e. when `now - last_us >= POLLING_PERIOD`.
It may happen that we sometimes have strict equality (`now - last_us ==
POLLING_PERIOD`) but, since any code execution takes time, sometimes
`now - last_us` will be strictly larger than `POLLING_PERIOD`. Every
time this happens `last_us` will be incremented by _more_ than
`POLLING_PERIOD`. This means that the small timing errors accumulate.

If, instead, `last_us` is updated by adding a constant amount, we still
have timing errors (because of the time needed to execute any code), but
they are not cumulative. In other words, we have jitter, but the
_average_ polling frequency is right.


message:
ESP32 send data while blinking LED

Can I program my ESP32 to send a string MQTT data while also blinking the InBuilt LED?

If yes, then how to do so

Thanks in advance

body:
The ESP32 have two core, each core can do diferents tasks. Then, you can send data with one core and blink the LED with another core.

To do this, you need to use a multicore programming. I recommend to use the `FreeRTOS` (ESP32 support this). [See more](https://www.freertos.org/).

Look the example "Let's multitask: Blink with Hello" [here](https://exploreembedded.com/wiki/Hello_World_with_ESP32_Explained), is that what  you want.

Read the [documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html) about the `FreeRTOS` in ESP32.

Example in Arduino IDE:
```
#include <Arduino_FreeRTOS.h>

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *)"Blink"   // A name just for humans
    ,  128  // Stack size
    ,  NULL
    ,  2  // priority
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  (const portCHAR *) "AnalogRead"
    ,  128 // This stack size can be checked & adjusted by reading Highwater
    ,  NULL
    ,  1  // priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
  }
}

void TaskAnalogRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  for (;;)
  {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);
    // print out the value you read:
    Serial.println(sensorValue);
    vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
  }
}
```
[Reference](https://create.arduino.cc/projecthub/feilipu/using-freertos-multi-tasking-in-arduino-ebc3cc).


message:
MKR1400-how do I troubleshoot a POST request?

I'm successfully sending a GET request (in the setup function, to load certificates,) but my POST request fails with a bunch of AT errors. I suspect this has to do with the way I'm formatting the POST. Any ideas would be appreciated.

Code follows:

    // MKRGSM - Version: 1.5.0
    #include <MKRGSM.h>
    #include <ArduinoJson.h>
    #include <Arduino_MKRGPS.h>

    const char PINNUMBER[]     = "";
    // APN data

    const char GPRS_APN[]      = SECRET_GPRS_APN;

    const char GPRS_LOGIN[]    = "";

    const char GPRS_PASSWORD[] = "";

    DynamicJsonDocument doc(1024);

    // initialize the library instance

    GSMSSLClient client;

    GPRS gprs;

    GSM gsmAccess(true);

    // Specify IP address or hostname

    char server[] = "webhook.site";
    char path[] = "/ce480c43-95a8-4f1e-b996-bc02f6d1adaa";
    int port = 443;

    void setup() {

      // initialize serial communications and wait for port to open:

      Serial.begin(9600);

      while (!Serial) {

        ; // wait for serial port to connect. Needed for native USB port only

      }

      // If you are using the MKR GPS as shield, change the next line to pass

      // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
      delay(200);

      if (!GPS.begin()) {

        Serial.println("Failed to initialize GPS!");

        while (1);

      }
      Serial.println("Starting Arduino GSM ping.");
      // connection state
      bool connected = false;

      // After starting the modem with GSM.begin()
      // attach the shield to the GPRS network with the APN, login and password
      while (!connected)
      {
        if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
            (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY))
        {
          connected = true;
        }
        else
        {
          Serial.println("Not connected");
          delay(1000);
        }
      }

      Serial.println("connecting...");

      // if you get a connection, report back via serial:
      // Use this to load Root Certs the first time
      if (client.connect(server, port))
      // Use this to not load Root Certs anymore as done last time and stored in modem's flash
    //  if (client.connect(server, port, false))
      {
            Serial.println("connected");

        // Make a HTTP request:

        client.print("GET ");

        client.print(path);

        client.println(" HTTP/1.1");

        client.print("Host: ");

        client.println(server);

        client.println("Connection: close");

        client.println();
      }
      else
      {
        // if you didn't get a connection to the server:
        Serial.println("connection failed");
      }
    }

    void loop() {

      ...GPS stuff happens here

      // print GPS values

      Serial.println();

      Serial.print("Location: ");

      Serial.print(latitude, 7);

      Serial.print(", ");

      Serial.println(longitude, 7);

      Serial.print("Altitude: ");

      Serial.print(altitude);

      Serial.println("m");

      Serial.print("Number of satellites: ");

      Serial.println(satellites);

      doc["latitude"] = latitude;
      doc["longitude"] = longitude;
      doc["altitude"] = altitude;

      String location;
      serializeJson(doc, location);
      Serial.print("Location string: ");
      Serial.println(location);

      Serial.println();

      Serial.println("Starting Arduino web client.");

      // connection state

      if (client.available()) {
        Serial.println("Sending location");
        client.print("POST ");
        client.print(path);
        client.println(" HTTP/1.1");
        delay(5);
        client.println("Content-Type: application/json;");
        delay(5);
        client.print("Content-Length: ");
        client.println(location.length());
        client.print("Host: ");
        client.println(server);
        delay(5);
        client.println("Connection: close");
        delay(5);
        client.println();
        delay(5);
        client.println(location);
        Serial.print("Successfully sent location");

        if (!client.available() && !client.connected()) {

          Serial.println();

          Serial.println("disconnecting.");

          client.stop();
        }
      } else {
        // if you didn't get a connection to the server:
        Serial.println("connection failed");
      }

    }

Here's what the output looks like:

> Location: 32.1208382, 35.2468376 Altitude: 640.40m Number of
> satellites: 5 Location string:
> {"latitude":32.12084,"longitude":35.24684,"altitude":640.4}
>
> Starting Arduino web client. Sending location
> AT+USOWR=0,13,"504F53542068747470733A2F2F"
>
> ERROR
> AT+USOWR=0,37,"2F63653438306334332D393561382D346631652D623939362D626330326636643161646161"
>
> ERROR AT+USOWR=0,9,"20485454502F312E31"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR
> AT+USOWR=0,31,"436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E3B"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,16,"436F6E74656E742D4C656E6774683A20"
>
> ERROR AT+USOWR=0,2,"3539"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,6,"486F73743A20"
>
> ERROR AT+USOWR=0,12,"776562686F6F6B2E73697465"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,17,"436F6E6E656374696F6E3A20636C6F7365"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR
> AT+USOWR=0,59,"7B226C61746974756465223A33322E31323038342C226C6F6E676974756465223A33352E32343638342C22616C746974756465223A3634302E347D"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR

I could send the data as parameters in the GET query, but that's ugly.

body:
Your HTTP request is badly formatted.  You have:

```
POST https://webhook.site/ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Content-Type: application/json
```

Instead the protocol is implied by the port you are connecting to, and the domain name does *not* go in the path on the server component - it has its own header.

Your request should look more like:

```
POST /ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Host: webhook.site
Content-Type: application/json
Content-Length: [x]
Connection: close

[location]
```

Where `[x]` is `location.length()` and `[location]` is the content of the `location` string.


body: The problem was that ```GSM gsmAccess;``` needed to be ```GSM gsmAccess(true)```. Unfortunately, while that solves the immediate problem, which is that the client was not initializing, there are other issues which deserve a separate question.


message:
DC Motor Acceleration with PWM

I'm not sure why this has been so difficult for me, but I'm trying to control the acceleration of a 10v DC motor with an Arduino UNO and an L298n H-Bridge. Using a 12v regulated power supply to power the motor

For the life of me, I can't get a smooth acceleration/deceleration for this. I want the motor to move back and forth with a potentiometer, slowing down as it reaches the '0' and '10' positions. This works, but it's not very smooth

```
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;

const int speed1 = 85;
const int speed2 = 92;
const int speed3 = 100;
const int speed4 = 110;
const int speed5 = 130;
const int speed6 = 190;

int state = 0;

const byte wiper        = A0; //Position of fader relative to GND (Analog 0)
double faderMax = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
byte motorSpeed = 255;  // Raise if the fader is too slow (0-255)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)

void setup() {
  Serial.begin(250000);
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  analogWrite(motorPWM, motorSpeed);
  calibrateFader(); }

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, 155);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(wiper) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, 155);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(wiper) + tolerance;
  delay(2500); }

void loop () {
  moveMotorUp();}

void moveMotorUp() {
  while (analogRead(A0) <= 100) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 100) && (analogRead(A0) <= 200)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 200) && (analogRead(A0) <= 300)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 300) && (analogRead(A0) <= 400)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 400) && (analogRead(A0) <= 500)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 500) && (analogRead(A0) <= 600)) {
    analogWrite (motorPWM, speed6);
    digitalWrite (motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 600) && (analogRead(A0) <= 700)) {
    analogWrite (motorPWM, speed5);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
   while ((analogRead(A0) > 700) && (analogRead(A0) <= 800)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 800) && (analogRead(A0) <= 900)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 900) && (analogRead(A0) <= 1000)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while (analogRead(A0) > 1000) {
    analogWrite (motorPWM, speed1);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW);
    moveMotorDown(); } }

void moveMotorDown() {

  while (analogRead(A0) > 1000) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 900) && (analogRead(A0) <= 1000)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 800) && (analogRead(A0) <= 900)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 700) && (analogRead(A0) <= 800)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 600) && (analogRead(A0) <= 700)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 500) && (analogRead(A0) <= 600)) {
    analogWrite (motorPWM, speed6);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 400) && (analogRead(A0) <= 500)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 300) && (analogRead(A0) <= 400)) {
    analogWrite (motorPWM, speed4);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 200) && (analogRead(A0) <= 300)) {
    analogWrite (motorPWM, speed3);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 100) && (analogRead(A0) <= 200)) {
    analogWrite (motorPWM, speed2);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 10) && (analogRead(A0) <= 100)) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while (analogRead(A0) <= 10) {
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW);
    moveMotorUp(); } }
```

I hope it's simpler than this - Any ideas?
Thanks

body:
I think you need to think a little differently. Instead of "Move it at this speed until you get to here" you need to think more along the lines of "Where am I? Where do I want to get to? How far away is it?"

Basically the further you have to go the faster you want to go. The closer you get to your target value the slower you want to go.

Simply put - you want to convert the distance between your current and target positions into a proportional speed.

Take one variable: the target value that you want to get to. Take one reading: the current location of the fader. Subtract one from the other.

Take the sign of the result - that defines what direction you want the motor to turn in.  Take the "absolute" (`abs(...)`) value of the result - that is the distance you are away from your target.  Divide that absolute value by a speed factor to keep it within the range of your PWM, or lower if you want to go slower. Set the speed of the motor to that result.

So if you want to get to 0 and you are currently reading 1000 from the fader then:

* Difference = 0 - 1000 = -1000
* Sign is negative, so set direction to "down".
* Distance is `abs(-1000)`, or 1000.
* Divide by 4 (max ADC is 1023, max PWM is 255 - 1023/4 = 255) = 250
* Set speed to 250

Then a moment later you may be reading 738 from the ADC - so this time:

* Difference = 0 - 738 = -738
* Sign is negative, so set direction to "down".
* Distance is `abs(-738)`, or 738.
* Divide by 4 (max ADC is 1023, max PWM is 255 - 1023/4 = 255) = 184
* Set speed to 184

Keep doing that until you get to your target value (or within a certain tolerance of it) at which point you stop and wait for a new target value to be selected (or automatically change the target value as per your sweep demo - if 0 then set to 1023. If 1023 then set to 0).

This method then allows you to go directly to any value you choose with a deceleration as it approaches that target.


message:
Unwanted ghosting with charlieplexed LEDs

I have a very simple PCB that uses 3 GPIO on a ATtiny85 to control 6 LEDs using charlieplexing.

When I try to program certain patterns of lit LEDs (pseudo PWM) I get some LEDs lighting dimly when they should be fully off.

Example where only top or bottom three LEDs should be on alternately:

[![Video][1]][1]

You can see that LEDs 2 and 5 are dimly glowing rather than being fully off.

I do not have problems when lighting the LEDs one at a time in sequence.

I do not have problems lighting odd and even LEDs alternately.

The schematic is:

[![schematic][2]][2]

The buttons are used to change up and down through 6 modes of operation. Mode 0 lights the LEDs one at a time in sequence. Mode 1 alternates the odd and even LEDs. Mode 2 lights upper or lower three LEDs alternately (and has ghosting problem), the other modes just steadily illuminate the corresponding LED.

The code is split into several files:

main.ino:

~~~
Button leftButton = Button(3);
Button rightButton = Button(4);
Sequencer sequencer = Sequencer(200); // ms per step
Alternator alternator = Alternator(0b00101010, 0b00010101);

void setup() {
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
}

// ------------------------------------------------------------------

const int maxMode = 5;
int mode = 0;

void loop() {
  if (leftButton.wasPressed())  {
    if (++mode > maxMode) { mode = 0; }
    initMode(mode);
  }
  if (rightButton.wasPressed()) {
    if (--mode < 0) { mode = maxMode; }
    initMode(mode);
  }

  switch(mode) {
    case (0): sequencer.check(); break;
    case (1):
    case (2): alternator.check(); break;
    default: lightLED(mode); break;
  }
}

// ------------------------------------------------------------------

void initMode(int mode) {
  switch (mode) {
    case (0): sequencer.reset(); break;
    case (1): alternator = Alternator(0b00101010, 0b00010101); break;
    case (2): alternator = Alternator(0b00111000, 0b00000111); break;
  }
}
~~~

Alternator.ino

~~~
class Alternator {

  private:
    unsigned long whenChanged = 0;
    int interval = 500; // ms
    byte pattern, pattern1, pattern2; // bitmap
    int count = 0;

  public:
  Alternator(byte pattern1, byte pattern2) {
    this->pattern1 = pattern1;
    this->pattern2 = pattern2;
  }

  void check() {

    if ((millis() - whenChanged) > interval) {
      if (pattern == pattern1) { pattern = pattern2; }
      else                     { pattern = pattern1; }
      whenChanged = millis();
    }

    if (++count > 5) { count = 0; }
    if (((pattern >> count) & 1) == 1) {
      lightLED(count);
    }

  }

};
~~~

Sequence.ino

~~~
class Sequencer {

  private:
    int seq;                            // LED# 0-5
    unsigned long whenLastStep;         // ms
    int stepTime;                       // ms
    const int aDay = 24 * 3600 * 1000;  // ms

  public:
    Sequencer(int stepTime) {
      if (stepTime < 1) { stepTime = 1; }
      if (stepTime > aDay) { stepTime = aDay; }
      this->stepTime = stepTime;
      this->seq = 0;
      this->whenLastStep = 0;
    }

    void check() {
      if ((millis() - whenLastStep) > stepTime) {
        lightLED(seq++);
        if (seq > 5) { seq = 0; }
        whenLastStep = millis();
      }
    }

    void reset() {
      this->seq = 0;
    }
};
~~~

Charlieplex.ino

~~~
const int highs[6] = {0,1,2,1,2,0};  // GPIOs for LEDs 0-5
const int lows[6]  = {1,0,1,2,0,2};

// Manipulates 3 GPIO outputs to light one of 6 LEDs.
void lightLED(int i) {
  int h, l;     // pin to set high, low
  if (i < 0 || i >= 6) {
    h = 99; l = 99;  // all LEDS off
  } else {
    h = highs[i];
    l = lows[i];
  }

  for (int j=0; j<=2; j++) {
    if (j==h || j==l) {
      pinMode(j, OUTPUT);
      if (j==h) {
        digitalWrite(h, HIGH);
      } else {
        digitalWrite(l, LOW);
      }
    } else {
      pinMode(j, INPUT); // tri-state
    }
  }
}
~~~

Buttons.ino

~~~
class Button {

  private:
    int pin;
    const int DebounceDelay = 100;      // milliseconds
    int lastState = HIGH;               // Previous status of button
    unsigned long whenLastPressed = 0;  // Last time button was pressed

  public:
    Button(int pin) {
      this->pin = pin;
      pinMode(pin, INPUT_PULLUP);
    }

    // Was there an up (HIGH) to down (LOW) transition since last call, and still held down?
    bool wasPressed() {
      bool result = false;
      if ((millis() - whenLastPressed) > DebounceDelay) {
        int state = digitalRead(pin);
        if ((state == LOW) && (lastState == HIGH)) {
          result = true;
          whenLastPressed = millis();
        }
        lastState = state;
      }
      return result;
    }

};
~~~

I'm not sure where I am going wrong, any ideas?

  [1]: https://i.stack.imgur.com/L7PRm.gif
  [2]: https://i.stack.imgur.com/pNYSG.png

body:
Charlieplexing code doesn't reset the state of unused pin and if the port value is HIGH + mode INPUT, it means the pull-up is enabled.

Solution is reset all pins to LOW before code starts changing directions. And the last step would be setting correct pin to HIGH.

If you want to do it in single loop, you might observe really short pulses (it might or might not be visible - at the higher frequencies it'll be more obvious)

It could be also much faster than using digitalWrite and pinMode, something like:

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

      void charlieplex(uint8_t i) {
        constexpr uint8_t clrpins = ~(_BV(PB0) | _BV(PB1) | _BV(PB2));
        constexpr uint8_t dirs[]  = { 0b011, 0b011, 0b110, 0b110, 0b101, 0b101};
        constexpr uint8_t outs[]  = { 0b001, 0b010, 0b010, 0b100, 0b001, 0b100};

        PORTB &= clrpins; // clear output pins
        DDRB  &= clrpins; // clear direction pins (0 == input, 1 == output)
        if (i < 6) {  // such easy condition if you use:  uint8_t i
          DDRB  |= dirs[i]; // And set the correct pins as outputs
          PORTB |= outs[i]; // And set the correct pin as high
        }
      }

It's not tested, but it should be pretty much it


body:
A secondary issue is that using `millis()` to update the timestamps will cause the interval to cumulatively drag.

To keep the interval constant, update:
 - `whenChanged` with `interval`
 - `whenLastStep` with `stepTime`.

**Alternator.ino**

```cpp
void check() {

  if ((millis() - whenChanged) > interval) {
    if (pattern == pattern1) { pattern = pattern2; }
    else                     { pattern = pattern1; }
    whenChanged += interval;  // Constant interval.
  }

  if (++count > 5) { count = 0; }
  if (((pattern >> count) & 1) == 1) {
    lightLED(count);
  }

}
```

**Sequence.ino**

```cpp
void check() {
  if ((millis() - whenLastStep) > stepTime) {
    lightLED(seq++);
    if (seq > 5) { seq = 0; }
    whenLastStep += stepTime;  // Constant time step.
  }
}
```

This subtle difference is explained very well by @edgar-bonet in his answer about [polling a sensor at 100 Hz][1].

Also, `Button::wasPressed()` is prone to a negative blip occurring at the time of sampling the input pin, i.e. the blip will be interpreted as a continuous press of `DebounceDelay` (100 ms). Compare with this [simple debouncer][2] I put on GitHub.

  [1]: https://arduino.stackexchange.com/a/84823/68310
  [2]: https://github.com/TimMathias/Arduino-Debouncer


message:
Assistance with PID DC Motor Acceleration

I'm working on a project that uses an Arduino UNO and a motorized fader to send and receive MIDI data from my computer/musical keyboard. I'm trying to set up my motor with PID to control the position and speed of the motor - Been having some difficulty, but after watching a few tutorials I think I'm starting to grasp the idea.

Here's the code that I came up with so far - I'm not sure if this is correct for PID control or not, but it makes my motor respond very strangely to any positioning data that is coming in.

```cpp
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 1

SoftwareSerial midiSerial (rxPin, txPin);

const byte wiper = 0; //Position of fader relative to GND (Analog 0)

const byte motorUp   = 4;
const byte motorDown = 5;
const byte motorPWM  = 6;

double faderMax = 0;
double faderMin = 0;

byte motorSpeed = 150;  // Raise if the fader is too slow (0-255)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)

int incomingCommand;
int incomingNote;
int incomingVelocity;

int currentPosition;
unsigned targetPosition;
unsigned long distanceToTarget;
unsigned PIDspeed;

void setup() {
  midiSerial.begin(31250);
  Serial.begin(250000);
  analogWrite(motorPWM, motorSpeed);
  calibrateFader();
}

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(wiper) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(wiper) + tolerance;
}

void loop() {

  while ( midiSerial.available() > 0) {
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read();
    midiSerial.write( incomingCommand);
    midiSerial.write( incomingNote);
    midiSerial.write( incomingVelocity);
    targetPosition = incomingVelocity*8.05511811024;
    currentPosition = analogRead(A0);
    distanceToTarget = targetPosition-currentPosition;
  }
  PIDspeed = abs(distanceToTarget)/6;

  if (distanceToTarget >=0) {
    analogWrite(motorPWM, PIDspeed);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW);
  }

  if (distanceToTarget <=0) {
    analogWrite(motorPWM, PIDspeed);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW);
  }
}
```

Updated code:
```cpp
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 1

SoftwareSerial midiSerial(rxPin, txPin);

const byte wiper = 0; //Position of fader relative to GND (Analog 0)

const byte motorUp = 4;
const byte motorDown = 5;
const byte motorPWM = 6;

double faderMax = 1023;
double faderMin = 0;

byte motorSpeed = 150;  // Raise if the fader is too slow (0-255)
byte tolerance = 10;  // Raise if the fader is too shaky (0-1023)
byte Proportional = 12;

unsigned int incomingCommand;
unsigned int incomingNote;
unsigned int incomingVelocity;

unsigned int PIDspeed;
int currentPosition;
int targetPosition;
int distanceToTarget;

void setup()
{
    midiSerial.begin(31250);
    Serial.begin(250000);
    calibrateFader();
}

void calibrateFader()
{
    digitalWrite(motorUp, HIGH);
    analogWrite(motorPWM, motorSpeed);
    delay(300);
    digitalWrite(motorUp, LOW);
    faderMax = analogRead(wiper) - tolerance;
    digitalWrite(motorDown, HIGH);
    analogWrite(motorPWM, motorSpeed);
    delay(300);
    digitalWrite(motorDown, LOW);
    faderMin = analogRead(wiper) + tolerance;
}

void loop()
{
    while (midiSerial.available() >= 3)
    {
        incomingCommand = midiSerial.read();
        incomingNote = midiSerial.read();
        incomingVelocity = midiSerial.read();
        if (targetPosition <= 1023)
        {
            midiSerial.write(incomingCommand);
            midiSerial.write(incomingNote);
            midiSerial.write(incomingVelocity);
        }
        targetPosition = incomingVelocity * 8.05511811024;
    }
    currentPosition = analogRead(A0);
    distanceToTarget = (targetPosition - currentPosition);
    PIDspeed = (abs(distanceToTarget) / Proportional) + 90;
    analogWrite(motorPWM, PIDspeed);
    if (targetPosition <= 1023)
    {
        if (distanceToTarget > 60)
        {
            digitalWrite(motorUp, HIGH);
        }
        if (distanceToTarget < 60)
        {
            digitalWrite(motorDown, HIGH);
        }
        if ((distanceToTarget >= -60) && (distanceToTarget <= 60))
        {
            digitalWrite(motorDown, LOW);
            digitalWrite(motorUp, LOW);
        }
    }
}
```

In this version, the motor is actually less responsive than before. I think it must have to do with the data that's coming in from my DAW, which isn't consistently a piece of command, note or velocity data. For example, if I select a different track in my DAW, it sends data into my Arduino. When I read anything greater than 0 bytes, the data still comes in, but the note, command and velocity readings are more sporadically located. It was suggested by another that I try using a MIDI parser, but that's a different topic I suppose.

body:
I see 2 main problems with your code, that would make it behave strangely:

- You are calculating the new motor speed and decide about the direction based on the variable `distanceToTarget`. But this variable is only updated, when there is data coming from your MIDI interface. I guess thats only happening, when you want to change the target position. But the motor control runs on **every** loop iteration, which will be way more often, than you can get the MIDI data. To solve this please move the lines

        currentPosition = analogRead(A0);
        distanceToTarget = targetPosition-currentPosition;

    out of the `while(midiSerial.available() > 0)` loop. Just put then right after it.

- At the start of your midi code you check for more than zero bytes being available from `midiSerial`, but then you are reading 3 bytes in total, without knowing, if there are actually 3 bytes to read. `SoftwareSerial.read()` will not wait for a byte to come in, it will just return -1. So it can very well be that, just one byte is already received, when the midi code is executed. The rest will be received later. So the rest of the variables is just garbage/invalid. Also this means that sender and receiver are now misaligned. The other 2 bytes (which are received later) will then be handled by the midi code next time as if they were byte 1 and 2 (not 2 and 3). So the next transitions will also be garbage/invalid, until it aligns itself again by chance.

    To solve this you should check for at least 3 bytes being available (since you want to read 3 bytes):

        while ( midiSerial.available() >= 3 ) {

---

Note: As of your comments you seem to have a misunderstanding, what PID and PWM actually is.

- PWM is just a way to drive the motor with variable speed by turning the pin on and off very fast, with different ratios between on and off time. With a high ratio towards on time the motor will turn faster than with a low ratio towards on time. This ratio translates to the range from 0 to 255 on an Arduino. So you need PWM to drive a motor with variable speed on the Arduino. You cannot cut that out.

- PID is a closed feedback loop control. It denotes a way to calculate a new output value (PWM motor value) based on the measured input value (measured current position). PID stands for Proportional Integral Differential, so for the different terms in the calculations. With PID first the deviation between measured input and target/setpoint is calculated then the PID function is evaluated (with its proportional, integral and differential part of the deviation). With that you get the output value, that you can feed to your output device (the motor here).

    PID has nothing to do with PWM. They are totally different things. Only when driving an electromechanical device you might need PWM in the same system as PID. PWM is the hardware way of driving the motor, PID is the way to calculate the output value in a closed feedback loop to reach the target position smoothly and fast.

Actually with your current code (when corrected as described above) already does the proportional part of PID (since you calculate the new speed from the distance to target, so the deviation from the target position). To get full PID you would also need to implement the rest. I would suggest using the [Arduino PID library][1], which already handles the calculation for you. You just need to call it correctly (refer to the examples of the library).

  [1]: https://github.com/br3ttb/Arduino-PID-Library/


body:
There is a fundamental problem with the way you are reading the serial data. Read this excellent article by @Majenko:
https://majenko.co.uk/blog/reading-serial-arduino

The following code will read the last 3 bytes. If, for example, there are 9 bytes available, it will ignore the first 6 bytes:

```cpp
while (midiSerial.available() >= 3)
{
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read();
. . .
}
```

This will read the next 3 bytes:

```cpp
if (midiSerial.available() >= 3)
{
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read();
. . .
}
```

Here is the tweaked `loop()` which:
 - uses `if (midiSerial.available() >= 3)` to read the next 3 bytes.
 - clips the `targetPosition` if it's out of bounds (0 to 1023).
 - clips the `PIDspeed` if it's out of range (0 to 255).
 - switches the other motor control signal off before enabling the current one just in case the `targetPosition` crossed zones between `loop()` iterations.

```cpp
const int QUIESCENT_BOUNDARY = 60;
const float INCOMING_VELOCITY_SCALE = 1023.0 / 255.0;

byte incomingCommand;
byte incomingNote;
byte incomingVelocity;

void loop()
{
    if (midiSerial.available() >= 3)                // Use `if` to get the next 3 bytes available.
    {
        incomingCommand = midiSerial.read();
        incomingNote = midiSerial.read();
        incomingVelocity = midiSerial.read();
        midiSerial.write(incomingCommand);
        midiSerial.write(incomingNote);
        midiSerial.write(incomingVelocity);
        targetPosition = incomingVelocity * INCOMING_VELOCITY_SCALE;
        if (targetPosition > 1023)                  // Clip if out of bounds.
        {
            targetPosition = 1023;
        }
    }
    currentPosition = analogRead(A0);
    distanceToTarget = targetPosition - currentPosition;
    PIDspeed = abs(distanceToTarget) / 6;           // TODO: Tune the PID equation.
    if (PIDspeed > 255)                             // Clip if out of range.
    {
        PIDspeed = 255;
    }
    analogWrite(motorPWM, PIDspeed);
    if (distanceToTarget > QUIESCENT_BOUNDARY)      // Above the positive bound of the quiescent zone.
    {
        digitalWrite(motorDown, LOW);               // Switch the down control off before switching the up control on.
        digitalWrite(motorUp, HIGH);
    }
    else if (distanceToTarget < -QUIESCENT_BOUNDARY)// Below the negative bound of the quiescent zone.
    {
        digitalWrite(motorUp, LOW);                 // Switch the up control off before switching the down control on.
        digitalWrite(motorDown, HIGH);
    }
    else                                            // In the quiescent zone.
    {
        digitalWrite(motorDown, LOW);
        digitalWrite(motorUp, LOW);
    }
}
```

That should help you to tune the PID equation.


message:
Why am I getting Invalid head of packet (0xF0) error when trying to upload code to esp8266?

**Solved** : In Mac I went back to Tools --> Boards Manager, then removed 3.0 and downgraded to 2.5 and it started working. I found the solution in [this][2] thread.

--------------

The current connection between uno R3 and esp8266 is

  **UNO** ----- **ESP8266**

    RX — RX
    TX — TX
    GND — GND
    3.3V — VCC (used bread board)
    3.3V — CH_PD (used bread board)
    GPIO - GND

   **UNO** ----- **UNO**

    Reset -- GND

Then ESP8266 send "OK" when I send AT from the serial monitor. When uploading the red light and blue blinks in esp8266 and rx and tx light blinks at uno r3.

I had to do `sudo launchctl stop /dev/cu.usbmodemxxx` before running below command.

Since I have GPIO connected to GND, I though that would trigger the programming mode, but for some reason it gives `Invalid head of packet`. I get same error when trying to upload code from arduino IDE.

I tried below command too from cmd line.

    $sudo python esptool.py -t --chip esp8266  --port /dev/cu.usbmodemxxx --before no_reset flash_id
    esptool.py v2.8
    Serial port /dev/cu.usbmodemxxx
    Connecting...TRACE +0.000 command op=0x08 data len=36 wait_response=1 timeout=0.100 data=
        0707122055555555 5555555555555555 | ... UUUUUUUUUUUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        55555555                          | UUUU
    TRACE +0.000 Write 46 bytes:
        c000082400000000 0007071220555555 | ...$........ UUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        5555555555555555 5555555555c0     | UUUUUUUUUUUUU.
    TRACE +0.000 Read 3 bytes: f8fef0
    TRACE +0.000 Read invalid data: f8fef0
    TRACE +0.000 Remaining data in serial buffer:
    .TRACE +0.056 command op=0x08 data len=36 wait_response=1 timeout=0.100 data=
        0707122055555555 5555555555555555 | ... UUUUUUUUUUUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        55555555                          | UUUU
    TRACE +0.000 Write 46 bytes:
        c000082400000000 0007071220555555 | ...$........ UUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        5555555555555555 5555555555c0     | UUUUUUUUUUUUU.
    TRACE +0.001 Read 1 bytes: f0
    TRACE +0.000 Read invalid data: f0
    TRACE +0.000 Remaining data in serial buffer: f0f0
    .TRACE +0.056 command op=0x08 data len=36 wait_response=1 timeout=0.100 data=
        0707122055555555 5555555555555555 | ... UUUUUUUUUUUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        55555555                          | UUUU
    TRACE +0.000 Write 46 bytes:
        c000082400000000 0007071220555555 | ...$........ UUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU

    ......

    A fatal error occurred: Failed to connect to ESP8266: Invalid head of packet (0xF0)

Below is the image of the arduino IDE with code and board selected as esp8266.

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

I am following this post https://iot-guider.com/esp8266-nodemcu/how-to-program-esp8266-with-arduino-uno/ and I have exact same hardwares.

**UPDATE:**

When I tried this connection in Windows it starts uploading code without error. So, my guess is its something to do with MAC.

  [1]: https://i.stack.imgur.com/k7Zc8.png
  [2]: https://forum.arduino.cc/t/esp-8266-timed-out-waiting-for-packet-header/597634/18

body:
The tutorial you linked to can not be trusted! There are mayor mistakes:

 1. They connect a 3.3V device with a 5V devices without taking any measures to convert the logic levels.
 2. Connecting Rx to Rx (or Tx to Tx) is typically not what you do if you want to communicate between devices. A transmitting line must be connected to a receiving line for that. In case the arduino is `Serial.print()`ing something himself, a bus contention can cause a short circuit and harm the UART pins.
 3. They are plugging the ESP into a breadboard which simply doesn't work! This will short several pins and possibly kill some hardware. At least it can't work like that.

I don't know if the person who did this tutorial just has no idea or is trolling, but you need to find a different tutorial (and - I'm sorry to say - possibly get a new ESP).

If all you want is to use the arduino as a USB to UART bridge, I suggest to remove the atmega chip from its socket on the arduino or make sure that it doesn't run a sketch were it prints something. The UART pins should also be configured as inputs.


message:
Store Integer Value of Money on an RFID Tag

I am working on making an Arduino based arcade. I want each user of the arcade to have an RFID card that stores the amount of credits (basically money) they have. I know that RFID tags have 1028 bytes of storage on them, but I don't know how to write an integer value to them.

The amount of credits each user has would be stored on the RFID, as well as their PIN.

The PIN would be 4 digits, with each digit an integer from 0-9, as is the standard with PINs. It would be stored as a single integer, between 0000 and 9999.

The credit would ALSO be stored on each card. This would be between 0 and 99 (Most that can be loaded at a time). This, too, would be treated as a single integer, for ease of use.

Both integers would be of the Arduino type `int`.

I am using the MFRC522 library with an RC522 reader/writer. I have an Arduino Uno, but can easily switch to an Arduino Nano.

Can someone tell me how to:
A. Write an integer value (stored as a variable in the sketch or accessed from the RFID memory) to an RFID card?
B. Access that information and retrieve it as an integer I could operate on (`+,-,÷,×, etc`)?

Thanks in advance!

body:
You can read data with :

    status = mfrc522.MIFARE_Read(blockNum, readBlockData, &bufferLen);

and write data by:

    status = mfrc522.MIFARE_Write(blockNum, blockData, 16);

However, there's a lot more to it, so check examples of the RFID library, or this external articles:

https://www.electronicshub.org/write-data-to-rfid-card-using-rc522-rfid/
https://playground.arduino.cc/Learning/MFRC522/

When you read the data in a memory block, you can get the bytes out you need and convert them to an int, or the other way around for writing.


message:
What is the chip in this board?

Doing some research about SD card adapters, I found these boards with a chip on them.

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

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

They are actually very common. They have a linear voltage regulator because UNO for example use 5V but SD card adapters use 3.3V. The voltage regulator has two capacitors one on the input one on the output. but what is C3? Looks like it is between the output and GND.

The other question is what is the other chip? I guess it turns sd card signals from 3.3 to 5v and viceversa. What is the name of this and what could be this chip model?

body:
> **but what is C3? Looks like it is between the output and GND.**

C3 is likely a 10 uF cap for the 3v3 output of the regulator.

[![schematic][1]][1]
(Source: [datasheet for Sunrom SD module](https://www.sunrom.com/get/192293) (PDF))

> The circuit design used in the AMS1117 series requires the use of
an output capacitor as part of the device frequency compensation.
The addition of 22µF solid tantalum on the output will ensure
stability for all operating conditions.
When the adjustment terminal is bypassed with a capacitor to
improve the ripple rejection, the requirement for an output
capacitor increases. The value of 22µF tantalum covers all cases of
bypassing the adjustment terminal. Without bypassing the
adjustment terminal smaller capacitors can be used with equally
good results.

(Source: [datasheet for AMS1117 voltage regulator](http://www.advanced-monolithic.com/pdf/ds1117.pdf) (PDF))

---

> **The other question is what is the other chip? I guess it turns sd card signals from 3.3 to 5v and viceversa. What is the name of this and what could be this chip model?**

At least some of these modules use the LVC125A quad bus buffer gate.

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

  [1]: https://i.stack.imgur.com/ik85c.png
  [2]: https://i.stack.imgur.com/DdJ1T.jpg


message:
Detect button press in a loop

I am designing simple "Simon Says game" using Arduino. Simon says is a game in which a LED pattern is played and user has to mimic the pattern. There are 10 Rounds. First Round = 1 led, second round = 2 leds and so on. When the first round is played, one led blinks and player has to press the corresponding button. Then if it presses the right button, next round plays in which two LEDs glow and player has to press 2 buttons in sequence. I am having problem in detecting the button press in a loop for more than 1 round. Here is snippet of the code:

    void loop() {
      for (int i = 1; i <= ROUNDS; i++)
      {
        digitalWriteGeneric(i);
        bool wait = 1;
        int expected = Sequence[i - 1];
        while (wait)
        {
          int value = digitalReadGeneric();
          if (expected == value)
          {
            Serial.print("Right");
            wait = 0;
            break;
          }
        }
      }
    }
    int digitalReadGeneric()
    {
      for (int i = 0; i < NUM_LIGHTS; i++)
      {
        Readings[i] = digitalRead(buttonPin[i]);
        if (Readings[i] == 1)
        {
          return i;
        }
      }

    }

Here, ROUNDS = 10
digitalwritegeneric is working fine, it plays the pattern for corresponding pattern. For round more than one how can i detect button press in sequence?. Kindly tell, what I am doing wrong.

body:
Looking into your `for`-loop:
```c
for (int i = 1; i <= ROUNDS; i++)
  {

    // Write sequence
    digitalWriteGeneric(i);

    // Read sequence
    bool wait = 1;
    int expected = Sequence[i - 1];
    while (wait)
      {
        int value = digitalReadGeneric();
        if (expected == value)
          {
            Serial.print("Right");
            wait = 0;
            break;

            // Setting vlag to false will exit the while loop
            // break will also exit the while loop
            // so only need to do 1 of the 2
            // but then you won't be able to read anymore, it exited the while-loop
          }
      }
  }
```

You only check the first button, and if this one is correct you go out of the `while` loop, ending the reading.

You can change the type of variable `wait` to an `uint8_t` (init to `0`) and if the `value` is right, increment `wait`. The while-loop becomes: `while (wait < i) {}`. You can use `break` to stop reading when the player clicked a wrong button.

To see if the player did the sequence correctly:
`if (wait == i) {"GOOD";} else {"BAD";}`


message:
Same structure taking different memory space on Uno and NodeMCU ESP8266, leading to data corruption when transferring via nRF24L01+

I'm trying to transfer data between a Arduino Uno board to a NodeMCU ESP8266 board, using nRF24L01+ transceivers module and RF24 library on both side. The data I'm transferring are stored in a ```struct``` defined this way:
```
// Struct declared in both code
struct sensorData {
    bool doorOpened;
    int light;
    int temperature;
    int humidity;
    float voltage_battery;
};
// Variable in Uno code (source node)
sensorData dataToSend;
// Variable in ESP8266 code (dest node)
sensorData dataToReceive;
```
But the data are not transferred properly between the two boards and I get random values or 0 when trying to display them from ESP8266 (values are correctly displayed from Uno).

Display in Uno (using ```signed short``` as data type, see following paragraphs):
[![Data displayed from Arduino UNO][1]][1]

Display in ESP8266 (using ```signed short``` as data type, see following paragraphs):
[![Data displayed from NodeMCU ESP8266][2]][2]

After some testing, I found out that memory-allocation on both boards are different, as Uno takes *2 bytes* to store ```int``` while ESP8266 takes *4 bytes*. Moreover, sensorData takes *11 bytes* of memory on Uno (1 for ```bool```, 2 for ```int``` and 4 for ```float```, which sums up to *11 bytes*), but takes *20 bytes* of memory on ESP8266 (1 for ```bool```, 4 for ```int``` and 4 for ```float```, which does NOT sum up to 20 !).

Trying to solve this, I tried changing ```int``` for ```signed int```, ```byte```, ```short```, ```signed short``` but the transmission problem remains. When using ```short``` or ```signed short``` (which takes *2 bytes* on both boards), my structure ```sensorData``` still takes *11 bytes* of memory on UNO while it takes *12 bytes* of memory on ESP8266. For some reason, ESP8266 always takes more space than needed to store ```sensorData```, probably causing bits to be wrongly placed when receiving data.

I'm sure that both boards, radio module and transmission protocol work as I successfully tested the same code with a smaller struct (```text``` was "Hello World !" and ```cmp``` was increased at each transmission):
```
struct Package {
    char text[16];
    long cmp;
};
```
Does anyone have faced this issue before ? How could I solve that ?

  [1]: https://i.stack.imgur.com/QaYxi.png
  [2]: https://i.stack.imgur.com/V2eSd.png

body: The esp8266 has a 32 bit mcu and the uno an 8 bit mcu so their variables have different storage requirements. You need to allow for this in your code.


body:
`int`, `long`, etc have different sizes depended on the compiler and target.

Use explicit sizes to make sure you're variables have the size you want. Eg. `uint8_t`, `int16_t` or `int32_t`, ... (as @Mat commented)

Also, I wouldn't use `bool` (if writing in `C`) as it's not really standard in `C` and the size is also implementation dependent: https://stackoverflow.com/questions/1608318/is-bool-a-native-c-type

Extra, there are different types of explicit sizes: https://stackoverflow.com/questions/5254051/the-difference-of-int8-t-int-least8-t-and-int-fast8-t
(but don't use it here otherwise you'll have again the same problem :))


body:
In addition to the rule of always using fixed and predictable sizes across different architectures, it's also a good idea to *pack* your structs. This prevents the compiler from padding smaller variables with blanks to align them with the architecture's word boundary when needed.  For example:

```c++
struct Package {
    uint8_t doorOpened;
    uint16_t light;
    int16_t temperature;
    uint8_t humidity;
    float voltage_battery;
} __attribute__((packed));
```

Depending on what "bytewise access" instructions are available on your target 32-bit architecture, without the packing you may end up with (worst case) the equivalent of:

```c++
struct Package {
    uint8_t doorOpened;
    // 3 bytes padding
    uint16_t light;
    // 2 bytes padding
    int16_t temperature;
    // 2 bytes padding
    uint8_t humidity;
    // 3 bytes padding
    float voltage_battery;
} __attribute__((packed));
```

Of course there may be a granular enough access method in the architecture which means the packing is irrelevant - but it's better to have it and it be ignored than to not have it and need it.


body:
There are three main issues you may need to deal with when passing structures between systems that use different processors.

The first is that data types vary in size between architectures. You can avoid this for integers by avoiding the basic C types and instead using the fixed size types from stdint.h/cstdint. For floating point types this is less of a problem as most systems use the IEEE single and double precision types for float and double.

The second is padding, according to the C standard padding is implementation dependent. In practice most compilers will insert the minimum amount of padding needed to meet alignment requirements. Exactly what the alignment requirements are also depend on the implementation, but the alignment requirement of a type is always a factor of it's size.

You can thus avoid compiler-generated padding on most architectures by designing your structure to place types on "natural" alignment (that is their offset in the structure is a multiple of their size) and to have a size that is a multiple of the largest type in the structure. So you might design your structure as.

    struct sensorData {
        int8_t doorOpened; //size 1 offset 0
        int8_t spare; //size 1 offset 1
        int16_t light; //size 2 offset 2
        int16_t temperature; //size 2 offset 4
        int16_t humidity; // size 2 offset 6
        float voltage_battery; //size 4 offset 8
    };

Another option is to use packed structures, but extreme care is needed when using such, especially in C++. It is easy to create unaligned pointers or references.

The final issue is byte order (also known as endian), if your systems use different byte orders for integer or floating point values you will need to insert conversions to deal with this.


body:
For all the reasons mentioned in the other answers (different types sizes, alignment requirements and endianness), it's often a bad idea to use structs for data that needs to be sent/received (be it over the network or stored in files), as interoperability is often a problem.

Using a plain array of bytes (i.e. uint8_t[]) is often a much better solution, together with functions to read/write data with specific types at specific offsets.

In many higher-level languages (perl, php, python...) this is often done using `pack`/`unpack` or equivalents, but as far as I know there is no direct equivalent in C.

You then end up using temporary variables, [`htons`/`ntohs`/`htonl`/`ntohl`](https://linux.die.net/man/3/htons) and `memcpy` to copy data between the temporary variables and the transmit buffer. Floats are a bit more tricky because even though their format is well defined, they endianness is not, and may not be the same as integers, but `htonf`/`ntohf` are rare. In your case, I would recommend converting to integers with a factor of 10 (if you need one digit) or 100 (if you need 2) for instance.

If you're using C++ you could consider using Google's [Protocol buffers](https://developers.google.com/protocol-buffers)


message:
how to use switch case with two push buttons, I don't know how to combine buttonState1 and buttonState2

```
import muvium.compatibility.arduino.*;

public class Class0 extends Arduino{

/*
Author: First Name MI. Last Name
Date: June 25, 2021
Title: Arduino Experiment 2
Description: Writing to the Output Pins using the FOR statement

Create a program that will display four different LED sequences having
different transition states repeated at different number of times and
that the whole program will repeat itself continuously

Apply the concept of using funcions for each of the four LED sequences,
 each of which are to be called upon from the main program.

This time simplify the LED sequence functions using FOR control statements
to achieve the required iterations

Pin modes of each LED pins are to be iterated together using a FOR statement

The circuit:
 * LEDs connected from digital pin 4-11, all with respect to ground.
*/
// ---------------------------------------------------------
// Declaration of Global Variables:
  int led1 = 4; // LED1 connected to digital pin 4
  int led2 = 4; // LED2 connected to digital pin 4
  int led3 = 4; // LED3 connected to digital pin 4
  int led4 = 4; // LED4 connected to digital pin 4
  int switchPin1 = 2; // PushButton connected to digital pin 2
  int switchPin2 = 3; // PushButton connected to digital pin 3
  int buttonState1 = 0; // variable for reading pushbutton status
  int buttonState2 = 0; // variable for reading pushbutton status
// ---------------------------------------------------------
  public void setup() {
    // the setup() method runs once, when the sketch starts
    // initialize the digital pins as outputs;

    for (led1 = 4; led1 < 12; led1++) {
      pinMode(led1, OUTPUT); // Configure pin 4 to 11 as outputs
    }
    pinMode(switchPin1, INPUT);// Configure pin 2 as input
    pinMode(switchPin2, INPUT);// Configure pin 3 as input
  }
// ---------------------------------------------------------
  public void loop() {
    // the loop() method runs over and over again,
    // as long as the Arduino has power

    // read the state of pushbutton value
    buttonState1 = digitalRead(switchPin1);
    buttonState2 = digitalRead(switchPin2);

    switch (buttonState1) {
      case (0):
        for (led1 = 7, led2 = 8; (led1 > 3) && (led2 < 12); led1--, led2++) {
        digitalWrite(led1, HIGH); // set the LED on
        digitalWrite(led2, HIGH); // set the LED on
        delay(500); // wait for 500 milliseconds
        digitalWrite(led1, LOW); // set the LED off
        digitalWrite(led2, LOW); // set the LED off
        }
        break;

      case 1:
        for (led1 = 11, led2 = 9, led3 = 7, led4 = 5; (led1 > 9) && (led2 > 7) && (led3 > 5) && (led4 > 3); led1--, led2--, led3--, led4--) {
        digitalWrite(led1, HIGH); // set the LED on
        digitalWrite(led2, HIGH); // set the LED on
        digitalWrite(led3, HIGH); // set the LED on
        digitalWrite(led4, HIGH); // set the LED on
        delay(500); // wait for 500 milliseconds
        digitalWrite(led1, LOW); // set the LED off
        digitalWrite(led2, LOW); // set the LED off
        digitalWrite(led3, LOW); // set the LED off
        digitalWrite(led4, LOW); // set the LED off
        }
        break;

      case 2:
        for (led1 = 11, led2 = 10, led3 = 9, led4 = 8; (led1 > 6) && (led2 > 5) && (led3 > 4) && (led4 > 3); led1-=4, led2-=4, led3-=4, led4-=4) {
          digitalWrite(led1, HIGH); // set the LED on
          digitalWrite(led2, HIGH); // set the LED on
          digitalWrite(led3, HIGH); // set the LED on
          digitalWrite(led4, HIGH); // set the LED on
          delay(500); // wait for 500 milliseconds
          digitalWrite(led1, LOW); // set the LED off
          digitalWrite(led2, LOW); // set the LED off
          digitalWrite(led3, LOW); // set the LED off
          digitalWrite(led4, LOW); // set the LED off
          }
          break;

      default:
        for (led1 = 11, led2 = 4; (led1 > 7) && (led2 < 8); led1--, led2++) {
          digitalWrite(led1, HIGH); // set the LED on
          digitalWrite(led2, HIGH); // set the LED on
          delay(500); // wait for 500 milliseconds
          digitalWrite(led1, LOW); // set the LED off
          digitalWrite(led2, LOW); // set the LED off
          }
    }
  }
}
```

body:
I don't know what that code is, but it's not Arduino code. It looks like it's wrapped in some other class.  But in *real* Arduino code...

To "combine" your two button states it helps to think of them as two individual bits within a byte. A byte is made up of 8 bits, and any of them can be on or off. If you associate your two buttons with two of those bits you can represent them as a single number in a byte.

For example if you use:

```c++
uint8_t buttonStates = (digitalRead(switchPin2) << 1) | digitalRead(switchPin1);
```

you create a single variable containing both states.  In simple terms that means "Read switchPin2, shift the result one bit to the left, then read switchPin1 and superimpose the two results together".

So the result is a byte where bit 1 is switchPin2 and bit 0 is switchPin1.

It gives you, then, a truth table of:

```
SP1 | SP2 | Variable
----+-----+----------
 0  |  0  | 0b00000000
 1  |  0  | 0b00000001
 0  |  1  | 0b00000010
 1  |  1  | 0b00000011
```

Which of course is the numbers 0-3 in decimal.

So then you can use a switch:

```c++
switch (buttonStates) {
    case 0: // switchPin1 == 0, switchPin2 == 0
        // do something
        break;
    case 1: // switchPin1 == 1, switchPin2 == 0
        // do something
        break;
    case 2: // switchPin1 == 0, switchPin2 == 1
        // do something
        break;
    case 3: // switchPin1 == 1, switchPin2 == 1
        // do something
        break;
}
```


message:
Arduino nano BLE sense Serial port Suddenly stopped working

Last week I got my new Arduino nanao ble sense. Today I was executing a code on it which reads every sensor data on it and print it on serial monitor. I changed some parameters in my code and upload my code, while the code was uploading I opened the serial monitor and code was fully uploaded. Suddenly i got an error on terminal saying cannot find upload port. After that my Arduino board was never detected by the system. I tried to $lsusb to check whether the device is mounted on usb port but it didn't show up.... I tried on different PC and even that not detected... Plzz let me know if my hardware is damaged in someway? OR is there a solution to this???

body:
All that has happened is that you don't have a sketch running. When you have a board with a native USB connection a sketch has to be running to make that USB connection *be* anything.

You corrupted your sketch, so it's not executing.

All you need to do is manually trigger the bootloader to install a new sketch. According to the "Getting started" page:

> NOTE: If the board does not enter the upload mode, please do a double press on the reset button before the upload process is initiated; the orange LED should slowly fade in and out to show that the board is waiting for the upload.


message:
Quick noob question about connecting 16x2 LCD

In [this tutorial][1] the writer used digital pin 2-5 and pin 11 and 12, can I use other I/O pins if I define it in the library?

    const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
    LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

  [1]: https://www.arduino.cc/en/Tutorial/LibraryExamples/HelloWorld

body: Yes, you can. There is nothing special about the pins an LCD like this uses, it's just simple IO.  You can even use the "Analog" pins for digital IO.  The only pins to stay away from, which is a good rule in general, are the TX and RX pins (pins 0 and 1 on the UNO) as they are used for communication with the PC through USB.  All the other pins are fare game for something as simple as an LCD.


message:
Loading code to a mega 2560

As part of my application, I need to be able to update the code on my mega 2560 in the field with a download from the internet.

I have found this code in the AT Mega 2560 data sheet

     ;-the routine writes one page of data from RAM to Flash
     ; the first data location in RAM is pointed to by the Y pointer
     ; the first data location in Flash is pointed to by the Z-pointer
     ;-error handling is not included
     ;-the routine must be placed inside the Boot space
     ; (at least the Do_spm sub routine). Only code inside NRWW section can
     ; be read during Self-Programming (Page Erase and Page Write).
     ;-registers used: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
     ; loophi (r25), spmcrval (r20)
     ; storing and restoring of registers is not included in the routine
     ; register usage can be optimized at the expense of code size
     ;-It is assumed that either the interrupt table is moved to the Boot
     ; loader section or that the interrupts are disabled
    ..equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words
    .org SMALLBOOTSTART
    Write_page:
        ; Page Erase
        ldi  spmcrval, (1<<PGERS) | (1<<SPMEN)
        call Do_spm

        ; re-enable the RWW section
        ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
        call Do_spm

        ; transfer data from RAM to Flash page buffer
        ldi  looplo, low(PAGESIZEB) ;init loop variable
        ldi  loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256

    Wrloop:
        ld   r0, Y+
        ld   r1, Y+
        ldi  spmcrval, (1<<SPMEN)
        call Do_spm
        adiw ZH:ZL, 2
        sbiw loophi:looplo, 2 ;use subi for PAGESIZEB<=256
        brne Wrloop

        ; execute Page Write
        subi ZL, low(PAGESIZEB)       ;restore pointer
        sbci ZH, high(PAGESIZEB)      ;not required for PAGESIZEB<=256
        ldi  spmcrval, (1<<PGWRT) | (1<<SPMEN)
        call Do_spm

        ; re-enable the RWW section
        ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
        call Do_spm

        ; read back and check, optional
        ldi  looplo, low(PAGESIZEB)   ;init loop variable
        ldi  loophi, high(PAGESIZEB)  ;not required for PAGESIZEB<=256
        subi YL, low(PAGESIZEB)       ;restore pointer
        sbci YH, high(PAGESIZEB)
    Rdloop:
        elpm r0, Z+
        ld   r1, Y+
        cpse r0, r1
        jmp  Error
        sbiw loophi:looplo, 1         ;use subi for PAGESIZEB<=256
        brne Rdloop

        ; return to RWW section
        ; verify that RWW section is safe to read
    Return:
        in   temp1, SPMCSR
        sbrs temp1, RWWSB     ; If RWWSB is set, the RWW section is not ready yet
        ret
        ; re-enable the RWW section
        ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
        call Do_spmr
        jmp Return

    Do_spm:
        ; check for previous SPM complete
    Wait_spm:
        in   temp1, SPMCSR
        sbrc temp1, SPMEN
        rjmp Wait_spm
        ; input: spmcrval determines SPM action
        ; disable interrupts if enabled, store status
        in   temp2, SREG
        cli
        ; check that no EEPROM write access is present
    Wait_ee:
        sbic EECR, EEPE
        rjmp Wait_ee
        ; SPM timed sequence
        out  SPMCSR, spmcrval
        spm
        ; restore SREG (to enable interrupts if originally enabled)
        out  SREG, temp2
        ret

I am trying to convert this to code I can use in my arduino project under wiring. My first question is the register. It looks like `spmcrval` is register 20, but how can I access that register from within my arduino project?

I have found constants like `SPMEN` in the arduino header, but not these register names.

Also, feel free, if you wish, to avoid the drama and say, "Here's the C source code," which will be worth a certain amount of hero worship.

Everything appears to use avrdude and so I'm trying to parse that as well.

body:
Only from bootloader section is it possible to write to flash on ATmega2560. Optiboot 8 has a do_spm function to write to flash. It is accesible over a header file available in [examples in the Optiboot GithHub repository][1].

After the updated application binary is written to free part of the flash by the running application it is necessary to copy the updated application to run location from address 0. This must be done again by the bootloader.

Optiboot builds in [MCUdude Mega Core][2] and Mighty Core have Optiboot enhanced with my copy_flash_pages function which copies the pages and then resets the MCU.

[My ArduinoOTA library][3] uses do_spm and copy_flash_pages function to store and apply uploaded sketch binary. The InternalStorage object can be used to [apply a downloaded binary][4] too.

  [1]: https://github.com/Optiboot/optiboot/tree/master/optiboot/examples/demo_dospm
  [2]: https://github.com/MCUdude/MegaCore
  [3]: https://github.com/jandrassy/ArduinoOTA
  [4]: https://github.com/jandrassy/ArduinoOTA/blob/master/examples/Advanced/OTASketchDownload/OTASketchDownload.ino


message:
ESP8266 AutoConnect ACSelect selection index

I'm trying to retrieve the current selected/saved index of my `AutoConnectSelect` Right now i'm creating a type that reads the saved json:

     AutoConnectSelect& bright = settingsAux["scr_brightness"].as<AutoConnectSelect>();

How can i get the index of the element selected in `bright` as an integer?

`bright.value` and `bright.value()` are both invalid in this context.

Any help or insight into how these types work would be appreciated.

body: The member i was looking for is `AutoConnectSelect.selected` I just subtract the value by one to get the index, as `.selected` starts from 1.


message:
playTone function of Buzzer

I am making "Simon says" game using Arduino on TinkerCad.
I am facing issue in Buzzer sound function.
I want something like this:

 1. Use the following steps to generate the tone for the red LED:
    Play 440 Hz for 150ms
     Wait for 1136us
     Play 440 Hz for 150ms

 2. Use the following steps to generate the tone for the yellow LED:
 Play 784 Hz for 150ms
 Wait for 638us
 Play 784 Hz for 150ms
3. Use the following steps to generate the tone for the blue LED:
 Play 587 Hz for 150ms
 Wait for 851us
 Play 587 Hz for 150ms
4. Use the following steps to generate the tone for the green LED:
 Play 880 Hz for 150ms
 Wait for 568us
 Play 880 Hz for 150ms

I have following functions for the above:

     void playTone2(int tone, int duration) {
      Serial.println(tone);
      for (long i = 0; i < duration * 1000L; i += tone * 2) {
        digitalWriteGeneric(buzzer, true);
        delayMicroseconds(tone);
        digitalWriteGeneric(buzzer, false);
        delayMicroseconds(tone);
      }
    }

    void playTone(int tone1) {
      Serial.println(tone1);
      if (tone1 == 440) {
        playTone2(440, 150);
        delayMicroseconds(1136);
        playTone2(440, 150);
      }
      if (tone1 == 784) {
        playTone2(784, 150);
        delayMicroseconds(638);
        playTone2(784, 150);
      }
      if (tone1 == 587) {
        playTone2(587, 150);
        delayMicroseconds(851);
        playTone2(587, 150);
      }
      if (tone1 == 880) {
        playTone2(880, 150);
        delayMicroseconds(568);
        playTone2(880, 150);
      }
      if (tone1 == 2700) {
        playTone2(250, 250);
        delay(250);
        playTone2(150, 250);
      }

    }

First there was only playTone code but I needed different values for different LEDs so I included playTone function and called playTone2 to it.
But the tones that I am getting are not accurate may be because of two functions. I will be able to resolve it if I could understand the working of playTone2 function. I tried but no use, kindly share how exactly playtone2 functions here so that I can edit my playTone function accordingly.

body:
Here is a simple sketch to test the tones used for each color of LED. I have not tested it with a speaker, but it compiles in the Arduino IDE, so perhaps it will work as is.

The call to `delayMicroseconds()` is "blocking" code, so you may want to change it to use "non-blocking" code, e.g. Use the `BlinkWithoutDelay` example in the IDE to make a `micros()` based timer.

```lang-c++
/* Arduino Uno. IDE 1.8.9
   Sketch uses 2540 bytes (7%) of program storage space.
   Global variables use 28 bytes (1%) of dynamic memory.

   red    LED: Play 440 Hz for 150ms Wait for 1136us Play 440 Hz for 150ms
   yellow LED: Play 784 Hz for 150ms Wait for 638us Play 784 Hz for 150ms
   blue   LED: Play 587 Hz for 150ms Wait for 851us Play 587 Hz for 150ms
   green  LED: Play 880 Hz for 150ms Wait for 568us Play 880 Hz for 150ms
*/
byte tonePin = 8;

void setup(){
  pinMode(tonePin, OUTPUT);
  RedLEDSound();
  YellowLEDSound();
  BlueLEDSound();
  GreenLEDSound();
}

void loop(){}

void PlayTone(unsigned int m_frequency, unsigned long m_duration, unsigned long m_pause){
  tone(tonePin, m_frequency, m_duration);
  delayMicroseconds(m_pause);
  noTone(tonePin);
}

void RedLEDSound(){
  PlayTone(440, 150, 1136);
  PlayTone(440, 150, 0);
}

void YellowLEDSound(){
  PlayTone(784, 150, 638);
  PlayTone(784, 150, 0);
}

void BlueLEDSound(){
  PlayTone(587, 150, 851);
  PlayTone(587, 150, 0);
}

void GreenLEDSound(){
  PlayTone(880, 150, 568);
  PlayTone(880, 150, 0);
}
```


message:
Analog read not working while using WiFi

I have an ESP32, the current program running on it uses WiFi but, if I use WiFi and Analog read at the same time, Analog read does not work.

Why does this happen and what's the way around it?

Hardware - ESP32, Pin 25 for the ADC

Code-
```
#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.begin("You really", "Want to know"); // If this line is commented then it works
}

void loop() {
  Serial.println(analogRead(25));
}
```

body:
The ESP32 has two ADCs. One of them, ADC2, is actively used by the WiFi.

From the IDF documentation:

> Since the ADC2 module is also used by the Wi-Fi, only one of them could get the preemption when using together, which means the adc2_get_raw() may get blocked until Wi-Fi stops, and vice versa.

That means you can't use the ADC on any of the ADC2 channels while WiFi is on: GPIO4, GPIO0, GPIO2, GPIO15, GPIO13, GPIO12, GPIO14, GPIO27, GPIO25 and GPIO26.

But you can use ADC1, which uses pins GPIO36, GPIO37, GPIO38, GPIO39, GPIO32, GPIO33, GPIO34 and GPIO35.


message:
DS3231 is unable to keep record of time

so i bought a DS3231 clock which i am using with [This][1] famous library .

    // DS3231_Serial_Easy
    // Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
    // web: http://www.RinkyDinkElectronics.com/
    //
    // A quick demo of how to use my DS3231-library to
    // quickly send time and date information over a serial link
    //
    // To use the hardware I2C (TWI) interface of the Arduino you must connect
    // the pins as follows:
    //
    // Arduino Uno/2009:
    // ----------------------
    // DS3231:  SDA pin   -> Arduino Analog 4 or the dedicated SDA pin
    //          SCL pin   -> Arduino Analog 5 or the dedicated SCL pin
    //
    // Arduino Leonardo:
    // ----------------------
    // DS3231:  SDA pin   -> Arduino Digital 2 or the dedicated SDA pin
    //          SCL pin   -> Arduino Digital 3 or the dedicated SCL pin
    //
    // Arduino Mega:
    // ----------------------
    // DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA pin
    //          SCL pin   -> Arduino Digital 21 (SCL) or the dedicated SCL pin
    //
    // Arduino Due:
    // ----------------------
    // DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA1 (Digital 70) pin

    #include <DS3231.h>

    // Init the DS3231 using the hardware interface
    DS3231  rtc(SDA, SCL);

    void setup()
    {
      // Setup Serial connection
      Serial.begin(9600);
      // Uncomment the next line if you are using an Arduino Leonardo
      //while (!Serial) {}

      // Initialize the rtc object
      rtc.begin();

      // The following lines can be uncommented to set the date and time
      //rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
      //rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
      //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
    }

    void loop()
    {
      // Send Day-of-Week
      Serial.print(rtc.getDOWStr());
      Serial.print(" ");

      // Send date
      Serial.print(rtc.getDateStr());
      Serial.print(" -- ");

      // Send time
      Serial.println(rtc.getTimeStr());

      // Wait one second before repeating :)
      delay (1000);
    }

Now the problem is, after i set a time it shows the time and date perfectly until i cut the power of the DS3231. while being connected to my PC when i disconnected the power of DS3231, i see the timer getting reset while it should have recorded and continued the timer. It outputs 'Monday 1.1.2021 0.0.0'

Is it the problem of my module? or i am doinng something mistake here? or the module works in this way?

whenever i disconnect arduino power from PC, it still continues to count but whenever i disconnect DS3231 from 5 v pin of Arduino, it resets back. Does that mean that the DS3231 need to use the 16Mhz crystal from Arduino to function properly??

  [1]: http://www.rinkydinkelectronics.com/library.php?id=73

body:
So you disconnect the 5V to the DS3231, but keep the SDA and SCL pins connected? By doing that, you are working outside of the recommended operating conditions.

If you leave the SDA and SCL pins connected, those pins will be at around 5V. The datasheet specifies that those pins shouldn't be higher that Vcc+0.3V. Where Vcc is 0V, in your case.

Removing power from the Arduino board will also remove the power from the I2C pins, keeping things within specifications.


message:
How to GET HTTP Request from Arduino to Firebase?

I have an Arduino UNO and SIM808 and I'm trying to send my GPS data to the Firebase. I have successfully created a website which I can post data from the website to the Firebase. However I'm trying to send my data from Arduino to the website which failed constantly. I have no idea what is the error.

These are my codes:

      /*
        ### Get GPS data
        1. This example is used to test SIM808 GPS/GPRS/GSM Shield's reading GPS data.
        2. Open the SIM808_GetGPS example or copy these code to your project
        3. Download and dial the function switch to Arduino
        4. open serial helper
        4. Place it outside, waiting for a few minutes and then it will send GPS data to serial

        create on 2016/09/23, version: 1.0
        by jason

      */
      #include <DFRobot_sim808.h>
      #include <SoftwareSerial.h>

      #define PIN_TX    10
      #define PIN_RX    11
      SoftwareSerial mySerial(PIN_TX, PIN_RX);
      DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

      #define APN "diginet"
      #define USER ""
      #define PASS ""
      unsigned long previousMillis = 0;
      long interval = 60000;

      String the_year, the_month, the_day, the_hour, the_minute, the_second, the_time;
      String latitude, longitude;

      //DFRobot_SIM808 sim808(&Serial);

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

        //******** Initialize sim808 module *************
        while (!sim808.init()) {
          delay(1000);
          Serial.print("Sim808 init error\r\n");
        }

        //************* Turn on the GPS power************
        if ( sim808.attachGPS())
          Serial.println("Open the GPS power success");
        else
          Serial.println("Open the GPS power failure");

      }

      void loop() {
        //************** Get GPS data *******************
        getGPS();

        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis > interval) {
          previousMillis = currentMillis;
          sendtoFirebase();
        }

      }

      void getGPS() {

        if (sim808.getGPS()) {
          delay(500);
          the_year = sim808.GPSdata.year;
          the_month = sim808.GPSdata.month;
          the_day = sim808.GPSdata.day;
          the_hour = sim808.GPSdata.hour;
          the_minute = sim808.GPSdata.minute;
          the_second = sim808.GPSdata.second;
          the_time = the_year + " / " + the_month + " / " + the_day + " " + the_hour + ": " + the_minute + ": " + the_second;
          Serial.print(the_time);
          //Serial.print(sim808.GPSdata.year);
          //types(sim808.GPSdata);

          latitude = String(sim808.GPSdata.lat, 6);
          longitude = String(sim808.GPSdata.lon, 6);
          Serial.println(latitude);
          Serial.println("longitude : ");

          Serial.println(longitude);

          sim808.latitudeConverToDMS();
          sim808.LongitudeConverToDMS();
          //Serial.print("latitude : ");
          //        Serial.print(sim808.latDMS.degrees);
          //        Serial.print("\^");
          //        Serial.print(sim808.latDMS.minutes);
          //        Serial.print("\'");
          //        Serial.print(sim808.latDMS.seconeds,6);
          //        Serial.println("\"");
          //    Serial.print("longitude :");
          //    Serial.print("longitude :");
          //    Serial.print(sim808.longDMS.degrees);
          //    Serial.print("\^");
          //    Serial.print(sim808.longDMS.minutes);
          //    Serial.print("\'");
          //    Serial.print(sim808.longDMS.seconeds, 6);
          //    Serial.println("\"");

          //    Serial.print("speed_kph :");
          //    Serial.println(sim808.GPSdata.speed_kph);
          //    Serial.print("heading :");
          //    Serial.println(sim808.GPSdata.heading);

          //************* Turn off the GPS power ************
          //sim808.detachGPS();
        }
      }

      void sendtoFirebase() {

        boolean newData = false;
        for (unsigned long start = millis(); millis() - start < 2000;) {
          while (sim808.getGPS()) {
            newData = true;
          }
        }

        if (newData) {
          newData = false;

          String deviceId = "ABC1235";

          Serial.print("Device ID:");
          Serial.println(deviceId);

          Serial.print("Time:");
          Serial.println(the_time);
          Serial.print("latitude:");
          Serial.println(latitude);
          Serial.print("longitude:");
          Serial.println(longitude);

          String temp;

          //build the URL to the proxy
          String url = "http://myfypproject.epizy.com/firebase.php?arduino_data=25.00";
          //  url += "&deviceid=";
          //  url += String(deviceid);
          //  url += "&lat=";
          //  url += String(latitude);
          //  url += "&lon=";
          //  url += String(longitude);

          Serial.println(url);
          sendATcommand("AT+CFUN=1", "OK", 2000);
          //AT+CGATT = 1 Connect modem is attached to GPRS to a network. AT+CGATT = 0, modem is not attached to GPRS to a network
          sendATcommand("AT+CGATT=1", "OK", 2000);
          //Connection type: GPRS - bearer profile 1
          sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
          //sets the APN settings for your network provider.
          sendATcommand("AT+SAPBR=3,1,\"APN\",\"diginet\"", "OK", 2000);
          //enable the GPRS - enable bearer 1
          sendATcommand("AT+SAPBR=1,1", "OK", 2000);
          //Init HTTP service
          sendATcommand("AT+HTTPINIT", "OK", 2000);
          sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 1000);
          //Set the HTTP URL sim800.print("AT+HTTPPARA="URL","http://ahmadssd.000webhostapp.com/gpsdata.php?lat=222&lng=222"\r");
          //sendATcommand("AT+HTTPPARA=\"URL\",\"http://myfypproject.epizy.com/firebase.php?arduino_data=25.00\"", "OK", 1000);
          mySerial.print("AT+HTTPPARA=\"URL\",\"");
          mySerial.print(url);
          sendATcommand("\"", "OK", 1000);
          //Set up the HTTP action
          sendATcommand("AT+HTTPACTION=0", "0,200", 1000);
          //Terminate the HTTP service
          sendATcommand("AT+HTTPTERM", "OK", 1000);
          //shuts down the GPRS connection. This returns "SHUT OK".
          //sendATcommand("AT+CIPSHUT", "SHUT OK", 1000);

        }

        return 1;
      }

      int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout) {
        uint8_t x = 0, answer = 0;
        char response[100];
        unsigned long previous;

        //Initialize the string
        memset(response, '\0', 100);
        delay(100);

        //Clean the input buffer
        while (mySerial.available() > 0) mySerial.read();

        if (ATcommand[0] != '\0') {
          //Send the AT command
          mySerial.println(ATcommand);
        }

        x = 0;
        previous = millis();

        do {
          //if there are data in the UART input buffer, reads it and checks for the asnwer
          if (mySerial.available() != 0) {
            response[x] = mySerial.read();
            //Serial.print(response[x]);
            x++;
            // check if the desired answer (OK) is in the response of the module
            if (strstr(response, expected_answer) != NULL) {
              answer = 1;
            }
          }
        } while ((answer == 0) && ((millis() - previous) < timeout));

        Serial.println(response);
        return answer;

      }

I keep get the error of 603.

    AT+HTTPACTION=0
    OK
    +HTTPACTION: 0, 603, 0

Below are my PHP, website to firebase codes:

        <?php
    require_once 'firebaseLib.php';
    // --- This is your Firebase URL
    $url = 'https://projectname-default-rtdb.asia-southeast1.firebasedatabase.app/';
    // --- Use your token from Firebase here
    $token = 'XXXXXXXXXXJYszyqIJxr3UuGl1Zr6qHG03K';
    // --- Here is your parameter from the http GET
    $arduino_data = $_GET['arduino_data'];
    // --- Set up your Firebase url structure here
    $firebasePath = '/GPSdata';

    /// --- Making calls
    $fb = new fireBase($url, $token);
    $response = $fb->set($firebasePath, $arduino_data);
    echo $url;
    sleep(2);

**UPDATE:**

I can get code 200, but there isn't any result in my firebase or my website.

body: It is just the server problem. I just changed a website and it works.


message:
Why float and not 16-bit Integer? Mpu6050 with atmega328P

I've been trying to follow this example code for interfacing my atmega328P with Mpu6050:
https://www.instructables.com/Accelerometer-MPU-6050-Communication-With-AVR-MCU/

And was wondering a couple of things. First of all, the sensors on an MPU6050 are 16-bit, which means that each sensor value such as Ax, Ay etc. are 2 byte each (8-bit + 8-bit = 16-bit = 2 bytes).

The code itself reads from the following line when obtaining the values: `AcX = Wire.read()<<8 | Wire.read();` where the MSB (8-bit) are first read, and then the LSB (8-bit); which gives us 2 bytes.

So what I don't understand is why he uses float values for storing the sensor-data and not a 16-bit int? Since Floats are 4 byte long; won't that just add a bunch of zeros to the obtained 2 bytes?

body:
We can't know this writer's reasons, but a typical reason why someone might use floats vs. ints is that they prefer not to manage the binary-point location and any possible overflows during the following calculations. Instead, they are willing to accept the tradeoff of execution-time vs. programming time, and the increased memory requirements (both RAM and Flash) of letting the floating-point library do it for them.

Update:

Or, as implied elsewhere, the programmer doesn't know how to calculate with integer arithmetic (which to be fair, is a little more complicated than just writing out the formula).