message:
I'm getting an error while uploading my code to esp8266 via an arduino (FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error)))

```
Arduino: 1.8.13 (Windows 10), Board: "Generic ESP8266 Module, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), dtr (aka nodemcu), 26 MHz, 40MHz, DOUT (compatible), 1MB (FS:64KB OTA:~470KB), 2, nonos-sdk 2.2.1+100 (190703), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

Executable segment sizes:

IROM   : 228624          - code in flash         (default or ICACHE_FLASH_ATTR)

IRAM   : 26756   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)

DATA   : 1248  )         - initialized variables (global, static) in RAM/HEAP

RODATA : 688   ) / 81920 - constants             (global, static) in RAM/HEAP

BSS    : 24880 )         - zeroed variables      (global, static) in RAM/HEAP

Sketch uses 257316 bytes (26%) of program storage space. Maximum is 958448 bytes.

Global variables use 26816 bytes (32%) of dynamic memory, leaving 55104 bytes for local variables. Maximum is 81920 bytes.

esptool.py v2.8

Serial port COM3

Connecting........_____....._____....._____....._____....._____....._____.....____Traceback (most recent call last):

  File "C:\Users\Reghunaath A A\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2/tools/upload.py", line 65, in <module>

    esptool.main(cmdline)

  File "C:/Users/Reghunaath A A/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.2/tools/esptool\esptool.py", line 2890, in main

    esp.connect(args.before)

  File "C:/Users/Reghunaath A A/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.2/tools/esptool\esptool.py", line 483, in connect

    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))

esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

_

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
```
I'm getting the above stated error message while I'm trying to upload a code to esp8266 via an arduino(I've removed the ATMEGA32 from my arduino). Sometimes it gets uploaded without a problem(very rarely) but mostly the upload fails.
I connected rx of arduino to rx of esp and same for tx too. 3.3v of arduino to enable and vcc of esp. graund of arduino to ground of esp and gpio0.

The code that I'm trying to upload:
```
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forevervoid lop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
  // but actually the LED is on; this is because
  // it is active low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}
```
My settings:
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/fv7X7.png
 EDIT: Also, I want to add one more thing when the message box says "Connecting........_____....._" during that time if i reset the esp the code starts uploading

body:
You need to set esp 8266 to flash mode.
Please connect en PIN to Gnd pin.
Then flash again.


sender: user

message:
NodeMCU ESP8266

I am doing a project and using NodeMCU ESP8266. My project includes sensors for UART, I2C and 4 interrupts. I need to read the data from these sensors and get these data via microUSB in real time. While reading about NodeMCU ESP8266 there are so many points that came across and have certain questions.

1. Do flash uses GPIO6-11 all the time? Can we use any of these pins for our purpose? What if someone needs an SPI communication, as these pins are locked by flash.
2. Can I use GPIO-0 (flash pin) for my purpose, as after flashing the MCU the pin will get free.
3. Do CP2102 uses GPIO 1 and GPIO 3? Can I use these pins for my purpose? (Given I need the data via USB, which I guess comes through CP2102)
4. Can I receive the sensor data from SoftUART bus and get that data to my computer via USB?

I am confused from the articles given over internet. I request if anyone knows how these work, please explain.

Thank you

sender: assistant

body:
> Do flash uses GPIO6-11 all the time? Can we use any of these pins for our purpose? What if someone needs an SPI communication, as these pins are locked by flash.

It is Quad SPI. The CS pins for this SPI interface are controlled by low level code. So you can't use this pins as GPIO and they have limited use as SPI too. If the flash access is set to normal SPI, the two pins io 9 and io 10 used for quad mode can be used as GPIO.

> Can I use GPIO-0 (flash pin) for my purpose, as after flashing the MCU the pin will get free.

You can use io 0 as GPIO. Only make sure it is HIGH at boot. The bootloader reads it at boot to determine if it should go to flashing mode. Other boot config pins are io 2, it must be HIGH at boot and io 15, which must be LOW at boot.

> Do CP2102 uses GPIO 1 and GPIO 3? Can I use these pins for my purpose? (Given I need the data via USB, which I guess comes through CP2102)

Pins io 1 and io 3 are wired to the USB chip and used for Serial. They can be used as io pins, if you don't need Serial communication over them. Serial in esp8266 Arduino can be swapped to different set of pins for use with a serial device. For output printing you can use Serial1 which has only TX. To [relay this output to USB][1] bridge io 2 (Serial1 TX) to io 4 (Serial TX wired to USB).

> Can I receive the sensor data from SoftUART bus and get that data to my computer via USB?

You can use SoftwareSerail or the trick mentioned above.

see [NodeMCU pins][2]

  [1]: https://arduino.stackexchange.com/questions/76299/nodemcu-wiring-for-serial1/76309#76309
  [2]: https://arduino.stackexchange.com/questions/75704/what-are-the-best-gpio-pins-to-use-for-my-project/75706#75706


message:
digital input pins on arduino nano with standard firmata and pyfirmata are always 'None'

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

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

I have connected pin D2 on my arduino nano to high, and tried it out with an arduino c program and it works.  However, when I load standard firmata onto the the controller from the arduino IDE and try the following python program:

```
import pyfirmata

board = pyfirmata.Arduino('/dev/ttyUSB0')

for x in range(2,14):
    print("%s %s" % (x, board.get_pin("d:%s:i" % x).read()))
```

I get this:

```
$ venv/bin/python test.py
2 None
3 None
4 None
5 None
6 None
7 None
8 None
9 None
10 None
11 None
12 None
13 None
```

I can write digital pins with fermata and pyfirmata, but I can't _read_.

I have also tried this:

```
import pyfirmata

board.digital[2].mode = pyfirmata.INPUT
board.digital[3].mode = pyfirmata.INPUT

for x in range(2,14):
    print("%s %s" % (x, board.digital[x].read()))
```

and other combinations, and always get None

(disconnecting the wire in the picture doesn't change anything either)

----

I have also just repeated the experiment with an arduino uno and get the same result

----

so I guess my questions are:
 - Can anybody spot anything obvious that I am doing wrong?
 - Can anybody confirm that pyfirmata input ever works?
 - What did you do that I am not doing?

body:
"None" indicates that there is no data to be found by read() because the incoming serial stream has never been serviced.  Launch an Iterator to start a new Python thread that services the serial port in the background.

    it = pyfirmata.util.Iterator(board)
    it.start()


message:
Arduino Modbus Slave Library Needed

We are building a circuit based on ATMega328* that :

1. Reads 32 current transducers, multiplexed into one Analog Input,
2. Reads 12 voltage transducers, multiplexed into one Analog Input,
3. Reads 6 temperature sensors, multiplexed into one Analog Input,
4. Manipulates all the readings with some math (like scaling, averaging etc.),
5. Calculates new variables (power, crest factor, etc.),
6. Tracks trends (max/min/avg) of certain (calculated) readings,
7. Stores some events (peaks/dips - max/min values) etc. with time stamps from RTC,
8. Generates Alarm Flags (by comparing readings to software-set thresholds),

The circuit should be connected as a ModBus Device (Slave) to an existing
Modbus network with several other devices on an RS485 interface.

The circuit should communicate all these calculated values and alarms
as well as some other info, like peak/max values with date and
time stamps that were recorded at their time of occurrence, to the
Modbus Master. We have the freedom of allocating the register numbers
and their formats etc. (Modbus Map) to the controller's vendor (SAUTER).
For example we tell them Register 30001 is the current sensor x,
30002 is voltage sensor y, etc.

We think that sending time stamps (of certain events) will be based on
"agreed-upon" coding of register values (MM, DD, YYYY, etc.) and the
same for alarms (to be sent as hex codes).

We have searched for libraries and got really confused from the
multitude of libraries out there, as well as the lack of documentation -:)

Can you please kindly help us :
select the proper Arduino Modbus Slave Library that :
1. Has MAX485 support,
2. Assigns Modbus registers to any arbitrary variables,
3. Issues Exception Responses to Modbus requests (e.g. non-existing registers
or un-supported Function Codes.
4. Complies to Modbus Standards
5. Has a manual !!

We found the "yaacov" library on Github but it assigns registers directly to "Pins".
Also we looked at its "issues" and one of them was very serious : in which frames
coming from the Master with corrupted CRC gets responded to and causes collision
with other slaves. We dont like that ! as it indicates that the library was not tested
in true industrial environment.

We also found that the Library at :

https://electronhacks.com/2014/04/arduino-modbus-plc-rtu/

somewhat fits to our requirements, however it lacks the RS485 support, and more
important, it has no documentation.

We really appreciate any kind support.

* The ATmega328 will be probably replaced with a larger CPU, but we are still
in development phase.

Thank you.

body:
With my post approaching one month without a single reply  :smiley-confuse: !
(for whichever reason) I would like to post for those who may need this library :

-------------------------------------------------------------------------------------
https://drive.google.com/file/d/0Bx5wWRfN_z7oMDlZMDhWbXM2VFU/view
-------------------------------------------------------------------------------------

The library is based on the original one written by Jason Vreeland [CodeRage]
Released 3/7/2010 under GNU license

and was used (and possibly modified) by "jhottell" on electronhacks.com :

https://electronhacks.com/2014/04/arduino-modbus-plc-rtu/

The major difference is the use of RS485.

I have written code and tested it on an "UNO" which worked perfectly with more
than one ModBus Slave Simulator under windows, including DAQ Factory which
is a professional package used in actual industry.


body:
## This is an awesome Modbus slave and Master Library

Required this library [<ModbusRtu.h>][1]

    #include <ModbusRtu.h>
    unsigned long TIME = 0;
    unsigned long LASTTIME = 0;
    unsigned long INTERVAL = 5000;

    int i = 0;
    // data array for modbus network sharing
    uint16_t au16data[16] = {
      3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, 11 };

    /**
     *  Modbus object declaration
     *  u8id : node id = 0 for master, = 1..247 for slave
     *  port : serial port
     *  u8txenpin : 0 for RS-232 and USB-FTDI
     *               or any pin number > 1 for RS-485
     */
    Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI

    void setup() {
      Serial.swap();
      Serial.begin( 19200 ); // baud-rate at 19200
      Serial1.begin( 19200 );
      slave.start();
    }

    void loop() {

      if ((millis() - TIME) > INTERVAL) {
        i++;

        if(i == 16){
          i = 0;

          for (int ii = 0; ii < 16; ii++)
          {
            au16data[ii] = 0;
          }
        }

        au16data[i] = 1;

        TIME = millis();
      }

      slave.poll( au16data, 16 );
    }

  [1]: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino


message:
ESP8266 OTA update with different flash size settings?

I have an ESP8266 in a project.  It's specifically this [ESP8266 SMT Module - ESP-12F][1] item.  It's been working great with OTA, but I realized belatedly that I didn't change the flash settings when I started compiling through the Arduino IDE several versions ago.  I had been using the setting "1 MB (FS:64KB OTA:~470KB)", and I've updated OTA over multiple versions with the same basic structure of firmware and using the same server-side set-up.

I can no longer update with that setting because my compiled sketch is now over the OTA size limit.  My chip actually has 4 MB, however, so this limit is artificial.  I tried changing to "4 MB (FS:2 MB OTA:~1019KB)", and that works under the following test conditions:

 1. I compile the "old" program with the 4-MB settings and I re-upload the old program via wired connection.
 2. I compile the "new" program that's to come via OTA with those same 4-MB settings.

That's fine for a test, but I already have one of these chips "deployed" in a location where it's hard to access it.  I'd like to update that deployed chip OTA while also changing the flash partition.  I'm willing to lose any files stored outside of the program itself.  So I'd like instead to have:

 1. A deployed, OTA-enabled chip with firmware running on the 1-MB partition structure noted above:
 2. (Any intermediate step needed)
 3. OTA update to new firmware that has been compiled with the 4-MB partition structure.

I'm willing to upload a dummy sketch at "Any intermediate step needed" to work around the current size of the sketch, but, after some experimentation, OTA seems to fail when the partition structure is different regardless of the size of the binary.

That's consistent with #2 in the answer here: https://arduino.stackexchange.com/questions/74750/esp8266-ota-issue, but that older question took a different direction with the OP and the #2 point there is stated without any detail.  I understand that in a broad sense, the prior answer covers my case, but I'm looking for more detail on the specific aspect of the flash partition settings.  Especially for these related questions:
 - Is there any work-around strategy available to change the flash partitioning between different versions served OTA?
 - If no, is the limitation determined by the software in the current OTA framework in the public libraries, or is it somehow fundamental to how the program is laid out in the hardware memory?

In theory at least, it seems like I ought to be able to force the new program to be written OTA at the same location that it would have been written had the old program also had the 4-MB partition. (Again noting that I'm willing to lose any other data in the flash to make this update work.)

  [1]: https://www.adafruit.com/product/2491

body:
The basic problem is that when you upload over OTA you don't upload the partition structure.

The ESP32's flash is split into a number of "partitions" or areas.  It might look something like:

```
+----+-+-------------+-------------+---------------------+
|BOOT|P|OTA Program 1|OTA Program 2| SPIFFS              |
+----+-+-------------+-------------+---------------------+
```

When you upload over UART you upload all that structure, and that structure can be changed.  When you upload over OTA you only upload one of "OTA Program 1" or "OTA Program 2". One of those is active and the other is inactive. You upload to the inactive one and then at the next reboot that becomes the active one. This allows the system to confirm that the program has been written correctly before running it to reduce the chances of bricking a device in the field.

Because of this you can *never* upload anything that doesn't fit into one of the OTA program partitions.

One risky option which you would have to do thorough local testing of first, is to write a program which, when executed, will change the partitioning. You would have to make sure that it runs in the lower OTA partition so that the inactive one is the one that gets both moved and expanded, which may take a little trial and error.

Once that has happened you should be able to upload a larger OTA program into the new, bigger, inactive OTA segment.

But that's only supposition and it's not something I have ever done or heard of anyone doing.


message:
Esp32: is OTA compatible with FREERTOS

Can I use OTA along with FreeRTOS tasks on ESP32. I ask this because in the following  [example][1] OTA seems to be enabled if FreeRTOS is disabled. Can for example upload firmware that runs on both cores over OTA?
Example taken from OTA [template project][2] by Andrea's Speiss

  [1]: https://github.com/SensorsIot/ESP32-OTA/blob/master/0TA_Template_Sketch/0TA_Template_Sketch.ino
  [2]: https://github.com/SensorsIot/ESP32-OTA

body:
You can't *not* use FreeRTOS. The whole ESP-IDF is based around it. The Arduino `setup()` and `loop()` run in their own FreeRTOS thread.

If you "turn off" FreeRTOS then nothing will work.

Whatever that "template" is from it's of no use to you.


body:
I was also believing that it is not possible but I handle it thanks to this post below;

https://github.com/SensorsIot/ESP32-OTA/issues/8

I applied what ever shared and it works like a charm together both FreeRTOS and OTA features.

As summary you need to create 2 custom header which includes your wifi credentials and OTA function. The remaining is same mostly.

credentials.h

    #pragma once
    const char* mySSID = "SSID of your AP";
    const char* myPASSWORD = "Password of your AP";

OTA.h

    #ifdef ESP32
    #include <WiFi.h>
    #include <ESPmDNS.h>
    #else
    #include <ESP8266WiFi.h>
    #include <ESP8266mDNS.h>
    #endif

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

    #if defined(ESP32_RTOS) && defined(ESP32)
    void ota_handle( void * parameter ) {
      for (;;) {
        ArduinoOTA.handle();
        delay(3500);
      }
    }
    #endif

    void setupOTA(const char* nameprefix, const char* ssid, const char* password) {
      // Configure the hostname
      uint16_t maxlen = strlen(nameprefix) + 7;
      char *fullhostname = new char[maxlen];
      uint8_t mac[6];
      WiFi.macAddress(mac);
      snprintf(fullhostname, maxlen, "%s-xxx", nameprefix, mac[3], mac[4], mac[5]);
      ArduinoOTA.setHostname(fullhostname);
      delete[] fullhostname;

      // Configure and start the WiFi station
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);

      // Wait for connection
      while (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("Connection Failed! Rebooting...");
        delay(5000);
        ESP.restart();
      }

      // Port defaults to 3232
      // ArduinoOTA.setPort(3232);

      // No authentication by default
      // ArduinoOTA.setPassword("admin");

      // Password can be set with it's md5 value as well
      // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
      // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

      ArduinoOTA.onStart([]() {
        String type;
        if (ArduinoOTA.getCommand() == U_FLASH)
          type = "sketch";
        else // U_SPIFFS
          type = "filesystem";

        // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
        Serial.println("Start updating " + type);
      });

      ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd");
      });

      ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
      });

      ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("\nAuth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("\nBegin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("\nConnect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("\nReceive Failed");
        else if (error == OTA_END_ERROR) Serial.println("\nEnd Failed");
      });

      ArduinoOTA.begin();

      Serial.println("OTA Initialized");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());

    #if defined(ESP32_RTOS) && defined(ESP32)
      xTaskCreate(
        ota_handle,          /* Task function. */
        "OTA_HANDLE",        /* String with name of task. */
        10000,            /* Stack size in bytes. */
        NULL,             /* Parameter passed as input of the task */
        1,                /* Priority of the task. */
        NULL);            /* Task handle. */
    #endif
    }

