text:
.elf and .hex equivalency? (code, eeprom, fuses, and lock bits all in one)
I have all configurations (eeprom data, fuses, lockbits) of my ATMega168A together with the code in my C files. The compilation creates an elf file that I use as an all-in-one programming file for production.
Just as a tryout, I converted the elf file to hex with avr-objcopy and saw that the code and configurations are still there (why wouldn't they).
My question is, if the two files are equivalent in case of using them for all-in-one programming. Is there any critical data stripping taking place between elf-to-hex conversion that could affect the actual programming?
Also, I tried again to convert the hex file to bin and saw again the same thing but of course with zero-padding. Except for the obvious different of file size, is there any practical difference when using the bin file and the hex file? Does this padding create any problems? (For example trying to write 0 to addresses that do not exist).
Thank you in advance.

My question is, if the two files are equivalent in case of using them for all-in-one programming. Is there any critical data stripping taking place between elf-to-hex conversion that could affect the actual programming?

Nothing critical, but data stripping does take place. Everything that is in the HEX file is in the ELF file. That is - all the compiled machine code and data.
Basically everything that gets written to the chip is in the HEX file, and the HEX file can be created from what is in the ELF file - ergo the ELF file contains everything that is in the HEX file.
However, not everything that is in the ELF file goes into the HEX file.
The ELF file contains a huge amount more information. Mostly that information is geared towards debugging. There are things like the names and locations of all the symbols in the code - that is, the functions and variables, etc. There are breakdowns of all the assembly instructions grouped by source code file and line number.
None of that is relevant for the Arduino environment, but when you're using professional tools to do your development you can use them for realtime debugging and tracing of your program while it's running on the real hardware.
None of that is relevant to putting your program on the chip. It's all used by the PC.

Majenko your answers are majestic! Thanks!


text:
Problemm with the MPU6050 library
I have a curiosity. What is the difference between adding a header file directly on the arduino IDE and the header file inside another h-file.
For example:
#include "MPU6050_6Axis_MotionApps20.h"
void setup()
{
}
void loop()
{

}

This last didn't give me any problem, but when I create a h-file and add inside that h-file that library, it gave me an error:
ARDUINO:
#include "Prueba.h"
void setup()
{
}
void loop()
{

}

Prueba.h
//#ifndef Prueba_H
//#define Prueba_H
//#define LIBRARY_VERSION   1.0.0

#include "MPU6050_6Axis_MotionApps20.h"
class Prueba
{
  public:
  Prueba();
};
//#endif

Part of the error code is:
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.cpp:1679:9: note: implicit this pointer type mismatch
 uint8_t MPU6050::getIntStatus() {
         ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.h:438:7: note: type 'struct MPU6050' itself violates the C++ One Definition Rule
 class MPU6050 {
       ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src/MPU6050.h:438:7: note: the incompatible type is defined here
 class MPU6050 {
       ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.cpp:1679:9: note: 'getIntStatus' was previously declared here
 uint8_t MPU6050::getIntStatus() {
         ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.cpp:1679:9: note: code may be misoptimized unless -fno-strict-aliasing is used
collect2.exe: error: ld returned 1 exit status
exit status 1

Can someone explain me this?
Thanks in advance.

why is ths commented out? ... //#ifndef Prueba_H

I have tried both. Commented and not.

Well I don't know exactly why this work, but base on this question this. To solve this I should add 'inline' keyword in every method definition on the MPU6050_6Axis_MotionApps20.h
Like this:
inline uint8_t MPU6050::dmpInitialize() {
    // reset device
    DEBUG_PRINTLN(F("\n\nResetting MPU6050..."));
    reset();
    delay(30); // wait after reset

    // disable sleep mode
    setSleepEnabled(false);

    // get MPU hardware revision
    setMemoryBank(0x10, true, true);
    setMemoryStartAddress(0x06);
    Serial.println(F("Checking hardware revision..."));
    Serial.print(F("Revision @ user[16][6] = "));
    Serial.println(readMemoryByte(), HEX);
    Serial.println(F("Resetting memory bank selection to 0..."));
    setMemoryBank(0, false, false);

    // check OTP bank valid
    DEBUG_PRINTLN(F("Reading OTP bank valid flag..."));
    DEBUG_PRINT(F("OTP bank is "));
    DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!"));

    // setup weird slave stuff (?)
    DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F..."));
    setSlaveAddress(0, 0x7F);
    DEBUG_PRINTLN(F("Disabling I2C Master mode..."));
    setI2CMasterModeEnabled(false);
    DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)..."));
    setSlaveAddress(0, 0x68);
    DEBUG_PRINTLN(F("Resetting I2C Master control..."));
    resetI2CMaster();
    delay(20);
    DEBUG_PRINTLN(F("Setting clock source to Z Gyro..."));
    setClockSource(MPU6050_CLOCK_PLL_ZGYRO);

    DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled..."));
    setIntEnabled(1<<MPU6050_INTERRUPT_FIFO_OFLOW_BIT|1<<MPU6050_INTERRUPT_DMP_INT_BIT);

    DEBUG_PRINTLN(F("Setting sample rate to 200Hz..."));
    setRate(4); // 1khz / (1 + 4) = 200 Hz

    DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]..."));
    setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L);

    DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz..."));
    setDLPFMode(MPU6050_DLPF_BW_42);

    DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec..."));
    setFullScaleGyroRange(MPU6050_GYRO_FS_2000);

    // load DMP code into memory banks
    DEBUG_PRINT(F("Writing DMP code to MPU memory banks ("));
    DEBUG_PRINT(MPU6050_DMP_CODE_SIZE);
    DEBUG_PRINTLN(F(" bytes)"));
    if (!writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) return 1; // Failed
    DEBUG_PRINTLN(F("Success! DMP code written and verified."));

    // Set the FIFO Rate Divisor int the DMP Firmware Memory
    unsigned char dmpUpdate[] = {0x00, MPU6050_DMP_FIFO_RATE_DIVISOR};
    writeMemoryBlock(dmpUpdate, 0x02, 0x02, 0x16); // Lets write the dmpUpdate data to the Firmware image, we have 2 bytes to write in bank 0x02 with the Offset 0x16

    //write start address MSB into register
    setDMPConfig1(0x03);
    //write start address LSB into register
    setDMPConfig2(0x00);

    DEBUG_PRINTLN(F("Clearing OTP Bank flag..."));
    setOTPBankValid(false);

    DEBUG_PRINTLN(F("Setting motion detection threshold to 2..."));
    setMotionDetectionThreshold(2);

    DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156..."));
    setZeroMotionDetectionThreshold(156);

    DEBUG_PRINTLN(F("Setting motion detection duration to 80..."));
    setMotionDetectionDuration(80);

    DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0..."));
    setZeroMotionDetectionDuration(0);
    DEBUG_PRINTLN(F("Enabling FIFO..."));
    setFIFOEnabled(true);

    DEBUG_PRINTLN(F("Resetting DMP..."));
    resetDMP();

    DEBUG_PRINTLN(F("DMP is good to go! Finally."));

    DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)..."));
    setDMPEnabled(false);

    DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer..."));
    dmpPacketSize = 42;

    DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time..."));
    resetFIFO();
    getIntStatus();

    return 0; // success
}
inline bool MPU6050::dmpPacketAvailable() {
    return getFIFOCount() >= dmpGetFIFOPacketSize();
}
inline uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (((uint32_t)packet[28] << 24) | ((uint32_t)packet[29] << 16) | ((uint32_t)packet[30] << 8) | packet[31]);
    data[1] = (((uint32_t)packet[32] << 24) | ((uint32_t)packet[33] << 16) | ((uint32_t)packet[34] << 8) | packet[35]);
    data[2] = (((uint32_t)packet[36] << 24) | ((uint32_t)packet[37] << 16) | ((uint32_t)packet[38] << 8) | packet[39]);
    return 0;
}
inline uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (packet[28] << 8) | packet[29];
    data[1] = (packet[32] << 8) | packet[33];
    data[2] = (packet[36] << 8) | packet[37];
    return 0;
}
inline uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    v -> x = (packet[28] << 8) | packet[29];
    v -> y = (packet[32] << 8) | packet[33];
    v -> z = (packet[36] << 8) | packet[37];
    return 0;
}
inline uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]);
    data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]);
    data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]);
    data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]);
    return 0;
}
inline uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = ((packet[0] << 8) | packet[1]);
    data[1] = ((packet[4] << 8) | packet[5]);
    data[2] = ((packet[8] << 8) | packet[9]);
    data[3] = ((packet[12] << 8) | packet[13]);
    return 0;
}
inline uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    int16_t qI[4];
    uint8_t status = dmpGetQuaternion(qI, packet);
    if (status == 0) {
        q -> w = (float)qI[0] / 16384.0f;
        q -> x = (float)qI[1] / 16384.0f;
        q -> y = (float)qI[2] / 16384.0f;
        q -> z = (float)qI[3] / 16384.0f;
        return 0;
    }
    return status; // int16 return value, indicates error if this line is reached
}
inline uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (((uint32_t)packet[16] << 24) | ((uint32_t)packet[17] << 16) | ((uint32_t)packet[18] << 8) | packet[19]);
    data[1] = (((uint32_t)packet[20] << 24) | ((uint32_t)packet[21] << 16) | ((uint32_t)packet[22] << 8) | packet[23]);
    data[2] = (((uint32_t)packet[24] << 24) | ((uint32_t)packet[25] << 16) | ((uint32_t)packet[26] << 8) | packet[27]);
    return 0;
}
inline uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (packet[16] << 8) | packet[17];
    data[1] = (packet[20] << 8) | packet[21];
    data[2] = (packet[24] << 8) | packet[25];
    return 0;
}
inline uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    v -> x = (packet[16] << 8) | packet[17];
    v -> y = (packet[20] << 8) | packet[21];
    v -> z = (packet[24] << 8) | packet[25];
    return 0;
}
inline uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) {
    // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g)
    v -> x = vRaw -> x - gravity -> x*8192;
    v -> y = vRaw -> y - gravity -> y*8192;
    v -> z = vRaw -> z - gravity -> z*8192;
    return 0;
}
inline uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) {
    // rotate measured 3D acceleration vector into original state
    // frame of reference based on orientation quaternion
    memcpy(v, vReal, sizeof(VectorInt16));
    v -> rotate(q);
    return 0;
}
inline uint8_t MPU6050::dmpGetGravity(int16_t *data, const uint8_t* packet) {
    /* +1g corresponds to +8192, sensitivity is 2g. */
    int16_t qI[4];
    uint8_t status = dmpGetQuaternion(qI, packet);
    data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384;
    data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384;
    data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1]
           - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (2 * 16384);
    return status;
}
inline uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) {
    v -> x = 2 * (q -> x*q -> z - q -> w*q -> y);
    v -> y = 2 * (q -> w*q -> x + q -> y*q -> z);
    v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z;
    return 0;
}
inline uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) {
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);   // psi
    data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y);                              // theta
    data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1);   // phi
    return 0;
}

