message:
Prevent Resetting of Null Weight when using HX711 with a load cell

Helllo,\
I am using the HX711 module and load cell with an arduino uno for force measurements.
I am using [this library](https://github.com/olkal/HX711_ADC).

I first use the example ["Calibration"](https://github.com/olkal/HX711_ADC/blob/master/examples/Calibration/Calibration.ino) code for calibration with a 200 g weight.
Then I save the calibration constant to the eeprom (choosing yes on the serial monitor).
Then the load cell is able to measure weights accurately.

After that I remove the weight from the load cell and run [this code](https://github.com/olkal/HX711_ADC/blob/master/examples/Read_1x_load_cell/Read_1x_load_cell.ino) after uncommenting the last line of this part of the above code:
```
LoadCell.begin();
  //LoadCell.setReverseOutput();
  float calibrationValue;
  calibrationValue = 696.0;
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512);
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // I have uncommented this
```

The weights are measured accurately.

**But when before powering the arduino, if I keep a weight on the load cell that weight is taken to be 0.**

For this I have done the following change to the code:
```
boolean _tare = false;
```

But I get the following output on the serial monitor (Note: The following output is obtained on startup when there is/there is no weight on the load cell):

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

**Questions:**
What is the use of the following line:
```
calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch
```
Is it useless for the code I am using above? Because I am using the calibration value from the eeprom.

Q2) Why is it showing -39000 as an output value?
And how to correct it?

**Alternate Statement:**
In other words, I want to use the HX711 module with the arduino and a load cell. I will first calibrate it with a known weight and save the calibration value.
Before powering up the arduino I will keep a weight on the load cell. After powering up the weight value should be the absolute value instead of making the Weight Null.

**EDIT1:**
I incorporate the changes suggested in the answers by @Edgar Bonet and also make the problem more clear just in case.
According to suggestions I have made the corresponding changes to the calibration code. Then I run that and the values are saved to eeprom. Code changes:
```
const int calVal_eepromAdress = 0;
const int tare_eepromAdress = sizeof(float);
```
and
```
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
        EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();
```

Now, I wish to run the [second script](https://github.com/olkal/HX711_ADC/blob/master/examples/Read_1x_load_cell/Read_1x_load_cell.ino) and for this to display the correct weights.
This should work in all cases regardless of whether a weight has not been kept on the load cell or has been kept and should be independent of the weight that has been kept.
To this script I have made the following changes:
```
const int calVal_eepromAdress = 0;
const int tare_eepromAdress = sizeof(float);
```
and
```
// Inside void setup()
void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  float tareValue;
  calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch
  tareValue = 0;
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
  EEPROM.get(tare_eepromAdress, tareValue);

  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    LoadCell.setTareOffset(tareValue);
    Serial.println("Startup is complete");
  }
}
```

**EDIT2:**
```
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
        EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());

        Serial.println(newCalibrationValue);
        Serial.println(LoadCell.getTareOffset());
```
Output:
```
-206.90
8368790
```

In the second script:
```
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
  EEPROM.get(tare_eepromAdress, tareValue);
  Serial.println(calibrationValue);
  Serial.println(tareValue);
```

Output:
```
-206.90
0.00
```

I am uploading my codes onto Github just in case. They can be found [here](https://github.com/atharvaaalok/LoadCell_Corrected).

Q) What is happening here?

**EDIT3:**
The following changes make it work like a charm:
In the "Calibration" script:
```
long tareValue = LoadCell.getTareOffset(); // Instead of float tareValue
```
Similarly in the second script:
```
long tareValue; // Instead of float tareValue
```

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

body:
In order to convert the raw ADC readings to a weight, the library needs
two coefficients:

* a “tare offset”, which is the raw reading when there is no weight on
  the scale
* a gain, or “calibration factor”, which is the ratio of a change in the
  ADC reading to the corresponding change in weight.

The examples provided with the library use the EPPROM to store and
retrieve the calibration factor, but not the tare offset. This makes
sense as, in common usage, a weight scale is always zeroed at power up,
or right after power up. This is usually desirable as one would often
place an empty container on the scale which should not affect the
displayed weight.

If you do not want to zero the scale at power-up, then you need your
sketch to remember the tare offset in addition to the calibration
factor. For this, you can use the methods of `LoadCell`:

```c++
// Get the tare offset (raw data value output without
// the scale "calFactor").
long getTareOffset();

// Set new tare offset (raw data value input without
// the scale "calFactor").
void setTareOffset(long newoffset);
```

Now, to the more specific questions:

> What is the use of the following line:
>
> ```c++
> calibrationValue = 696.0;
> ```

None. It is just an example. You are supposed to either replace this
number with your measured calibration factor, or remove this line and
read `calibrationValue` from the EEPROM.

> Why is it showing -39000 as an output value?

Because the tare offset has not been set, so it presumably defaults to
zero.

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

**Edit**: Answering extra questions in comment.

> Do I need to store this value to the eeprom when running the
> calibration script?

You can store it whenever it is convenient to you. The calibration
script seems a good place.

> I am not able to get this into code. I read the source files but I am
> unsure about what changes to make.

What you may try (untested):

1. right after the line

   ```c++
   const int calVal_eepromAdress = 0;
   ```

   add this:

   ```c++
   const int tare_eepromAdress = sizeof(float);
   ```

2. Right after this:

   ```c++
   EEPROM.put(calVal_eepromAdress, newCalibrationValue);
   ```

   add this:

   ```c++
   EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());
   ```


sender: user

message:
Is there a way to connect two Arduinos, when one of them has all of its pins occupied?

I want to connect an Arduino Uno to an Arduino Nano, so that it can send signals. The problem is that the Arduino Uno has a motor shield connected to it, and it takes up all pins of the Arduino.

This is a picture of the whole motor shield contraption if it helps:

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

Does anybody know any solution for this?

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

sender: assistant

body:
Pins 0 and 1 are serial pins which are also connected to usb, and you use them when you are programming your board or when you send anything to serial. It is unlikely that any shield uses it unless it has to and it although has a benefit of being able to listen to what the Arduino sends.
I think hitching a ride on pins 1 and 0 (rx/tx) would be the easiest. SO you can print or write to them the same way as you respond to yourself.

Just a warning that when you are sending data between two boards and Print numbers they come as symbols of the numbers, not the numbers themselves So ``` Serial.print(7) ``` would arrive to the next arduino as number 55 or symbol '7'. If you are sending numbers between two arduinos you can use write ```Serial.write(7);``` which does not change data, but your serial monitor on a computer wont read it right, or you can send them as symbols, but then the arduino listening may have to convert number symbol to the number. (sooner or later you will have to create yourself a simple function to convert symbols to numbers in your project...


message:
Code does not run when arduino is powered with AC adapter

I'm trying to implement the circuit as shown with an arduino nano. The project runs fine when powered via USB port of the arduino. However, the code freezes when connected to an AC adapter. When switched back to power supply via USB, the code does not run and resetting the board has no effect. The board starts to work again only when the code is re-uploaded.

Tried the following to troubleshoot the issue with no success.
1) Changed the power supply
2) Tried with a blink sketch and an example code of U8glib
3) Eliminated the MOSFET's Q1 & Q2 to simplify further

The only other component in question seems to be the buck converter connected between the AC adapter and the nano board. But it is rated for 5V,3A and should not be of concern I believe. Appreciate your inputs.

Edit:Uploaded a blink sketch to the nano. Works ok over the USB power. But it starts resetting randomly when connected to the power supply. Swapped the buck converter with an LDO and it seems to work flawlessly. The output of the buck converter reads about 5.18V and according to the Atmega328p datasheet, it can accept upto 5.5V. Could the problem be associated with the switching frequency of the buck?(The stated switching frequency is about 500kHz) P.S- I'm using the nano clone. Not sure if it adheres to the original parameters as stated in the Atmega datasheet.
[![enter image description here][1]][1]

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

body:
Is the buck converter properly filtered?

Many ebay/amazon supplies are done too cheaply. While LEDs will run from practicaly anything with at-least some sign of correct specs, combination of back converter trying to keep-up with changing current and compensate to achieve correct voltage, while voltage regulator is adjusting and as such changing the consumption characteristics... dependant on buck converters changes.
MCU requirements for clean supply are lot greater them that of LEDs.
Bunch of suitable capacitors after the buck converter, but before the arduino might do it. Hopefuly somebody better then me in that area might advice you bout capacitor values. mine rough guess would be 100nF of about 20V.


message:
Pro Micro COM port disappeared after upload

I uploaded a sketch to my Pro Micro and it stopped showing in serial ports. Other Arduinos show up just fine.

I've tried to detect serial devices using pyserial and it's also not seeing anything. I've tried to reset the board by connecting the reset pin to ground twice in quick succession but it's not doing anything.

The board might be broken, but it seems unlikely to me as it's not connected to anything high powered.

The sketch I uploaded does use serial, but that hasn't been a problem before.

Any ideas on how to recover the board?

body:
The Pro Micro uses a single processor (ATmega32U4) unlike some of the other Arduinos which have a separate processor for USB communications.

When reset, it will appear as a USB device for a couple of seconds, and then if the sketch does not use Serial, or uses it inappropriately, it could stop responding. For example, if the code went into a loop.

It is highly unlikely that the board just "broke". I suggest keeping the processor in Reset (tie Reset to Ground) while you compile a new sketch, and then release Reset when it tells you it is starting to upload.

You haven't posted your code, but it quite possibly is the problem. For example, you might have disabled interrupts.


message:
Send HEX number over serial

I have a RS232 device that I am able to communicate with using RealTerm on a windows PC.

The device is expecting a hex string like `AA BB 03 01 03 EE`

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

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

---

How would I send the equivalent string from an arduino? (I feel confident the arduino is wired correctly since I can see incoming uart data)

Things I have tried

```
void setup() {
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop() {
      Serial.println('AA BB 03 01 01 EE', "OCT");
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.print('0xAA 0xBB 0x03 0x01 0x01 0xEE', "DEC");
      delay(3000);
      Serial.print('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.print('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.print('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', HEX);
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE', HEX);
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE');
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE', HEX);
      delay(3000);
      Serial.write('AA BB 03 01 01 EE');
      delay(3000);
      Serial.write('0xAA 0xBB 0x03 0x01 0x01 0xEE');
      delay(3000);
}

```
I've also tried using double quotes as mentioned in the comments

```
     Serial.write("AA BB 03 01 01 EE");
     delay(3000);

     Serial.write("0xAA 0xBB 0x03 0x01 0x01 0xEE");
     delay(3000);

     Serial.write("101010101011101100000011000000010000000111101110");
     delay(2000);

```

Additionally I've tried writing the serial one line at a time
```
  Serial.write(0xaa); // AA
  Serial.write(0xbb); // BB
  Serial.write(0x03); // 03
  Serial.write(0x01); // 01
  Serial.write(0x01); // 01
  Serial.write(0xee); // EE
  Serial.write(0x0d); // \r
  Serial.write(0x0a); // \n
  delay(3000);
```

Additional Information

- [controlling projector using arduino](https://www.youtube.com/watch?v=bQ7qvjxSUXU)
- [Adding \r\n to hex sent over arduino](https://www.reddit.com/r/Esphome/comments/i8srtv/projector_control/?sort=confidence)

body:
As noticed by jsotola in a comment, your device doesn't seem to be
expecting HEX at all, but rather plain binary. `Serial.print()` is not
appropriate, as it is designed for sending ASCII text. For binary data,
you should prefer `Serial.write()`. More specifically, for sending
arbitrary binary data, the proper method is

```c++
size_t Print::write(const uint8_t *buffer, size_t size)
```

Applying this to your example gives:

```c++
const size_t packet_length = 6;
uint8_t packet[packet_length] = {0xaa, 0xbb, 0x03, 0x01, 0x03, 0xee};
Serial.write(packet, packet_length);
```


body:
if device expects actual numbers, then it does not receive them in hex format or decimal, but in binary. in which case you would need an array of numbers and then go with them using for loop (or purpouse made function.
```
byte sequence[]={0xAA, 0xBB, 0x03, 0x01, 0x01, 0xEE};
for(byte i=0; i<sizeof(sequence);i++) Serial.write(sequence[i]);
```
if you have to send it as a HEX, then its most likely a case of hex representation and you can use printf for that
```
Serial.printf("0xX 0xX 0xX 0xX 0xX 0xX", 0xAA, 0xBB, 0x03, 0x01, 0x01, 0xEE);
```

Another  think is that you should be careful using `println` when communicating with other devices.
`println` ads extra character (number) for new line, after the data you wish to send. if you only want to send data you wish to send, then use `print` instead

Edit:
Thanks for the note from Edgar Bonet, I was warned that printf is still not a standard instruction outside of the ESP core.
Its well worth adding it up by yourself. Look for a guide on arduino playground.


message:
How to send an array of unknown size via I2C (from slave to master)?

When I try something like this, everything works.

Slave:
```c++
    # define DEFAULT_DATA_SIZE 256

    byte DATA[DEFAULT_DATA_SIZE];

    void requestEvent()
    {
      Wire.write( (byte*) DATA, sizeof(DATA));
    }

    void receiveEvent(int numBytes)
    {
      for (int i = 0; i < numBytes; i++) {
        DATA[i] = Wire.read();
      }
    }
```
Master:
```c++
    # define DEFAULT_DATA_SIZE 5

    void writeData(byte data[], int numBytes) {
      Wire.beginTransmission(I2C_SLAVE_ADDRESS);
      for (int i = 0; i < numBytes; i++)
      {
        Wire.write(data[i]);
      }
      Wire.endTransmission();
    }

    void readData() {
      byte data[DEFAULT_DATA_SIZE];
      Wire.requestFrom( I2C_SLAVE_ADDRESS, DEFAULT_DATA_SIZE );
      if ( Wire.available() == sizeof( data))
      {
        Wire.readBytes( (byte *) data, DEFAULT_DATA_SIZE);
      }
      Serial.print("Byte Array: ");
      for (int i = 0; i < DEFAULT_DATA_SIZE; i++ ) {
        Serial.print(data[i]);
        Serial.print(" ");
      }
      Serial.println();
    }

    byte data[5] = {0x1, 0x2, 0x3, 0x4, 0x5 };

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

      writeData(data, sizeof(data));
      delay(500);
      readData();
    }

    void loop() {

    }
```
But this only works when the master knows how long the array needs to be.
If I set the value of `DEFAULT_DATA_SIZE` not to 5, but more, then I get a set of random numbers.

I tried to make the slave pass the length of the array first, and then the array itself. But for some reason it doesn't work and I also get random numbers.

Slave:
```c++
    #include <Wire.h>
    # define I2C_SLAVE_ADDRESS 12
    # define DEFAULT_DATA_SIZE 256

    byte DATA[DEFAULT_DATA_SIZE];
    int RECEIVED_NUMBYTES = 0;
    bool isNumBytesSended = false;

    void setup()
    {
      Wire.begin(I2C_SLAVE_ADDRESS);
      delay(1000);
      Wire.onRequest(requestEvent);
      Wire.onReceive(receiveEvent);
    }

    void loop()
    {
    }

    void requestEvent()
    {
      if (!isNumBytesSended) {
        isNumBytesSended = true;
        Wire.write(RECEIVED_NUMBYTES);
      }
      else {
        isNumBytesSended = false;
        Wire.write( (byte*) DATA, sizeof(DATA));
      }
    }

    void receiveEvent(int numBytes)
    {
      RECEIVED_NUMBYTES = numBytes;
      for (int i = 0; i < numBytes; i++) {
        DATA[i] = Wire.read();
      }
    }
```
Master:
```c++
    #include <Wire.h>
    # define I2C_SLAVE_ADDRESS 12
    # define DEFAULT_DATA_SIZE 10

    void writeData(byte data[], int numBytes) {
      Wire.beginTransmission(I2C_SLAVE_ADDRESS);
      for (int i = 0; i < numBytes; i++)
      {
        Wire.write(data[i]);
      }
      Wire.endTransmission();
    }

    void readData() {
      Wire.requestFrom( I2C_SLAVE_ADDRESS, 1 );
      int numBytes = Wire.read();
      Serial.println("numBytes: " + String(numBytes));

      byte data[numBytes];
      if ( Wire.available() == sizeof( data))
      {
        Wire.readBytes( (byte *) data, numBytes);
      }
      Serial.print("Byte Array: ");
      for (int i = 0; i < numBytes; i++ ) {
        Serial.print(data[i]);
        Serial.print(" ");
      }
      Serial.println();
    }

    byte data[5] = {0x1, 0x2, 0x3, 0x4, 0x5 };

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

      writeData(data, sizeof(data));
      delay(100);
      readData();
    }

    void loop() {

    }
```
Master outputs:

>01:20:13.844 -> numBytes: 5\
    01:20:13.878 -> Byte Array: 11 8 212 8 22 \
    01:21:51.222 -> numBytes: 0\
    01:21:51.255 -> Byte Array: \
    01:21:54.323 -> numBytes: 5\
    01:21:54.323 -> Byte Array: 11 8 212 8 22 \
    01:22:01.682 -> numBytes: 0\
    01:22:01.717 -> Byte Array: \
    01:22:04.280 -> numBytes: 5\
    01:22:04.314 -> Byte Array: 11 8 212 8 22 \
    01:22:06.879 -> numBytes: 0\
    01:22:06.912 -> Byte Array: \
    01:22:10.386 -> numBytes: 5\
    01:22:10.420 -> Byte Array: 11 8 212 8 22

Please tell me the best way to solve this problem. Maybe transfer all values one byte at a time, and put a special delimiter between the beginning of new data?

body:
yes, the idea of sending one byte at a time and specifying the length of the array worked. I'm surprised that I didn't do that sooner :)

SLAVE:

    #include <Wire.h>
    # define I2C_SLAVE_ADDRESS 12
    # define DEFAULT_DATA_SIZE 256

    byte DATA[DEFAULT_DATA_SIZE];
    int pointer = 0;

    void setup()
    {
      Wire.begin(I2C_SLAVE_ADDRESS);
      delay(1000);
      Wire.onRequest(requestEvent);
      Wire.onReceive(receiveEvent);
    }

    void loop()
    {
    }

    void requestEvent()
    {
      if (pointer > DATA[0]) {
        Wire.write(0);
      }
      else {
        Wire.write(DATA[pointer++]);
      }
    }

    void receiveEvent(int numBytes)
    {
      DATA[0] = numBytes;
      for (int i = 1; i <= numBytes; i++) {
        DATA[i] = Wire.read();
      }
      pointer = 0;
    }

MASTER:

    #include <Wire.h>
    # define I2C_SLAVE_ADDRESS 12

    void writeData(byte data[], int numBytes) {
      Wire.beginTransmission(I2C_SLAVE_ADDRESS);
      for (int i = 0; i < numBytes; i++)
      {
        Wire.write(data[i]);
      }
      Wire.endTransmission();
    }

    void readData() {
      Wire.requestFrom( I2C_SLAVE_ADDRESS, 1 );
      int numBytes = Wire.read();
      Serial.println("numBytes: " + String(numBytes));

      byte data[numBytes];

      for (int i = 0; i < numBytes; i++) {
        Wire.requestFrom( I2C_SLAVE_ADDRESS, 1 );
        data[i] = Wire.read();
      }
      Serial.print("Byte Array: ");
      for (int i = 0; i < numBytes; i++ ) {
        Serial.print(data[i]);
        Serial.print(" ");
      }
      Serial.println();
    }

    byte data[8] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 };

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

      writeData(data, sizeof(data));
      delay(100);
      readData();
    }

    void loop() {

    }


message:
How to store a struct in a file?

I'm trying to store (read&write( a struct using `LittleFS` on ESP8266.

Appreciate assistance

    struct oper_string
    {
      bool state;     /* On or Off */
      uint8_t step;   /* Step, in case of PWM */
      uint8_t reason; /* What triggered the button */
      time_t ontime;  /* Start Clk */
      time_t offtime; /* Off Clk */
    };

body:
you can think of a struct as an array (group) of variables which might be of a different sizes and struct helps you take specific portion of this string.
Lets say you have a struct of
```
struct foo{
   bool first;
   uint8_t Second;
   uint16_t Third;
} structMember;
```
Then it is stored in a row in exactly same order as they have been defined
```
---------------------------
| bool | uint8_t | uint16_t|
|1 byte| 1 bytes | 2 bytes |
--------------------------
1B+1B+2B = sizeof(srtuctMember)
```
File.write()
saves date in a file in block of 1Byte each.

When you send array to the function it actualy receives only  a ***pointer*** to its beginning.
That is why many functions take a size as a second argument.

When you send a data into a function in a format its not designed to take you can tell the compiler that the function should trait it as a different type of variable.
Lets say we have function defined as
`void sampleFunction(byte var1)`
then we can use it by
```
char x='j';
sampleFunction((byte) x);
```
which tells compiler to treat 'x' as if it was `byte`.

when you pass array you are not really passing the actual data, but an information where the data is(same with the struct member), so by putting asterisk after the definition you are telling compiler the format of data it ***points*** to.
and when you read it back you will get all the contend back as same data in same order... which struct then divides in a same way

```
file.write((byte*) &StructMember,sizeof(structMember));
```


body:
Just as a complement to Tomas' answer (which is perfectly valid), I
would like to point out that consecutive members of a struct may not be
adjacent in memory. Some structs have padding within them, which is
needed to satisfy [alignment requirements][align].

The struct given by Tomas as an example will not have padding, but yours
may. For example, on my 64-bit PC, your struct is stored as follows:

| offset | size | member    |
|--------|------|:----------|
|    0   |   1  | state     |
|    1   |   1  | step      |
|    2   |   1  | reason    |
|    3   |   5  | (padding) |
|    8   |   8  | ontime    |
|   16   |   8  | offtime   |

In the table above, “offset” is the position of the member relative to
the start of the struct. The padding after `reason` is needed in order
to align `ontime` at an address that is multiple of 8. Your ESP
being a 32-bit machine, it is likely to use only a single byte of
padding.

Padding may be an issue for two reasons:

1. It can differ between computer architectures. Thus, if you plan to
   write the file on the ESP and read it back on your PC (or vice
   versa), it is one of the possible sources of incompatibility, the
   others being endianness and member sizes.

2. It is a waste of disk space, although this might not be an issue if
   you are only loosing 1 byte out of 20.

If padding can be problematic, the only valid option is to write and
read the struct one member at a time. Conversely, if the file is only
ever going to be accessed by the ESP, and you don't mind loosing a few
percent of the file to padding, then don't worry, follow Tomas' advice,
and read and write the struct as an array of bytes: it is just simpler.

[align]: https://en.wikipedia.org/wiki/Data_structure_alignment


body:
one can write a struct directly into a SPIFS/ FFAT file like this:

     * EXAMPLE READING AND WRITING A C++ STRUCT TO A FILE
     */
    #include <FS.h>
    #include <SPIFFS.h>

    typedef struct {
      char someString[10];
      float someFloat;
    } MyStruct;

    MyStruct myStruct = { "test test",1.7 };

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);

      if(!SPIFFS.begin()){
          Serial.println("Card Mount Failed");
          return;
      }

      strncpy( myStruct.someString, "testtesttest", sizeof(myStruct.someString) );
      File myFile = SPIFFS.open("/somefile.txt", FILE_WRITE);
      myFile.write((byte *)&myStruct, sizeof(myStruct));
      myFile.close();
    }

    void loop() {
      // put your main code here, to run repeatedly:
      File myFile = SPIFFS.open("/somefile.txt", FILE_WRITE);
      myFile.read((byte *)&myStruct, sizeof(myStruct));
      myFile.close();
      Serial.printf( "read: %s, %.2f\n", myStruct.someString, myStruct.someFloat );
      delay(1000);
    }