OTA Template sketch.ino

    #define ESP32_RTOS  // Uncomment this line if you want to use the code with freertos only on the ESP32
                        // Has to be done before including "OTA.h"

    #include "OTA.h"
    #include "credentials.h"

    void setup() {
      Serial.begin(115200);
      Serial.println("Booting");

      setupOTA("TemplateSketch", mySSID, myPASSWORD);

      // Your setup code
      /*  Example
      pinMode(2, OUTPUT);
      */
    }

    void loop() {
    #ifdef defined(ESP32_RTOS) && defined(ESP32)
    #else
      ArduinoOTA.handle();
    #endif

      // Your code here
      /* Example
      digitalWrite(2, HIGH);
      delay(500);
      digitalWrite(2, LOW);
      delay(1000);
      */
    }


message:
How can I get my LCD display to display Chinese and Japanese characters?

I'm making a project that requires me to display Chinese and Japanese characters on an LCD. However, the 16x2 LCD display I have does not seem to support displaying Chinese and Japanese characters.

If I do something like `lcd.print("おはよう世界");` or `lcd.print("简体中文测试");`, it seems to display just a bunch of jumbled random characters (which I am assuming have their character values add up to the values of the characters in the code).

How can I get my LCD to display Chinese and Japanese characters?

Or, if there's no way to do it without buying a new one that supports it, where can I buy one?

body:
Displaying Kanji or Chinese characters is way beyond the ability of an LCD that displays 5 pixel by 7 pixel characters.

To understand the limitations, take a piece of graph paper and draw out a set of 5x7 rectangles. See if you can define ANY recognizable Japanese or Chinese characters on your graph paper.

Maybe a couple of characters? (Then again, maybe not.)

You need a display with a lot more resolution, like an OLED graphics display. You are also struggling against a microcontroller that doesn't have support for Unicode. It's just not up to the job. You'd be much better off with a Raspberry Pi and a screen like a smart-phone color LCD screen. Install Linux and you can have native support for Unicode.

As others have pointed out, hiragana or katakana would be more practical, and there are some low-res LCDs that support those characters.


body:
Your LCD uses a single byte for the character to display, so there are < 256 characters possible. 8 of them are userdefineable, the others are predefined in the LCD-ROM.

The Arduino IDE uses utf-8 code, which takes more than a single byte for all non-ascii characters like in your "おはよう世界".

Even if the character set contains the ones you want to display, you need an escape sequence to have them properly in your print statement.


message:
MPU6050 Problem with NodeMCU

I am using MPU6050 as a part of IMU of my drone, and I wrote this program for Arduino Nano to fetch the orientation of the MPU6050 module in 3D space. And that works perfectly fine, but when I uploaded this exact code to a NodeMCU, the output started getting increased only, i.e., whenever there's any change of orientation of the module, the output, instead of showing the specific orientation, gets increased on and on. Can you please help me out with interfacing the MPU6050 with my NodeMCU. I am providing the program underneath.