#ifdef USE_OLD_DMPGETYAWPITCHROLL
inline uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Z axis)
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Y axis)
    data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
    // roll: (tilt left/right, about X axis)
    data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z));
    return 0;
}
#else
inline uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Z axis)
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Y axis)
    data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
    // roll: (tilt left/right, about X axis)
    data[2] = atan2(gravity -> y , gravity -> z);
    if (gravity -> z < 0) {
        if(data[1] > 0) {
            data[1] = PI - data[1];
        } else {
            data[1] = -PI - data[1];
        }
    }
    return 0;
}
#endif

inline uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) {
    return 0;
}

inline uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) {
    uint8_t status;
    uint8_t buf[dmpPacketSize];
    for (uint8_t i = 0; i < numPackets; i++) {
        // read packet from FIFO
        getFIFOBytes(buf, dmpPacketSize);

        // process packet
        if ((status = dmpProcessFIFOPacket(buf)) > 0) return status;

        // increment external process count variable, if supplied
        if (processed != 0) (*processed)++;
    }
    return 0;
}

inline uint16_t MPU6050::dmpGetFIFOPacketSize() {
    return dmpPacketSize;
}
#endif

I don't know why the guys that made this library didn't add this. Maybe I'm missing something.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
can we use TCRT5000 sensor instead of IR proximity sensor?
I am planning to make a human following robot which requires two IR proximity sensors.
I already have two TCRT5000 sensor. Can I use it instead of it?

your question is like I am baking an apple cake that requires two apples. I already have two yellow apples. Can I use them instead?

I meant is TCRT5000 different from regular ir proximity sensor?

what's a regular IR proximity sensor?

https://www.amazon.in/VEEROBOT-Infrared-Proximity-Obstacle-Detecting/dp/B0115NCT4U/ref=asc_df_B0115NCT4U/?tag=googleshopdes-21&linkCode=df0&hvadid=397008884140&hvpos=&hvnetw=g&hvrand=11247381740971132298&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9297848&hvtargid=pla-391398992335&psc=1&ext_vrnc=hi

your question is off topic here because it is not about the arduino ... it is also vague, and is not answerable until you provide some operational requirements, such as detection distance

An IR distance sensor is mainly an IR LED and an IR phototransistor.  Thats what the TCRT5000 is. Though the ready to use boards incorporate more electronics to output an analog voltage according  to the signal (rough measurement of distance) and a digital output using a threshold (controllable via the potentiometer). If you use the TCRT5000 you might need to add more electronics to actually get the desired results. Most likely you would need an amp circuit to get a good signal to measure

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to remove any previous program from Arduino?
I have a Arduino UNO and I want to remove the previously uploaded code....how to do that?

Why do you want to remove the code?

Just upload a new one. I frequently "blank" an arduino when I'm done with it by uploading "Blink.ino" from the examples included with the IDE. (The only reason I've had to remove old code is to avoid an issue where I might later wire up the Arduino in a way that is dangerously incompatible with the old code running on it.)

examples/01.Basics/BareMinimum would be even better, as it doesn't set pin 13 to OUTPUT. Which would be a problem if your next project has a button connected to pin 13, and you accidentally press the button before uploading new code.

@sniggerfardimungus can I upload the empty sketch that is present when we open the Arduino IDE? I mean ony the void setup and void loop one....

Replacing your sketch with another doesn't actually "remove" the previous one. Is that really necessary? If you're trying to prevent the first one from executing, replacing it, as already suggested by @Juraj, is a simple and proper solution.
If you need to prevent anyone ever being able to read any part of the previous one, you'd need to load another sketch at least as large as the previous one so it over-writes all of it, or create and run a modified "bootloader" program that erases the parts of flash you wish to obscure.
(Your question doesn't address your reason for wanting to "remove" the sketch. I'm adding this for completeness; not because I think it's likely.)

I got it. just upload blank code that is written when you start arduino ide.


text:
Communication between ESP01 Arduino NANO and using External Interrupt in Arduino NANO for other than communication program same time
I have done communication between ESP01 and Arduino NANO (ATMEGA328 based). ESP pins used are GPIO-0 and GPIO2. In NANO, used D2 and D3. This program working Ok. Now I want to add external interrupt in my Arduino NANO program while continuing communication with ESP01. But I cannot use D2 and D3 because it was used by communication program. Now Arduino NANO's limit is it has only two interrupt pins which are D2 and D3. So if I use this for external interrupt program, I lose communication with ESP01. Can anybody help me to use my both task at the same time: Task1- External interrupt in Arduino Nano, Task2- Communication with ESP01. Your reply will help me to solve this issue. Thanks in advance.

Don't use D2 and D3 for the communication? There's plenty of other pins on a Nano...

so move the SodtwareSerial to other pair of pins. 4 and 5 are good for PWM but 6 and 7 are not special.

D2 and D3 Pins on Arduino nano support external Interrupt. Hence, you have to use one of those for the interrupt.
Since you are using softwareSerial() you can easily remap it to other digital pins of the Nano.
Pins from D4-D12can be used for communication.
You just have to change the parameters in the softwareserial() as below:
SoftwareSerial mySerial(4, 5); // RX, TX;;for example

how do you know OP is using SoftwareSerial? it is not mentioned in the question. I made a wild guess in a comment


text:
Cannot change fuses on ATmega32U4
I have a custom board based on Arduino Leonardo (ATmega32u4).
As usual I used the Arduino IDE to burn the bootloader with my Atmel ICE ISP programmer.
This time it failed complaining about some errors writing the fuse bits.
So I tried to manually set them with avrdude but it turns out it can't.
I first dumped out the current values:
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: safemode: lfuse reads as 5E
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as F3

avrdude> d lock
>>> d lock
0000  ff

Then I tried to change, say, lfuse to 0xFF:
avrdude "-C/home/mark/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" -v -patmega32u4 -catmelice_isp -Pusb -Ulfuse:w:0xff:m

here the output:
avrdude: reading input file "0xff"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.09s

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

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x5e != 0xff
avrdude: verification error; content mismatch

avrdude: safemode: lfuse reads as 5E
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as F3
avrdude: safemode: lfuse changed! Was ff, and is now 5e
Would you like this fuse to be changed back? [y/n] y

But it failed:
avrdude: safemode: Wrote lfuse to ff, read as 5e. 9 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 8 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 7 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 6 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 5 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 4 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 3 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 2 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 1 attempts left
avrdude: safemode: Wrote lfuse to ff, read as 5e. 0 attempts left
avrdude: and COULD NOT be changed
avrdude: safemode: Fuses not recovered, sorry

I can program the MCU with a firmware (using the ISP programmer) and it works, so it's not damaged. What can I do in order to fix this writing issue on the fuse bits?


text:
ESPAsyncDNSServer cannot find AsyncUDP anymore
I'm using this ESP32AsyncDNSServer library on my ESP32 application.
Suddenly (I'm not sure what I did) it does not compile anymore:

.pio/libdeps/Aphrodite/ESPAsyncDNSServer/src/ESPAsyncDNSServer.h:8:10: fatal error: AsyncUDP.h: No such file or directory

Here the related code of the library:
#ifdef ARDUINO_ARCH_ESP32
#ifndef Stream_h
#include <Stream.h>
#endif
#include <AsyncUDP.h>
#else
#include <ESPAsyncUDP.h>
#endif

but of course AsyncUDP.h does exist:

/home/mark/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src/AsyncUDP.h

What could prevent the compiler to find it?

for whatever reason, adding this to your platformio.ini env section helps:
[env]
lib_compat_mode = strict # default is "soft"

I guess the more clean version would be to add this to your lib_deps
lib_deps =
    ESP32 Async UDP # important! otherwise "AsyncUDP.h" blabla is missing..
    <your libs following>


text:
UDP packet loss and very high ping time
Scenario
I'm writing a code for Nucleo-144 F429ZI. It receives UDP packets (actually OSC bundles) and send back an answer when the command is completed.
Issues
It work fine most of the time. But there are two issues that sometime happen:

a message sent from the board is not received by the PC
the board receives the messages with a very long delay (up to 4 s) and in this situation also a ping shows this delay

What I tried
I changed:

board
switch
cables
PC, O.S. and software

The behavior is the same.
In the firmware I checked all the return values and no one reports an error. Hence, I assume the messages actually leave the board. But apparently they don't reach the PC. Please note that I'm talking about 1 on 1000+ packets.
It seems (even it is hard to guess) that especially the second issue is more frequent if the PC sends packets to multiple IP. Example:

PC sends packets to 192.168.100.1 only: the second issue happens very rarely (i.e. given 2 packets per seconds, it may took days)
PC sends packets to other 10 boards in the same network: the second issue happens within minutes

When this happens, the only way to recover the correct behavior is to reset the board. Even disconnect and reconnect the Ethernet cable does nothing.
** Code **
I wrote a fake firmware to reproduce the problem (it does nothing but answer after some time). As said, running this code with a single board connected it works fine for a long time. But anyway, you might spot some mistake in the UDP handling:
#include <LwIP.h>
#include <ArduinoQueue.h>
#include <STM32Ethernet.h>
#include <EthernetUdp.h>
#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#define UDP_TX_PACKET_MAX_SIZE 1024

EthernetUDP Udp;
IPAddress remoteIP;
unsigned long oldTick;
OSCBundle bundleServo;
char answer[128];
int ch;
float pos;

int getIndex(OSCMessage &msg, int patternOffset)
{
  char buf[8];
  msg.getAddress(buf, patternOffset + 1, 8);

  return atoi(buf);
}

void servo_fade_handler(OSCMessage &msg, int patternOffset)
{
    ch = getIndex(msg, patternOffset);
    pos = msg.getFloat(0);
    oldTick = millis();
}

void bundle_send(OSCBundle *bundle)
{
  Udp.beginPacket(remoteIP, 8888);
  bundle->send(Udp);
  Udp.endPacket();
  bundle->empty();
}

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

  IPAddress localIP = IPAddress(192, 168, 100, 2);
  IPAddress netmask = IPAddress(255, 255, 0, 0);
  IPAddress dns = IPAddress(192, 168, 1, 1);
  IPAddress gateway = IPAddress(192, 168, 1, 1);

  Ethernet.begin(localIP, netmask, dns, gateway);
  Udp.begin(8888);
}

void loop()
{
  uint8_t data[UDP_TX_PACKET_MAX_SIZE];
  uint16_t size = Udp.parsePacket();

  if (size > 0 && size < UDP_TX_PACKET_MAX_SIZE)
  {
    Udp.read(data, size);
    remoteIP = Udp.remoteIP();

    OSCBundle bundle;
    bundle.fill(data, sizeof(data) - 1);
    data[size] = '\0';

    if (bundle.getError())
    {
      Serial.print("[OSC] Error: ");
      Serial.println(bundle.getError());
      return;
    }

    int bundleSize = bundle.size();
    for (int i = 0; i < bundleSize; i++)
    {
      OSCMessage msg = bundle.getOSCMessage(i);
      msg.route("/servo/fade", servo_fade_handler);
    }
  }
  else Udp.flush();

  if ((oldTick > 0) && ((millis() - oldTick) > 500))
  {
      bundleServo.empty();
      sprintf(answer, "/servo/fade/2/%u", ch);
      bundleServo.add(answer).add(pos);
      bundle_send(&bundleServo);
      oldTick = 0;
  }
}

Question
I do know the theory says the UDP protocol is not reliable. But after 15 years of experience I never lost a single packet even in very messy environments with hundreds of devices. Here we're working on a simple LAN: one PC, one switch and less than 10 boards. No Internet connection, no WiFi, no other stuff.
What are the possible causes for the issues? Understood them, I can investigate them one by one

maybe some filtering should be set on the Ethernet adapter to not process packets targeted to other MAC addresses. because without the filter the lwip stack has to process it

Maybe this question would be better asked of the authors of the Nucleo core and networking libraries. If you've ruled out everything except the software then it must be the software, so ask the authors of the software.

the author and experts are here https://www.stm32duino.com/

@Juraj, would you please provide an example of how to set up such a filter?

the STM32Ethernet library uses the Ethernet peripheral of the MCU. so it would be a register of the MCU.

@Juraj, if you want you can make an answer. Anyway, do you really think that 10 messages of 30-40 bytes each can hang the board for 4 seconds?


text:
Arduino New Optiboot Bootloader on custom ATMega328p board, ATMEL Studio and AVRdude
I am about to ask a kind of complex question due to the number of system parts involved and the system architecture I am planning to use.
First of all I have a tiny bit of experience with the Arduino Nano and a professional experience with C microcontroller programming.
What I would like is to create a custom ATMega328p board that does something and be able to update whatever firmware is running on it using the UART port.
1) Firmware updating
Since I am not so familiar with bootloaders, I would skip for now writing my own, so I would like to use the newest Arduino Bootloader for ATMega328p to support the firmware updates.
2) Custom program compilation
What I definitely do NOT want is use Arduino Sketch IDE to compile whatever application code. I am using Atmel Studio up to now for whatever bootloaderless applications I was doing and I would like to keep using that with my own project and code structure. The question here is, do I need to make any linker modifications or modifications in the code in Atmel Studio projects in order to be able to "transform" my code into application code so that can coexist with the bootloader?
3) Updated firmware programming
After the board is on the field running with the Optiboot bootloader and an outdated firmware, I would like to use a thirdparty software to communicate with the bootloader and update the application code. Since the optiboot bootloader used by Arduino uses the STK500 communication protocol and functionality, could I use AVRdude to communicate with the bootloader and flash the applications code only through UART?
Do you think this concept could work?
Thank you in advance.
polylogic