the code above is available on [this](https://gist.github.com/CelliesProjects/7fab9013517583b3a0922c0f153606a1) Github Gist.


message:
What's the difference between CloudTemperature, CloudTemperatureSensor and Float data types?

I have a SHT30 sensor for Wemos and I am learning to use Arduino IOT Cloud.

I use **float** data type for my `temperature` variable but I see two more data types:

**CloudTemperature**

**CloudTemperatureSensor**

What are the differences? Shouldn't use **float**?

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

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

body:
From the [technical reference][1] for the Arduino Cloud on arduino.cc:

> For your convenience, IoT Cloud provides specialized types which are just wrappers around basic types but declare the variable semantics more explicitly. This enables smarter integrations with third-party services (such as Alexa) and better visualization of widgets in dashboards.
>
> You can use them just like a normal variable of the wrapped type, since they support assignment and comparison operators.

These types are actually wrapper classes, which add some functionality to better integrate in cloud services. You can use these just as the normal data types.

---

You can even look at how they are defined. Let's look at `CloudTemperature` for example. All the files can be found in the [ArduinoIoTCloud repo][2] on github.

The types are defined in the [PropertyContainer.h][3] file:

    ...
    #include "types/CloudFloat.h"
    ...
    typedef CloudFloat CloudTemperature;
    ...

So `CloudTemperature` is actually just `CloudFloat`, which is included from the corresponding header file. When we look at the [CloudFloat.h][4] file we find:

    class CloudFloat : public Property {
      protected:
        float _value,
              _cloud_value;
    ...

So internally `CloudFloat` is just a float value with added functionality. And you can use it like any other float, since below that part that I've shown here all the operators (like `/`, `*`, `+`, ...) are overwritten (so the class knows what to do with these operators).

`CloudTemperatureSensor` is found at [CloudTemperatureSensor.h][5] and inherits from `CloudFloat` so works basically the same way (it only overwrites the assignment operator; the rest is the same as `CloudFloat`).

---

> Shouldn't use float?

I haven't tried that myself. But from the documentation it sounds like there is no reason to not use the specialized types, since they provide the same functionality and more.

  [1]: https://docs.arduino.cc/arduino-cloud/getting-started/technical-reference
  [2]: https://github.com/arduino-libraries/ArduinoIoTCloud
  [3]: https://github.com/arduino-libraries/ArduinoIoTCloud/blob/41660e01a813de414c6e26fdfe4119465d78ffaa/src/property/PropertyContainer.h
  [4]: https://github.com/arduino-libraries/ArduinoIoTCloud/blob/master/src/property/types/CloudFloat.h
  [5]: https://github.com/arduino-libraries/ArduinoIoTCloud/blob/master/src/property/types/automation/CloudTemperatureSensor.h


message:
Arduino Serial to USB=>serial data issue

I am using Mega 2560 to receive serial data from another device but the data appears on the serial terminal are strange characters. then i connected my USB to serial cable (HL-340) to the device and tried in serial terminal(Termite), data is landing fine.
Replaced Arduino with another one since I believed there could be a problem, but the problem persisted.
for further investigation i have connected my Arduino (Mega-2560) to my serial(USB->Serial) cable directly to receive data on the terminal but strangely even this is showing the wrong data (Arduino terminal is displaying the wright data but the data appears on the other terminal is wrong) sendind "c" receiving "N"...
what could be the reason for this..its a simple code to print character on the screen.
Thx

[![HL-340 USB-Serial cable][1]][1]
[![Arduino Mega-2560][2]][2]
[![Code and Terminal's data][3]][3]

  [1]: https://i.stack.imgur.com/oXKzD.jpg
  [2]: https://i.stack.imgur.com/Xioio.jpg
  [3]: https://i.stack.imgur.com/sN5Yr.png

body:
You need to be careful. Normal devices that have a "Serial" interface actually have an RS232 interface. While the data transmission scheme is similar with the "Serial" interface on the Uno/Mega (UART on TTL logic), RS232 has totally different voltage levels (up to -15 to +15V), which can kill your Arduino.

To connect an RS232 device to an Arduino you need a level converter (to convert between the RS232 levels and the TTL (Transistor Transistor Logic) level of the Arduino. The chip MAX232 is typically used for this. There are many resources about that on the web and even ready to use modules, which are equipped with a MAX232 and a RS232/Serial plug.


message:
Novice learning Serial.readString()

New to Arduino, getting into String variables and reading them from serial monitor.
Basically what I'm trying to do is have the user input either red, green, yellow. Whichever String they enter the LED comes on.

What is happening seems to be that the if statements are not true and are never entered thus not LEDs come on. I do have a serial.Println(myColor) at the end which displays myColor as the user has inputted into serial monitor. I just don't understand why the if statements are not firing. its really weird.

    String msg="What LED do you want to turn on?";
    String myColor;
    int redPin = 12;
    int greenPin = 13;
    int yellowPin = 8;

    void setup(){
    Serial.begin(9600);
    pinMode(redPin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(yellowPin, OUTPUT);
    }

    void loop(){
        //LED ColorDEmo

        Serial.println(msg);                //print the question to serial monitor
        while(Serial.available() == 0){     //while we wait do nothing till data is available

        }
        myColor = Serial.readString();      // set myColor to serial value

        if (myColor == "red"){              // if the value is red
            Serial.println("In red");
            turnOffLEDS();                  // turn off all LEDS
            digitalWrite(redPin, HIGH);     // turn on red lED
        }

        if (myColor == "green"){            // if the value is green
            Serial.println("In green");
            turnOffLEDS();                  // turn off all LEDS
            digitalWrite(greenPin, HIGH);   // turn on green LED
        }

        if (myColor == "yellow"){           // if the value is yellow
            Serial.println("In yellow");
            turnOffLEDS();                  // turn off all LEDS
            digitalWrite(yellowPin, HIGH);  // turn on yellow LED
        }
        Serial.println(myColor);            // print myColor

    }

    // turns all LEDS off
    void turnOffLEDS(){
        digitalWrite(yellowPin, LOW);
        digitalWrite(greenPin, LOW);
        digitalWrite(redPin, LOW);
    }

body:
thank you @jsotola

throught he debugging you mentioned i was able to learn that the '\n' was added to the end of the string. Instead of using
`Serial.readString()` I used `Serial.readStringUntil('\n');`

this would check for a delimiter character '\n' then stop. Thus, my myColor variable would be red instead of red'\n'


body:
Avoiding String objects (back to the basics) often makes life easier.
Simply check if the answer contains one of the characters 'd' 'g' 'y'

Or (and) simplify your *protocol* to only send one character.

BTW:You might notice a delay in readString, waiting for a multi-character input to finish, because Serial.available() is true already after the first character of an input, and [readString terminates only if it times out][1]

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/serial/readstring/


message:
Trouble connecting barcode scanner to ESP32 devkit using UART - fails to connect over serial

I'm having trouble connecting a [SparkFun 2D Barcode Scanner Breakout](https://www.sparkfun.com/products/18088) (effectively a DE2120) to a 30-pin ESP32 dev kit v1 (marked ESP-WROOM-32) and running the [SerialScan](https://github.com/sparkfun/SparkFun_DE2120_Arduino_Library/tree/main/examples/Example1-SerialScan) sample application for this sensor successfully.

I believe I have the two devices connected as per the instructions:

> ESP32 -> DE2120
> 3V3 -> 3.3v
> GND -> GND
> RX2 -> RX
> TX2 -> TX

In the sample code I have pins configured as follows:

    SoftwareSerial softSerial(25,27);

(according to the mapping [here](https://www.mischianti.org/wp-content/uploads/2020/11/ESP32-DOIT-DEV-KIT-v1-pinout-mischianti.png) these are the TX2/DX2 and the right pin numbers)

But something is not right: the sample code never reports a connection being made. Tracing this back, it looks like isConnected() [here](https://github.com/sparkfun/SparkFun_DE2120_Arduino_Library/blob/main/src/SparkFun_DE2120_Arduino_Library.cpp) is always returning false, which means sendCommand() is either timing out or getting a DE2120_COMMAND_NACK.

I'm stumped. I've tried 2 different scanner units, replaced all the cables, tried swapping pin numbers around, and done a load of trials using HardwareSerial too with no success. The scanner unit itself responds to commands when I connect it to a laptop and talk to it over USB serial.

Any ideas? I am assuming there is something deeply trivial I'm getting wrong (e.g. in the physical connection or in the specifics of serial connections on ESP32). Generally I've found example code from Arduino libraries runs first time, but I am relatively new to Arduino.

Update 7/20: I have tried with pins 16 and 17, and also with RX2->TX and TX -> RX2. I have scanned the setup barcode as per the [instructions](https://learn.sparkfun.com/tutorials/2d-barcode-scanner-breakout-hookup-guide/all).

body:
Answering my own question: this is about the scanner not getting enough power from the ESP32 devkit board, I think.

When I power both the barcode scanner and the ESP32 from separate power supplies (both USB) I can connect from the ESP32 to the scanner and read codes just fine.

However when I power the scanner from the ESP32, following the instructions in the [hookup guide](https://learn.sparkfun.com/tutorials/2d-barcode-scanner-breakout-hookup-guide/all), the scanner is unresponsive.


message:
Gyro reading of MPU6050 drifts too much on fast changes only

I am trying to write a simple sketch for the MPU6050.

The problem is that the sensor is pretty much solid when stationary or changing the angle steadily at slow to mid angular velocities but if I try to change the angle too fast there's a huge drift in the readings by pretty much tens of degrees in either direction as shown in the below images from the serial plotter.

On slow to mid changes in the pitch angle the gyro is tracking the accelerometer pitch almost identically (it drifts a little over time but it's normal and acceptable for the complementary filter).

On fast changes however the pitch drifts instantly by tens of degrees from the accelerometer. The huge drift makes the complementary filter pretty much useless in correcting the output

It's my first try with the sensor so I don't have any experience with its parameters. But the problem seems to be in the lines of integrating the new angular velocities in roll and pitch.

 - I got lazy and used the default sensitivity scale factors; does this have anything to do with this behaviour?

 - The dt measured for the Arduino is 20 ms between readings; is this too slow for the fast changes or something?

 - The datasheet also mentioned a programmable output range. Does this need to be programmed for more bandwidth and accurate results?

## EDIT:
I tried to read a bit about the sensitivity scale factor. It seemed that increasing the angular velocity beyond 250 degrees per second is not measured when selecting the default configuration.

After some testing I realized that 1000 deg/s is a good configuration for me; the drift certainly is much better but still not what I hoped for.
It still drifts by +- 10 degrees in two or three seconds of moving it around.

## Slow to Mid changes output: ##
[![Slow to Mid speed changes in the pitch][1]][1]

## Fast changes output: ##
[![Fast changes in the pitch][2]][2]

```
#include <Wire.h>
#define CAL_AVERAGE 2000

const int MPU = 0x68; //I2C address of MPU6050
const float alpha = 0.95;

double ax, ay, az;
double gx, gy, gz;

//float accAngleX, accAngleY, accAngleZ;
//float gyroAgnleX, gyroAngleY, gyroAngleZ;

double accErrorX, accErrorY, accErrorZ;
double gyroErrorx, gyroErrorY, gyroErrorZ;

double accRoll, accPitch;
double gyroRoll, gyroPitch, gyroYaw;

double roll, pitch, yaw;

double dt, currentTime, previousTime;

void setup(){
  previousTime = 0;

  Serial.begin(115200);
  Wire.begin();     //init the communication

  //reset the mpu
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);
  Wire.write(0x00);
  Wire.endTransmission(true);

  //calibrate here
  calculateError();
}

void loop(){
  readAcc();
  readGyro();

  //get roll and pitch of accelerometer
  accRoll = atan2(ay, az) * 180 / PI;
  accPitch = atan2(ax, az) * 180 / PI;

  currentTime = millis();
  //set gyro roll and pitch for accelerometer roll and pitch on first reading only
  if (previousTime != 0) {
    //get roll, pitch and yaw of gyro
    dt = currentTime - previousTime;
    dt /= 1000;
    gyroRoll += gx * dt;
    gyroPitch += -gy * dt;
    gyroYaw += gz * dt;
  } else {
    gyroRoll = accRoll;
    gyroPitch = accPitch;
    gyroYaw = 0;
  }

  previousTime =  currentTime;

  roll = alpha*gyroRoll + (1 - alpha)*accRoll;
  pitch = alpha*gyroPitch + (1 - alpha)*accPitch;
  yaw = gyroYaw;

  //finally print the values collected
  printData();
}

void readAcc(){
  //first read accelerometer data
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true);

  //accelerometer raw data
  ax = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
  ay = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
  az = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;

  ax -= accErrorX;
  ay -= accErrorY;
  az -= accErrorZ;
}

void readGyro(){
  //second read gyro
  Wire.beginTransmission(MPU);
  Wire.write(0x43);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true);

  //gyro raw data
  gx = ( (Wire.read() << 8) | Wire.read() ) / 131.0;
  gy = ( (Wire.read() << 8) | Wire.read() ) / 131.0;
  gz = ( (Wire.read() << 8) | Wire.read() ) / 131.0;

  gx -= gyroErrorx;
  gy -= gyroErrorY;
  gz -= gyroErrorZ;
}

void calculateError(){
  float axErr = 0, ayErr = 0, azErr = 0;
  float gxErr = 0, gyErr = 0, gzErr = 0;

  for (int i = 0; i < CAL_AVERAGE; i++) {
    readAcc();
    az = az - 1;

    axErr += ax;
    ayErr += ay;
    azErr += az;

    readGyro();

    gxErr += gx;
    gyErr += gy;
    gzErr += gz;
  }

  accErrorX = axErr/CAL_AVERAGE;
  accErrorY = ayErr/CAL_AVERAGE;
  accErrorZ = azErr/CAL_AVERAGE;

  gyroErrorx = gxErr/CAL_AVERAGE;
  gyroErrorY = gyErr/CAL_AVERAGE;
  gyroErrorZ = gzErr/CAL_AVERAGE;
}

void printData() {
  Serial.print(ax);
  Serial.print(",     ");
  Serial.print(ay);
  Serial.print(",     ");
  Serial.print(az);

  Serial.print(",               ");

  Serial.print(gx);
  Serial.print(",     ");
  Serial.print(gy);
  Serial.print(",     ");
  Serial.print(gz);

  Serial.print(",               ");

  Serial.print(accPitch);
  Serial.print(",     ");
  Serial.print(accRoll);

  Serial.print(",               ");

  Serial.print(gyroPitch);
  Serial.print(",     ");
  Serial.print(gyroRoll);
  Serial.print(",     ");
  Serial.print(gyroYaw);

  Serial.print(",               ");

  Serial.print(pitch);
  Serial.print(",     ");
  Serial.print(roll);
  Serial.print(",     ");
  Serial.print(yaw);

  Serial.print(",     ");
  Serial.println(dt);
}

```

  [1]: https://i.stack.imgur.com/qbPlS.png
  [2]: https://i.stack.imgur.com/OBhg7.png

body:
Consider what might happen if the code or hardware [dead reckoning][1] capabilities were too slow to accurately sample short events. Such as a sudden stop. Robbed of the opportunity to integrate a fast deceleration event, the code and hardware might continue to report motion.

To speed up code execution, consider switching from trigonometry based calculations to [quaternion calculations][2].  In general this replaces time consuming repetitive summation algorithms with simple math calculations more suitable for embedded processors.

To speed up the hardware, consider an Arduino platform with a faster processor.

Also consider more creative solutions suitable for your application:
 * If angular momentum is more important than linear motion sample the accelerometer only every other time through your main loop.
 * Or, if motion is totally random, and the device is on Earth, consider zero-calibrating the gyroscope when there is no movement perceived by the accelerometer.  Specifically, when there is a 9.8m/s*s vector sensed by the accelerometer and the pitch, roll and yaw of the accelerometer is not changing.

  [1]: https://en.wikipedia.org/wiki/Dead_reckoning
  [2]: https://en.wikipedia.org/wiki/Quaternion


body:
In his answer, st2000 recommends you use quaternions, rather than Euler
angles, for tracking the orientation of your vehicle. I will give the
exact same recommendation, but for a different reason: the formulas you
use, namely

```c++
gyroRoll += gx * dt;
gyroPitch += -gy * dt;
gyroYaw += gz * dt;
```

are just plain wrong. They are correct if rotations only ever happen
along a single axis. They are also “kinda good” (correct as a
first-order approximation) if the angles involved are very small. But in
the general case, they are wrong. A easy way to convince yourself of
this fact is to notice that the final (yaw, pitch, roll) being the sum
of many small contributions, they do not depend on the _order_ in which
these contributions were added. In other words, these formulas imply
that the composition of rotations is commutative, which I hope you know
is not the case.

The only reasonable ways of composing many rotations (which is what this
attitude-tracking code tries to do) are rotation matrices and
quaternions, the latter being more efficient.

Now, a few remarks:

 1. You should not track (`gyroRoll`, `gyroPitch` and `gyroYaw`)
    independently from (`roll`, `pitch`, `yaw`), otherwise your
    complementary filter becomes inefficient at canceling gyro drift.
    You should instead merge those variable into a single triplet.

 2. The line

    ```c++
    ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
    ```

    gets you the two bytes from the MPU in an unspecified order. They
    may be in the right order with this particular version of this
    particular compiler when run with this particular set of options,
    but you should not count on this order being reliable. You should
    instead read the two bytes in two separate statements.

 3. If you do not care about the yaw, you may just track the gravity
    vector instead of the full attitude. This should save you the calls
    to `atan2()` and possibly simplify the math further. You may not
    even need the quaternions after all.


message:
Avrdude verification error when uploading to Arduino Mega 2560

I have been getting the error
```avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x036c
0xb8 != 0xf8
avrdude: verification error; content mismatch
avrdude done.  Thank you.
```
When trying to upload the example blink sketch to an Arduino mega 2560.

I did some googling and found that the common recommendation to solve this is to flash the bootloader.

Which does fix the issue for the first upload after flashing, but the issue reappears after one upload. But every time I flash the bootloader I do get one successful upload following that with no errors.

The mismatch is always at 0x036c every time.

body:
The verification is there to check two possible error situations: Transmission error while uploading or faulty flash memory. Apparently, the error can also happen for a bunch of other reasons (see the linked answer), but these two cases should still be considered. Since another Arduino works with the same cable, it's unlikely a communication error and hence, based on all we know, I am assuming your Arduino is bad.

You might be lucky that for some reason (the fault is in some piece of code that's not actually used) the program works despite the error, but it's likely that sooner or later you'll get very strange crashes or otherwise undefined behavior.


message:
How can I force an I2C module (for 1602 and 2004) to work with a 1601 LCD at my Arduino Micro

I'm new to Arduino and want to build a Button Box. When I buyed the parts I didn't watched out for the specifications of the I2C module. When I tried to print sth on the LCD nothing happened (in retro perspective it's logical). I wouldn't like to have to buy a new LCD.

How can I make the LCD work with the I2c module?

LCD - http://cdn-reichelt.de/documents/datenblatt/A500/DEM16101SYH.pdf

I2C-module - http://mantech.co.za/datasheets/products/lcd2004-i2c.pdf

it's wired correctly (VCC to 5V, GND to GND, SDA to SDA and SCL to SCL)

The Code I used is the "Hello World" Example thats included in the LiquidCrystal_I2C library, but with a few changes:

    //YWROBOT
    //Compatible with the Arduino IDE 1.0
    //Library version:1.1
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,1);  //instead of LiquidCrystal_I2C lcd(0x27,20,4);

    void setup()
    {
      lcd.init();                      // initialize the lcd
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(3,0);
      lcd.print("Hello, world!");
      lcd.setCursor(2,0); //isntead of lcd.setCursor(2,1);
      lcd.print("Ywrobot Arduino!");
       lcd.setCursor(0,0); //instead of lcd.setCursor(0,2);
      lcd.print("Arduino LCM IIC 2004");
       lcd.setCursor(2,0); //instead of lcd.setCursor(2,3);
      lcd.print("Power By Ec-yuan!");
    }

    void loop()
    {
    }

body:
Welcome Chritzelopf! Yes pull up resistors are required by the I2C definition. Your link on the driver shows they are not included and no schematic to  indicate otherwise. The I2C bus is driven by open collector/drain semiconductor devices. This configuration will pull the line low but not source any current into it other then possibly some leakage. When the outputs of the I2C device are off the bus is pulled high or placed in the recessive state by the pull up resistors. When one or more of the devices turn on the bus is now in the dominate state or low. This configuration allows anything to turn on or off without damaging other devices on the bus. I like the pull up(s) to be in the 4.7K for 5V and about 3.3K in the 3V3v.

Some modules come with pull ups that are permanently connected, others are selectable with jumpers etc. This is NOT the A0 - A? jumpers which are address select lines. I always check the modules to determine if there are pull ups enabled and adjust my other resistances to get an appropriate value, sometimes even removing them.


message:
ESP8266 web server not responding when running a http request function

I am trying to build something that can control a stepper motor based on weather information from openweathermap. I've set up a ESP8266 webserver to manually control motor movement with buttons and I have set up the structure to talk to openweathermap API to get the information I want (printing them to serial monitor for now for testing).

However, when I combined the 2 things break. The current code allows me to get weather perfectly but I can no longer connect to my web server running in STA mode. Something in the `getWeather()` function is messing with the web server because if I remove `getWeather()` from my loop the web server works.

Any idea what I am doing wrong here?

    #include <SPI.h>
    #include <AccelStepper.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPClient.h>  // http web access library
    #include <ArduinoJson.h>        // JSON decoding library

    // Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
    #define dirPin 5
    #define stepPin 4
    #define motorInterfaceType 1
    bool motorStop;
    bool motorCW;
    bool motorCCW;

    AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

    //Put your SSID & Password
    const char* ssid = "[ssid]";  // Enter SSID here
    const char* password = "[password]";  //Enter Password here

    //OpenWeatherMap API key
    String apiKey= "[apikey]";

    //OpenWeatherMap location
    String location= "lat=37.30&lon=-121.91";
    String unit= "metric";

    const unsigned long postingInterval = 1000*60*60; // delay between updates, in milliseconds

    WiFiClient client;

    ESP8266WebServer server(80);

    // Set your Static IP address
    IPAddress local_IP(192, 168, 86, 248);
    // Set your Gateway IP address
    IPAddress gateway(192, 168, 86, 1);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress primaryDNS(192, 168, 86, 1);

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

    // Configures static IP address
    if (!WiFi.config(local_IP, gateway, subnet,primaryDNS)) {
      Serial.println("STA Failed to configure");
    }

      stepper.setMaxSpeed(1000);

      Serial.println("Connecting to ");
      Serial.println(ssid);

      //connect to your local wi-fi network
      WiFi.begin(ssid, password);

      //check wi-fi is connected to wi-fi network
      while (WiFi.status() != WL_CONNECTED) {
      delay(1000);
      Serial.print(".");
      }
      //Print out connection info
      Serial.println("");
      Serial.println("WiFi connected..!");

      server.on("/", handle_OnConnect);
      server.on("/cw_on", handle_CW_on);
      server.on("/cw_off", handle_CW_off);
      server.on("/ccw_on", handle_CCW_on);
      server.on("/ccw_off", handle_CCW_off);
      server.on("/mstop", handle_stop);
      server.onNotFound(handle_NotFound);

      server.begin();
      Serial.println("HTTP server started");
    }

    void loop() {

      server.handleClient();
      if(motorStop)
      {stepper.setSpeed(0);}
      if(motorCW)
      {stepper.setSpeed(400);}
      if(motorCCW)
      {stepper.setSpeed(-400);}

      // Step the motor with a constant speed as set by setSpeed():
      stepper.runSpeed();

      getWeather();
    }

    void getWeather()
    {
      // if there's a successful connection:
      if (client.connect("api.openweathermap.org", 80))
      {
        Serial.println("connected");
        // send the HTTP PUT request:
        client.println("GET /data/2.5/onecall?" + location + "&exclude=current,minutely,hourly" +  "&appid=" + apiKey);
        client.println("Host: api.openweathermap.org");
        client.println("Connection: close");
        client.println();

        const size_t capacity = 8*JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(8) + 16*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 8*JSON_OBJECT_SIZE(6) + 8*JSON_OBJECT_SIZE(14) + 1810;
        DynamicJsonDocument doc(capacity);

        deserializeJson(doc, client);

        float lat = doc["lat"]; // 37.3
        float lon = doc["lon"]; // -121.91
        const char* timezone = doc["timezone"]; // "America/Los_Angeles"
        int timezone_offset = doc["timezone_offset"]; // -25200

        JsonArray daily = doc["daily"];

        // tomorrow's forecast (daily_1)
        JsonObject daily_1 = daily[1];
        long daily_1_dt = daily_1["dt"]; // 1596225600
        long daily_1_sunrise = daily_1["sunrise"]; // 1596201109
        long daily_1_sunset = daily_1["sunset"]; // 1596251761

        JsonObject daily_1_temp = daily_1["temp"];
        float daily_1_temp_day = daily_1_temp["day"]; // 306.61
        float daily_1_temp_min = daily_1_temp["min"]; // 288.67
        float daily_1_temp_max = daily_1_temp["max"]; // 306.61
        float daily_1_temp_night = daily_1_temp["night"]; // 288.67
        float daily_1_temp_eve = daily_1_temp["eve"]; // 295.94
        float daily_1_temp_morn = daily_1_temp["morn"]; // 293.26

        JsonObject daily_1_feels_like = daily_1["feels_like"];
        int daily_1_feels_like_day = daily_1_feels_like["day"]; // 303.31
        float daily_1_feels_like_night = daily_1_feels_like["night"]; // 287.59
        float daily_1_feels_like_eve = daily_1_feels_like["eve"]; // 293.77
        float daily_1_feels_like_morn = daily_1_feels_like["morn"]; // 292.42

        int daily_1_pressure = daily_1["pressure"]; // 1015
        int daily_1_humidity = daily_1["humidity"]; // 17
        float daily_1_dew_point = daily_1["dew_point"]; // 278.68
        float daily_1_wind_speed = daily_1["wind_speed"]; // 3.12
        int daily_1_wind_deg = daily_1["wind_deg"]; // 318

        JsonObject daily_1_weather_0 = daily_1["weather"][0];
        int daily_1_weather_0_id = daily_1_weather_0["id"]; // 800
        const char* daily_1_weather_0_main = daily_1_weather_0["main"]; // "Clear"
        const char* daily_1_weather_0_description = daily_1_weather_0["description"]; // "clear sky"
        const char* daily_1_weather_0_icon = daily_1_weather_0["icon"]; // "01d"

        int daily_1_clouds = daily_1["clouds"]; // 0
        int daily_1_pop = daily_1["pop"]; // 0
        float daily_1_uvi = daily_1["uvi"]; // 9.53

        // print out weather information
        Serial.print("Tomorrow's Forecast");
        Serial.print("Temperature: ");
        Serial.println(daily_1_feels_like_day);
        Serial.print("Weather: ");
        Serial.println(daily_1_weather_0_main);
        delay (postingInterval);
      }
      else
      {
        // if you couldn't make a connection:
        Serial.println("connection failed");
        delay (postingInterval);
      }
    }

    void handle_OnConnect() {
      motorStop = HIGH;
      motorCW = LOW;
      motorCCW = LOW;
      Serial.println("Motor: Stopped");
      server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
    }

    void handle_CW_on() {
      motorStop = LOW;
      motorCW = HIGH;
      motorCCW = LOW;
      Serial.println("Motor: Running Clock-wise");
      server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
    }

    void handle_CW_off() {
      motorStop = HIGH;
      motorCW = LOW;
      motorCCW = LOW;
      Serial.println("Motor: Stopped");
      server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
    }

    void handle_CCW_on() {
      motorStop = LOW;
      motorCW = LOW;
      motorCCW = HIGH;
      Serial.println("Motor: Motor: Running Counter Clock-wise");
      server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
    }

    void handle_CCW_off() {
      motorStop = HIGH;
      motorCW = LOW;
      motorCCW = LOW;
      Serial.println("Motor: Stopped");
      server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
    }

    void handle_stop() {
      motorStop = HIGH;
      motorCW = LOW;
      motorCCW = LOW;
      Serial.println("Motor: Stopped");
      server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
    }

    void handle_NotFound(){
      server.send(404, "text/plain", "Not found");
    }

    String SendHTML(uint8_t mstop,uint8_t cw, uint8_t ccw){
      String ptr = "<!DOCTYPE html> \n";
      ptr +="<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
      ptr +="<title>LED Control</title>\n";
      ptr +="\n";
      ptr +="\n";
      ptr +="\n";
      ptr +="
Weather Station
\n";
      ptr +="
Runs either direction continuously
\n";

       if(cw)
      {ptr +="
Motor running Clock-wise
Stop\n";}
      else
      {ptr +="
Motor not running Clock-wise
Run\n";}

      if(ccw)
      {ptr +="
Motor running Counter Clock-wise
Stop\n";}
      else
      {ptr +="
Motor not running Counter Clock-wise
Run\n";}

      ptr +="\n";
      ptr +="\n";
      return ptr;
    }

body:
At the end of `getWeather()` you call `delay(postingInterval);`

`postingInterval` is set to `60*60*1000` ... one hour. That means `getWeather()` won't return for one hour and nothing else in `loop()` will be processed during that time, including the web server.

You need to remove that `delay()` call and rewrite your loop to check if `postingInterval` milliseconds have passed and only call `getWeather()` if they have.


message:
Setup loops: never enters loop - restarting?

I uploaded the following to my UNO with WiFi:

    #include <SPI.h>
    #include <Wire.h>
    #include "Adafruit_CCS811.h"

    Adafruit_CCS811 ccs; // The air quality sensor

    String Dataline = "";

    void setup() {
      Wire.begin();

      Serial.begin(115200);
      Serial.println("SET UP");
    }

    void loop() {
      // wait a second between measurements.
      delay(1000);

      Dataline = "";
      Dataline = Dataline + getTime();
      Dataline = Dataline + AIRSensor();
      Dataline = Dataline + "...";
      Serial.println(Dataline);
    }

    String getTime() {
      String OUT = "Tim::";
      OUT += String(millis());
      return OUT;
    }

    String AIRSensor() {
      if (ccs.available()) {
        if (!ccs.readData()) {
          float temp = ccs.calculateTemperature();
          String CO2 = (String)ccs.geteCO2();
          return "CO2::" + CO2 +"TAQ::" + (String)temp;
        }
      } else {
        return "CO2::-999,TAQ::-999";
      }
    }

The output is simply "SET UP" repeated:

    SET UP
    SET UP
    SET UP
    ...

It never enters the loop or prints anything else out. Does this mean the UNO is resetting? How do I troubleshoot?

body:
You can tell that something is going wrong between your `println`. Some advice in this case: eliminate the `String` entirely and replace the `println` with a series of `print`. This would let you narrow down which function is causing the problem. It also can save some memory, which is a nice bonus in embedded programming.

I suspect in this case the problem is your use of C-style casts to `String` in `AIRSensor()`. `(String)whatever` and `String(whatever)` do very different things, and the former is not something you want here, or something you should be using very often in C++ code.

The code in `loop` is running, but it is crashing and causing the hardware to reset. Since it is crashing before it reaches the first visible behavior in `loop`, it just looks like `setup` is running over and over.


message:
How to set number in address field?

I want to build structure of record. The problem is that I can't build the address field correctly. Can any one help me?

P.s: the address[16:2] is start from bit 61 to bit 47 so please you can't say you should shift it by 32.

[![the Record that I want to Build][1]][1]

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

body:
For this I would use *[bit fields](https://en.cppreference.com/w/cpp/language/bit_field)*:

```c++
typedef union {
    struct {
        uint8_t raw[8]; // Raw access to the bytes
    };
    struct {
        unsigned data:32;
        unsigned cs14:1;
        unsigned cs13:1;
        unsigned cs12:1;
        unsigned cs11:1;
        unsigned cs10:1;
        unsigned cs9:1;
        unsigned cs8:1;
        unsigned cs7:1;
        unsigned cs6:1;
        unsigned cs5:1;
        unsigned cs4:1;
        unsigned cs3:1;
        unsigned cs2:1;
        unsigned cs1:1;
        unsigned cs0:1;
        unsigned address:15;
        unsigned parity:1;
        unsigned stop:1;
    };
    struct {
        unsigned :32;
        unsigned cs:15;
        unsigned :17;
    };
} Packet;
```

Then you can:

```c++
Packet p;
p.data = 0x493DE26CUL;
p.address = 0x13f3;
p.cs3 = 1;
// or
p.cs = 0x0080;
```

etc.


message:
Non-blocking sketch

So far, a part of this code works fine, but Relay 1 keeps turning on and off instead of staying off.

My purpose is to turn Relay 7 on, wait 3s, turn Relay 8 on, wait 10s, turn Relay 6 on, wait 10s, turn Relay 7 off, wait 10s, turn Relay 5 on, wait 3s, turn Relay 6 off, wait 10s, turn Relay5 on, wait 3s, turn Relay 6 off, wait 10s, turn Relay4 on, wait 3s, turn Relay 5 off, wait 10s, turn Relay 3 on, wait 3s, turn Relay 4 off, wait 10s, turn Relay 2 on, wait 3s, turn Relay 3 off, wait 10s, turn Relay 1 on, wait 10s, turn Relay 1 off, wait 3s, turn Relay 8 off, without looping, only one sequence.

I need some help.

```c++
int RelayPompe = 2;
int RelayVanne7 = 3;
int RelayVanne6 = 4;
int RelayVanne5 = 5;
int RelayVanne4 = 6;
int RelayVanne3 = 7;
int RelayVanne2 = 8;
int RelayVanne1 = 9;

const unsigned long eventInterval1 = 10000;
const unsigned long eventInterval2 = 3000;
const unsigned long eventInterval3 = 15000;
const unsigned long eventInterval4 = 20000;
unsigned long previousTime1 = 0;
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;
unsigned long previousTime4 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(RelayPompe, OUTPUT);
  pinMode(RelayVanne1, OUTPUT);
  pinMode(RelayVanne2, OUTPUT);
  pinMode(RelayVanne3, OUTPUT);
  pinMode(RelayVanne4, OUTPUT);
  pinMode(RelayVanne5, OUTPUT);
  pinMode(RelayVanne6, OUTPUT);
  pinMode(RelayVanne7, OUTPUT);
  digitalWrite(RelayPompe, HIGH);
  digitalWrite(RelayVanne1, HIGH);
  digitalWrite(RelayVanne2, HIGH);
  digitalWrite(RelayVanne3, HIGH);
  digitalWrite(RelayVanne4, HIGH);
  digitalWrite(RelayVanne5, HIGH);
  digitalWrite(RelayVanne6, HIGH);
  digitalWrite(RelayVanne7, HIGH);
}

void loop() {
  unsigned long currentTime = millis();
  if (currentTime - previousTime1 >= eventInterval1) {
    digitalWrite(RelayPompe, LOW);
    previousTime1 = currentTime;
  }
  if (currentTime - previousTime2 >= eventInterval2) {
    digitalWrite(RelayVanne1, LOW);
    previousTime2 = currentTime;
  }
  if (currentTime - previousTime3 >= eventInterval3) {
    digitalWrite(RelayVanne2, LOW);
    previousTime3 = currentTime;
  }
  if (currentTime - previousTime4 >= eventInterval4) {
    digitalWrite(RelayVanne1, HIGH);
    previousTime4 = currentTime;
  }
}
```

body:
For this kind of thing I'd be inclined to create an array (maybe of structs) describing what you want the relays to do, then write a program that steps through that array executing each "instruction" in sequence. That way it separates out what you want to do from how you want it to be done (if that makes sense).

So you could make a simple struct:

```c++
typedef struct {
    uint8_t relays;
    uint32_t postDelay;
} RelayState;
```

Then you can make an array using that struct to describe your relay states. Using a bitmap for your relays (bit 0 is relay 1, bit 1 is relay 2, etc) means you can pack everything into one integer and describe the relays in binary notation:

```c++
RelayState states[] = {
    { 0b01000000,  3000 }, // Relay 7 on, wait 3 seconds
    { 0b11000000, 10000 }, // Relay 8 on, wait 10 seconds
    { 0b11100000, 10000 }, // Relay 6 on, wait 10 seconds
    { 0b10100000, 10000 }, // Relay 7 off, wait 10 seconds
    { 0b10110000,  3000 }, // Relay 5 on, wait 3 seconds
    // ... etc ...
    { 0, 0 } // Marker for the end of the array
};
```

If ever you want to change the sequence you just change the contents of that array with no need to mess with the rest of your program.

It can also be useful to create an array with your relay pins in it:

```c++
const uint8_t relayPins[8] = { 9, 8, 7, 6, 5, 4, 3, 2 };
```

Now you just need to write a small program that only has to deal with the current entry in the array - set the relays according to the first part then delay according to the second part, and step to the next entry.  Something that could look like:

```c++
void setup() {
    // Set the relay pins to outputs
    for (int i = 0; i < 8; i++) {
        pinMode(relayPins[i], OUTPUT);
    }

    // Set the initial state from the first entry in the array
    setRelays(states[0].relays);
}

void loop() {
    static uint32_t ts = millis(); // Storage for the time
    static uint8_t pos = 0;

    if ((millis() - ts) >= states[pos].postDelay) { // Our time is up
        ts = millis(); // Record the time
        pos++; // Move to the next entry
        if ((states[pos].relays == 0) && (states[pos].postDelay == 0)) { // Last entry marker
            pos = 0; // Start from the beginning again
        }
        setRelays(states[pos].relays);
    }
}

// Small helper function to set the relays according to a bitmap
void setRelays(uint8_t bm) {
    for (int i = 0; i < 8; i++) {
        digitalWrite(relayPins[i], bm & (1 << i));
    }
}
```

Note: this code has not been tested, just written "off the cuff", and may not even compile. But regardless, it should give you a rough idea of the methodology.

----

The format of the bitmaps is very simple. They're just a binary representation of a number where each bit is one relay. Turn that bit on and the corresponding relay turns on.

* Relay 1: 0b00000001
* Relay 2: 0b00000010
* Relay 3: 0b00000100

etc.  Just set a 1 for a relay to be on and a 0 for a relay to be off at that point in time.

So turn relay 1 on is 0b00000001, then turn on relay 4 at the same time is 0b00001001, and then turn relay 1 off again is 0b00001000 (relay 4 is still on).


message:
Error while burning bootloader onto ATMega-8A using Arduino Mega 2560: avrdude: invalid byte value

So, I'm trying to burn the bootloader onto an ATMega 8A with an Arduino Mega 2560 as ISP.
I made the necessary connections, and got this error:

    C:\Program Files (x86)\Arduino\hardware/tools/avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega8 -cstk500v1 -P\\.\COM3 -b19200 -e -Ulock:w:0x3f:m -Uhfuse:w:0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}:m -Ulfuse:w:0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}:m

    avrdude: Version 5.11, compiled on Sep  2 2011 at 19:38:36
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2009 Joerg Wunsch

             System wide configuration file is "C:\Program Files (x86)\Arduino\hardware/tools/avr/etc/avrdude.conf"

             Using Port                    : \\.\COM3
             Using Programmer              : stk500v1
             Overriding Baud Rate          : 19200
    avrdude: Send: 0 [30]   [20]
    avrdude: Send: 0 [30]   [20]
    avrdude: Send: 0 [30]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
             AVR Part                      : ATMEGA8
             Chip Erase delay              : 10000 us
             PAGEL                         : PD7
             BS2                           : PC2
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom         4    20   128    0 no        512    4      0  9000  9000 0xff 0xff
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               flash         33    10    64    0 yes      8192   64    128  4500  4500 0xff 0x00
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               lfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               hfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               lock           0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               calibration    0     0     0    0 no          4    0      0     0     0 0x00 0x00
                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : STK500
             Description     : Atmel STK500 Version 1.x firmware
    avrdude: Send: A [41] . [80]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [02]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [81]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [01]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [82]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [12]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [98]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
    avrdude: Send: A [41] . [84]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [85]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [86]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [87]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [89]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

    avrdude: Send: A [41] . [81]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [01]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [82]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [12]
    avrdude: Recv: . [10]
    avrdude: Send: B [42] p [70] . [00] . [00] . [01] . [01] . [01] . [01] . [02] . [ff] . [00] . [ff] . [ff] . [00] @ [40] . [02] . [00] . [00] . [00]   [20] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
    avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
    avrdude: Send: P [50]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
    avrdude: AVR device initialized and ready to accept instructions

    Reading | avrdude: Send: V [56] 0 [30] . [00] . [00] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [1e]
    avrdude: Recv: . [10]
    avrdude: Send: V [56] 0 [30] . [00] . [01] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [93]
    avrdude: Recv: . [10]
    ################avrdude: Send: V [56] 0 [30] . [00] . [02] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [07]
    avrdude: Recv: . [10]
    ################################## | 100% 0.06s

    avrdude: Device signature = 0x1e9307
    avrdude: Send: V [56] . [a0] . [01] . [fc] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [ff]
    avrdude: Recv: . [10]
    avrdude: Send: V [56] . [a0] . [01] . [fd] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [ff]
    avrdude: Recv: . [10]
    avrdude: Send: V [56] . [a0] . [01] . [fe] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [ff]
    avrdude: Recv: . [10]
    avrdude: Send: V [56] . [a0] . [01] . [ff] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [ff]
    avrdude: Recv: . [10]
    avrdude: erasing chip
    avrdude: Send: V [56] . [ac] . [80] . [00] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [00]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [81]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [01]
    avrdude: Recv: . [10]
    avrdude: Send: A [41] . [82]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [12]
    avrdude: Recv: . [10]
    avrdude: Send: B [42] p [70] . [00] . [00] . [01] . [01] . [01] . [01] . [02] . [ff] . [00] . [ff] . [ff] . [00] @ [40] . [02] . [00] . [00] . [00]   [20] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
    avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
    avrdude: Send: P [50]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]
    avrdude: reading input file "0x3f"
    avrdude: writing lock (1 bytes):

    Writing | avrdude: Send: V [56] X [58] . [00] . [00] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [ff]
    avrdude: Recv: . [10]
    ################################################## | 100% 0.02s

    avrdude: 1 bytes of lock written
    avrdude: verifying lock memory against 0x3f:
    avrdude: load data lock data from input file 0x3f:
    avrdude: input file 0x3f contains 1 bytes
    avrdude: reading on-chip lock data:

    Reading | avrdude: Send: V [56] X [58] . [00] . [00] . [00]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [ff]
    avrdude: Recv: . [10]
    ################################################## | 100% 0.02s

    avrdude: verifying ...
    avrdude: 1 bytes of lock verified
    avrdude: reading input file "0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}"
    avrdude: invalid byte value (0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}) specified for immediate mode
    avrdude: read from file '0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}' failed
    avrdude: Send: Q [51]   [20]
    avrdude: Recv: . [14]
    avrdude: Recv: . [10]

    avrdude done.  Thank you.

These are my fuse bits:

    # General
    8.name=ATmega8 (8MHz Internal Clock on breadboard)
    8.upload.tool=avrdude
    8.upload.maximum_data_size=1024
    8.bootloader.tool=avrdude
    8.bootloader.unlock_bits=0x3f
    8.bootloader.lock_bits=0x0f
    8.bootloader.low_fuses=0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}
    8.bootloader.high_fuses=0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}
    8.build.core=MCUdude_corefiles
    8.build.variant=standard
    8.build.board=AVR_ATmega8
    8.build.mcu=atmega8
    8.build.bootloader_led=B5

    # Upload port select
    8.menu.bootloader.uart0=Yes (UART0)
    8.menu.bootloader.uart0.upload.maximum_size=7680
    8.menu.bootloader.uart0.upload.protocol=arduino
    8.menu.bootloader.uart0.upload.port=UART0
    8.menu.bootloader.uart0.build.export_merged_output=true
    8.menu.bootloader.uart0.bootloader.bootrst_bit=0
    8.menu.bootloader.uart0.bootloader.file=optiboot_flash/bootloaders/{build.mcu}/{build.f_cpu}/optiboot_flash_{build.mcu}_{upload.port}_{upload.speed}_{build.f_cpu}_{build.bootloader_led}.hex

    8.menu.bootloader.no_bootloader=No bootloader
    8.menu.bootloader.no_bootloader.upload.maximum_size=8192
    8.menu.bootloader.no_bootloader.build.export_merged_output=false
    8.menu.bootloader.no_bootloader.bootloader.bootrst_bit=1
    8.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex

    # EEPROM
    8.menu.eeprom.keep=EEPROM retained
    8.menu.eeprom.keep.bootloader.eesave_bit=0
    8.menu.eeprom.erase=EEPROM not retained
    8.menu.eeprom.erase.bootloader.eesave_bit=1

    # Brown out detection - This is the first part of the low fuse bit concatenation
    8.menu.BOD.2v7=BOD 2.7V
    8.menu.BOD.2v7.bootloader.bod_bits=10
    8.menu.BOD.4v0=BOD 4.0V
    8.menu.BOD.4v0.bootloader.bod_bits=00
    8.menu.BOD.disabled=BOD disabled
    8.menu.BOD.disabled.bootloader.bod_bits=11

    # Compiler link time optimization
    8.menu.LTO.Os=LTO disabled
    8.menu.LTO.Os.compiler.c.extra_flags=
    8.menu.LTO.Os.compiler.c.elf.extra_flags=
    8.menu.LTO.Os.compiler.cpp.extra_flags=
    8.menu.LTO.Os.ltoarcmd=avr-ar

    8.menu.LTO.Os_flto=LTO enabled
    8.menu.LTO.Os_flto.compiler.c.extra_flags=-Wextra -flto -g
    8.menu.LTO.Os_flto.compiler.c.elf.extra_flags=-w -flto -g
    8.menu.LTO.Os_flto.compiler.cpp.extra_flags=-Wextra -flto -g
    8.menu.LTO.Os_flto.ltoarcmd=avr-gcc-ar

    8.menu.clock.8MHz_internal=8 MHz internal
    8.menu.clock.8MHz_internal.upload.speed=38400
    8.menu.clock.8MHz_internal.bootloader.sut_cksel_bits=100100
    8.menu.clock.8MHz_internal.bootloader.ckopt_bit=1
    8.menu.clock.8MHz_internal.build.f_cpu=8000000L

Should I try deleting unnescessary stuff from the fuse bits?

I tried checking the fuse bits, but they're pretty much alien to me. Any help is welcome.
Thanks in advance
Me

Edit: I am using Arduino IDE v1.0.5 and have selected "Arduino as ISP" in the programmer.

body:
1.0.5 is from 2013 and a lot has changed in the IDE since then, particularly between the 1.0.x versions and the 1.5.x versions. Most people wind up with 1.0.5 because it's in the Ubuntu's (and other Linux distribution's) package repo(s).

Anyway, it's likely that this old version doesn't define some of the things your board definition is referencing. E.g. you're referring to names that exist in the 1.8.x platform.txt file that don't exist in the 1.0.5 IDE. When the IDE fails to replace a key placeholder, it leaves it like you're seeing in your avrdude commandline: `-Uhfuse:w:0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}:m -Ulfuse:w:0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}:m
` You should not be seeing these `{blah}` references in your command-lines when compiling or uploading.

Actually, 1.0.5 predates the handling of [`.menu.` style properties](https://arduino.github.io/arduino-cli/0.23/platform-specification/#custom-board-options). E.g. They used to have entire separate boards.txt entries for the [ATMega328P based nano](https://github.com/arduino/Arduino/blob/1.0.5/hardware/arduino/boards.txt#L65) and the [ATMega168 based nano](https://github.com/arduino/Arduino/blob/1.0.5/hardware/arduino/boards.txt#L86) and these are now handled by a single board with a [`.menu.cpu.` section](https://github.com/arduino/ArduinoCore-avr/blob/1.8.5/boards.txt#L208-L253) for the selection of the MCU used. So under 1.0.5 none of your `.menu.` properties are failing to be replaced by the IDE.

So, I would start by getting rid of the old IDE and instead installing the latest [from the official site](https://www.arduino.cc/en/software) and seeing if that improves things.

That said, if you want to use the ATMega8A with Arduino it would probably be better to use [MCUdude MiniCore](https://github.com/MCUdude/MiniCore) rather than modifying the regular boards.txt file. You'll need a new IDE in order to use that anyway.


message:
Stepper motor and blink LED

I connected a LED stick to a stepper motor. Is it possible to blink the LED without stopping the motor rotation?

I am using SparkFun RedBoard Plus, Qwiic LED Stick - APA102C, Adafruit Stepper motor - NEMA-17 size - 200 steps/rev and Adafruit Motor Shield V2

Thanks

Script:

    #include <Adafruit_MotorShield.h>
    #include <Wire.h>
    #include "Qwiic_LED_Stick.h"

    LED LEDStick;
    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

    void setup() {
      Wire.begin();
      Serial.begin(9600);
      while (!Serial);
      Serial.println("Stepper test!");

      if (!AFMS.begin()) {
        // if (!AFMS.begin(1000)) {
        Serial.println("Could not find Motor Shield. Check wiring.");
        while (1);
      }
      Serial.println("Motor Shield found.");
      myMotor->setSpeed(25);  // 25 rpm

      if (LEDStick.begin() == false) {
        Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
        while (1);
      }
      Serial.println("Qwiic LED Stick ready!");
    }

    void loop() {
      Serial.println("Single coil steps");
      myMotor->step(200, FORWARD, SINGLE);

      LEDStick.setLEDColor(10, 10, 10);
      delay(1000);
      LEDStick.LEDOff();
      delay(1000);
    }

body:
Often, the solution to most simultaneous software delay problems is a [state machine][1]. Generally, a state machine is an infinite loop with no or few delays.  The state machine's job is to keep track of all the possible state the software is to control.

In this case we might try to implement:
1. LED on & motor active.
2. LED off & motor active.
3. LED on & motor is not active.
4. LED off & motor is not active.

The [library Adafruit_StepperMotor][2] you have chosen might be blocking.  This text from the [Arduino reference step library][3] admits this similar function is blocking:

> This function is blocking; that is, it will wait until the motor has finished moving to pass control to the next line in your sketch.

If so, and the call to step() blocks the LED action for longer then is tolerable, consider calling step() with fewer step such that the blocking delay is tolerable.  For example, 100 steps are desired, consider calling step 10 times only advancing the motor 10 steps each time.

Back to the state machine.  To keep track of the above 4 state you need 2 flags.  An LED flag and a Motor flag.  Control the LED flag using mills() not delay().

mills():

> Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Consider writing the state machine code to immediately turn the LED on and save the current value returned from mills().  Each subsequent time through the state machine check if mills() returns a value 1000 more than the value saved (do consider that mills() will eventually overflow and start over at zero).  When it does toggle the LED, save the new mills() returned value and start checking each subsequent time through the state machine.

As we are running the state machine over and over again as fast as the processor can manage, we can also test an externally set flag to run the motor.  We need to determine if the call to step() is blocking.  If it is we need to determine the maximum number of steps / delay tolerable by the LED feature.  If we discover this is, say, 10 step, we need to devise code to divide the desired number of steps into individual calls of 10 or less steps. If this approach is desired, control the state machine's motor flag by activating it when the number of steps is > 0.  Subtracting 10 from the number of steps every iteration through the state machine.  And setting the state machine's motor flag to deactivate when steps is = 0.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine
  [2]: http://adafruit.github.io/Adafruit_Motor_Shield_V2_Library/html/class_adafruit___stepper_motor.html
  [3]: https://www.arduino.cc/reference/en/libraries/stepper/step/


message:
Can an Arduino Uno be used to measure the frequency of a square wave of up to 600 kHz?

I am doing a project with a color sensor, where the output of the color sensor is a PWM square wave.

To measure its frequency using an Arduino Uno I am using the `pulseIn()` function, but I can't get the correct result.

Can an Arduino Uno measure a frequency of up to 600 kHz using the `pulseIn()` function?

body:
The [documentation for pulseIn](https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/) states that it can be used for intervals of 10 microseconds to 3 minutes.

600 kHz *frequency* will have an *interval* of 1.6 microseconds and thus is not suitable for this application. (1 / 600000 = 0.000001666).

I have code on [my web page about timers](https://www.gammon.com.au/timers) for a sketch that can measure up to 8 MHz with only 0.5% error.

This code is reproduced below:

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

    // Timer and Counter example
    // Author: Nick Gammon
    // Date: 17th January 2012

    // Input: Pin D5

    // these are checked for in the main program
    volatile unsigned long timerCounts;
    volatile boolean counterReady;

    // internal to counting routine
    unsigned long overflowCount;
    unsigned int timerTicks;
    unsigned int timerPeriod;

    void startCounting (unsigned int ms)
      {
      counterReady = false;         // time not up yet
      timerPeriod = ms;             // how many 1 ms counts to do
      timerTicks = 0;               // reset interrupt counter
      overflowCount = 0;            // no overflows yet

      // reset Timer 1 and Timer 2
      TCCR1A = 0;
      TCCR1B = 0;
      TCCR2A = 0;
      TCCR2B = 0;

      // Timer 1 - counts events on pin D5
      TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

      // Timer 2 - gives us our 1 ms counting interval
      // 16 MHz clock (62.5 ns per tick) - prescaled by 128
      //  counter increments every 8 µs.
      // So we count 125 of them, giving exactly 1000 µs (1 ms)
      TCCR2A = bit (WGM21) ;   // CTC mode
      OCR2A  = 124;            // count up to 125  (zero relative!!!!)

      // Timer 2 - interrupt on match (ie. every 1 ms)
      TIMSK2 = bit (OCIE2A);   // enable Timer2 Interrupt

      TCNT1 = 0;      // Both counters to zero
      TCNT2 = 0;

      // Reset prescalers
      GTCCR = bit (PSRASY);        // reset prescaler now
      // start Timer 2
      TCCR2B =  bit (CS20) | bit (CS22) ;  // prescaler of 128
      // start Timer 1
      // External clock source on T1 pin (D5). Clock on rising edge.
      TCCR1B =  bit (CS10) | bit (CS11) | bit (CS12);
      }  // end of startCounting

    ISR (TIMER1_OVF_vect)
      {
      ++overflowCount;               // count number of Counter1 overflows
      }  // end of TIMER1_OVF_vect

    //******************************************************************
    //  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
    //  16Mhz / 128 / 125 = 1000 Hz

    ISR (TIMER2_COMPA_vect)
      {
      // grab counter value before it changes any more
      unsigned int timer1CounterValue;
      timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
      unsigned long overflowCopy = overflowCount;

      // see if we have reached timing period
      if (++timerTicks < timerPeriod)
        return;  // not yet

      // if just missed an overflow
      if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
        overflowCopy++;

      // end of gate time, measurement ready

      TCCR1A = 0;    // stop timer 1
      TCCR1B = 0;

      TCCR2A = 0;    // stop timer 2
      TCCR2B = 0;

      TIMSK1 = 0;    // disable Timer1 Interrupt
      TIMSK2 = 0;    // disable Timer2 Interrupt

      // calculate total count
      timerCounts = (overflowCopy << 16) + timer1CounterValue;  // each overflow is 65536 more
      counterReady = true;              // set global flag for end count period
      }  // end of TIMER2_COMPA_vect

    void setup ()
      {
      Serial.begin(115200);
      Serial.println("Frequency Counter");
      } // end of setup

    void loop ()
      {
      // stop Timer 0 interrupts from throwing the count out
      byte oldTCCR0A = TCCR0A;
      byte oldTCCR0B = TCCR0B;
      TCCR0A = 0;    // stop timer 0
      TCCR0B = 0;

      startCounting (500);  // how many ms to count for

      while (!counterReady)
         { }  // loop until count over

      // adjust counts by counting interval to give frequency in Hz
      float frq = (timerCounts *  1000.0) / timerPeriod;

      Serial.print ("Frequency: ");
      Serial.print ((unsigned long) frq);
      Serial.println (" Hz.");

      // restart timer 0
      TCCR0A = oldTCCR0A;
      TCCR0B = oldTCCR0B;

      // let serial stuff finish
      delay(200);
      }   // end of loop

---

> Whether Arduino UNO can measure the frequency upto 600 KHz if we use the pulseIn() function?

No. Not using pulseIn. However see the code above for a way of measuring such a frequency.


message:
Blink LED without delay with stepper motor

Based on a [previous question][1] I modified the script to use blink without delay.

Unfortunately, it does not work, any idea why?

I am using SparkFun RedBoard Plus, Qwiic LED Stick - APA102C, Adafruit Stepper motor - NEMA-17 size - 200 steps/rev and Adafruit Motor Shield V2.

Modified code (based on @Michel Keijzers, see below):

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    #include "Qwiic_LED_Stick.h" // Click here to get the library: http://librarymanager/All#SparkFun_Qwiic_LED_Stick

    // Variables will change:
    int ledState = LOW;             // ledState used to set the LED

    unsigned long previousMillis = 0;        // will store last time LED was updated

    // constants won't change:
    const long interval = 500;           // interval at which to blink (milliseconds)

    LED LEDStick; //Create an object of the LED class

    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

    void setup() {
      Wire.begin();
      Serial.begin(115200);
      while (!Serial);
      Serial.println("Stepper test!");

      if (!AFMS.begin()) {
        // if (!AFMS.begin(1000)) {
        Serial.println("Could not find Motor Shield. Check wiring.");
        while (1);
      }
      Serial.println("Motor Shield found.");
      myMotor->setSpeed(50);  // 50 rpm

      //Start up communication with the LED Stick
      if (!LEDStick.begin())  {
        Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
        while (1);
      }

      Serial.println("Qwiic LED Stick ready!");
    //  LEDStick.setLEDColor(255, 0, 0);
      LEDStick.setLEDBrightness(1);
    }

    void loop() {
      unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;

        ledState = !ledState;
        // set the LED with the ledState of the variable:
        uint8_t intensity = ledState == HIGH ? 255 : 0;
        LEDStick.setLEDColor(intensity, intensity, intensity);
      }

      Serial.println("Single coil steps");
      myMotor->step(200, FORWARD, SINGLE);
    }

Code:

    #include <Wire.h>
    #include <Adafruit_MotorShield.h>
    #include "Qwiic_LED_Stick.h" // Click here to get the library: http://librarymanager/All#SparkFun_Qwiic_LED_Stick

    // Variables will change:
    int ledState = LOW;             // ledState used to set the LED

    unsigned long previousMillis = 0;        // will store last time LED was updated

    // constants won't change:
    const long interval = 1000;           // interval at which to blink (milliseconds)

    LED LEDStick; //Create an object of the LED class
    Adafruit_MotorShield AFMS = Adafruit_MotorShield();
    Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

    void setup() {
      Wire.begin();
      Serial.begin(115200);
      while (!Serial);
      Serial.println("Stepper test!");

      if (!AFMS.begin()) {
        // if (!AFMS.begin(1000)) {
        Serial.println("Could not find Motor Shield. Check wiring.");
        while (1);
      }
      Serial.println("Motor Shield found.");
      myMotor->setSpeed(50);  // 50 rpm

      //Start up communication with the LED Stick
      if (LEDStick.begin() == false) {
        Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
        while (1);
      }

      Serial.println("Qwiic LED Stick ready!");
    }

    void loop() {
      unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        // set the LED with the ledState of the variable:
        LEDStick.setLEDColor(50, 50, 50);
      }

      Serial.println("Single coil steps");
      myMotor->step(200, FORWARD, SINGLE);
    }

  [1]: https://arduino.stackexchange.com/questions/90281/stepper-motor-and-blink-led

body:
You only set (assign) `ledState`, but you never use it.

I think the following fragment

    // set the LED with the ledState of the variable:
    LEDStick.setLEDColor(50, 50, 50);

Should be something like:

    // set the LED with the ledState of the variable:
    uint8_t intensity = ledState == HIGH ? 255 : 0;
    LEDStick.setLEDColor(intensity, intensity, intensity);

This 'converts' the ledState into white (RGB values 255) when HIGH or black/off (RGB values 0) when LOW.

Also you can change the line

    if (LEDStick.begin() == false) {

into

    if (!LEDStick.begin()) {

and change the lines

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

into

    // if the LED is off turn it on and vice-versa:
    ledState = ledState == LOW ? HIGH : LOW;

or even

    ledState = !ledState;