```
#include <Wire.h>
const int MPU = 0x68; // MPU6050 I2C address

char status;                // Declaring all the necessary variables
double T, P;
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll_sensor, pitch_sensor, yaw_sensor;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        // end the transmission
  calculate_IMU_error();  // Call this function if you need to get the IMU error values for your module
  delay(20);
}
void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14, true); // Read 6 registers total, each axis value is stored in 2 registers

  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value

  // Calculating roll_sensor and pitch_sensor from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * (180 / PI)) - AccErrorX;
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * (180 / PI)) - AccErrorY;

  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14, true); // Read 4 registers total, each axis value is stored in 2 registers

  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;

  // Correct the outputs with the calculated error values
  GyroX = GyroX - GyroErrorX;
  GyroY = GyroY - GyroErrorY;
  GyroZ = GyroZ - GyroErrorZ;

  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + (GyroX * elapsedTime); // deg/s * s = deg
  gyroAngleY = gyroAngleY + (GyroY * elapsedTime);
  yaw_sensor =  yaw_sensor + (GyroZ * elapsedTime);

  // Complementary filter - combine acceleromter and gyro angle values
  roll_sensor = (0.94 * gyroAngleX) + (0.06 * accAngleX);
  pitch_sensor = (0.94 * gyroAngleY) + (0.06 * accAngleY);

  // Print the values on the serial monitor
  Serial.print("                   roll_GY: "); Serial.print(roll_sensor);
  Serial.print("         pitch_GY: "); Serial.print(pitch_sensor);
  Serial.print("         yaw_GY: "); Serial.print(yaw_sensor);
  Serial.println();

}
void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 300 times
  while (c < 300) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * (180 / PI)));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * (180 / PI)));
    c++ ;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 300;
  AccErrorY = AccErrorY / 300;
  c = 0;
  // Read gyro values 300 times
  while (c < 300) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);

    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();

    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }

  //Divide the sum by 300 to get the error value
  GyroErrorX = GyroErrorX / 300;
  GyroErrorY = GyroErrorY / 300;
  GyroErrorZ = GyroErrorZ / 300;
}
```

body:
I see that you are reading 16-bit integers from the IMU like this:

    // doesn't work on 32-bit systems
    void loop() {
        ...
        AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
        AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
        AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
        ...
        GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // ...
        GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
        GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
        ....
    }

While all too often I am forced to use "#ifdef" to set up platform-specific code for each platform,
in this case I'm pretty sure it's possibly to write cross-platform compatible code that will work on both platforms;
perhaps something more like this:

    // warning: untested, but I think it should work
    int16_t wire_read_16(){
        int16_t value = (Wire.read() << 8 | Wire.read());
        return value;
    }

    void loop() {
        ...
        AccX = (wire_read_16()) * (1.0f / 16384.0f); // X-axis value
        AccY = (wire_read_16()) * (1.0f / 16384.0f); // Y-axis value
        AccZ = (wire_read_16()) * (1.0f / 16384.0f); // Z-axis value
        ...
        GyroX = (wire_read_16()) * (1.0f / 131.0f); // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
        GyroY = (wire_read_16()) * (1.0f / 131.0f);
        GyroZ = (wire_read_16()) * (1.0f / 131.0f);
        ....
    }

I see that
onehorse is apparently having exactly the same problem at
["integer type definitions on Teensy 3.1"][1]

It sounds like maybe you've stumbled over a quirk of the C programming language where "int" varies from system to system.
(See Ido Gendel, ["The problem with ints"][2]).
The "int" in some systems (such as the ATmega based Arduinos) is a 16-bit integer.
The "int" in some other systems (such as the ARM based Arduinos, perhaps including NodeMCU) is a 32-bit integer.
(
https://arduino.stackexchange.com/questions/41879/inttypes-vs-arduino-defined-integral-types
; ["Arduino reference: int"][3]
)
In yet other systems, "int" is a variety of other sizes.

For example, when your IMU is trying to send you a "-2",
it sends 0xFFFE.
When the nano puts that into its "int" which is a 16-bit integer, it then later properly interprets that as meaning "-2".
I suspect what's happening is that
when the other system puts that value into its "int" which is a 32-bit integer, that somehow ends up containing
0x0000FFFE which means +65534,
but what *should* have happened is "sign extension" so that 32-bit integer ends up containing
0xFFFFFFFE which means "-2".
By sticking that value into an intermediate "int16_t" variable, we're explicitly telling the compiler that it's a signed 16-bit integer,
so later when that compiler sticks it into a 32-bit integer it sign-extends properly.

The C compiler (correctly) handles an int divided by a float by converting both values to floats (and sign extending properly), and then dividing. Likewise with an int divided by a double.

  [1]: https://forum.pjrc.com/threads/25799-integer-type-definitions-on-Teensy-3-1
  [2]: https://www.idogendel.com/en/archives/104
  [3]: https://www.arduino.cc/en/Reference.Int


message:
What exactly does the return type do in a function?

something I've never understood and still don't is, what does the return type do specifically? Everyone in tutorials just say that void returns nothing and int returns int, etc. But what does that mean? Where is it returning to?  I can't seem to understand what everyone's talking about when they discuss functions.

body:
It returns it to whatever the function is being assigned to.

Take the function:

```cpp
int plus(int a, int b) {
    return a + b;
}
```

That function takes two integers, adds them together, and "returns" them *as an integer*.

You can then do:

```cpp
int c = plus(3, 4);
```

and `c` will be handed the value `7` by the function.

Equally you can do:

```cpp
Serial.println(plus(3, 4));
```

And the `Serial.println()` function will be handed the value `7` for printing.

The type of the return defines the kind of data that *can* be returned.

Oh, and `void` doesn't mean "returns nothing", but means "doesn't return anything" - which means you can't assign it to anything since there's nothing returned to assign.


body:
The reason is that a function is evaluated just as any other expression would be. Every expression - `(x**x - 3*x + 5), for instance - has a value and a type (unless the type is void, then it has no value, or not a defined one), and that includes functions. The compiler needs to know the type of every element of the expression in order to know how to use that element in an operation (arithmetic or other kinds). Sometimes a value has to be converted from one type to another to combined with another element or assign to a variable, and knowing the type of each element is the only the compiler knows how to accomplish this.

Here is an example:

`float squareroot(float x);` could declare a function that takes a floating point number and returns its square root as a floating point number. If you assign that value to an integral of variable, the compiler needs to see that the functions does not return an integer but a float, so it includes the appropriate code to convert the float to an integer (by truncating the fractional part, in this case).

If the function could be written without declaring its return value type, the compiler would be unable to make the conversion, or even to know whether one will be needed.


message:
Running Arduino with 2 outputs and 2 inputs

Totally new to Arduino, 3 weeks old!

I am doing a project with 2 inputs (2 x ultrasonic sensors) and 2 outputs (buzzer and send SMS)

The code to run the buzzer and sms works perfectly individually. For the buzzer, it will stop buzzing after approx 5 seconds.

I would love them to run **concurrently** but it didn't work as planned when I upload the code on the board.

I've read on forums to use **millis / blinkwithoutdelay** but am unsure how I can incorporate those functions on my mode as the examples posted online are different from my project.

The following is the code I have created.

Would appreciate if I can get some help from the experienced folks here.

```cpp
#define TRIG A0 //Module pins
#define ECHO A1
#define TRIG1 A2 //Module pins
#define ECHO1 A3
#define Buzzerpin 13

int ctn = 0;

void setup() {
  Serial.begin(9600); // Serial monitoring
  pinMode(TRIG, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO, INPUT_PULLUP);
  pinMode(TRIG1, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO1, INPUT_PULLUP);
  pinMode(Buzzerpin, OUTPUT);
}