your question boils down to asking if it is possible to build an Arduino UNO

ask and discus AVR questions on https://www.avrfreaks.net/forum

Since I am not so familiar with bootloaders, I would skip for now writing my own, so I would like to use the newest Arduino Bootloader for ATMega328p to support the firmware updates.

Even people who do know about bootloaders rarely bother writing their own when there is a perfectly good one with good support and good cross-platform tools available.  Why would you?

The question here is, do I need to make any linker modifications or modifications in the code in Atmel Studio projects in order to be able to "transform" my code into application code so that can coexist with the bootloader?

No. The bootloader resides at a high memory address, and your code at address 0x0000 just like normal.  A fuse is set to say "Boot at the bootloader address", and another lets you set the size of the bootloader area (and thus the bootloader address).

Since the optiboot bootloader used by Arduino uses the STK500 communication protocol and functionality, could I use AVRdude to communicate with the bootloader and flash the applications code only through UART?

Yes. This is what the Arduino IDE does. It just runs avrdude to communicate with the bootloader.  If you turn on verbose mode in the preferences you should be able to see what the exact command is that it runs so you can replicate it in your own program or script.

I would add that the only purpose of the bootloader is flashing over UART.

@Juraj Sure, if you want to state the obvious.

Majenko! Thank you so much for the answer!It seems that this is pretty standard since I managed to compile a custom program in Atmel Studio and load it to the uC via cmd avrdude. Im not sure if I need to post a different question but I was wondering the following; in order to increase security:
I could modify the optiboot code to first receive a predetermined set of chars via UART before it goes into STK500 mode.Would that be doable?Apart from cold-reset, I would like to be able to call the bootloader from the app code. How could I call it and should I reset some registers before I call it?

That would constitute a new question. I'm not going to be able to answer those in comments.


text:
More than 3 SPI devices read by a single arduino
I've been working on a project that involves SSI Rotary Encoders from CUI. They are being read through the SPI interface, and I am bit-shifting appropriately to account for the differences between SSI and SPI. Unfortunately, I am pretty limited in knowledge of how the SPI interface works, but I am attempting to connect 5 of these encoders to the Arduino (nano) to create a simple robot.
Everything was working great when I had 3 encoders, however, when I add a fourth to the same Arduino, all of the encoders stop reading. I am struggling to determine my next steps. According to one source, it appears that an Arduino is allowed a maximum of three SPI devices, but I am wondering if it is possible to have the other two read through a software interface? Here's a link to the source I found: https://esp32.com/viewtopic.php?t=1972. If you have any suggestions, please let me know!

how are you connecting the devices?

From what I see you can use Arduinos shifIn function for "software serial". But I don't see why it shouldn't work with more that 3 encoders. Ehe esp32 forum post said, that's just a software limit. You'd have to set the Chip Select pin for that encoder manually. Some something like digitalWrite(CS_ENCODER_4, LOW); SPI.readSomething(); digitalWrite(CS_ENCODER_4, HIGH);

that's a link to the ESP32 docs, not nano, and it's a limit for distinct SPI lines, not multi-device lines like you should probably be using.


text:
Serial.availableForWrite versus Serial.flush
Is there a difference between the following two line codes?

while (Serial.availableForWrite <= 0) {}

versus

Serial.flush()

Thanks!

The line
while (Serial.availableForWrite() <= 0) {}

waits until the serial output buffer is not full. Whereas
Serial.flush();

waits until the serial output buffer is empty.

https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/

availableForWrite Get the number of bytes (characters) available for writing in the serial buffer without blocking the write operation

Write operations on Arduino streams wait if they can't write the data to output. You can use the count returned by availableForWrite to avoid this blocking.
https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/

flush Waits for the transmission of outgoing serial data to complete.

One use of flush() is to wait until the data are sent away before putting the MCU into sleep mode.


text:
Play computer *.wav files through Arduino
I am doing mice behavioral training.
I have an arduino-controlled box for that.
The sounds are play using Mp3 player controlled b the arduino.
However, the mp3 player is not good enough for my needs.
I need two clear sounds of 10 msec duration and freqiencies of 5000Hrz and 1000Hrz.
(I prefer pure sine waves but can compromise on triangle or, for now, even square).
The problem is that the mp3 is not fast enough and the volume is too low for 10 msec durations. When I tried to build gain circuit it became too noisy.
I tried to use the Tone function but it is again not good for 10 msec sounds. espacially in the jigj frequency/
I created the wavefiles in Matlab.
The PC plays the file in the right volume with no nose.
However, I don't know how to make the arduino play the files from the computer.
Is there a relative simple way to do it, without bying extra hardware?
If now, is there ANY way of doing it?
or another option, Is there a way for the arduino to play files from a wave generator? (I have these in my lab)
Thanks!

what was wrong with tone()? for me it makes nice high beeps