void loop() {

  digitalWrite(TRIG, LOW); // Set the trigger pin to low for 2uS
  delayMicroseconds(2);

  digitalWrite(TRIG, HIGH); // Send a 10uS high to trigger ranging according to specs
  delayMicroseconds(20);

  digitalWrite(TRIG, LOW); // Send pin low again
  delayMicroseconds(2);

  digitalWrite(TRIG1, LOW); // Set the trigger pin to low for 2uS. Give a short LOW pulse beforehand to ensure a clean HIGH pulse
  delayMicroseconds(2);

  digitalWrite(TRIG1, HIGH); // Send a 10uS high to trigger ranging according to specs
  delayMicroseconds(20);

  digitalWrite(TRIG1, LOW); // Send pin low again
  delayMicroseconds(2);

  int distance = pulseIn(ECHO, HIGH, 26000); // Read in times pulse
  int distance1 = pulseIn(ECHO1, HIGH, 26000); // Read in times pulse
  distance = distance/58;
  distance1 = distance1/58;

  if (distance < 25) {
    Serial.print("\r");
    delay(1000);
    Serial.print("AT+CMGF=1\r");
    delay(1000);
    /*Replace XXXXXXXXXX to 10 digit mobile number & ZZ to 2 digit country code*/
    Serial.print("AT+CMGS=\"+YYXXXX\"\r"); // YY is the country code XXX is the number
    delay(1000); //
    //The text of the message to be sent.
    Serial.print("HELLO There");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);
  }
  else {}

  if (distance1 < 25 && ctn < 150) {
    ctn += 1;
    digitalWrite(Buzzerpin, HIGH);
  }
  else {
    digitalWrite(Buzzerpin, LOW);
  }

  if (distance1 > 25 && ctn >= 150) {
    ctn = 0;
    digitalWrite(Buzzerpin, HIGH);
  }
}
```

body:
First thing: you should call `pulseIn()` right after sending the TRIG
pulse. If you wait too much, you will miss the start of the echo pulse.
For instance, here:

```cpp
int distance = pulseIn(ECHO, HIGH, 26000);
int distance1 = pulseIn(ECHO1, HIGH, 26000);
```

the second `pulseIn()` is starting too late, because of the time taken
by the first one.

Next, the general approach for doing things is a non-blocking fashion
(and thus being able to handle concurrent tasks) is to program each task
in the form of a [finite state machine][fsm]. Combine this with the
timing technique used in the “Blink without delay” Arduino tutorial if
you need time-triggered actions.

Here I would use one state machine for sending the SMS and another one
for the buzzer. The first one is the most complex:

**Edit**: I expanded on how I designed this state machine.

In a canonical finite state machine implementation, each action is
associated with a state transition. We then have a transition for each
command sent to the GSM module, and we can label the states according to
which commands have already been sent, like this:

SENT\_NOTHING → SENT\_CR → SENT\_CMGF → SENT\_CMGS → SENT\_MSG →
SENT\_ALL.

All of the above transitions send a string to the GSM module. The first
one (SENT\_NOTHING → SENT\_CR) is triggered by the distance detected
being less than 25 cm. The following ones are time-triggered one
second after the previous one. We have to add one final transition
(SENT\_ALL → SENT\_NOTHING) that performs no action but lets the system
“forget” it has sent an SMS and thus makes it ready to send a new one.
This transition would also be time-triggered, after a potentially long
delay (how often would the user like to receive those reminders?). In
the code below, this last delay is one second, which I believe is too
short, but matches the last `delay(1000)` in the code you posted. The
implementation would be like this:

```cpp
static enum {
  SENT_NOTHING, SENT_CR, SENT_CMGF, SENT_CMGS, SENT_MSG, SENT_ALL
} sms_state = SENT_NOTHING;
static uint32_t time_last_command_sent;
uint32_t now = millis();
switch (sms_state) {
  case SENT_NOTHING:
    if (distance < 25) {
      Serial.print("\r");
      time_last_command_sent = now;
      sms_state = SENT_CR;
    }
    break;
  case SENT_CR:
    if (now - time_last_command_sent >= 1000) {
      Serial.print("AT+CMGF=1\r");
      time_last_command_sent = now;
      sms_state = SENT_CMGF;
    }
    break;
  case SENT_CMGF:
    if (now - time_last_command_sent >= 1000) {
      Serial.print("AT+CMGS=\"+YYXXXX\"\r");
      time_last_command_sent = now;
      sms_state = SENT_CMGS;
    }
    break;
  // and so on for the cases SENT_CMGS and SENT_MSG...
  case SENT_ALL:
    if (now - time_last_command_sent >= 1000) {
      sms_state = SENT_NOTHING;  // forget we sent an SMS
    }
    break;
}
```

I have an issue with this implementation though: it is overly
repetitive, as the cases SENT\_CR, SENT\_CMGF, SENT\_CMGS and SENT\_MSG
are essentially copies of the same code. In order to make the code
[dryer][dry], I prefer merging them into a single state, and splitting
the state information into two variables: `sms_state` and
`commands_sent`. The new possible values for `sms_state` are now:

* SMS\_READY: the code is ready to send the message as soon as it is
  required by the detected distance.
* SMS\_SENDING: it has started to send the commands to the GSM module,
  but is not done yet.
* SMS\_DONE: the SMS has been sent, but no other one will be sent until
  some time has elapsed, after which it will transition to SMS\_READY.

The mapping to the “full” machine states is then:

     full state    │ sms_state   commands_sent
    ───────────────┼───────────────────────────
     SENT_NOTHING  │ SMS_READY         0
     SENT_CR       │ SMS_SENDING       1
     SENT_CMGF     │ SMS_SENDING       2
     SENT_CMGS     │ SMS_SENDING       3
     SENT_MSG      │ SMS_SENDING       4
     SENT_ALL      │ SMS_DONE          5

It could be argued that `sms_state` is redundant, as all the state
information is contained in `commands_sent`. I still wanted to keep
`sms_state` in order to easily `switch` on it. This is not the only
possible approach though, and it would be perfectly sensible to write
something like

```cpp
if (commands_sent == 0) {
  // handle the case SMS_READY
} else if (commands_sent < command_count) {
  // handle the case SMS_SENDING
} else {
  // handle the case SMS_DONE
}
```

For the buzzer, there are only two states: BUZZER\_OFF and BUZZER\_ON.
The transitions are conditioned by the measured distance and, for the ON
→ OFF transition, also by the time it has been ON.

Here is my tentative, untested implementation of this approach:

```cpp
#define TRIG A0 //Module pins
#define ECHO A1
#define TRIG1 A2 //Module pins
#define ECHO1 A3
#define Buzzerpin 13

// Commands to be sent to the GSM module.
const int command_count = 5;
const char * const commands[command_count] = {
  "\r",
  "AT+CMGF=1\r",
  "AT+CMGS=\"+YYXXXX\"\r",
  "HELLO There",
  "\x1a"
};

void setup() {
  Serial.begin(9600);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT_PULLUP);
  pinMode(TRIG1, OUTPUT);
  pinMode(ECHO1, INPUT_PULLUP);
  pinMode(Buzzerpin, OUTPUT);
}

void loop() {
  // Measure both distances.
  digitalWrite(TRIG, LOW);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(20);
  digitalWrite(TRIG, LOW);
  int distance = pulseIn(ECHO, HIGH, 26000) / 58;
  digitalWrite(TRIG1, HIGH);
  delayMicroseconds(20);
  digitalWrite(TRIG1, LOW);
  int distance1 = pulseIn(ECHO1, HIGH, 26000) / 58;

  // Timing for both state machines.
  uint32_t now = millis();

  // Send the SMS.
  static enum {SMS_READY, SMS_SENDING, SMS_DONE} sms_state;
  static uint32_t time_last_command_sent;
  static int commands_sent = 0;
  switch (sms_state) {
    case SMS_READY:
      if (distance < 25) {
        Serial.print(commands[commands_sent++]);
        time_last_command_sent = now;
        sms_state = SMS_SENDING;
      }
      break;
    case SMS_SENDING:
      if (now - time_last_command_sent >= 1000) {
        Serial.print(commands[commands_sent++]);
        time_last_command_sent = now;
        if (commands_sent >= command_count) {
          sms_state = SMS_DONE;
        }
      }
      break;
    case SMS_DONE:
      if (now - time_last_command_sent >= 1000) {
        commands_sent = 0;
        sms_state = SMS_READY;
      }
      break;
  }

  // Drive the buzzer.
  static enum {BUZZER_OFF, BUZZER_ON} buzzer_state;
  static uint32_t time_buzzer_started;
  if (buzzer_state == BUZZER_OFF && distance1 < 25) {
    digitalWrite(Buzzerpin, HIGH);
    buzzer_state = BUZZER_ON;
    time_buzzer_started = now;
  } else if (buzzer_state == BUZZER_ON && distance1 >= 25
             && now - time_buzzer_started >= 2000) {
    digitalWrite(Buzzerpin, LOW);
    buzzer_state = BUZZER_OFF;
  }
}
```

[fsm]: https://majenko.co.uk/blog/finite-state-machine
[dry]: https://en.wikipedia.org/wiki/Don't_repeat_yourself


body:
Using the blinkwithoutdelay approach is not incorporating functions, it is a coding style.

The idea is that you write your loop code to pass through without any delays, or with only very tiny delays. On each pass through the loop, you see how much time has passed, and if it's been 5 seconds since you started the buzzer, you turn off the buzzer.

You can probably get away with the microsecond delays that you use in your ultrasonic sensor code. Those delays are so small that they will only cause **very** short pauses in your app.

The `delay(1000)` calls in your loop are not going to work. Each one of those causes EVERYTHING to stop for a full second. You won't check the ultrasonic sensor, you won't change the buzzer state, you won't do ANYTHING, for 5 seconds, once you enter the body of that `if` statement. Those delay calls have to go.


message:
Arduino Nano - How to add multiple sensors? Lithium battery requirements? LED requirements?

I am new to arduino and need help with a couple projects I am working on. One involves the use of 2 sensors - one pulse sensor, and one vibration sensor. Both need to be plugged into the "5v" pin but there seems to be only one. Is there a way I could split the pins to add multiple sensors? Will data be taken in simultaneously, and be cross compared with each other for code execution? I dont want to use breadboaard and want to wire directly to chip.

Also, I need to wire up a rechargeable lithium battery to both projects, I have a 3.7v 1000 Mah lithium battery and a charging port, but do I need more? Ive seen battery regulators, and other parts people recommend, but I want to make sure it will work with just those 2 parts.

I also need to wire a multicolor LED to the board, but do I need any resistors? I see them often for others people projects, but I do not have any and am wondering if I need them.

Thanks if you can answer any of these questions. Totally new to EE

body:
Warning: unexperienced experiments even with low voltage may result in dangerous situations. E.g. a typical 10 Ohm resistor on 5 V may get so hot that it starts burning. Make yourself familiar with basic electronics, ideally with the help of someone else who can explain it to you. That person should especially explain the safety instructions first.

> Both need to be plugged into the "5v" pin but there seems to be only one.

5 Volts means that this is a voltage source. In an ideal voltage source, you can basically plug in as many components as you like.

A real world voltage source will have a power limit. So you need to find datasheets of all components: the Arduino and the sensors. You can then read how much power the Arduino can provide and you can read how much power the sensors need.

As long as the Arduino can provide more power than the sensors need, that's ok. If it can't stuff will become more complicated, since you'll need another 5 V source and find a way to connect them safely.

>  Is there a way I could split the pins to add multiple sensors?

One does not split pins, one connects additional wires to a pin.

> Will data be taken in simultaneously, and be cross compared with each other for code execution?

The 5V pin is only a voltage source. It will not provide or receive data. You'll need another pin or even multiple other pins to send and receive data.

Sometimes you can only have one device per pin (like a digital out pin), sometimes you can have multiple devices on a few pins (like I²C, SPI, 1Wire).

Typically, you would define what you need and then buy the components so you can build it. This requires a bit of knowledge, so watch some tutorials or introduction videos first.

> I dont want to use breadboaard and want to wire directly to chip.

Sorry to be that direct, but at your level of understanding, that's probably not a good idea. Build it on a breadboard first and once it works as intended, make it a soldered circuit.

> I need to wire up a rechargeable lithium battery to both projects, I have a 3.7v 1000 Mah lithium battery and a charging port, but do I need more?

As you said your components need 5 V, a 3.7 V battery will not help you at all.

You also need to be careful with the terms: a Mah is something totally different than a mAh. Don't confuse other people by mixing Mega (millions) with milli (1/1000).

Other than that, again, read the data sheets, find out how much current each component needs and sum it up. Then divide the 1000 mAh by the value you found, e.g. 100 mA and you'll get 10 h. That's how long it will last. Maybe it's good for your purpose, maybe not. How should we know that?

> I want to make sure it will work with just those 2 parts.

That's great. Just consider all the aspects written in the data sheets of the components and it'll be fine.

> I also need to wire a multicolor LED to the board, but do I need any resistors?

Yes. Read the data sheet of the multicolor LED and build a voltage dividor according to the values you find.

> Totally new to EE

That's probably true. Maybe you want to start at the beginning and not jump into such a complex project. Get some resistors, measure voltages, measure currents. Make an LED light up. Learn about Ohms law, you'll need it very often. Once you got familiar with the basic stuff, come back to this project.

Honestly, I think you'll destroy components if you start with "a couple of projects".


body:
This is an addition to the answer of Thomas Weller.

> Also, I need to wire up a rechargeable lithium battery to both projects, I have a 3.7v 1000 Mah lithium battery and a charging port, but do I need more? Ive seen battery regulators, and other parts people recommend, but I want to make sure it will work with just those 2 parts.

I guess with "charging port" you simply mean a plug, where you can connect a power supply to charge the Li battery. Then the answer is: No, you cannot do it with only the battery and the plug. Lithium batteries are rechargeable, yes, but there is much to consider for charging. You must never ever overcharge the battery or discharge it beyond a certain point. Otherwise the battery gets broken (the result can be between simply holding less and less or no power, to the battery exploding).

Also you need to know the battery level to accurately charge or turn of the device, when the battery is empty. Lithium batteries mostly don't change their voltage enough between the full and empty states. Thus Li battery devices have a circuit, that measures, how much power is coming in (while recharging) and how much power is taken out (for powering a device), to determine the current battery level.

At your stage you cannot build that yourself, and also I wouldn't recommend that to anyone. You can by Li battery charger/regulator boards, which will do all that for you, and they are not expensive. There are also microcontroller boards, that incorporate that support for Li batteries.


body:
A multicolor LED as in an RGB LED?

To power and LED you will need current limiting resistors.

For an RGB LED you'll need 3, one each for the red, green, and blue channels. You'll need to do some math to figure out what resistance values you need. You need to know the supply voltage (5V) the voltage drop of the LED, and the current to supply to the LED.

Here is a link to an LED resistor calculator: https://ohmslawcalculator.com/led-resistor-calculator

The formula is R = (source_voltage -  LED_voltage_drop) / LED_current

So if you have a 20 mA LED with a 1.3V voltage drop, and you are powering it from 5V (all fairly common values) you'd get:

(5-1.3)/0.02 = 185 Ω.

Then you would round up to the nearest resistor value.

You can safely use a higher resistance value than what you calculate. That will cause the LED to be dimmer. If you use a lower resistance you risk burning out the LED, or even burning out your Arduino.

For 20% resistors, that would be a 220Ω resistor. (The percent is a tolerance value. 20% resistors can have their actual resistance vary by as much as 20% from one to the next. You can get resistors in 20%, 10%, 5%, 2%, 1% tolerances, and even lower. The lower the tolerance value, the more they cost, and the more resistors you need to have all the possible values.

Don't use that value however. Look up the voltage drop and current for your LED and plug them into the above formula.

If you want to vary the apparent color of an RGB LED through software you can hook each color channel to a different PWM output pin on your Arduino. You then set each color channel to a different "duty cycle" to vary the brightness of that color.


body:
**For the 5v pin:**
If you wire 2 sensors to the 5v pin, it will not effect sensor readings of either sensors, and should return separate sensor values regardless of whether or not they are both wired to the 5v pin.

In order to wire both sensors to 1 5v pin, without involving a breadboard you have 2 options:

 1. wire both sensor pins, and the 5v pin onto a custom pin header PCB that connects 3 or more pin headers together
 2. Strip 3 jumper wires and solder them together (2 for the sensors and 1 for the 5v pin)

**For the lithium batteries:**
It says on their website: that the operating voltage is 5v, So your battery voltage needs to be at least that. It might be a good idea to get 2
[(store.arduino.cc)](https://store.arduino.cc/usa/arduino-nano#:~:text=The Arduino Nano is a,instead of a standard one.)

**For the LEDs:**
If it is a standard LED, it should be able to withstand voltages of 3.3v or under. Thus the resistor is only absolutely essential for higher voltages. However, it is recommended to use a resistor even with voltages of 3.3v or below, because low resistance could shorten the lifespan of the LED


message:
Is it required to delete variables before going to sleep?

This tutorial shows how to put the arduino to sleep and use a watchdog to wake up at intervals:

https://youtu.be/urLSDi7SD8M

I been studding c++ and as I am getting better I am instantiating objects with the `new` keyword. I have learned that if you create something with the `new` keyword you are responsible for deleting it from memory when you no longer needed. But I do not know if this applies when you put arduino to sleep.

**Anyways my question is in the comments of the code:**

    Foo * someObject;

    void setup()
    {
        someObject = new Foo(arg1, arg2, ..); // crete an instance of someObject
       // init pins etc..
    }

    void loop()
    {
         if(button1Pressed())
         {

              // **** DO I HAVE TO DELETE OBJECTS BEFORE GOING TO SLEEP? Do I need this line? ****
              delete someObject;

              gotToSleepAndWakeUpIn4Seconds() ;  // places arduino in sleep mode and wakes up again in 4 seconds

              int x = 0; // this line never executes arduino is on sleep mode and will wake up again in 4 seconds
         }

         // more code
         if(something)
            someObject->executeFunction1();

         // etc...
         // ....
    }

body:
You have probably learnt that objects created with `new` are stored in
the heap, while globals are stored in the .data and .bss sections, and
locals on the stack¹. This distinction, however, only exists in the
software. At the hardware level, .data, .bss, heap and stack are just
arbitrary portions of the RAM.

Think of what would happen if the RAM was erased, or somehow corrupted,
when the microcontroller sleeps. Not only would that affect the
heap-based objects, but also every variable in the program. And even the
return address from the call to `gotToSleepAndWakeUpIn4Seconds()` would
be lost, so the CPU would not know where to resume execution when it
wakes up. The only reasonable thing to do at wakeup would then be to
restart the program from scratch. And this is actually what happens when
you reset the microcontroller².

But a sleep is not a reset. The contents of the RAM is preserved while
sleeping. This means that the _whole state_ of the program is preserved:
locals, globals and heap-based objects. No need to delete and re-create
stuff.

As a side note, if you can allocate memory statically, this is usually
better than dynamic allocation, ans you avoid the risk of heap
fragmentation:

```cpp
Foo someObject(arg1, arg2, ..);  // static global instance

void loop()
{
    // Some code, then,

    if (something)
        someObject.executeFunction1();
}
```

Notes:
¹ As an optimization, locals of the _current_ stack frame may be in CPU
registers, but this doesn't change the conclusion.
² On AVR, a warm reset doesn't loose the RAM, but it is then
reinitialized by the C runtime. A cold reset (power-cycle) does loose
the RAM.


message:
I2C comunication, ESP->Nano on endTransmission no ACK fron nano

i am trying to communicate between ESP(master) and arduino nano(slave). This is only a prototype and all works fine. But i want to  add multiple arduinos and therefor i need to detect if the arduino is connected.

I use the return function from wire.endTransmission as shown in i2c scanner to detect devices. But it doesnt work.

On the arduino i have this program:

    #include <Wire.h>

    const int16_t I2C_SLAVE = 0x22; // 0x22 = 34 cize izba 3(30)

    void setup() {
      Wire.begin(I2C_SLAVE);

    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

on the ESP i am trying this:

    Wire.beginTransmission(I2C_adress[adress]);
    int error = Wire.endTransmission();

    Serial.println(error);

**It returns only 2 (received NACK on transmit of address)
Why? When i have other code on the slave (with onRecive and onRequest all works and comunicates)**

Thank you.

body:
I'm a fool, I tried to detect other devices in the setup function before the `Wire.begin(PIN_SDA, PIN_SCL,  I2C_MASTER);`
I Found it only because of you. The rubber duck. I started to write the program down to post it here and bingo.
That was the reason why the master had the "NACK" answer. The master was not started yet.

Thank you


message:
How to Set RTC in ES32 using NTP server?

I am working on ESP32 And want to set RTC from the NTP server. How can I get epoch value I have done this thing on CC3200 launchpad and used an NTP server library to obtain epoch value.

body:
this snippet from setup() sets on esp32 the NTP for internal RTC and uses epoch seconds to set time to TimeLib library.
```
  configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
  time_t now = time(nullptr);
  while (now < SECS_YR_2000) {
    delay(100);
    now = time(nullptr);
  }
  setTime(now);