When I play 10000Hrz sound with 10msec duration I hear only click. I dont hear the sound. It is important since in the experiment I am conducting, The mice must hear and discriminate between the 5000Hrz, to 10000Hrz frequencies. The Mp3 was fine for 200 msec duration bur not for 10 msec. The computer is doing a very good job but I need the Arduino to control it..

This code will create a steady 20 KHz output. Adjust the duration to reflect the period of your frequencies.
byte triggerOut = 19;

unsigned long currentMicros;
unsigned long nextMicros;
unsigned long duration = 25UL; // flip every 50uS = 20KHz pulse
unsigned long elapsedMicros;

void setup() {
  pinMode (triggerOut, OUTPUT);
}
void loop() {
  while (1) {
    currentMicros = micros();
    elapsedMicros = currentMicros - nextMicros;
    if (elapsedMicros >= duration) {
      nextMicros = nextMicros + duration;
      PINC = PINC | 0b00111111; // toggle D19 output by writing it input port.
    }
  }
}

Add some lines to start the output after a button push, and count the number of cycles to only output the time duration you want.
10,000 KHz = 0.1mS period, 10ms/0.1ms = 100 cycles.
Divide the 0 to 5V output down to 1V, and drive a computer self powered speaker to create the noise you want.

I will try that. Thanks!

Two options:

Write software for the PC to react to serial commands sent by the Arduino, or
Use a more powerful Arduino-like board with a DAC and do wavetable synthesis.

The Arduino Due and many of the other smaller ARM-based boards (like M0 boards) are a good candidate for option 2 because they are faster than a traditional Arduino and have a built-in DAC.  However, a proper I2S CODEC chip attached to a powerful MCU would be the preferred method for high-quality playback.
Note that your amplification system is of critical importance. It's common for many cheap amplifiers to limit higher frequencies. You need an amplifier with a good flat response over and above the maximum frequency you want to reproduce. Just slapping together any old "gain" circuit is probably not going to be good enough. Most op-amp based solutions have a ratio (Gain Bandwidth Product) that reduces the bandwidth as the gain increases.

Yes, I might order a more powerful module.. Thanks!


text:
Porting Arduino for ATMEGA16U2
I have a bunch of ATMEGA16U2 in my drawer and I need to make a small production of custom boards with Arduino-based firmware.
After a Google search I learn the ATMEGA16U2 is often hosted on the Arduino boards as USB converter and there some hacks to reprogram it. But this is not my goal... I'm trying to understand how to compile and download the firmware using Arduino IDE and this MCU as target.
I guess (also from this old question) I need to update both the bootloader and the specification of the board.
Questions:

before reinvent the wheel are you aware of a ready-to-use porting for ATMEGA16U2? I did a search find nothing relevant

what is the official guide to update the files (bootloader + boards.txt) to support a new MCU? I find forum threads only

this could help https://arduino.stackexchange.com/questions/54484/adding-a-custom-board-to-the-arduino-ide/60660#60660 using AVR core as referred core

@Juraj thanks I'm reading the answer - but as said it's again a public forum... where is the official documentation that explains in detail each step?

there is a link in the answer to the official doc, but there is no tutorial

@Juraj I saw but it's about arduino-cli. If it's correct I'm going to study it :)

Arduino IDE uses the arduino-cli

Ok, because it's not installed by default I didn't understand that.

I don't agree with the decision of closing the question. Actually, my questions are precise and different than what reported in the other answers.


text:
Different meanings of pid and vid in boards.txt
Let's see the leonardo section in boards.txt:
leonardo.name=Arduino Leonardo
leonardo.vid.0=0x2341
leonardo.pid.0=0x0036
leonardo.vid.1=0x2341
leonardo.pid.1=0x8036
leonardo.vid.2=0x2A03
leonardo.pid.2=0x0036
leonardo.vid.3=0x2A03
leonardo.pid.3=0x8036

leonardo.upload.tool=avrdude
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.maximum_data_size=2560
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
leonardo.upload.use_1200bps_touch=true
leonardo.upload.wait_for_upload_port=true

leonardo.bootloader.tool=avrdude
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F

leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341
leonardo.build.pid=0x8036
leonardo.build.usb_product="Arduino Leonardo"
leonardo.build.board=AVR_LEONARDO
leonardo.build.core=arduino
leonardo.build.variant=leonardo
leonardo.build.extra_flags={build.usb_flags}

What are the meanings of the leonardo.vid|pid.* and of the leonardo.build.vid|pid?
Perhaps the first are for the USB serial device at runtime and the second for the bootloader?

The build ones are used when compiling the Arduino core. The others are used to identify the board when it resets into the bootloader so it can find the right com port to upload to

Ok, but the problem is the run-time pid/vid are 2341:8036. If the first set is used to identify the bootloader should not contain these values, otherwise it's impossible to detect it!

@Mark The runtime ones can be whatever you like. The IDE opens the (manually) selected COM port at 1200 baud which resets the board into the bootloader. Then it waits for a new device to appear that matches one of the bootloader VID/PID pairs (any one will do) at which point it records the COM Port and passes that to avrdude to upload the program.

It's exactly what I'm doing right now. But because even the default run-time VID/PID pairs for Leonardo are in that set, I cannot be sure if it's the bootloader or not! Example: if the reset does not work, I assume there is a bootloader while it's still the application serial channel.

@Mark If the reboot didn't work then there won't be a new device.


text:
Disable USB support for mega32u4
I have a custom Leonardo board (mega32u4-based) that does not use at all the USB features.
When I build my sketch (vscode and platformio) I read:
Compiling .pio/build/leonardo/FrameworkArduino/CDC.cpp.o
Indexing .pio/build/leonardo/libFrameworkArduinoVariant.a
Compiling .pio/build/leonardo/FrameworkArduino/HardwareSerial.cpp.o
Archiving .pio/build/leonardo/lib02e/libFadeLed.a
Compiling .pio/build/leonardo/FrameworkArduino/HardwareSerial0.cpp.o
Indexing .pio/build/leonardo/lib02e/libFadeLed.a
Compiling .pio/build/leonardo/FrameworkArduino/HardwareSerial1.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/HardwareSerial2.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/HardwareSerial3.cpp.o
Archiving .pio/build/leonardo/libfa3/libWire.a
Indexing .pio/build/leonardo/libfa3/libWire.a
Compiling .pio/build/leonardo/FrameworkArduino/IPAddress.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/PluggableUSB.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/Print.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/Stream.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/Tone.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/USBCore.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/WInterrupts.c.o
Compiling .pio/build/leonardo/FrameworkArduino/WMath.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/WString.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/abi.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/hooks.c.o
Compiling .pio/build/leonardo/FrameworkArduino/main.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/new.cpp.o
Compiling .pio/build/leonardo/FrameworkArduino/wiring.c.o
Compiling .pio/build/leonardo/FrameworkArduino/wiring_analog.c.o
Compiling .pio/build/leonardo/FrameworkArduino/wiring_digital.c.o
Compiling .pio/build/leonardo/FrameworkArduino/wiring_pulse.S.o
Compiling .pio/build/leonardo/FrameworkArduino/wiring_pulse.c.o
Compiling .pio/build/leonardo/FrameworkArduino/wiring_shift.c.o

I wonder if I can disable the USB support (CDC, PluggableUSB, USBCore) and also network stuff (IPAddress) in order to save flash space.

I think the optimizer will kick that stuff out when you don't use it. So that should already happen.

USBCore creates the com port for upload and handles the 1200 baud 'touch' for reset to bootloader before upload

@Juraj, yes but as I said I have no bootloader neither any USB com port

@Juraj done. I can't find any entry about IPAddress but all the USB stuff is there

main.cpp has USBDevice.attach();

@Juraj sorry I don't understand you. Which main.cpp? Anyway, is it possible to save flash space disabling the USB stuff?

https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp

I doubt the optimizer will determine that it can eliminate the USB ISRs and their dependencies. Where the core conditionally compiles the USB parts based on the presence of USB peripheral register definitions, you're left with a bunch of options that aren't great. E.g. modifying the core to not include these features all or to extend the expression with something like && !defined(NO_ARDUINO_USB_STACK). Or to fake out the core by (not/un)defining the USB peripheral with a modified avrlibc, again perhaps conditionally. And maybe modifying board.txt to pass feature flags for that purpose.


text:
I2C communication between Attiny85 as master and arduino UNO as slave
I want to make my Attiny85 and my Arduino UNO communicate together with I2C protocol. Since Attiny do not support Wire library, I use TinyWire by lucullusTheOnly and Wire on the Uno.
The Attiny is sending data as the master to the Uno, the slave.
Here is my code:
Master
#include <TinyWire.h>

byte slave_address = 10;

void setup() {
    // config TinyWire library for I2C master functionality
    TinyWire.begin();
}

void loop() {
    TinyWire.beginTransmission(slave_address);
    TinyWire.send('c');
    // endTransmission sends the bytes in the buffer to the slave and returns 0 if there was no error
    TinyWire.endTransmission();
    delay(500);
}

Slave
#include <Wire.h>