```

The ESP32 examples library in IDE examples folder has example SimpleTime.


message:
Holding buttons (keyboard)

I made a wireless keyboard, but I just need 4 button for my project: left control, left shift, F1, F2.
The problem: When I hold button - it acts like many key presses and releases, but I need, that when I press & hold button - it also acts like I press & hold it.

Could you please help me?

Here is source code:

Transfer_e5.ino:  https://www.paste.org/108039

Receiver_e5.ino:  https://www.paste.org/108040

Or 1 rar package:
https://easyupload.io/o3c5sp

Thank you

Or I can put them just here, if you wish.

Receiver:

    #include <Keyboard.h>
    #include <RF24Network.h>
    #include <RF24.h>
    #include <SPI.h>

    RF24 radio(8,7); // (ce,cs)
    RF24Network network(radio);

    const uint16_t this_node = 00;
    const uint16_t other_node = 03;

    unsigned int laser_state=0;
    const unsigned long my_interval = 500;
    unsigned long last_sent;
    unsigned int income=0;

    void setup(void)
    {
      Serial.begin(115200);
      pinMode(9,INPUT_PULLUP);

      SPI.begin();
      radio.begin();
      network.begin(90,this_node);

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

    void loop(void){
      digitalWrite(4,LOW);
      network.update();

      if ( network.available() ) {
        RF24NetworkHeader header;
        network.read(header,&income,sizeof(income));

        if(income==10){
          Serial.println("f1");
          Keyboard.press(KEY_F1);
          income=0;
        }

        if(income==11){
          Serial.println("f2");
          Keyboard.press(KEY_F2);
          income=0;
        }

        if(income==12){
          Serial.println("ctrl");
          Keyboard.press(KEY_LEFT_CTRL);
          income=0;
        }

        if(income==13){
          Serial.println("shift");
          Keyboard.press(KEY_LEFT_SHIFT);
          income=0;
        }

        Keyboard.releaseAll();
      }

      unsigned long now = millis();

      if ( now - last_sent >= my_interval  )
      {
    //    Serial.print("pin ");
    //    Serial.println(digitalRead(9));
        last_sent = now;
        laser_state = digitalRead(9);

        RF24NetworkHeader header(other_node);
        bool ok = network.write(header,&laser_state,sizeof(laser_state));
      }
    }

Transfer

    #include <RF24Network.h>
    #include <RF24.h>
    #include <SPI.h>

    RF24 radio(8,7);
    RF24Network network(radio);

    const uint16_t this_node = 03;
    const uint16_t other_node = 00;

    unsigned int laser_state=0;
    const unsigned long interval = 5;
    unsigned long last_sent;

    unsigned int b1=1;
    unsigned int b2=1;
    unsigned int b3=1;
    unsigned int b4=1;

    unsigned int d1=10;
    unsigned int d2=11;
    unsigned int d3=12;
    unsigned int d4=13;

    //TR1
    int btn1 = 3;
    int btn2 = 4;
    int btn3 = 5;
    int btn4 = 6;

    void setup(void)
    {
    //  Serial.begin(9600);
      pinMode(btn1,INPUT_PULLUP);
      pinMode(btn2,INPUT_PULLUP);
      pinMode(btn3,INPUT_PULLUP);
      pinMode(btn4,INPUT_PULLUP);

      SPI.begin();
      radio.begin();
      network.begin(90,this_node);
    }

    void loop(void){
      network.update();

      unsigned long now = millis();

      if ( now - last_sent >= interval  )
      {
        last_sent = now;

        b1 = digitalRead(btn1);
        b2 = digitalRead(btn2);
        b3 = digitalRead(btn3);
        b4 = digitalRead(btn4);

        if(b1==0){
    //      Serial.println("F1");
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,&d1,sizeof(d1));
        }

        if(b2==0){
    //      Serial.println("F2");
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,&d2,sizeof(d2));
        }

         if(b3==0){
    //      Serial.println("Ctrl");
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,&d3,sizeof(d3));
        }

        if(b4==0){
    //      Serial.println("Shift");
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,&d4,sizeof(d4));
        }
      }
    }

body:
The root problem is that you send each several ms new key event and on receiver each time you get this event, you call `Keyboard.press` and right away `Keyboard.release`. So, it behaves as several key press-releases.

At sender side you should send 2 types of events:
1) Key pressed (and which button)
2) Key released (and which button)

At receiver side you should
1) When you receive "press" event, call `Keyboard.press`, and don't call `Keyboard.release`
2) When you receive "release" event, call `Keyboard.release`

**Edit: I've made changes to your source code, please, try it**

Transfer

    #include <RF24Network.h>
    #include <RF24.h>
    #include <SPI.h>

    RF24 radio(8,7);
    RF24Network network(radio);

    const uint16_t this_node = 03;
    const uint16_t other_node = 00;

    unsigned int laser_state=0;
    const unsigned long interval = 5;
    unsigned long last_sent;

    unsigned int b1=1;
    unsigned int b2=1;
    unsigned int b3=1;
    unsigned int b4=1;

    unsigned int d1=10;
    unsigned int d2=11;
    unsigned int d3=12;
    unsigned int d4=13;

    //TR1
    int btn1 = 3;
    int btn2 = 4;
    int btn3 = 5;
    int btn4 = 6;

    void setup(void)
    {
    //  Serial.begin(9600);
      pinMode(btn1,INPUT_PULLUP);
      pinMode(btn2,INPUT_PULLUP);
      pinMode(btn3,INPUT_PULLUP);
      pinMode(btn4,INPUT_PULLUP);

      SPI.begin();
      radio.begin();
      network.begin(90,this_node);
    }

    void loop(void){
      network.update();

      unsigned long now = millis();

      if (now - last_sent >= interval)
      {
        last_sent = now;

        auto newB1 = digitalRead(btn1);
        auto newB2 = digitalRead(btn2);
        auto newB3 = digitalRead(btn3);
        auto newB4 = digitalRead(btn4);

        unsigned int packet[2];

        if(newB1 != b1){
    //      Serial.println("F1");
          packet[0] = d1;
          packet[1] = newB1;
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,packet,sizeof(packet));
        }

        if(newB2 != b2){
    //      Serial.println("F2");
          packet[0] = d2;
          packet[1] = newB2;
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,packet,sizeof(packet));
        }

         if(newB3 != b3){
    //      Serial.println("Ctrl");
          packet[0] = d3;
          packet[1] = newB3;
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,packet,sizeof(packet));
        }

        if(newB4 != b4){
    //      Serial.println("Shift");
          packet[0] = d4;
          packet[1] = newB4;
          RF24NetworkHeader header(other_node);
          bool ok = network.write(header,packet,sizeof(packet));
        }

        b1 = newB1;
        b2 = newB2;
        b3 = newB3;
        b4 = newB4;
      }
    }

Receiver

    #include <Keyboard.h>
    #include <RF24Network.h>
    #include <RF24.h>
    #include <SPI.h>

    RF24 radio(8,7); // (ce,cs)
    RF24Network network(radio);

    const uint16_t this_node = 00;
    const uint16_t other_node = 03;

    unsigned int laser_state=0;
    const unsigned long my_interval = 500;
    unsigned long last_sent;

    void setup(void)
    {
      Serial.begin(115200);
      pinMode(9,INPUT_PULLUP);

      SPI.begin();
      radio.begin();
      network.begin(90,this_node);

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

    void loop(void){
      digitalWrite(4,LOW);
      network.update();

      unsigned int income[2] = {0, 0};

      if ( network.available() ) {
        RF24NetworkHeader header;
        network.read(header,&income,sizeof(income));

        auto keyCode = income[0];
        auto keyPress = !income[1];

        if(keyCode == 10){
          Serial.println("f1");

          if (keyPress) {
            Keyboard.press(KEY_F1);
          } else {
            Keyboard.release(KEY_F1);
          }
        }

        if(keyCode == 11){
          Serial.println("f2");

          if (keyPress) {
            Keyboard.press(KEY_F2);
          } else {
            Keyboard.release(KEY_F2);
          }
        }

        if(keyCode == 12){
          Serial.println("ctrl");

          if (keyPress) {
            Keyboard.press(KEY_LEFT_CTRL);
          } else {
            Keyboard.release(KEY_LEFT_CTRL);
          }
        }

        if(keyCode == 13){
          Serial.println("shift");

          if (keyPress) {
            Keyboard.press(KEY_LEFT_SHIFT);
          } else {
            Keyboard.release(KEY_LEFT_SHIFT);
          }
        }

        keyCode = 0;
      }

      unsigned long now = millis();

      if ( now - last_sent >= my_interval  )
      {
    //    Serial.print("pin ");
    //    Serial.println(digitalRead(9));
        last_sent = now;
        laser_state = digitalRead(9);

        RF24NetworkHeader header(other_node);
        bool ok = network.write(header,&laser_state,sizeof(laser_state));
      }
    }


message:
Can we use UART COMMUNICATION with MCP23017?

I am using MCP23017 as a GPIO expander with Arduino in my project. I have too many serial devices and no pins left on Arduino for UART communication.

I am wondering if I can use this MCP23017 GPIO expander pins for UART communication or not?

body:
No. No you can't. Serial takes precise timing and fast reactions. Things you can't do with a remote device like that.

Instead there are SPI UART devices specifically for the job, such as the MAX3107.


body:
I can think of one way.

In theory you could use the GPIO pins of the mcp23017 to control a couple of 2-way multiplexers. With these multiplexers you could split your Rx/Tx pins to more than one serial bus.

May it be obvious that you cannot used the split busses at the same time. So depending on your specific use-case this may or may not be a solution.


message:
Serial port usage in code

I want to write a function that defines a serial port based on a flag but I'm not sure it's possible.

For example:

    void writeToSerial(bool useSerial1)
    {
       SerialPortClass serialPortObject; // Is there some way of defining a generic Serial port object and reusing it below?

       if (useSerial1)
       {
          serialPortObject = Serial1;
       }
       else
       {
          serialPortObject = Serial2;
       }

       serialPortObject.write("test123");
    }

body:
According to sources at `c:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial*` (on Windows platform), you can use pointer to `Stream` class (because `Serial`s are inherited from `Stream`).

So, your function could look like this:
```
void writeToSerial(bool useSerial1)
{
   Stream* serialPortObject;

   if (useSerial1)
   {
      serialPortObject = &Serial1;
   }
   else
   {
      serialPortObject = &Serial2;
   }

   serialPortObject->write("test123");
}
```


body:
This is not a proper answer, but rather a suggestion to reconsider your
approach. The code posted in the question is obviously just a simplified
example, and printing “test123” is likely not your final goal. I assume
what you really want to do is print out some information about some
variables. You can then collect these variables into a data structure (a
C++ object) and make `writeToSerial()` a method of this object. The
object can the be printed like so:

```c++
myDataStructure::writeToSerial(true);   // printed to Serial1
myDataStructure::writeToSerial(false);  // printed to Serial2
```

In this case, what I suggest is to instead explicitly `print()` (or
`println()`) the object to the relevant serial port, like this:

```c++
Serial1.print(myDataStructure);
Serial2.print(myDataStructure);
```

This makes the code self-explanatory, and easier to maintain.

Obviously, you cannot just print arbitrary objects this way, as
`Serial1` and `Serial2` would have no idea about how to serialize them.
But the thing is, you can teach them! Make your class derive from
`Printable`, implement the virtual `printTo()` method, and you will be
able to print it to any serial port, LCD, or whatever understands
`print()`:

```cpp
class MyDataStructure : public Printable {
public:
    size_t printTo(Print& p) const {
        return p.print("test123");
    }
};

MyDataStructure someData;

void setup() {
    Serial1.begin(9600);
    Serial2.begin(9600);
    Serial1.println(someData);
    Serial2.println(someData);
}