void setup() {
  Wire.begin(10);                // join i2c bus with address #10
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

I connect the pin like this :
Arduino --> Attiny
SCL ---- PIN 7
SDA ---- PIN 5

I try to pull-up the clock and data line with 2.2k resistors but nothing happened, I receive nothing on the Uno from the Attiny.
Any idea ? Thanks !

Also asked at: http://forum.arduino.cc/index.php?topic=524760 If you're going to do that then please be considerate enough to add links to the other places you cross posted. This will let us avoid wasting time due to duplicate effort and also help others who have the same questions and find your post to discover all the relevant information.

As per Stackexchange rules, I don't think he is obligated to post links to other forums where he has asked for an answer. It's his choice. Nevertheless, thanks for posting the link to the forums, it helps other readers.

The pure master functionality of the TinyWire library is currently buggy. As a work around you can initiate the library on the ATTiny also as a slave with an address. When the endTransmission() function is called, the library switches temporarily to master mode for sending the bytes. I've tested this with your code in my own setup and it works. (Be sure, that the frequency in the ATTiny is set right. I tested the library only for 8MHz. For my own ATTiny's I had to do an extra step and set the correct fuses with avrdude)
I think the pure master part is blocking itself after the first transmission. I will add an issue in the github project. Maybe I can fix this in some time.
Chrisl aka lucullusTheOnly
EDIT: I had to think about this and looked into the library. The problem was found easily. In twi.cpp there is a NOISE_TESTING define block in the master send/receive function, which is constantly triggering error #6 (unexpected stop condition). In slave mode this doesn't happen, because directly before sending as a master it calls the master init function, which clears all USI flags, including the stop condition flag, that is polled in the send/receive function.
I have deactivated the NOISE_TESTING in the github project. If you don't want to download the current version, you can just open twi.h and comment the definition of NOISE_TESTING.

I finally move to the Serial library but I will test your new code soon!

I have the same issue even though I have the latest Github version with the NOISE_TESTING define block disabled.
I believe it has something to do with the line 359 in TWI.cpp where the stop condition isn't issued if a NACK happens:
      if( temp_result.result & (1<<TWI_NACK_BIT) )
  {
    if ( USI_TWI_state.addressMode )
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
    else
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
    return (FALSE);
  }

I think it should be :
      if( temp_result.result & (1<<TWI_NACK_BIT) )
  {
    if ( USI_TWI_state.addressMode )
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
    else
      USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
    USI_TWI_Master_Stop();
    return (FALSE);
  }

I tried it on ISIS in pure master only and it worked. I don't know if this is a viable solution or if it will cause any conflict with how the rest of the lib works.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Measuring Lithium ion cell voltage used to power Arduino via a boost module
Can I measure lithium ion cell voltage with Arduino ADC which is used to power the same Arduino through a boost module (XL6009)? The output voltage of boost module is 9 volts.

Sidenote: why are you boosting the voltage to 9V (and presumably using the voltage regulator on the nano to bring it back to 5V)?

@Gerben Because the lithium ion cell voltage can be in the range of 3-4.2 volts depending upon the charge level. So to operate the analog circuit  (using LM358) and Arduino nano at a stable voltage I have to boost the input voltage. Plus the XL6009 module will keep the output voltage stable at 9V regardless of the input voltage.

I'm the author of a library called BatterySense and you can use it to achieve your goal. In the repository Readme you can also find wiring diagrams and usage examples, but to give you a rough idea...

Verify the negative side of your battery has continuity to the GND pin of your Arduino: you need to identify if the boost module is messing the common ground, but if you have continuity then you are fine
Add a connection from the battery positive terminal going into one of the Arduino analog pins
Use the BatterySense library to get the battery voltage and percentage level

Thanks so much OP and Roberto. I also want to measure a LiPo that is powering my Arduino. Great library, I've just checked it out. I suspect that I have the case where my battery negative terminal is not directly connected to GND, as part of the design, sot hat an over-discharge protection IC can do it's job. Any suggestions for that scenario? Here's the Circuit and PCB
https://easyeda.com/GreatScott/LiPoChargeProtectBoost_copy-3d9f4c3ddc7347d7861776340b9b90b7 which is linked to from GreatScott!'s excellent youtube video here https://www.youtube.com/watch?v=Fj0XuYiE7HU

I believe you might get more visibility if you post a proper question rather than a comment, may be referring to this question and answer in yours... I don’t know how you can work around with a non shared GND, but I’ll definitely interested in the answers you’ll get ;-)

Thanks Robert, that's a great suggestion. I'll experiment with measuring the voltage with and without the over-discharge protection IC, trying it anyway, as I suspect the arduino will only be measuring the voltage when it's actually on, and therefore connected to ground via the MOSFET that the protection IC turns on and off. If it gives weird results / there's some difference in the measured battery voltage, then I'll post a new question. Thanks again, will tag you / this!

Cool library guy. +1

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
ATMEGA AVcc pin - low pass filter
I am a newby to the world of electronics and IC chips, and am looking to make an ATMEGA328 based board to monitor 12v batteries. The board will be powered from the batteries being monitored, with a regulated power supply taking 12v input and outputting 5v to the board.
The data sheet for the ATMEGA328 chip says that AVcc should be connected externally to Vcc via a low-pass filter. A bit of internetting tells me the low-pass filter will filter out noise above a specific frequency, and provides links to calculators that show the affect of different resistor / capacitor pairs.
My problem is that, I have no idea what frequencies I need to filter! All / any advice much appreciated.
Further info: voltage measurements will be via voltage divider circuits, amp hour consumption will be via sensors, all of which will be connected to analog pins for ADC conversion.

The filter is only needed if low noise is important to your application.
For monitoring batteries, you probably don't need the accuracy level at
which you would want the filter. For what it's worth, the Arduino Uno
doesn't have such filter: it's AVCC is connected straight to VCC.
If you really want the filter, the exact characteristics are not
critical. The datasheet suggests 10 µH + 100 nF, so this
should be a safe choice.

Edit: To answer the question in the comment, yes, it is generally
advised to use decoupling capacitors, usually something like
100 nF, even when powered from a voltage regulator.
Notice that both the VCC and the AVCC pins are very close to a ground
pin. Best practice is to use one decoupling cap for each (A)VCC/GND
pair, and to place that cap as close as possible to the pins.

many thanks for this, and apologies for not spotting this in the data sheet. If I choose not to insert the low pass filter, would there be any benefit in fitting a low value capacitor, to smooth the AVcc input, or should I expect the output from the regulated voltage supply to be okay?


text:
Does the Arduino Yun have to be powered exactly at 5V?
I'm working on a senior project and I am using a ATX PSU to supply power to the Arduino Yun and other components. If I'm not mistaken, its powered through the usb. I took a usb cord, strip the sheath and put the proper connections on the breadboard and connected the red wire from the PSU to the breadboard as well. When I measure it, the voltage is 5.1V max. I'm scared to hook it up to the Arduino since I read that if its above 5, it will fry it. Is this voltage fine? If not, will I have to put resistors on it to get it down?

The physicist in me has to mention that the words measure and exactly cannot be used together. Your measurement of 5.1V will have an uncertainty (unfortunately often mis-called "error") of +/- x%, so the real value is in a range. The x% is indicated on the measurement device and the range must be matched (worst case) with the data sheet of the component. As a further side note, the +/- x% may actually be +x%, -y% (the uncertainty is different depending on the direction) and can even be a function (in each case), where the uncertainty depends on the measured value.

It is fine. That is only 2% too high. The microcontroller is the ATmega32U4 and it can have 5.5V. The wifi module runs at 3.3V, and it has a voltage regulator. Some voltage is also lost in the cable. If the voltage is 6V, then you are in the danger zone, but not with 5.1V.
There are clones and shields of the Arduino Yún. Each has its own power supply demands. You should read what the specifications are for your board. The official Yún board requires 5V from the USB cable or 5V at the VIN pin.

The official USB voltage tolerance is 4.75-5.25, so 5.1 is within usb tolerance, thus I would expect a device that can be powered from USB to be just fine

You was right about the voltage being loss in the cable, once I hook it up to my arduino, the voltage dropped to 5.070V, which made me feel better.

I would avoid directly powering any micro without voltage regulation. Things like zener diodes and dedicated regulators adds complexity. But you can pretty much power it off any positive rail at or above 5v DC.(Use nothing greater than the specs) They can also be had and implemented for very little, that and they are used on the UNO board.

You said “you can pretty much power it of any positive rail at or above 5v DC.“ Power what? An Arduino? (NO!) A regulator? It depends on the type of regulator. Linear regulators need a higher input voltage than their output voltage. Buck/boost power supplies are a lot more flexible. I’d be careful about making unclear statements like that, lest a naive reader feed 12V into VIN on his Arduino and fry the board and everything connected to it.


text:
EspAsyncWebServer process HTTPS to HTTP
I read this issue. But I didn't understand it.
Like the author I don't have an SSL certificate and I don't want to have one (because if I had one I could live with HTTPS!).
I just want to process any https://<url> request like it was http://<url>. It can be a redirect but the answer states:
server.on("/redirect/internal", HTTP_GET, [](AsyncWebServerRequest *request){
  request->redirect("/hello");
});

server.on("/redirect/external", HTTP_GET, [](AsyncWebServerRequest *request){
  request->redirect("https://techtutorialsx.com/");
});

Ok, but how to detect if the request was HTTP or HTTPS?

the web browser will probably freak out if you redirect to an unsecure webpage

http uses port 80 ... https uses port 443