void loop(){}
```

See the answer to [Is it possible to print a custom object by passing it
to Serial.print()?][q53732] for an example with actual data in the
object.

[q53732]: https://arduino.stackexchange.com/questions/53732/is-it-possible-to-print-a-custom-object-by-passing-it-to-serial-print


message:
Why is it considered bad practice to use the 'new' keyword in Arduino?

I previously asked this question:

*https://arduino.stackexchange.com/questions/77031/is-it-required-to-delete-variables-before-going-to-sleep*

On that question, @Delta_G posted this comment:

> ... Really on a microcontroller I would create the object in a smaller scope and try to do **everything in my power to avoid having to use `new` or any other form of dynamic allocation.** .... etc.

That comment got three likes and when I google about dynamic allocation using Arduino, everyone also tries to stay away from that. In summary from all the research I did, my conclusion is now **Do not allocate memory unless you really really have to**.

I am using the [Visual Studio][1] IDE to create my C++ libraries that I intend to use with Arduino. On the Arduino IDE I just reference those libraries and the code compiles great. Visual Studio is very powerful and it enables me to create really nice code, because I can test it on my computer before running it on Arduino. For example, I created this library:

    // MyQueue.h

    typedef struct QueueItem
    {
        void* item;

        QueueItem* next;

        QueueItem()
        {
            item = nullptr;
            next = nullptr;
        }

    } QueueItem;

    class Queue
    {
    public:
        unsigned char count;        /* Number of items on queue */
        QueueItem* first;           /* Points to first item on the queue */

        Queue()                     /* Constructor */
        {
            count = 0;
            first = nullptr;
        }

        void enqueue(void* item)    /* Enqueue an object into the queue */
        {
            count++;

            if (first == nullptr)
            {
                first = new QueueItem();
                first->item = item;

                // Log message because we are using the "new" keword. We need to make sure we dispose QueueItem later

                #ifdef windows

                std::cout << "Creating " << first << endl;

                #endif // windows
            }
            else {

                // Find last item
                QueueItem* current = first;
                while (current->next != NULL)
                {
                    current = current->next;
                }
                QueueItem* newItem = new QueueItem();
                newItem->item = item;

                // Log message because we are using the "new" keyword. We need to make sure we dispose QueueItem later
                #ifdef windows
                std::cout << "Creating " << newItem << endl;
                #endif // windows

                current->next = newItem;
            }
        }

        void* dequeue()
        {
            if (count == 0)
                return nullptr;

            QueueItem* newFirst = first->next;

            void* pointerToItem = first->item;

            // Log message we are deleting an object because we created it with the 'new' keyword
            #ifdef windows
            std::cout << "Deleting " << first << endl;
            #endif // windows

            delete first;
            first = newFirst;
            count--;

            return pointerToItem;
        }

        void clear()                /* Empty queue */
        {
            while (count > 0)
            {
                dequeue();
            }
        }

        ~Queue()                    /* Destructor. Dispose everything */
        {
            clear();
        }
    };

Now on my Arduino sketch, I can have the following code if I reference that header file.

    typedef struct Foo
    {
        int id;
    } Foo;

    void someMethod()
    {

        Queue q;

        // Create items
        Foo a;
        a.id = 1;

        Foo b;
        b.id = 2;

        // Enqueue a,b and c
        q.enqueue(&a);
        q.enqueue(&b);

        // Deque
        Foo * pointerTo_a = (Foo*)q.dequeue();
        int x = pointerTo_a->id; // =1

        Foo * pointerTo_b = (Foo*)q.dequeue();
        int y = pointerTo_b->id; // =2

        // Error
        Foo * test = (Foo*)q.dequeue();
        // test == null pointer
    }

--------

Most people say do not use void pointers. Why!? Because I am using void pointers I can now use this queue class with whatever object I want!

**So I guess my question is: Why is everyone trying to stay away and avoid code like this?**
----

I am using the [NRF24L01][2] radio module to send messages to several Arduinos. It is convenient to have a queue of messages to be sent. **I would be able to code the same program without allocating memory and avoiding the `new` keyword. But that code will look ugly in my opinion.**

In this quarantine I decided to learn C++ and that has changed the way I code Arduino. The moment I learned C++ I stopped using the Arduino IDE. I been a backed developer for 12 years, and that is the reason why I learned C++ in a couple of months. Arduino is just a hobby for me. **I am still very new to microcontrollers and I will like to understand why people stay away from the full power of C++ when it comes to microcontrollers**. I know I have only 2 kilobytes of RAM. I will not be allocating that much memory. I still want to take advantage of the C++ programming language by using the `new` , `delete` , `poineters` and destructors`. I want to keep using Visual Studio to write powerful C++ libraries.

In C++ I write interfaces like this

    // Note I use uint32_t instead of 'unsigned long' because an unsigned long is different size on Windows than on Arduino. Also I use an unsigned short instead of an int because an unsigned short is the same size on Windows and Arduino.

    class IArduinoMethods
    {
    public:

        // Unsigned long in Arduino
        virtual void delay(uint32_t delayInMilliseconds) = 0;

        virtual void print(const char* text) = 0;

        virtual uint32_t millis() = 0; // Get elapsed time in milliseconds
    };

And I then implement the classes like this. For example, this is the class that I will use when testing my code on a windows computer:

    // Class to be run on Windows.
    class ArduinoMockWindows : public IArduinoMethods
    {
    public:

        // Inherited via IArduinoMethods
        virtual void delay(uint32_t delayInMilliseconds) override
        {
            // This code will be different on Arduino, and that is why I need this dependency
            Sleep(delayInMilliseconds); // Windows
        }

        virtual uint32_t millis()
        {
            //clock_begin = std::chrono::steady_clock::now();

            std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
            auto duration = now.time_since_epoch();
            // etc..
            return someDuration;

        }

    };

Because a Windows computer cannot send NRF24 radio messages, I can implement an interface (dependency) that will write to a file, for example instead of sending a real radio packet just for testing.

The caveat is that my libraries will require these dependencies. For my library to work, I will have to pass it an object of type `IArduinoMethods` and `INrfRadio`. If I am running my code on Windows I will pass it a class that will implement those methods that can run on windows. **Anyways the point is not to show how C++ works. I am just showing how I use pointers and allocate memory for a lot of things.**

Because I allocated memory I was able to test my library on Windows and on Arduino for example. I may also create unit tests. I see so many benefits by allocating memory. If I am organized and remember to free the objects I no longer use, I can gain all this benefits. **Why people do not code like this when it comes to Arduino?**

--------

Edit 1
---

------

Now that I understand how heap fragmentation works, I know I have to be careful when using the `new` keyword.

I hate when people do what they are told to do without understanding how things work. For example, the answer https://arduino.stackexchange.com/a/77078/51226 from **Why is the queue library in this question for starters?**. There are going to be times when a ring buffer works better and other times when the `new` keyword works better. Probably the ring buffer will work best for most cases.

Take the following scenario where you only have 1 KB of memory left.

1. There is a hierarchy of nodes where a node have a child and a sibling. For example, node A can have child B and sibling C. Then child B can have another child, etc.

(I will be storing this in memory)

2. I have a queue of work that needs to be done.

(I will have to store this work somewhere)

3. I will have a queue of events

(I will have to store this somewhere)

**If I use what most people say I should do then I will be have to:**

1. Reserve 500 kB to be able to store nodes (I will be limited to n number of nodes)

2. Reserve 250 kB for the queue of work that needs to be done.

3. Reserve 250 kB for the queue of events.

*This is what most people will do* and it will work great with no problems of heap fragmentation.

**Now this is what I will do**

1. Ensure that everything that I allocate is of size 12 bytes. A node only has its id (unsigned int), child (pointer), type (unsigned char), etc.. with a total of 12 bytes.

2. Ensure that all the work that will be enqueued is of size 12 bytes as well.

3. Ensure that all the events that will be enqueued is of size 12 bytes as well.

Now if I have more work than events, this will work. I just have to program in my code that I never allocate more than 70 items. I will have a global variable that has that count of allocations. My code will be more flexible. I will not have to be stuck with strictly 20 events, 20 work and 30 nodes. If I have fewer nodes then I will be able to have more events. **Anyways my point is that one solution is not better than the other. There are going to be scenarios when one solution is better.

In conclusion, just understand how heap fragmentation works and you will gain a lot of power by using the new keyword. Do not be a sheep and do what people tell you to do without understanding how things work.**.

-----

Edit 2
-----

------

Thanks to @EdgarBonet, I ended up storing Nodes on the stack. Here is why:

I have a hierarchy of nodes that can be represented as:

    typedef struct Node
    {
       unsigned short id;
       Node * sibling;
       Node * child;
    } Node;

As you can see every node is only 6 bytes. That is another reason why I did not care to much about allocating Nodes at the beginning. If I allocate this node on the heap I will be losing 2 more bytes (33%) for every allocation because on every allocation the size of the node has to be stored. As a result I created these two methods and a buffer:

    // For this to work a node can never have an id of 0 !!!

    Node nodeBuffer[50];                     /* Buffer to store nodes on stack */

    Node* allocateNode(Node nodeToAllocate)  /* Method to store a node */
    {
        // Find first available spot where a node can be saved
        for (char i = 0; i < 50; i++)
        {
            if (nodeBuffer[i].id == 0)
            {
                nodeBuffer[i] = nodeToAllocate;
                return & nodeBuffer[i];
            }
        }
        return nullptr;
    }

    void freeNode(Node* nodeToFree)          /* Method to delete a node */
    {
        nodeToFree->id = 0; // If the id of a node is 0 this is my convention of knowing it is deleted.
    }

And on my code I used to have things like:

    Node * a = new Node();
    a->id = 234423;
    // ....
    // .. etc
    // ..
    delete a;

Now I just have to replace that code with:

    Node * a = allocateNode({});
    a->id = 234423;
    // ....
    // .. etc
    // ..
    freeNode(a);

And my code works exactly the same without having to use the `new` keyword. I thought it was going to be complicated to refactor the code and create a buffer.

I made this modification because I wanted to be able to store more nodes on my code. By loosing that 33% I was not going to be able to create that many. **If I only allocate objects of the same size and I do not allocate that many it is perfectly fine to use the `new` keyword.** > Also in the case of the queue I will allocate and delete objects very fast. Because the objects will not persist on memory for too long, and the chances of having heap fragmentation are very low.

  [1]: https://en.wikipedia.org/wiki/Microsoft_Visual_Studio
  [2]: https://www.youtube.com/watch?v=7rcVeFFHcFM

body:
Most Arduinos (like the Uno or Nano) have very few RAM, thus you first need to make sure that you never allocate too much memory. Dynamically allocating memory can also lead to heap fragmentation (heap being the part of memory where dynamic allocation happens).