This isn't something you can do.
What you're asking for is like saying "I have to screw something together but I really only want to use a hammer, so how do I hammer the screw?". The answer is, you don't.
In this case the ESP32 is a server. The web browser is a client. The web browser is speaking HTTPS. When the browser makes an HTTPS request to the server, HTTPS is the only thing the browser will accept. HTTPS include a security layer (that's the "S" part) which is what requires certificates. If the server is not capable of handling that security layer (which it's not if it doesn't have an SSL certificate) then the only thing it can do is reject the connection by either not listening for it or immediately closing it
There is no communication between the client and server if the server isn't configured with certificates and can't speak TLS (the security layer) with the client. Allowing the server to downgrade the security when the client requests it would be a huge general security issue for the web. It's designed to not allow this.
Either support HTTPS properly, get the client to speak HTTP, or just don't do this at all. Those are your options.
As for detecting HTTP vs HTTPS, it depends on the port your server listened on. If you listen on port 80, you get HTTP requests. If you listen on port 443 you get HTTPS. If you're not listening on a port, the request of that type is refused (reset).

Ok got it. I thought it was easier because I saw some IoT devices that do this. Just a clarification: it's not a www application, it's just a configuration page hosted on an MCU device. No security issue here. And TLS is an overkill for this kind of job. Unfortunately, if you don't specify the protocol the browsers assume it's HTTPS and most users wonder why the page is not loaded...


text:
"Cast" BluetoothSerial to HardwareSerial
I have a function that accept an HardwareSerial class as argument:
void ProcessLine(HardwareSerial *serial, char *line)
{
    // do something
    serial->write("blablabla");
}

In my code I also have a BluetoothSerial that shares the required functions (i.e. write()) with HardwareSerial.
To avoid to duplicate the code of my ProcessLine() that is quite long, is there a way to "cast" a BlutoothSerial to a HardwareSerial?

Stream is the common base class https://arduino.stackexchange.com/questions/78719/can-you-use-serial-port-as-a-variable/78725#78725

No, you don't "cast" between them. Instead you make use of polymorphism.
In the Arduino framework most classes fit into a "tree" with similar classes "hanging off" a common parent "branch".  In this case both BluetoothSerial and HardwareSerial, being both serial classes, are both children of the Stream class.  Indeed it is this Stream class (which itself is a child of the Print class) which gives these objects most of their functions.
So unless you need access to some function that is specific to the HardwareSerial class (such as the .begin(...) function) you should always work up the tree to the class that provides the most restrictive set of functions that suit your needs. In this case, since you are only printing data, it would be the Print class.  If you were reading data you would choose the Stream class.
So if you change your function to accept Print *serial instead of HardwareSerial *serial then it will accept any object that ultimately inherits from the Print object - so any serial objects, any network stream objects, etc.


text:
ESP32 AsyncWebServer with softAP does not serve pages
I'm trying to create a AsyncWebServer after enabling the SoftAP:
#include <Arduino.h>
#include <SPIFFS.h>
#include <WiFi.h>
#include <WiFiAP.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

WebApp webapp;

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

  File f = SPIFFS.open("/index.html");
  String s = f.readString();
  Serial.println(s);
  f.close();

  WiFi.softAP("ssid", NULL);
  WiFi.softAPsetHostname("ssid");
  Serial.println(WiFi.softAPIP());

  webapp.Begin();
}

void loop()
{
}

class WebApp
{
public:
    WebApp();
    void Begin();

private:
    AsyncWebServer _server;
};

#include "webapp.h"

WebApp::WebApp() : _server(80)
{
}

void WebApp::Begin()
{
  _server.on("/", HTTP_GET, [this](AsyncWebServerRequest *request)
  {
    Serial.println("GET request");
    _server.serveStatic("/", SPIFFS, "/").setDefaultFile("/index.html");
  });

  _server.onNotFound([](AsyncWebServerRequest *request){
    request->send(404);
  });

  _server.begin();
  Serial.println("[WEB] HTTP server started");
}

The SoftAP brings up the network and I can connect to it (softAPgetStationNum() tells me that 1 client is connected). It answers to pings.
The index.html is stored into the flash (the contents is printed out correctly).
But when I try to open the root page (192.168.4.1) it prints out "GET request" but the browser request timeouts and nothing is received.
Am I missing anything in the code?

The usage of serveStatic() is wrong. It's not intended to be used inside a callback. Just place the call in the setup of the webserver, i.e.:
void WebApp::Begin()
{
  _server.serveStatic("/", SPIFFS, "/").setDefaultFile("/index.html");

  _server.onNotFound([](AsyncWebServerRequest *request)
  {
    request->send(404);
  });

  _server.begin();
  Serial.println("[WEB] HTTP server started");
}

I don't have enough rep to make a comment on your post, but is it possible that when you give the parameter for the function setDefaultFile() that the forward slash on /index.html is causing the path of the file to be //index.html instead of /index.html.
Because serveStatic is probably appending the filename of setDefaultFile() to the root directory of / (the third parameter of serveStatic()), you're probably getting an extra character you don't want in your filepath.
TL;DR you don't need the / in index.html for setDefaultFile().
See https://github.com/me-no-dev/ESPAsyncWebServer#serving-files-in-directory for the example.

I'll try this as soon as possible. But in that case should not just fall into a 404?

Tried. It changes nothing. I can reach the page using the complete address (i.e. 192.168.4.1/index.html) but often the wdt triggers and the ESP32 reboots. The pages are very light, less than 6 kBytes

Reloading the page usually leads to 404

I confirm the issue is still there.


text:
Which pin triggered MCP23017 interrupt
This is my first post here, so apologies in advance if I've done something against any forum guidelines!
I have a project where I am monitoring multiple switch states with an Arduino using multiple MCP23017 ICs. I found a fantastic article by Nick Gammon which pretty much does what I want for the first element of the project at least. There are 2 small errors in his expanderWriteBoth and expanderRead routines - swap "send" for "write", and "receive" for "read" and the code works out of the box.
However - Nick's code will only display which pin has triggered the interrupt when the input pin is grounded. If you remove the ground to return the pin to the previous state, it will not state that this pin has changed state.
Can anybody see why this is the case? I have been through the datasheet for the MCP over and over again with no clues...
Any help appreciated,
Thanks.

i think that there were no 2 small errors in 2011 ... libraries change over time

He's not storing previous state, so it's hard to figure out which buttons were released.

The datasheet for the MCP23017 shows that the inturrupt condition can be compared with the previous state - the IC stores the previous state internally. If you set DEFVAL to clear, and INTCON to clear, it should compare with previous state.


text:
Adafruit IO + Esp-Now
So i am using adafruit io and esp-now on an esp32 to recieve voice commands from the internet and sensor values from another esp32. Independently, they both work quite fast but together the esp-now recieving speed slows down greatly with more packets lost. Any reason for that?


text:
Need help: Cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
I'm trying to convert the string that I receive from the Websocket to uint8_t that I can copy to the data bytes of CAN protocol frame. I'm using an ESP32 chip and programming it on an Arduino IDE. The string that it receives from the websocket is "0322F12155555555".
#include <WiFi.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <esp32_can.h>
#include <SPI.h>
#include <string.h>