In most cases you would want to allocate memory of different sizes (for example arrays of different sizes) or just different objects (with each having it's own size) (!!! This is the key point here). Then you are going to delete some of these objects which will create holes inside the memory. They can be filled again with objects with the same or less size. As time passes and more allocation and deleting happens these holes tend to get smaller, up to the point where none of your new to allocate objects can fit in there. That memory then is unusable. This phenomenon is called heap fragmentation.

These holes appear naturally also on a PC but there are 2 key differences:

1. The Arduino has such little RAM that the holes can fill up your memory very very fast.

2. While the PC has an operating system, which manages the RAM (defragmenting it or putting unused stuff away into a paging/swap file), the Arduino does not have an OS. So noone keeps an eye on the real available RAM and noone tidies up the memory once in a while.

That does not mean that you cannot use dynamic allocation on an Arduino, but that is very risky depending on what exactly you are doing and how long the program should work without failing.

Considering this big caveat, you are very limited on how to use dynamic allocation. Doing it too much will result in very unstable code. The remaining possibilities, where it might be safe to use it, can also be easily done with static allocation. For example take your queue, which is basically a linked list. Where is the problem with allocating an array of `QueueItem`s at the start. Each item gets a way to determine if it is valid. When creating a new item you just pick the first element in the array, which has a non-valid item, and set it to the desired value. You still can use the data via the pointers, just as before, but now you have it with static allocation.

You might find that the code looks uglier that way but you need to adapt to the platform that you use.

Note that this does **not** apply when you are going to create **only objects with the same size**. Any deleted object will leave a hole where any new object can fit into. The compiler uses that fact. So in that case you are safe. Just every object that you dynamically create in your program needs to be the exact same size. That of course also includes objects that are created inside different libraries or classes. For this reason it can still be a bad design choice, as you or others (if you want to publish your code), may want to pair your library with other code.

Another way to be safe is to only create and delete objects in closed cycles, meaning, that a created object needs to be deleted before the next object is created. Though that is not fitting for your application.

---

'Bigger' microcontrollers, for example the non-Arduino boards with the ESP32, have much more memory. Thus the use of dynamic allocation is not that bad on them. Though you still don't have an OS to manage the RAM.


body:
Dynamic allocation is generally discouraged in embedded applications because you cannot guarantee that you do not exceed (attempt to allocate more than) the available memory. Static allocation will generally have this guarantee although out-of-memory bugs may still be possible.

Additionally, far fewer services or tools are available to automatically manage and mind the memory for you. Any service that does so will consume computational resources.

This means that you inherently create a mechanism in your device that would cause a memory (heap) overflow and possible undefined behavior (UB). This is true **even if your code is bug-free and has no memory leaks.**

In non-critical, exploration, learning, and prototype applications this may not be important.

Consider that without careful consideration undefined behavior can result in hardware failures and unsafe performance, for example if the device reconfigures GPIO through an errant write to the correct registers during a crash.


body:
### For starters, fix your library ###

As noted by @crasic, dynamic memory allocation is generally not recommended for embedded systems.  It may be acceptable for embedded devices which have a larger amount of free memory - embedded Linux is commonly used, for example, and all Linux apps/services will tend to use dynamic memory allocation - but on small devices such as an Arduino there simply is no guarantee that this will work.

Your library illustrates one common reason why this is a problem.  Your `enqueue()` function creates a `new QueueItem()` but does not check that the allocation succeeded.  The result of failed allocation may either be a C++ `bad_alloc` exception, or it may be returning a null pointer, which when you reference it will give a system memory access exception (SIGSEGV signal in Linux, for example).  It is nearly universal in Linux and Windows programming to ignore memory allocation failure (as encouraged by most textbooks), because the massive amount of free RAM and the existence of virtual memory makes this very unlikely, but this is unacceptable in embedded programming.

More generally though, as @crasic says, memory fragmentation can leave even non-buggy code unable to allocate memory.  The result will be a failure to allocate memory, but the code will at least know this has happened and will probably be able to continue.

### But better, use a fixed-size FIFO queue instead ###

Your code relies on dynamic allocation to add and remove elements in a queue.  It is perfectly possible (and equally easy coding-wise) to create a fixed-size array for the queue, so the various failure modes of dynamic allocation simply do not apply.  An item to be queued is simply copied into the next free queue slot, and a queue slot is marked free when it has been used.  (Don't forget to use a mutex when adding and removing items from the queue, because adding and removing will often be called from different places.)

The queue can be made whatever size you feel is appropriate (allowing for how much RAM you have).  With a fixed size, you are forced to make a design decision on what should happen if the queue overflows - do you delete the oldest data to make room for the new value, or do you ignore the new value?  This may seem an unwelcome new feature, but it is a ***good*** thing, because the third option which you've currently got is that your code goes "Aaaarrggghhh I don't know what to do!" and crashes fatally, and we don't really want that.


body:
I'm adding this not so much to add to the answer as to add some real world implications for those that may be down this particular rabbit hole.  It's nice to talk about what could happen theoretically, but a new programmer may still be tempted to think that he can out-think these limitation and still do something useful.  Here is some real world talk about why that is foolish even if you are capable.

Let's say we're developing code on an Arduino UNO.  We've got 2K of RAM to work with.  We have a class that loads a list of names, maybe it's a building access device or something.  Anyways, this hypothetical class has a name field to store someone's name.  And we decide to use the String class to hold the name as a String.

Let's say after our program is all there and doing what it's doing that there is 500 bytes left for this list of objects, each with a name field that could be of varying length.  So we run along nicely for years with a crew of 14 or 15 people with an average name length of 30 characters or so.

But one day a new guy signs up.  And his name is really long.  Let's say it takes 100 characters.  Even if we're smart coders and only have one copy of this String in memory, we've got it there and suddenly it doesn't fit.  Now a program that has worked for years suddenly fails.  And nobody knows why.

So the solution is easy right?  Enforce a maximum limit on the length of the name.  Some simple code that checks the name length and we can write a great piece that still allows the variable name length and won't let you create a new user if there's less than that much left.  Seems simple enough, but then Becky in accounting gets married and her last name changes from Smith to Wolfeschlegelsteinhausenbergerdorff and suddenly our program breaks again for no reason.

So the solution is simple right?  We'll enforce a maximum length and we'll be sure to reserve enough memory for each object that it can afford to have the maximum length name.  And that's something that we do most efficiently without dynamic allocation since we already know the size of the object.

I hear what you're saying, "but Delta-G, if we have all those short names in there, why are we going to waste all that memory on them when we don't have to.  Let's only save space for a long one if we have a long one."  And I like your thinking, this is good thinking.  But it doesn't help anything to save that memory.  If you do save some, what are you going to do with it?  If your program uses it, then there is no longer room for the longer case and suddenly you have to enforce an even shorter maximum length to accommodate that usage.

Say for instance we have 500 bytes of room and we enforce a maximum length of 50 bytes for 10 users.  And let's say that when the names are short we want to let the program use some of that saved space.  If the program can encroach 100 bytes into that space when the names are short, then why wouldn't the same situation happen with long names?  So really since the program can use all but 400 bytes then there's really only 400 bytes of room and we have to enforce a 40 byte maximum for 10 users or 50 bytes for 8.

Since you're going to have to make that sacrifice anyway, then it only makes sense to remove the work of dynamic allocation and just make things fixed sizes or use fixed size buffers.

If we had a PC with gigabytes of memory, we wouldn't even be thinking about this.  But on an Arduino UNO with 2K bytes of memory it can become a big problem really fast.

The other problem is that these bugs are so insidious.  If out of memory bugs just caused a simple crash and the thing no longer worked then it wouldn't be nearly so scary.  But that's not how out of memory bugs work on a microcontroller.  It all depends on how things are arranged in memory by the compiler.

These bugs often manifest as something that seems to work most of the time but has some funny bugs nobody can explain.  Maybe there's only a problem if someone has a name that is exactly 26 characters long and tries to open the door on a Wednesday.  Or maybe the issue will only arise if Becky logs in immediately after Bob.  Maybe it just garbles three letters on the screen but other than that everything works.  Maybe with a different name changed that suddenly turns into our lock opens for anyone.  There's no guessing or explaining out of memory bugs.  So we have to be super careful to avoid even the remote possibility of running into one.

And that's why we avoid using dynamic allocation on small microcontrollers.  At the end of the day, there's nothing you can save with it, and even if you could the consequences of getting something a little wrong are terribly frustrating.  With these types of programs you almost always have to end up enforcing some sort of limit on everything and once you're enforcing limits there's no use for dynamic allocation anymore.


message:
Using Two Arduino to Lower Power Consumption

I am planning to build a water quality sensor with ph, temperature, and dissolved oxygen, conductivity. The power consumption looks like it will be very high especially due to the signal isolator, I'm estimating about 250mA. I'm going to place it in a remote area so I need it to be as power-efficient as possible.

I was thinking would this work?

What if I use two Arduino to control the power? The first Arduino will control the power supply to second Arduino, which has the sensor installed, using a timer(RTC) to turn off the power for 30 minutes and on for 30 seconds for it to read the sensor data.

Can this work? What would the circuit look like?

For the isolator, I was thinking to use Tentacle Shield and in the documentation, it says that the isolator itself uses about 150mA plus the sensor circuit.
https://www.whiteboxes.ch/docs/tentacle/t1/#/

Thanks for the help.

body:
Actually, you can just run 1 Arduino and use it for

 - All needed measurements
 - Control power supply to sensors (power off when unneeded)
 - Additional: use low-power modes of MCU installed in Arduino

**Upd:** About 2nd option:
You can use electric relay or transistor to control power supply to sensor. Often sensors have several connections: ground (-), Vin(+) and some signal connections. So between power supply and Vin(+) of sensor you can put electric relay. Control pin of electric relay connect to any free pin on Arduino. Therefore, Arduino can enable and disable power supply to sensor just by settings 1 or 0 to that pin. I recommend you to use electric relay, because it is easier, but if you want to try transistor, you can refer to this question & answers: https://electronics.stackexchange.com/questions/95089/switching-9v-using-a-npn-transistor-and-an-arduino

About 3rd option: Arduinos are based on some MCU (often AVR, not always). These MCUs have several low-power modes. You can directly control power mode of MCU to achieve better power-efficiency.

So, you can do 1st and 2nd options, and try to do the 3rd one:

 - Investigate which MCU installed in your Arduino
 - Investigate which power modes it supports
 - Implement power management according to datasheet of this MCU

For example, if you have Arduino Mega 2560, then it is based on ATmega2560 MCU, find datasheet (https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf) and there find info about power/sleep modes (page 50) and ways to "wake up" from these modes.

Also you can read about it here: https://microchipdeveloper.com/8avr:avrsleep

Also you can try to find some handy libraries for Arduino, for example "Low-Power" and just use them without diving into MCUs, datasheets, etc

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