uint8_t payload1;
char payload2[100];
...
AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
...
// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num,
                      WStype_t type,
                      uint8_t * payload,
                      size_t length) {
...
      Serial.printf("[%u] Received text: %s\n", client_num, payload);
      strcpy(payload2, (const char*)payload);
      payload1 = (uint8_t)(payload2);
...

Error:
error: cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
       payload1 = (uint8_t)(payload2);
                                    ^

I'm segmenting the data into an array later, but I'm not confident that my cast is correct. Can someone please help with this? Thanks
-- Keith

It should be uint8_t * not uint8_t.

@Majenko, I have to finally segment the data and copy it into an array that accepts uint8_t. How do I do that?

I think it sounds like you need to do a lot more than just casting. You need to interpret the content of the string.

You can't just cast a string to a numeric type - C just doesn't work that way. What you're actually casting is the address in memory that the string resides at.
Instead you need to take the content of the string and interpret it.
For instance, you might take each pair of characters and combine them into a HEX value in a string that you then interpret as a number. That could be done a number of ways.
For example:
char temp[3]; // Temporary space for the conversion string
// Copy two characters into the temporary string
temp[0] = payload[0];
temp[1] = payload[1];
// and terminate the string properly
temp[2] = 0;
// Convert the string using base 16
uint8_t val = strtol(temp, NULL, 16);

In your example string you have 16 characters, which would be 8 bytes of data. So you could put it in a loop:
char temp[3]; // Temporary space for the conversion string
uint8_t vals[8]; // Array to store your values

// Iterate over the values
for (int i = 0; i < 8; i++) {
    // Copy two characters into the temporary string
    temp[0] = payload[i * 2];
    temp[1] = payload[i * 2 + 1];
    // and terminate the string properly
    temp[2] = 0;
    // Convert the string using base 16
    vals[i] = strtol(temp, NULL, 16);
}

Of course there are "lighter" ways of doing it that don't involve an intermediate string or the strtol() function.  For example I often use this little function:
uint8_t h2d(char hex) {
    if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case
    return(hex & 0xf);
}

That takes a single character and converts it from hex to decimal. So you can combine that with bit shifting and OR to create a byte from two characters:
val = h2d(payload[0]) << 4 | h2d(payload[1]);

In your loop that would look like:
for (int i = 0; i < 8; i++) {
    // Convert the string using base 16
    vals[i] = h2d(payload[i * 2]) << 4 | h2d(payload[i * 2 + 1]);
}


text:
Maintain constant PWM voltage with changing Vcc
I am making an arduino project with a single lithium ion battery, and want to be able to maintain a constant PWM voltage, even when the battery goes from 4.2-3.2v. I have been able to read the Vcc using the internal 1.1v reference, so I am wondering if I can make some sort of feedback system to increase the duty cycle when the battery discharges, in order to keep the same average voltage on the PWM. I want to be able to make it 3.2v constant, which should be attainable on Vcc from 4.2-3.2, with 100% duty cycle when the battery is at 3.2v.

That's just a math problem, and a simple one at that.  Read your voltage, calculate the PWM to get the average you want, then apply that PWM.  What part is sticking you?

That would work. Just note that the 1.1V reference can differ slightly, from chip to chip. So depending on your margin of error, you might have to do a bit of calibration. PS it sound like you already know, but just to reiterate; PWM output doesn't give out an analog voltage, despite the misleading analogWrite function name. You'd have to do some filtering to convert the PWM to a analog voltage.

Wouldn't a voltage regulator do that better than an Arduino?

Simple:
duty =  (3.2 / vcc) * 255;


text:
ESP32: best way to embed certificates
I'm using the Arduino framework on an ESP32 based board. The board has an SD card slot, but I'm not going to use it.
Anyway, I need to store somewhere the certificates. To the the firmware I've just hardcoded them into the code:
const char *rootCABuff = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\n" \
...
"hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n" \
"-----END CERTIFICATE-----\n";

const char certificateBuff[] = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIDWTCCAkGgAwIBAgIUZXjPNnJFXMntXOki9BT+QmDFciUwDQYJKoZIhvcNAQEL\n" \
...
"gGXtqlgPnenkZPTaBr9c8o+WjgQXFLM+Jwnw3/53dUI9zBcybTaptI63o3Ct\n" \
"-----END CERTIFICATE-----\n";

const char privateKeyBuff[] = \
"-----BEGIN RSA PRIVATE KEY-----\n" \
"MIIEpAIBAAKCAQEAuuKsFy98/xsJclnWo0d+qm8KImLEILB64BbH7WaYi3NnznLg\n" \
...
"uHfBLQQDrA0HDRvYpAUNw/b2H4dpUK/nGM4FFVMP7V8RM2t2923nhQ==\n" \
"-----END RSA PRIVATE KEY-----\n";

Of course this is not suitable for production where each unit will have a different set of certificates.
So wonder what is the best way to store them.
The obviously idea is into flash. So I tried to enhance my settings class, based upon the Preferences library. In the official documentation I read:

String values are currently limited to 4000 bytes. This includes the null terminator. Blob values are limited to 508000 bytes or 97.6% of the partition size - 4000 bytes, whichever is lower.

But if I do something like this:
Preferences prefs;
prefs.begin("settings", false);
Serial.println(prefs.freeEntries());

it return 460, even if I still have plenty of flash:
Flash: [=======   ]  73.8% (used 967234 bytes from 1310720 bytes)

Is there another library more suitable to store such a data that can be used with Preferences?

Hi mate, you could also use spiffs memory, check here, it may help you: https://diyprojects.io/esp32-get-started-spiff-library-read-write-modify-files/

I don't know this libraries but "freeEntries" does not look like something that returns a size in bytes. Looks like it is telling you how many more values you can store. (Similar to max number of files that some filesystems have, not total available free space.)

You don't need any library. How many certs you intend to store? For ESP32, any variable that declared as const is stored in flash memory, and internally it does not have to copy the data from flash to RAM but uses the Flash MMU to map the memory segments into either IRAM or normal RAM, so it doesn't take up your ESP32 RAM. Alternatively, you could stored it in SPIFFS or FS as a file.

@hcheung Sorry I explained it wrong. I need to store only those certificates. The problem is I cannot change the code every time a program a new board! So I'm going to "download" the data via serial line, and save it into the flash at run-time.

@Mat, got it. I'm going to give it a try to see if I can actually save them like my other preferences.

@k.Cyborg, good advice. I will try spiffs hoping it can be used together the other stuff.

I don't know what you need that Preferences thing for, but I would use SPIFFS/FAT anyway. Simply store the certificate in a file in flash and read that file when you need it. The required space is no problem as you can choose the size for file system in the partition table and also you can upload the file (there is a plugin in the arduino IDE for this purpose) after flashing the firmware, so having different certificates on individual devices is no problem.
I saw that you tagged the question with 'eeprom': the esp has no eeprom but emulates it with a blob in flash, so using any flash library is just as fine. The esp also supports wear-leveling, which makes using flash an even better option as the dedicated eeprom-partition, which was used in an older version of the sdk, would wear out orherwise. The "eeprom" is just there to be consistent with the use of other arduino's eeproms.

Yeah, I've just tried it and it's very handy! Just a clarification: I'm using PlatformIO inside Visual Studio Code and I only found a way to put the desired files into a data folder to be uploaded. Is there something better? Because I will need to replace the files for each unit...

You can use the sdk's bare features, nsmely the tools mkspiffs and esptool.py to create the flash binary and to upload it. See this anser: https://arduino.stackexchange.com/a/51581/38721


text:
Recommended way to fork a library
I want to extend a library, available on github to add some features I need.
Of course I will made available the new source code as well.
Because it's the first time I do this, I'm not sure how to do.
My idea:

fork the original repository
create a new branch
make the changes
commit them locally
push the new branch on another (mine) repository (of course, to avoid messing up the original one)

Is it correct?
How to test the library while developing it? I mean, in which folder I have to clone the repo?

Almost.

Fork the library to your account
Check out your fork
Edit as needed
Commit locally
Push back to your fork

Your fork is yours to do with as you wish. Github makes it easy, should you wish, to then pass those changes back up to the original repository (make a "pull request"). But you don't have to do that (and probably don't want to).
You can make a new branch if you like, but that's pointless - your fork is, in effect, a branch itself (well, it's an entire new tree really).

If he plans to make a pull request, then creating a new branch will make things easier.


text:
Hysteresis and scaling range
Here I asked about how to add an hysteresis on ADC readings. The answer received was very good and it worked out of the box.
Still I'm having troubles trying to generalize the resample function in order to map the input values to a different range of output values, where the lower rail is not zero.
If the lower rail was zero, it would be enough to change the shifts with a multiplication/division for 1024 / max. But I cannot understand how to handle the lower rail when min > 0.
My attempt:
int Menu::resample(int adc, int *value, byte min, byte max)
{
    // sanity checks omitted: min < max and max < 128

    double m = 1015.0 / (max - min); // 1015 = 1023 - 8 (1 LSB of low-res output)
                                     // otherwise it reaches 126 even if max = 127
    int q = min << 3;

    int lowerTest = (q + *value * m) - ADC_HYSTERESIS;
    int higherTest = (q + (*value + 1) * m) + ADC_HYSTERESIS;

    int lowerOutput = min + (adc + ADC_HYSTERESIS) / m;
    int higherOutput = min + (adc - ADC_HYSTERESIS) / m;

    if (adc < lowerTest) *value = lowerOutput;
    else if (adc >= higherTest) *value = higherOutput;

    if (*value > max) *value = max;
    if (*value < min) *value = min;
    return *value;
}

There is something wrong in my math, since the comparison always falls under the first if (i.e. *value = lowerOutput).
May you help me to fix this code so I can have an hysteresis on any scaled output?
Note: instead of using a static variable for value as in the answer, I use a struct:
slider.value = resample(adc, &slider.lastValue, slider.min, slider.max);

where:
typedef struct
{
    int value;
    int lastValue;
    int min;
    int max;
} slider_t;

slider_t slider;

First, a couple of comments about this first attempt.
There is no point in storing in slider_t both lastValue and value.
The way this is used, both fields are always updated with the same
value: lastValue is updated by pointer inside resample(), while
value is updated by assigning it the value returned by resample(). I
would suggest removing the field lastValue and either:

providing value by value (rather than by pointer) to resample(),
or

providing a reference to a slider_t as the only parameter.

The first approach is better if you want to avoid resample() and
slider_t being tightly coupled.
Next, there is a mix between int and byte types. If you want to save
memory, and improve consistency, I would use byte for all low-res
values living in the output domain of resample(). Actually, I would
use uint8_t, which is the same, only more standard.
Then, there are a few things I do not understand in this code:

Why 1015? It seems to me this number should be dependent on the
width of output range.

Why min << 3? Again, this is a division by 8, while the proper
factor should be probably be output-range dependent.

Now, for the solution, I would try this approach:

Compute the minimum and maximum possible output values consistent with
the provided input, accounting for the hysteresis.

Constrain the output to remain within this bracket.

In code:
uint8_t Menu::resample(int adc, uint8_t value, uint8_t min, uint8_t max)
{
    value = constrain(value, min, max);  // just in case...
    uint8_t lower = map(adc - ADC_HYSTERESIS, 0, 1024, min, max+1);
    uint8_t upper = map(adc + ADC_HYSTERESIS, 0, 1024, min, max+1);
    return constrain(value, lower, upper);
}

Some points worth noticing:

I do not know whether this was originally intended, but the Arduino
function map(x, in_min, in_max, out_min, out_max) does a poor job
at mapping the interval [in_min, in_max] to [out_min,
out_max]. It does, however, do a good job at mapping [in_min,
in_max) to [out_min, out_max) (mind the semi-open intervals).
This is why the four last parameters of the call to map() are (0,
1024, min, max+1), rather than (0, 1023, min, max).

The first call to constrain() can be removed if the caller bears
the responsibility of guaranteeing this precondition.

If the precondition is valid (or, like here, enforced), it will also
hold for the returned value, provided adc is within [0, 1024).

This method would be called like this:
slider.value = resample(adc, slider.value, slider.min, slider.max);

It's unbelievable how a quite complex task can be solved with few lines of code. I'm impressed. Thank you!


text:
Serial Enable Maxim RS485 Pin
If I want to use a MAXIM 485 for a RS485 communication, is there any option to include the Control DE and RE' pin in a natural manner in the code, instead changing the control pin everytime I made a Serial.print()?
Should I overload the HardwareSerial object in order to add those pin operations everytime?

No, there isn't - you have to do it manually. And don't forget to flush.
You could inherit HardwareSerial if you really wanted - or just write a couple of functions to do the sending and controlling of the DE pin.

Should i use a slight delay and distinct signals for controlling the DE and RE' pins? Or it is enough to join them in the design?. When should I have different signals for them?

I usually tie them together. And no need for a delay normally.

The only time you might want separate control of directions is if you are doing fancy collision detection by reading what you're sending and seeing if it matches what you sent.


text:
Faster Arduino Mega
I am using Arduino Mega 2560 for interfacing devices such as the Maxim MAX22500E and TI ADS1241.
Now I am requiring more speed for hopefully the same coding, and I am thinking in the Arduino Due (84 MHz Clock) which is enough faster than the Arduino Mega (16MHz Clock) but imposes working with 3.3V, hence using some 3.3V 5V level conversion for every input and output.
If I want to keep the same "arduino" coding environment, is there another faster 5V processor? Or should I focus in the strategy of interfacing the 5V devices from a 3.3V processor?

There are "unofficial" Arduino ports to the popular STM32 micro controllers, which feature 5V tolerant pins (but can't output 5V). Apart from that, Majenko is right, 5V is hardly needed anymore - otherwise, there wouldn't be so many 3.3V-controllers!

"... Arduino Due (84 MHz Clock) which is enough faster than the Arduino Mega (16MHz Clock) ..." - Note that you can't just compare clock speeds across vastly different processors like that. The Mega has an 8-bit AVR microcontroller, the Due has a 32-bit ARM core. In this case, it's likely the speed difference is larger than the clock speed difference suggests, but in general that's not an assumption you can make.

You should begin working with 3.3V. 5V is getting rarer and rarer as far as "real world" applications go.
Many devices that you have been using at 5V will also work at 3.3V (such as the MAX22500E). Running those at 3.3V will mean you don't need logic level translation.
Others, like the ADS1241, have "split power" where you can have different logic voltage (DVDD) and analog voltage (AVDD), so you just run the logic at 3.3V and the analog at 5V so you don't need a logic level translator.
For those few rare devices that have to run at 5V and don't have a 3.3V equivalent, yes you will need to use some logic level shifting.

Thanks. That was the kind of guidance i was needing... I will go fully into 3.3V...


text:
EEPROM Arduino library for ESP8266 is not working
I am trying to use EEPROM library from Arduino framework for my ESP8266 project (NodeMCU). I am using Atom with Platformio.
Initialization of EEPROM is attempted at void setup() in main.cpp:
EEPROM.begin(80);

The compiler throws an error at this line with:
request for member 'begin' in '0', which is of non-class type 'int'

This is strange as I just follow a simple example from GitHub.
I include <EEPROM.h> just as <Arduino.h> and many others (<ESP8266WiFi.h>, <ESP8266WebServer.h>, <ESP8266mDNS.h>). Platformio has created .pio\build\nodemcuv2\lib32c\EEPROM directory with EEPROM.cpp.o inside but compilation fails.
How can I make it work and what else should I check to find the problem?

run the example code that is in the Arduino IDE

Instead of describing your code, show your code.

@Majenko, it's almost 2.5K lines. Not easy to bring the relevant part quickly.

Then write some code that is only a few lines and demonstrates the problem.

Exactly what @Majenko said - if this is a problem then it should be easy to demonstrate in 10 lines of code. If you can't reproduce it in 10 lines of code then you have a very large clue as to what's going on.

you have not the right EEPROM library.

Have you tried compiling one the examples supplied with the ESP8266 Arduino BSP (after adding #include <Arduino.h> to the top, of course) - maybe the eeprom_write one? If that works, you will be able to narrow it to something else in your code. Otherwise, you've probably got a corrupt install, or wrong platformio.ini configuration. You didn't add EEPROM to the lib_deps, did you? As you should be using the espressif8266 platform provided EEPROM library.

Thank you all for your help. At first I thought it's about the library I use (just as @Juraj supposed). Then your advices to try pure examples (which proved to work fine) led me to search for conflicts.
Eventually I found an external lib that had #define EEPROM (nothing to do with Arduino, it's for other MCUs to communicate).
I was misguided by a vague compiler error. Normally for a direct naming conflict (as in this case) it says clearly: "redefinition of ..."
So be warned, this type of error should be considered as a conflict to look for.
Once again, many thanks for everyone's help!

The problem here is that these symbols exist in different layers. The problem one was a "preprocessor macro" which gets replaced verbatim in a first pass through the code. Only once that is done is the code compiled - so first off all references to EEPROM get replaced with 0 (I guess) and then it's compiled, which leaves you with 0.begin(80); that of course fails to compile. There's no redefinition to report an error on.


text:
ESP32 partition table and writing location
In my ESP32 project I have the following platformio.io file:
[env:esp32-poe]
platform = espressif32
board = esp32-poe
framework = arduino
lib_deps =
    openslab-osu/SSLClient@^1.6.7
    knolleary/PubSubClient@^2.8
    bblanchon/ArduinoJson@^6.16.1
monitor_speed = 115200

[env:custom_builtin_table]
board_build.partitions = default.csv

the default.csv table is this one:
# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x140000,
app1,     app,  ota_1,   0x150000,0x140000,
spiffs,   data, spiffs,  0x290000,0x170000,

I noticed that when I upload the code to my ESP32 the output is like this:
[...]
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 17104 bytes to 11193...
Writing at 0x00001000... (100 %)
Wrote 17104 bytes (11193 compressed) at 0x00001000 in 0.3 seconds (effective 521.5 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 128...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (128 compressed) at 0x00008000 in 0.0 seconds (effective 5621.7 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 27422.0 kbit/s)...
Hash of data verified.
Compressed 1003456 bytes to 585011...
Writing at 0x00010000... (2 %)
[...]

Hence, it writes at:

0x1000
0x8000
0xe000 (otadata)
0x10000 (app0)

But I cannot understand what are the first two writings.

0x1000 is the "second stage" bootloader. This is the code that is responsible for loading the code according to the layout specified in the partition table.

In ESP-IDF, the binary image which resides at offset 0x1000 in flash is the second stage bootloader. Second stage bootloader source code is available in components/bootloader directory of ESP-IDF. Note that this arrangement is not the only one possible with the ESP32 chip. It is possible to write a fully featured application which would work when flashed to offset 0x1000, but this is out of scope of this document. Second stage bootloader is used in ESP-IDF to add flexibility to flash layout (using partition tables), and allow for various flows associated with flash encryption, secure boot, and over-the-air updates (OTA) to take place.

0x8000 is the partition table itself.

Second stage bootloader reads the partition table found at offset 0x8000. See partition tables documentation for more information. The bootloader finds factory and OTA partitions, and decides which one to boot based on data found in OTA info partition.

All this is detailed in the ESP-IDF manual.


text:
Generalize webserver routing
I'm following the examples for ESP32:
  AsyncWebServer _server(80);

  _server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
  {
    request->send(SPIFFS, "/index.html", String(), false);
  });

  _server.on("/css/index.css", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/css/index.css", "text/css");
  });

  _server.onNotFound([](AsyncWebServerRequest *request){
    request->send(404);
  });

_server.begin();

With this approach I have to know in advance each file I store in the SPIFFS and add a handler for each one.
Is there a more elegant way to automatically serve any file that exists in the flash?

You can tell the webserver to serve the static content from a specific folder:
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");

In this case it serves on the root URL the content from the SPIFFS root. So if I place a file called image.jpg in the SPIFFS root it will be served at /image.jpg.
For more information you can look at the corresponding section of the libraries Readme file.

What does static actually mean in this specific context?

In this case it means files that are placed in SPIFFS (aka flash). These files can of course also be written and thus deliver a more dynamic content. But then you should mind the limited write cycles of flash memory. So its mainly meant for the static (not changing) files of your website, but can also be used to serve changing files. In one of my projects I use it to serve a log file of relatively rare events


text:
Distributing power evenly to multiple pins
It's an arduino board, model UNO R3. I have 3 5cmx10cm heating pad power required 5V DC up to 1A and can withstand up to 12V DC. These 3 heating pad are wired up onto arduino board with red wires connected to pin 8 pin 9 and pin 10 on the digital side of the arduino and the black wire connected to GND (ground). Lastly I have a toggle on and off switch connected to the arduino with the red wire attached to digital pin 2 and the black wire to 5V. The arduino uno R3 withstand 20voltage and the 5V heating pads can withstand 12V. I would like my 20V external power to heat up all 3 heating pads evenly, how can I do this? Is it possible? Thank you!

You could put the three pads in series, so they run on 15-36 Volt. But I suspect there's more wrong here. You can't connect a 1A heating pad to an Arduino pin directly, as it can't deliver that much current, and will likely get damaged. The on-off switch also needs a (pull-down) resistor to work reliably.

Do not connect these heating pads to your Arduino. You will overload the Arduino. Also don't connect AC power to the Arduino.

To be clear, you should not try to draw power from Arduino pins. An arduino is made to output very low power control signals out of it's pins, NOT power. (You should draw at most 20 milliamps from each pin on the Arduino. That's 20 thousandths of an amp.)

Can you state the full goal of the project? Are you supposed to be turning the heating pad on and off with the Arduino? (The rest of my answer assumes that that is what you want to do.)
You will need a source of DC power to drive the Arduino. (You can't power an Arduino with AC.)
You will need a 5V relay so you can turn off the power to the heating pad from a logic pin on the Arduino. There are various relay modules made to be controlled by microcontrollers like Arduinos. This one, for example: https://www.jameco.com/z/VMA406-Velleman-Arduino-Compatible-5V-Relay-Module_2255306.html?CID=GOOG&gclid=EAIaIQobChMIr9bSioLT4AIVkpOzCh3X7gqbEAQYBSABEgLf1PD_BwE
Then you will be able to rig the Arduino to turn the relay on and off. You'll wire the power for the heating pad through the relay. You will also need a way to lower the voltage of your power supply to the 5V - 12V range you mentioned. A 1:2 step-down transformer would be a good choice for that.

I can power arduino with an AC-DC which I have. I got 120V AC input to 12V DC output that can work. Do I still need a relay and step down transformer? Will the arduino be using some of that power to power it self?

You still have not explained what you are trying to do very clearly, so it's really hard to answer your questions.

YES YOU NEED A RELAY, assuming your goal is to control the heating pad from the Arduino. An Arduino cannot drive high power devices like heaters. You need to set up the relay as a switch. A digital line from the Arduino will turn the relay on and off.  The relay will switch power to your heating pad on and off.

Note that feeding 12V into the Arduino's barrel connector will put a lot of strain on it's voltage regulator. A linear voltage regulator like the one in the Arduino takes excess voltage and converts it to heat. So the Arduino's power supply will have to "burn off" 12-5, or 7 volts as heat. The voltage regulator will get quite hot.