text:
ESP32 IR remote
my board is a firebeetle esp32 that I am using as an IR remote.
After using the Ken Shirrif IRremote library for about 6 months successfully, then the time came to change a few things on the web front end. This has been a disaster.
I tried to recompile my working code that the board is currently using and got errors everywhere I turned.
So i switched libraries to this one;
https://github.com/ExploreEmbedded/Arduino-IRremote
Now it does compile successfully, with the only change between the two libraries was to pull out the pin I defined for IR tx in the Ken Shirriff library. For example; previously my code looked like this to work with the old library.

IRsend irsend(33);

Now it looks like this;
IRsend irsend;

As stated, it does compile; only issue is that IR doesn't work. It says in the library that pin 5 is defined as the tx pin for the ESP32 in boarddefs. Snip from boarddefs where I believe pin 5 is defining IR tx.
// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing
// them out in the common code, they are defined to no-op. This allows the code to compile
// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written
// for that -- merlin
// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100%
// reliability because the arduino code may be interrupted and cause your sent waveform to be the
// wrong length. This is specifically an issue for neopixels which require 800Khz resolution.
// IR may just work as is with the common code since it's lower frequency, but if not, the other
// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
// https://github.com/ExploreEmbedded/ESP32_RMT
#elif defined(IR_TIMER_USE_ESP32)
#define TIMER_CHANNEL       1
#define TIMER_LENGHT        8 //8-bit Timer
#define TIMER_PWM_PIN      5
#define TIMER_ENABLE_PWM    ledcAttachPin(TIMER_PWM_PIN, TIMER_CHANNEL);
#define TIMER_DISABLE_PWM   ledcDetachPin(TIMER_PWM_PIN);
#define TIMER_RESET
#define TIMER_ENABLE_INTR
#define TIMER_DISABLE_INTR
#define TIMER_INTR_NAME

//---------------------------------------------------------
// Unknown Timer
//
#else
#   error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
#endif

#endif // ! boarddefs_h

I know it says that IR with the ESP32 will not work, but it said the same thing for several libraries that i've used that do work, most notably the one by Ken; which appears to have moved here.
https://github.com/z3t0/Arduino-IRremote
Quick example of my code;
#include "IRremote.h"
  IRsend irsend;
int khz = 38;
String input;
  String tv;
void changehdmi() {
if (Server.args() > 0 ) {
  for ( uint8_t i = 0; i < Server.args(); i++ ) {
    if (Server.argName(i) == "input") {
      input = String(Server.arg(i));
      Serial.println("input is " + input);
    }
    if (Server.argName(i) == "tv") {
      tv = String(Server.arg(i));
      Serial.println("tv is " + tv);
    }

  }
}
if (input == "1" && tv == "1") {
  unsigned int irSignal[] = {9000, 4450, 600, 550, 550, 550, 600, 550, 550, 550, 600, 500, 600, 550, 550, 600, 550, 550, 600, 1650, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1650, 600, 1650, 550, 1700, 550, 550, 600, 550, 550, 1700, 550, 550, 600, 500, 600, 550, 550, 600, 550, 550, 600, 1650, 550, 1700, 550, 550, 600, 1650, 550, 1700, 550, 1700, 550, 1700, 550}; // NEC FF906F
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
}
else if (input == "2" && tv == "1") {
  unsigned int irSignal[] = {9000, 4500, 550, 550, 600, 550, 550, 550, 550, 600, 550, 550, 600, 550, 550, 550, 550, 550, 600, 1650, 600, 1700, 500, 1700, 600, 1700, 500, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 550, 550, 1700, 550, 1700, 550, 1700, 550, 550, 550, 550, 600, 550, 550, 550, 600, 1700, 500, 600, 550, 550, 600, 500, 600, 1650, 600, 1650, 600, 1650, 550}; // NEC FFB847
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
}

Has anyone gotten this to work recently? The libraries that are available seem to have lost support for this functionality.

For the ESP32, you should really check out IRremoteESP8266, which also works on your board, and is frequently updated, very widely used, and lets you use any compatible GPIO pin easily.
Here's a sample of a simple IR send demo:
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

#define IR_PIN 4

IRsend irsend(IR_PIN);  // Set the GPIO to be used to sending the message.

void setup() {
  irsend.begin();
  Serial.begin(115200);
}

void loop() {
  Serial.println("NEC");
  irsend.sendNEC(0x00FFE01FUL);
  delay(2000);
}

This example will send an NEC code very 2 seconds. The library also has extensive support for other formats, as well as raw.
If you want to be extra safe, the creator of the project menions here that GPIO 4 and 18 are safe, but I know for a fact that many other ESP32 pins are okay to use as well.


text:
Ways to add pins in an arduino
I'm making a project for school where I'm using flex sensors and converting that into words on an LCD (similar to the signing glove if you're familiar with that).
I ran into a problem since the Arduino I'm using doesn't have enough pins for all of my flex sensors and my LCD monitor.
I'm considering getting another Arduino with more pins but I might not have time to order it since my project is due in a couple of days. I was thinking about connecting two arduinos but I'm not sure if that would work (first year coding/engineering student) Any other suggestions as to how I can create more pins?
Your input is greatly appreciated!
The Arduino I'm using is a sparkfun redboard (it only has 6 analog pins and a separate place to plug in the LCD monitor which I connected to where it says ISP f you look on the link you will see what I'm talking about SparkFun RedBoard - Programmed with Arduino).
I'm using four flex sensors
LCD:

This can be done with the existing board. LCD can be driven by only with the digital pins. Check the below link for the wiring diagram.
https://www.arduino.cc/en/Tutorial/LiquidCrystalDisplay
Since there are 6 Analog pins available, all flex sensors can be easily connected.

This seems like a 1602 display. Note there are also I2C modules that connect to a 1602 making it possible to use it with only I2C wires (and VCC/GND).
See I2C-LCD-interface for a description, although there are many (similar) ones.
For the flex sensors you have 6 analog pins (hope that is enough). If not, than you need an external ADC (analog digital converter). Or connect a second Arduino and use I2C/SPI/Serial to transport the information from one Arduino to Another.

source: Stack Exchange

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

sort: votes


text:
I want my arduino mega to read from all 4 serial ports at the same time, running sequentially through each one
I currently have the code running through Serial1, which works exactly as I want it to:
int RFIDResetPin = 13;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);
  Serial.println("Arduino is ready");
}

void loop(){

  char tagString1[13];
  int index = 0;
  boolean reading1 = false;
  ///////////////////////////////////////
  //this reads from the reader installed
  //on serial1, which is pin 19
  //////////////////////////////////////
  while (Serial1.available() > 0) {

    int readByte1 = Serial1.read(); //read next available byte

    if (readByte1 == 2) reading1 = true;
    if (readByte1 == 3) reading1 = false;

    if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
      tagString1[index] = readByte1;
      index++;
    }
  }
  Serial.print("Reader 1: "); //read out any unknown tag
  Serial.println(tagString1);

  clearTag(tagString1); //Clear the char of all value
  resetReader(); //reset the RFID reader
}

void resetReader() {
  ///////////////////////////////////
  //Reset the RFID reader to read again.
  ///////////////////////////////////
  digitalWrite(RFIDResetPin, LOW);
  digitalWrite(RFIDResetPin, HIGH);
  delay(150);
}

void clearTag(char one[]) {
  ///////////////////////////////////
  //clear the char array by filling with null – ASCII 0
  //Will think same tag has been read otherwise
  ///////////////////////////////////
  for (int i = 0; i < strlen(one); i++) {
    one[i] = 0;
  }
}

However, I want to add serial0, 2, and 3 as well. there are 2 main questions I have
1) is it possible to have copy paste this section of the code:
    while (Serial1.available() > 0) {

    int readByte1 = Serial1.read(); //read next available byte

    if (readByte1 == 2) reading1 = true;
    if (readByte1 == 3) reading1 = false;

    if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
      tagString1[index] = readByte1;
      index++;
    }
  }
  Serial.print("Reader 1: "); //read out any unknown tag
  Serial.println(tagString1);

  clearTag(tagString1); //Clear the char of all value
  resetReader(); //reset the RFID reader
}

while changing some of the variable names to connect the other serial ports? I saw something here, but don't know how to implement it, or if it even would work for me.
and
2) since I am routing the incoming data through serial0, Is it possible to have this code working on it as well?

There might be a way to do it if in the void loop I set up certain functions, and then treat each function as its own void tag (unsure if that is the correct terminology). That is basically what the link does, but I have no idea how I would go about setting that up in code.

Is there something that defines the end of the data? For example linefeed? Is there a start byte? What kind of data is received.

I didn't four serial ports in your code. What I understand is that you hadn't upload your full code or you just created four object for a single port. As @jsotola said you can't read all serial at the same time with single ALU or Ardunio you need four ALU or arduino to process four peripherals at the same time. If you are going to sequential reading my advice will be that you first read the data from all ports first the go for data analysis part.

@Jot CR/LF used to for new line defined beginning and end of data

@jsotola true, I meant sequentially, good point

@vaibhav correct, I want it to be read sequentially

Then I would put every incoming character in a buffer. A buffer per serial port. When the cr/lf is received then the data in the buffer can be processed. Perhaps all the buffers and all the serial ports can be put into an array or a array of structs.

The Arduino already reads from the 4 serial ports at the same time. Or
at least as close to “at the same time” as possible with a single CPU:
every time a byte is received at one port, an interrupt is triggered
that reads the byte from the UART and puts it into a buffer. You can
then get it from the buffer using Serial.read().
What you now have to do is move the bytes from these buffers (which
belong to the Arduino hardware serial library) into you own buffers for
further processing. You can do this by checking the ports sequentially
and processing each one in turn. Everything will be fine as long as you
do not have blocking code in there. If you do block, then you run the
risk of having one of the library buffers overflow. The code you posted
is non-blocking, so you are fine.

is it possible to have copy paste

You should avoid programming by copy-and-paste. It's not that it won't
work (it will), but you would be creating a maintenance nightmare.
Instead, put the code you would want to copy-paste into a function, and
call that function as many times as required. For example:
void handlePort(Stream &port, const char *readerName, char *tagString)
{
    boolean reading1 = false;
    while (port.available() > 0) {
        int readByte1 = port.read(); //read next available byte

        if (readByte1 == 2) reading1 = true;
        if (readByte1 == 3) reading1 = false;
        if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
            tagString[index] = readByte1;
            index++;
        }
    }
    Serial.print(readerName); //read out any unknown tag
    Serial.print(": ");
    Serial.println(tagString);

    clearTag(tagString); //Clear the char of all value
    resetReader(); //reset the RFID reader
    }
}

And you call it in loop():
handlePort(Serial1, "Reader 1", tagString1);
handlePort(Serial2, "Reader 2", tagString2);
...

problem is, I want the reader to change names as well. for instance, when it is going through serial1, I want it to say "Reader1", fro serial2, I want "Reader 2" and so on.

Also, tagString1 in the loop() is throwing an error

@Rambunctiouslad: 1. Anything you want to change from port to port should be passed as an argument to the function. Specifically, for the "Reader 1"/"Reader 2" issue, see the code in my amended answer. 2. Re “tagString1 in the loop() is throwing an error”: sorry, I don't have a crystal ball to tell me what the error is.

all the errors was my own stupidity, as I called it wrongly. Once i figured out what was going on, I was able to fix it, and now everything works. thanks for the help

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


text:
Controlling multiple 12v solenoids with 5v relay modules (Arduino Reset Issue)
I have 4 12V(1A) solenoids running on a 12V(4.16A) power supply.
Each solenoid circuit is controlled by a 5V relay module connected to the Arduino Uno (powered by USB).
The solenoids actuate properly but eventually the Arduino resets, typically when multiple solenoids are turned on/off in fast succession. This is accompanied by random character artifacts on the LCD display (connected to the Uno) during operation but before the reset.
From what I've gathered there are back EMF surges occurring when the solenoids lose their charge. Here are some possible remedies I've found:

Add a flyback diode (IN4004) to each solenoid circuit. (Redirect the surge)
Add a capacitor (4700 - 10,000 uF) to the 5v supply (from the Uno) for the relays. (Filter the surge)
Provide a separate 5v power source to the relay modules instead of using power from the Uno. (Isolate the surge)

Any input on which solution(s) should be applied or other possible causes for the Uno reset and LCD distortion is appreciated.

Those 5V relay modules already have flyback diodes, so I don't see how providing a separate 5V source for these modules will help. A schematic would certainly help here.

Some of those 5V "digital" relays can be wired using a separate power supply for the relays and the Arudino. You have to move a jumper to use separate power supplies.
My guess is that you're powering both your Arudino and your relay coils from the same 5V supply, and when you energize all 4 relays at the same time you draw too much current and the Arduino doesn't get enough voltage and resets.
Read up on your relay modules, and either re-wire them using 2 different 5V supplies, or switch your 5V supply to a higher current supply. (and possibly adding a filtering capacitor to the Arduino to smooth out the power fluctuations as the relays energize and de-engergize)
I used a 4-channel relay unit in a project of mine that has optical isolation of the relay control lines, and can be wired to use separate power supplies for the Arudino and the relay power. When wired with separate power supplies, the relay's control lines just draw CMOS logic levels to control the different relay channels, and get the power for the coils independently from the microcontroller's power.

Here is another path to explore :

Try to use separate rail for the 5v relays
Use a transistor or darligton array (such as ULN2003) for controling your 5v relay.
ALWAYS put a feedback diode when you use an inductive load it can break your Arduino !!

My analyse :

Arduino and many other µc have limited output current on IO, be sure to not overload these value by using transistor or darligton array.
The voltage regulator on the Arduino can provide around 200 mA of power. I you are overloading the value use an external power supply for your circuit.
The solenoid can draw lot of current of the power supply, try to measure if a voltage drop occur on loads. It can cause the arduino to reset due to low voltage.

The relay modules seem to already have to needed circuitry (transistor and flyback diode). What do you think? You are right, that the symptoms suggest a voltage drop. I think that is the way to investigate further.

If you have already put the required circuitry for driving properly each relay. I think you can investigate for voltage drop.

Would adding an additional flyback diode (assuming the relay module already has one) to the circuit cause problems? I'll find a suitable 5v rail for the relays, this seems like the culprit. 4 relays, LCD screen, MIDI In/out, and an IR receiver are likely drawing more than the 200 mA available.

I don't see how are the relays optoisolated. there is no separate VCC and ground input for the "behind the optocoupler" circuit.


text:
Use ATTiny as a battery-backed RAM?
So, I found an interesting article the other day, and I'm trying to build a project that could benefit from a battery-backed memory (no wear limits, but keeps data over power cycling). The article lists how an extremely small current from an LED (acting as a photocell in the lit room) accidentally powered the AVR during a RAM-endurance test.
But, what if this is done on purpose with a battery?
(Article here: https://wp.josh.com/2014/03/03/the-mystery-of-the-zombie-ram/)
The problem with this idea (since the RAM can already be backed up, as shown in the article, though the author does not seem to have considered this) is that I need a way to keep an array of memory ignored by the C initializer. It would be the height of hilarity to have the memory survive the power-off event only to be nuked by the chip's powerup reset code. The listed example at that article would work, for the first requirement, but would break almost anything else I might try to do (since it overrides the entire initializer). (Comment on the reset issue: https://wp.josh.com/2014/03/03/the-mystery-of-the-zombie-ram/#comment-598)
Also, assuming I tried this, would I simply damage the pin rather than provide power? I plan to use a pin continually set to input attached to the positive side of a lithium coin cell, with a common ground. In theory, powering the AVR (and I think at any voltage) through the VCC pin would cause the chip's diodes to disconnect the battery, but if it's unplugged, the core would receive enough power to keep the RAM alive.
Of course, my question is whether it would instead stupidly try to keep the core running when power is disconnected (in the original article, the nanowatts from the LED couldn't do that, so it's forced to shut down, but I don't know if this is solely due to power limits or if it would shut down the main systems if there's no connection over VCC). In this case, it might try to draw more than the 1mA rating over that parasitic supply, and try to power the entire chip when I don't want it to (thus frying the clamping diode or something equally bad).
I wonder if it would be possible simply to put a large resistor (10K? 1M?) in series with the battery in this case? That would automatically limit the supply to less than 1mA.

You're mad. Just use an NVSRAM chip. https://www.microchip.com/wwwproducts/en/23LCV512

Re “keep an array of memory ignored by the C initializer”: just add __attribute__((section (".noinit"))).

I probably am. But I'm trying to avoid purchasing stuff (and its shipping times) for now. It does seem to work though, so thank you, Edgar. This is actually fairly awesome, in the fact that it can be done, in a "Oh, how is that even a thing?!" fashion...

@EdgarBonet - use the Answer box to answer, please. People are not supposed to look in the comments under the question for the answer. Then it can be accepted and you can get some rep. :)

Please write an answer to this and describe, how you did it. That sounds very interesting, though somewhat mad XD

this is not an Arduino question

Why would you want to depend on zombie ram, if you can just put the ATTiny in deep sleep mode? The ATTiny is able to sleep for years on a single coin cell. Use a diode to connect VCC to the Vcc-pin of the ATTiny. Use another diode to connect the battery to that same Vcc pin. Connect VCC (via a resistor) to the interrupt pin of the ATTiny, so if can see if it's running on battery, or not.

To the above two comments, I'm trying to use an ATtiny that's already in my project as a peripheral (I2C slave and rapid data-sampler) to store data as well. I can't simply put it in sleep mode because it needs to communicate with other components, which would either drain the backup battery faster or require isolating its backup power supply from the main rail. My question was also mostly about the software part of the design (and to a lesser extent chip behavior), which should probably count as Arduino more than electronics.

Expanding on my previous comment...

I need a way to keep an array of memory ignored by the C initializer

You can achieve this by instructing the compiler to store the array in
the “.noinit” memory section:
int my_array[ARRAY_LENGTH] __attribute__((section(".noinit")));

Your array will end up sitting somewhere between the .bss and the heap
(if any), and will not be touched by the __do_clear_bss routine from
the C startup code.

my question is whether it would instead stupidly try to keep the core
  running when power is disconnected

Most likely. In order to avoid that, I suggest you enable the brown-out
detection by setting the BODLEVEL fuses. This feature of the
ATtiny is specifically meant to prevent the CPU core from running if the
supply voltage is below some configurable threshold.

For anyone wanting to know further how I implemented this, I did set the BOD fuse on my device. Still, not wanting that sort of fun (referring to having the chip try to actually run via the backfed power) to happen at all, I wired a 1M resistor in series with the supply backfed through the pin (which was set to INPUT in all cases. HIGH would result in attempting to charge the backup battery, and LOW may well sink the input current and negate the benefits) in an effort to force the current to be high enough to power the RAM but too low for it to run. It also makes sure that too much current cannot flow through the pin.
My results were somewhat inconsistent, and it doesn't help that the device can actually end up powered by whatever indicator LED is added to show that it worked!
Still, there's a good chance that this can be used as an NVRAM if the code is written for it. As for that, just store an array with the values, and write onReceive and onRequest code to index that and send it back out!
Fair warning: If the power bus is connected to other components, the AVR won't keep its memory. Use a diode to prevent power from escaping.


text:
ESP32 Alexa Integration; Cannot correctly control more than one device
I created a garage door opener recently that is controllable through Alexa, using this library: https://github.com/Aircoookie/Espalexa
Everything is operating as expected, meaning I was able to detect my device and control the garage (using routines).
The issue came when I went to integrate Alexa into another previously completed/operational project. I was able to successfully discover and control the second board, kind of.
At this point I have added two ESP32 boards to Alexa, named differently of course. When I went to test the second board(meaning that it was successully discovered, and the ESP was receiving most commands) I noticed that Alexa was also opening my garage. If i unplugged my garage door opener(first board to be added) the second board starts to all receive commands, although degraded; for example;
In the above noted library Alexa should be able to control 'brightness' of dimmable lights. Of course this device is not a dimmable light but for the purposes of the integration, this library emulates smart lights. I am never able to see Alexa trying to set a brightness whose value is not 0.
Example, this is successfully executed on board 2, sometimes only when board 1 is unplugged:
void alexa_change_hdmi(EspalexaDevice* d) {
    Serial.println("Executing");
    uint8_t brightness = d->getValue();
    Serial.println(brightness);
    doing more things....

Here, brightness is always printed as 0.
So, after I added board X to alexa and tested successfully, I added board Y to alexa. Board X receives both commands for X and Y most of the time. Vice versa if board Y is the only device on. This is not intended by design. I would like to control them separately(preferably through the use of one alexa device).
I'm not sure if this (^) is related to the inability of Alexa to tell the two distinct board apart. I'm not sure why i'm not getting a brightness level, I would like to use it to make decisions, example;
if (brightness == '2.55') {
unsigned int irSignal[] = {9000, 4450, 600, 550, 550, 550, 600, 550, 550, 550, 600, 500, 600, 550, 550, 600, 550, 550, 600, 1650, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1650, 600, 1650, 550, 1700, 550, 550, 600, 550, 550, 1700, 550, 550, 600, 500, 600, 550, 550, 600, 550, 550, 600, 1650, 550, 1700, 550, 550, 600, 1650, 550, 1700, 550, 1700, 550, 1700, 550}; // NEC FF906F
irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
}

Has anyone seen this issue integrating several ESP32 devices with one Amazon Echo? Has anyone ever gotten brightness to successfully pass into the function that alexa triggers?
EDIT*
After doing some more testing it appears that ESPALEXAWITHASYNCWEBSERVER is causing Alexa to not be able to differentiate between the distinct boards. This implies that if you want to use more than one device with this library, you cannot use the async example.
As a side effect, brightness always returns 0 when not using the async library, meaning you can really only use this library to control on and off state, not brightness, if you have more than one ESP device. ASYNC example correctly returns brightness, all other examples return 0, no matter what you set the brightness to.

Try this library , in past i have used 5 device at a time
fauxmoesp

Faumo is not working for me, unable to detect devices


text:
NTP rollover-safe design with ESP8266 (Curiosity)
The Arduino NTP implementation is rather naive in some respects. It basically just grabs the time in seconds from the raw packet, and then converts it to Unix time via subtraction. How would it be possible to create an implementation that is safe from at least this next NTP rollover (due in 2036)? I'd rather not design something that might suddenly fail in strange ways in a decade or two when I have forgotten why it might do so (but it's not horribly important if it's not easily fixed).
If it can make it to 2100, I'd have larger problems (the RTC would crap itself), so just this rollover is fine.
The existing implementation (https://github.com/arduino-libraries/NTPClient/blob/master/NTPClient.cpp):

unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;

this->_currentEpoc = secsSince1900 - SEVENZYYEARS;

This implementation is perfectly fine. The calculations are done with
unsigned numbers, so they are naturally rollover safe. The day NTP time
rolls over, secsSince1900 will become a very small number, and
subtracting SEVENZYYEARS from it will cause an extra roll over. Owing
to the rules of modular arithmetics, these two rollovers compensate and
you are guaranteed to get the correct result modulo
232 s.
In the end, you get a Unix time as an unsigned 32-bit integer. Unix time
is traditionally signed, which makes the 32-bit representation roll over
in January 2038. The authors of this library have instead chosen to
represent it as an unsigned number, which means it will roll over in
February 2106.

Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

@RDragonrydr: carry propagates from low to high in addition/subtraction.  The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result.  Same for left shift, or the low N bits of an N x N multiply.  See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

I knew that, but I didn't know that the Arduino's method would manage to handle the rollover in NTP, not quite accidentally, but without needing to detect it per se. I figured that, since the time is an absolute delta past a certain start date, that any rollover would HAVE to give the wrong time once it occurred.


text:
Arduino DUE- flash space for user
I need for my project to save only 32bit in non-volatile storage.
What is the easiest/cheapest way to do that in Arduino DUE?
ArduinoDUE is Atmel SAM3X8E so according to the attached table (from Atmel DS)

In the chip I have 4KB of NFC SRAM. NFC = Nand Flash Controller, so I have 4KB of internal flash in the internal SRAM?
Thanks,

You'll probably need to "walk" the value through at least one erase block worth of program flash.  Beware some flash architectures with ECC do not permit overwriting unprogrammed bits in a partially programmed word; which may be several bytes long.  So it's best if you can define the erase value as "unused" and simply search until you find the last unerased value, appending any new values on the end.

It looks like there's at least one library out there to emulate EEPROM functionality in the DUE using Flash.
https://github.com/sebnil/DueFlashStorage

ROM is not good for me. I need to be able to READ and WRITE, but the data should survive power loss

you misunderstand what is meant by EEPROM... it is READ / WRITE


text:
Using Serial.write() to send a uint32_t send one byte x4 or send 4 bytes x1
In the IRremote library, IR signals are decoded and held in results.value.  My project uses the NEC protocol which is 32 bits, so the IR code will always be 4 bytes.

uint32_t dCodedIR;
//
//  code exists here that we can ignore
//
dCodedIR = results.value

This decoded signal is then sent out the serial port to a second MCU which will be waiting for incoming data:
while (!Serial.available())  {
}

After this, there will ideally be a complete code of 4 bytes waiting in the FIFO. I will allow for times when < 4 bytes are ready (check for more, timed out? NO:loop   YES:reset), but this should rarely happen. So I want to optimize the sending code so that the receiver has the best chance of avoiding split groups. In theory, is it better to write as single bytes and repeat 4 times, or make a 4-byte array to send once?
Serial.write(dCodedIR & 255);
Serial.write((dCodedIR >> 8) & 255);
Serial.write((dCodedIR >> 16) & 255);
Serial.write((dCodedIR >> 24) & 255);

or
byte sendBuf[4];
//
//
sendBuf[3] = (byte) dCodedIR & 255;
sendBuf[2] = (byte) (dCodedIR >> 8) & 255;
sendBuf[1] = (byte) (dCodedIR >> 16) & 255;
sendBuf[0] = (byte) (dCodedIR >> 24) & 255;
Serial.write(sendBuf, 4);

(Since there will be plenty of storage space for the code, with performance being the priority, I decided against using for loops because updating an index, testing it, and looping would seem to add overhead.)

Unless you are using very high baud rates, (at least higher than
115.2 kb/s), it should make no difference.
The reason is that either version of your code should run faster than
the UART. Serial.write() doesn't wait for the bytes to be sent out the
wire. Instead, it just stores those bytes in a ring buffer that belongs
to the HardwareSerial library. When the UART is ready to accept an
outbound byte, it triggers an interrupt. The corresponding ISR takes one
byte from the ring buffer and handles it to the UART. Since the UART
itself is double-buffered, all this happens while the previous byte is
being sent.
The end result is that, with either version of your code, you end up
with a continuous byte stream. The start bit of the second byte comes
right after the stop bit of the first byte, and so on. The stream
doesn't pause until the full message is sent. That is, unless you have
somewhere in your program overly long critical sections that can impose
excessive latency to the whole process.
Side note: if your MCU is little endian (most Arduinos are), you
could also avoid one copy and just do
Serial.write((byte *) &dCodedIR, 4);

Addendum: The details may depend on the MCU you are using. On an
Uno, or similar AVR-based boards, the UART has no knowledge of the
software ring buffer. It rises the UDRE0 (data register empty) flag
whenever it is ready to accept an outbound byte in its sender data
register. When there is data in the buffer, the software enables the
data register empty interrupt, which is tied to the UDRE0 flag.

Re the interrupt handling: see expanded answer. Re Serial.available(): I don't know how the timing of your receiving code works.


text:
Can you put Ardupilot on any flight controller?
Some FC's say that they support cleanflight and have no mention of Ardupilot. Is this just because its what's recommended or because it's all that works?

Probably the Ardupilot is based on Atmel MCU, like Arduino. The newest flight controller are based on STM32F4 and STM32F7.

This is a usage question which should be asked on the support forum for the software in question, it is not an electronic design question fitting here.  If you were personally trying to port the software and had a very specific question about a difficulty in your attempt to match a particular capability with a different MCU's peripherals, that might be on topic if well supported with the details of the problem.

There are pre-built binaries for many flight controllers.
http://firmware.ardupilot.org/ lists out the different ardupilot builds (arducopter, arduplane, etc.) and by clicking on them , you can see the different versions, then the different builds per version.
This document goes into more detail on the file structure they use for pre-built binaries.


text:
Program Arduino Mega Adk on linux
for a project my supervisor gave me a Arduino Mega ADK board (https://store.arduino.cc/arduino-mega-adk-rev3) and the usb-cable.
I only programmed a Atmega32 8 bit controller on linux ubuntu. I have no possibility to use windows (i heard it's easy to program the arduino using atmel studio). I can only use ubuntu 16.04. Is there a convient way to program the Arduino like a microcontroller?
I'm not aloud to use the highlevel Arduino libraries. I have to do a cascaded control for a dc-motor and sensor-fusion.
Thanks in advance.
If it's offtopic, could you transfer me to a suitable board?

You can still use the Arduino bootloader even if you don't use the Arduino libraries and development flow.  Easiest approach is to install the Arduino IDE, put it in verbose mode, use it once, and copy out the avrdude command line it generates, then adapt that to your own project.  You can use their avr-gcc install, too.

You can use Eclipse, along with AVR-GCC and AVRDude and an AVR plug-in for Eclipse. Debugging may be a little painful since you don't have all the tools that Atmel Studio gives you. I'd question your employer if you aren't allowed to use the best (free) tools even if they do run on Windows.
Really all you need is the avr-gcc and avrdude to write software for it, you can use any text editor (although it isn't really convienent).  Seems like they are pigeon-holing you into a difficult job. Good luck.

the thing is that unfortunately no windows computer is available

i can use the atmega libraries i think

Eclipse runs on Linux Ubuntu, as well as all the other tools I linked to...

yes i know, i just explained the the supervisors behaviour. Thank you, i'll take a look at it :)


text:
Rotary encoder using interrupt
This is my first time working with a rotary encoder and interrupts.  I am using a Pro Micro which has interrupt pins at pin0 and pin1.  The code below works as expected.
My question: do I need to use an interrupt pin for PinB as well, or can I use any digital pin?
It does not seem to work when I choose PinB = 9, for example.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

// Used for generating interrupts using CLK signal
const int PinA = 0;

// Used for reading DT signal
const int PinB = 1;

// Used for the push button switch
const int PinSW = 8;

// Keep track of last rotary value
int lastCount = 50;

// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 50;

// ------------------------------------------------------------------
// INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT
// ------------------------------------------------------------------

void isr ()  {
  static unsigned long lastInterruptTime = 0;
  unsigned long interruptTime = millis();

  // If interrupts come faster than 5ms, assume it's a bounce and ignore
  if (interruptTime - lastInterruptTime > 5) {
    if (digitalRead(PinB) == LOW)
    {
      virtualPosition-- ; // Could be -5 or -10
    }
    else {
      virtualPosition++ ; // Could be +5 or +10
    }

    // Restrict value from 0 to +100
    //virtualPosition = min(100, max(0, virtualPosition));

  }
  // Keep track of when we were here last (no more than every 5ms)
  lastInterruptTime = interruptTime;
}

// ------------------------------------------------------------------
// SETUP    SETUP    SETUP    SETUP    SETUP    SETUP    SETUP
// ------------------------------------------------------------------
void setup() {
  // Just whilst we debug, view output on serial monitor
  //  Serial.begin(9600);

  lcd.init();                      // initialize the lcd

  lcd.backlight();

  // Rotary pulses are INPUTs
  pinMode(PinA, INPUT);
  pinMode(PinB, INPUT);

  // Switch is floating so use the in-built PULLUP so we don't need a resistor
  pinMode(PinSW, INPUT_PULLUP);

  // Attach the routine to service the interrupts
  attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);

}

// ------------------------------------------------------------------
// MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP
// ------------------------------------------------------------------
void loop() {

  // Is someone pressing the rotary switch?
  if ((!digitalRead(PinSW))) {
    virtualPosition = 50;
    while (!digitalRead(PinSW))
      delay(10);
    //    Serial.println("Reset");
  }

  // If the current rotary switch position has changed then update everything
  if (virtualPosition != lastCount) {

    lcd.clear();
    lcd.print(virtualPosition);

    // Keep track of this new value
    lastCount = virtualPosition ;
  }

  //delay(100);
}

think about how the code works now, with just a single interrupt ... then think about what would happen if you had interrupt on both data pins of the encoder ... one thing to note is that you would have twice as many interupts per revolution of the encoder, but they would not be symmerical if you are interrupting on only one edge ... i am assuming that you are using a quadrature encoder

attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW); I think you mean FALLING, otherwise the ISR will continuously get called when the pin is LOW, leaving barely any CPU cycles for you main code.

Let me rephrase:  The code above works perfectly fine as is (yes it could be optimized per @Gerben).  It uses a single interrupt on PinA.  When I try to assign PinB to any other physical digital pin (other than Pin1), it no longer works.  I cannot understand why.

I don't see why it won't work. There is nothing special about pins 1 and 9. 1 indeed is a interrupt pin, but you don't use that here. Pretty strange.

How would I use this as a subroutine instead of a main loop?  For example, setting a max val, then running another sub until max val is hit.  I'd assume we'd use another input for the break trigger.

Found my error... on the ProMicro, the pins are not arranged 0, 1, 2, 3, 4, 5 etc instead they arranged 1, 0, 2, 3, 4, 5 etc... On the board I misread TXO and RXI as TX0 and RX1 and just didn't notice it on my pinout sheet.... so I had D0 and D1 swapped. All works well now. Learning more everyday! I appreciate your time...


text:
Restart variable every day
How can I restart a variable every day? I have an RTC1307. The problem is that I can't use an alarm event because the Arduino will be shut down during that hour. So I need a more reliable solution.
Will this work? A date could be an integer?
#include <EEPROM.h>
#include "RTClib.h"

int  lastDay;
int EE_ADDR = 0;
int totalLitres;

void setup() {
  EEPROM.get(EE_ADDR, lastDay);
}

void loop() {
DateTime now;
  if (now.day() != lastDay) // this happens exactly once a day.
    totalLitres = 0; // reset the accumulated volume

  lastDay = now.day();
}

Why does your Arduino shut down? And is your intention to prevent the shut down from happening?

I still don't understand the problem ... if the Arduino is shut down, it will restart and the variable gets its initial value again.

Ya, you gotta be a little more clear.   You want to zero a variable every day but there is a chance the arduino is not running when the new day starts?   One option would be to store a "lastResetDay" variable in EEPROM.  Then on startup, and periodically in your code, you will pull them variable from EEPROM, check it against the current day value from the RTC, if they match-do nothing. If they dont match then zero the flow variable and strore the current day back in EEPROM.

think about what will happen if the day changes right after the if statement compares the two values

@jsotola: Nothing special will happen: now.day() does not change by itself. DateTime is nothing but a container for timestamp items (year, month, day, hours, minutes and seconds). If you don't explicitly initialize it, is gets default-initialized to 2000-01-01T00:00:00 (the default used to be 2106-02-06T06:28:16, until this pull request got accepted).

Here are a few suggestions:

Since your RTC has some non-volatile RAM (NVRAM) onboard, you could
use it instead of the EEPROM. This way you will not have to worry
about the EEPROM endurance.
If there is the possibility that the device gets power-cycled within a
single day, you probably want it to preserve the liter count. This can
be achieved by periodically saving this count to the NVRAM, and
restoring it at startup. You can save often, as you don't have
endurance limits.
If the device is started after a full month of being off, if should
notice some days have passed, even it the day number is the same as
when it was turned off. Instead of saving just the day number, I would
store the total number of days elapsed since 2000 Jan 1.

Untested implementation of the above suggestions:
#include <Wire.h>
#include <RTClib.h>

const uint32_t NVRAM_UPDATE_PERIOD = 10000;  // 10 seconds

/* Addresses for data items saved in the RTC's NVRAM. */
const uint8_t ADDRESS_LITERS    = 0x00;
const uint8_t ADDRESS_RESET_DAY = 0x02;

RTC_DS1307 rtc;
uint16_t liters;
uint16_t reset_day;

/*
 * If `liters' has not been reset today, reset it now and update both
 * the RAM and NVRAM copies of `reset_day'.
 */
void reset_liters_if_needed()
{
    uint16_t current_day = rtc.now().secondstime() / 86400;
    if (current_day > reset_day) {
        liters = 0;
        reset_day = current_day;
        rtc.writenvram(ADDRESS_RESET_DAY,
                (uint8_t *) &reset_day, sizeof reset_day);
    }
}

void setup()
{
    /* Pull the initial `liters' and `rest_day' from NVRAM. */
    rtc.begin();
    rtc.readnvram((uint8_t *) &liters, sizeof liters,
            ADDRESS_LITERS);
    rtc.readnvram((uint8_t *) &reset_day, sizeof reset_day,
            ADDRESS_RESET_DAY);
    reset_liters_if_needed();
}

void loop()
{
    /* Periodically update the NVRAM. */
    static uint32_t last_nvram_update;
    if (millis() - last_nvram_update >= NVRAM_UPDATE_PERIOD) {
        reset_liters_if_needed();
        rtc.writenvram(ADDRESS_LITERS,
                (uint8_t *) &liters, sizeof liters);
    }
}

For extra safety you may want to add a large capacitor in order to keep
the Arduino powered for a few milliseconds after being unplugged. And a
circuit that detects when it gets unplugged in order to immediately save
the data and stop accessing the NVRAM before it gets out of juice. This
kind of trick has already been discussed here, you should be able to
find the relevant questions and answers.

@santilococo: Just beware that a float is 4 bytes. If you store liters as a float at address 0, you can put reset_day at address 4, but not at address 2.

@santilococo: No, sizeof(float) is 4.


text:
Increasing range of a DC-offset signal (software)
I am trying to read a signal with a DC offset of 511 (as seen by the ADC). The signal's tiny with regards to the offset, and I'm feeding it to a library that does a Fourier transform on it. It comes from a 3.5mm audio jack with AC coupling and the offset so I can see the full signal.
How may I increase the range of the signal? I am thinking something like the input signal is (490-530) and I want an output of (400-630) or something (numbers solely for example). The issue is that I still need the resulting signal to be centered around 511 AND I don't know the exact amplitude of the input (since it varies based on volume and particular audio going in at the moment).
I can assume that the volume of the audio input is relatively fixed (I need to be able to adjust this gain later, but I'm assuming the volume will be constant at some value per time I'm running the project), so I don't need envelope-following or something, but I'm not sure how to do this even so.

You need to add an op-amp to increase the signal gain before you feed it into the ADC.

This sounds like an XY problem to me. Why do you want to increase the signal range? What problem do you think you will solve by doing this?

I can't feasibly modify the hardware for this project. I need the FFT to register sounds without the audio source being turned to eardrum-rupturing levels, so it needs to be in software. I'm looking for some sort of filter that I can run on the array of samples that, say, doubles the offset each value has from the center. I would actually need it to do a smoother mapping (an example in a non-offset design would be values 0-30 become 0-100, so 15 is now 50. I could handle that, but not with the offset, though the same general idea applies). Would this do anything too weird to the FFT result?

You can't magic more resolution out of thin air (well, you can, but it slows down your sampling - you would "oversample" and average a number of sequential samples).
Instead you need to boost your signal before it gets to the ADC using an op-amp.  The simplest circuit (which also inverts the signal, but you don't really care about that I suspect) is:

simulate this circuit – Schematic created using CircuitLab
That circuit will both invert the signal (if you care, just do a little bit of maths in your program to flip the signal, but for FFT you don't really care) and double the amplitude around the mid-point. The doubling is controlled by the ratio of R1 to R2 (20000:10000 = 2:1 = doubled). The mid-point offset is created by R3/R4 - you don't need to manually add your own offset.

This was my first idea, but I'm trying to fix up a project I've already built that does not have room to add more components. I also have no op-amps on hand. As a result, I'm looking for a way to fudge the input into a larger numeric range via some sort of mapping.


text:
Callback functions when using a class
This question is somewhat similar to How to pass non-static class member to callback?, but there are a few differences, especially since a lot of my uses have "interesting" additional complexities. I'd like to understand better my options in using them, since I have not gained enough understanding from other answers (and I need to write both the callback and the function that calls it).
I have a number of libraries that produce "events" that I'd like to be able to write separate classes or functions to respond to (so I don't need to customize every library every time I develop something). The annoying part is that I've long-since discovered the this pointer that's hidden in class method calls, which prevents me from passing currentgui.leftbutton as a function to menu.leftbuttonpressed(void (*callbackfuncptr)(void)).
I'm also using the ESP8266 web server library, which needs a callback in the context of the server object that can call the server as a global to actually get the data sent to it! (Unless the server passes its own this as a parameter to the callback, which I don't know since the documentation consists almost solely of a small number of "examples" which don't show the majority of the actual features of the web server, rather than a real explanation.)
I could use some variant of a pointer to a class method, but the syntax for that is eye-gouging and I'm using more than one class to provide callbacks to (especially for the task scheduler), so this would require customizing the library to handle pointers to every class I use again. I can't use polymorphism, either, since some classes contain multiple scheduler callbacks to be done on different times/conditions.
How do I handle these callbacks? My current method is to write a function that wraps the method's function, but that relies on a specific instance of that method, so it can't be reused. It's also really awkward since I'm now dealing with multiple functions/methods that are now very similar.
I would also like to be able to have a class, that when passed a web server object, registers itself as a callback to a particular page event (I want to write a network connection manager similar to the WiFiManager library, but with the ability to integrate with an existing webpage. I have all the code, but it currently can't be nicely integrated into a standalone class because of this issue). It needs to store a pointer to the server object to get the data once the callback's called, but it also needs to be attached to the callback of the class that holds that particular pointer AND the other handler functions once the data's retrieved.
There is already a library that does something similar, but I can't figure out at all how this works, since I was under the impression that this is not possible. Can someone help me understand how the following class operates?
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/src

Can you clarify ... if the server needs a callback, and you provide a callback, are you expecting to access server variables or functions? If so, your callback would need to be derived from the server class would it not? Can someone help me understand how the following class operates - this is rather a broad question. A quick glance seems to show it is using lambda functions and templates, but apart from that I think you will need to narrow down what it is you want to know.

the ESP8266HTTPUpdateServer registers a lambda function as server->on handler. a lambda function is not a member of a class

The Object-Oriented Programming (OOP) way of doing this is to use virtual member functions and subclassing. This allows access to the member data. A callback will require the object as a parameter but will not have access to private or protected member data or functions.

@NickGammon, It uses normal functions, not ones that derive from the class. They call the same instance of the class' member functions to get data back. I'd like to know how to get a class I wrote (nothing special about it, but how do I connect it?) to register itself as a callback so IT gets data and I don't need a bunch of disconnected non-class functions around.

@Juraj, I begin to think that might be it. Can you post an answer explaining more and how exactly they did that? If the function is inline but not part of the class, that would work, I think... But how do they still get access to class members in it?

@MikaelPatel I've done that for my menuing system, but it doesn't really apply here? I can only access inherited members if they exist in the parent, so I can't easily do more than one entry point (let alone name them all well) for subclasses, and at very minimum the web server won't take polymorphic child classes, since it just accepts vanilla callback functions instead. Friend functions are also rather a problem.

The ESP8266WebServer uses callback functions to handle HTTP request by your code. This callback functions can't be members of a class. But you can use anonymous functions to implement this callbacks. And if you like you can implement them as 'redirects' to functions of your objects.
server.on("/leftbutton", []() {
  currentgui.leftbutton(server);
}

Note: this anonymous functions are called lambda functions and they can do some tricks with parameters too

Bonus Internet points for the link. Looks like I need to figure out how those capture clauses work, though, since it looks like that example uses them...
Thanks!

I have since run into issues doing this with my own callback-accepting functions, as it would appear that lambdas have a compiler-defined type. How do I write callback-handling code that can take a lambda?

They call the same instance of the class' member functions to get data back.

Yes, but if they eventually call the class' member function to get data, other than static data, then the need to know what instance of the class to get the data from.

I'd like to know how to get a class I wrote (nothing special about it, but how do I connect it?) to register itself as a callback so IT gets data and I don't need a bunch of disconnected non-class functions around

If function X (not a member of this class) needs to be able to access the data from instance A or instance B then clearly X needs to know which instance it is looking at (the this pointer). This is not a syntax thing, you need to have a way of solving this problem.
In fact, when you say "a class I wrote" then that would also have instance data (its own this) so now you are trying to connect two instances of two classes.
How many server objects do you have? If just one in this particular case you might be able to fudge your way around it by storing its this somewhere, or making some glue routines.

Yes, but if they eventually call the class' member function to get data, other than static data, then the need to know what instance of the class to get the data from. -- yes, that's the problem. I need to store the this per-instance of MY class, but also connect a member of my class TO its callback, so the callback gets my instance that can access ITS instance!
Connecting two instances of two classes -- yes, exactly. There should be a way to do this, right? Someone said something about lambda functions being used in the existing example, but I don't understand what they did.

A lambda function is just an anonymous function. That is, you can put a lambda function "inline" instead of having to name a function declared elsewhere. Other than that, they don't help solve this problem. I think you need to make up an example and edit that into your question. And to be honest I think this is a pure C++ problem, which might be better asked at Stack Overflow. The fact that it is an Arduino is irrelevant to the issue of what you are trying to do with classes and instances of classes.

That might be a fair point. I was uncertain, though, if there might be some extra method that Arduino happened to use or implement that might make this easier.

@RDragonrydr Arduino just uses g++ - the industry-standard compiler (or one of them, anyway). There is no special "Arduino" functionality that you can call on.

I was thinking that maybe they overloaded the callback registering function, or some other method that would simplify it. I'm just using the lambdas now, though...


text:
ESP8266-01 Does not receive or respond to AT Commands
I have an ESP8266 wifi module that I want to test, to use it later. I uploaded the original Espressif AT firmware "ESP8266 AT Bin V1.7.0" from: https://www.espressif.com/en/support/download/at.
FTDI seems to be connected to the ESP all properly, since firmware upload successfully finished and prompted:

Leaving...
  Hard resetting via RTS pin...

I use the Arduino IDE's serial monitor at 115200 baud rate set to "both NL & CR", to send the commandS "AT", "AT+GMR" e.t.c.
No response ever returns. I have no idea about what am I doing wrong, or why esptool.py can connect to the board smoothly but there is a problem with sending AT commands to it.
Thanks for all suggestions in advance. Please comment if you need any other information about the issue.
P.S: I have two modules bought at different times. Both of them wont work with AT commands.

Try 76800 baud rate - A couple of my esp boards needed this - You can change the rate permanently if needed

how did you flash it? the bin on the Espressif download is for 2MB module (yes, strange). Flash Download Tool can upload it right to 4 MB module, but esptool can't. and how do you power the module?


text:
Sending multi-byte data over I2C between different processors
I have been attempting to read data from an ATTINY84 via an ESP8266. Both are programmed via the Arduino IDE, though as PlatformIO is a proxy for that, I'm not certain what version of the ATTINY core is in use.
I have both devices connected to the I2C bus, with the Arduino as a slave.
The ESP sends a code requesting a particular type of data, then calls Wire.requestFrom() to get 8 bytes of data. I am concerned over both my implementation and about potential endian-ness issues (even if it should turn out not to be an issue on these two particular devices, I'd like to know my future options).
The ATTINY code is a complex function that is called when there is a request (and the right option code, but that's probably not very relevant). It writes eight bytes using Wire.write after uncompressing them from the relevant arrays. (I have a lot of ADC data that technically should not fit in RAM.)
Since this is is a callback function or possibly an interrupt, do I need to be concerned about data corruption if the code is too slow to write the values onto the bus? I have to imagine it's trying to read them even as it writes. I can also provide code snippets if it would help.

I am also unsure if I am running into Endian-ness issues by using bitshift to grab the 2 and 8 bits from the ADC return value. Would this always give me the correct values, or does the C++ compiler (as I assume it does not) simply refuse to handle differences between the data order?
Specifically, if I shift a uint16_t (or any non-trivial datatype) right by 8 bits, and mask out the bottom 8 with &0xFF, do I always get the second-least-significant (in this particular case, high) byte, or can the compiler produce alternate outputs based on byte order?
Does Arduino have an equivalent of network byte order (or does Wire automatically do so for its overrides of the functions) that I can get around this potential issue with?

There seems to be multiple questions in what you are asking. Here I try
to answer specifically this one:

if I shift a uint16_t (or any non-trivial datatype) right by 8 bits,
  and mask out the bottom 8 with &0xFF, do I always get the
  second-least-significant (in this particular case, high) byte, or can
  the compiler produce alternate outputs based on byte order?

Short answer: yes, you get the second-least-significant byte,
irrespective of the platform's native endianness.
Now, I'll expand on this answer by showing the different ways you
can convert an uint16_t to a sequence of bytes, and the implications
on the byte order.
If you want to control the endianness, and you want your code to work
independently of the native endianness of the platform, then bit
shifting is the way to go. Let's assume you want to convert this:
uint16_t data;

into this:
uint8_t bytes[2];

You can do it this way in order to get the least significant byte first:
bytes[0] = data >> 0;  // least significant byte
bytes[1] = data >> 8;  // most significant byte

Or you can instead do the assignments the other way around
(data >> 8 goes to bytes[0]...) if you want MSB first. Note that
there is no point in masking, as the assignment does it implicitly.
In contrast, if you wanted to put the bytes in native endianness (the
endianness of the platform), the traditional way to do it is to cast the
address of the number to a pointer to bytes, then read from this
pointer:
bytes[0] = ((uint8_t *) &data)[0];  // first byte
bytes[1] = ((uint8_t *) &data)[1];  // last byte

You can swap the indices on one side of the assignments if you want to
instead reverse the byte order. But note that this kind of casting is
now frowned upon, as it violates aliasing rules. A common alternative is
to have the number and the byte array share the memory within an
union:
union {
    uint16_t data;
    uint8_t bytes[2];
} x = { .data = some_16_bit_value };
do_something_with(x.bytes[0]);  // use first byte
do_something_with(x.bytes[1]);  // use second byte

These are the main byte-splitting idioms you may come across. If your
purpose is to have an endianness that you control and is independent of
the platform, then stick with the first option: the old good bit
shifting.

That answers most of what I wanted, although the part about pointer-casting doesn't have the results I was hoping to hear. What happens if I send a uint32_t, for example, through Wire.write() (or an equivalent function) directly, though? Does that send in native byte order, or does Wire handle that automatically? I'd like to avoid bit-shifting for some of my more complex messages if possible.

I kinda had three sub-questions, which I'll admit kinda doesn't help matters, but they are also somewhat related. One was what the bit-shifting actually does, the second is if the Wire library handles endian-ness discrepancies on its own, and the third (which is a bit less related) is exactly how/when data is written or requested when the master requests data -- is there a chance of the slave not having it ready in time or writing too slowly (that would cause some later section of the message to be wrong while the first was correct).

@RDragonrydr: Wire.write() doesn't handle endianness. It sends either a single byte (Wire.write(value) sends only the LSB of value) or a byte array when called as Wire.write(const uint8_t *buffer, size_t length).


text:
How can I receive signal from remote control using tcrt5000 sensor module
how can I use tcrt5000 sensor module instead of TSOP31238 (TSOP1738) IR receiver to get signal from remote control? I want to create remote control for my PC to navigate through my slide shows. Thanks in advance.

why do you want to use the tcrt5000? ... how is the Arduino used in your project?

@jsotola, because I have only this sensor :) and haven't other

what are you using for remote control?

@jsotola usual ir remote control

there is no such thing as "usual ir remote control" ... there are differences between brands in the way that keypresses are encoded

The TCRT5000 and the TSOP31238 are very different. The TCRT5000 is actually a reflective distance sensor. It has an IR LED and a simple IR phototransistor, not more. The TSOP31238 in contrast is meant to receive data from IR remotes. IR remotes work with modulation of IR light. The IR LED is pulsed with a frequency of 38kHz (in the case of the TSOP31238). This frequency is modulated with the actual data, meaning there are different time lengths were there is no IR signal and where there is a 38kHz IR signal.
The TSOP31238 detects the IR light with a phototransistor, like the TCRT5000 has. But then the signal is processed with an amplifier, a band pass to filter out all frequencies but the 38kHz and then demodulated, so that you don't see the 38kHz signal on the output, but only the pulse lengths.
The demodulation should actually be the least complex part to build yourself. That can be even done by code. But to get good results, you also need the other parts. You would have to build an amplifier circuit with an opamp. And would have to build the bandpass (for example with an LC element).
You can build these things yourself, but: The sensor, that you have, is not meant for receiving IR remote signals. The parts, that you would need to make the signal usable, will cost way more, than just buying a TSOP. Also it will be a lot easier and most likely better working (processing the signal from a phototransistor can be tedious). I suggest, that you buy a TSOP chip fitting to your remote control.

Thanks a lot for extended answer. In this case that I use many triggers in remote control maybe I agree with you. So if  will used TSOP it simple way to make scratch and take a goal. I found another solution to use 2 pin IR led. link
link2

Yes, such things are possible. I didn't include it, because mostly these solutions will have a worse performance and are way more difficult to use (The standard libraries don't work for this). It may be suitable for you, especially, if you want to do it for the sake of learning. If you want to achieve a specific target, then I would advice to use the easiest solution.


text:
Program Arduino then Remove Atmega?
Can I program an Arduino and then remove the micro-controller from it and use it on a breadboard without reprogramming the micro-controller again?
My steps would be:

create my Arduino code.
I upload the compiled code to the board.
I remove the Ic and use it alone without the whole board.

Will the code be preserved on the microcontroller?

Yes. The programming of the arduino microcontroller sets the values inside the FLASH. This is non volatile memory and as such won't be erased by taking out the IC.
Please note that this is assuming a DIP package IC as these can be removed without force, heat and stress. A TQFP, and SMT packages like that, IC might get damaged by moving them in such a way. This doesn't mean it has to be erased, it is still non volatile storage, but the moving process is much more dangerous for the chip.
I would recommend connecting the whole arduino or if you really need the whole chip: designing your own board/circuit which allows you to program the chip without moving it around as this is really tedious and not worth the effort. Also moving the chip around is a ESD hazard.
Also please note that you'll need to add a clock source for the chip to work (most of the time). Or you'll need to enable an internal PLL. It will in any case require more effort on your part to make sure that the MCU can work. Therefore using the whole arduino board is preferable.

It's not a PLL, it's an RC oscillator.

Yes you can do it (as said by Tarick).
Note about clock:
Be sure to program it correctly:

Do not add a bootloader if you don't need one
Do not use an external oscillator if you don't have one on your new board! This is important, since if you remove it you will not be able to start or programming it again!

So, before you remove the IC, set this on your Arduino (I assume it is an ATMega328):

8MHz internal (leave external only if you have an oscillator in the new board!)
Bootloader: no

You will see that you do not have this options if you select a normal Arduino, since it already has an oscillator.
So you should use the board manager and add this:
https://github.com/MCUdude/MiniCore

As code is stored in the flash memory, your code won't erase until some unexpected happens. But the question might comes in whether your code will work properly or not when you remove microcontroller from arduino board and connect with breadboard.
As you are planning to remove the microcontroller, I am guessing you are using Arduino Uno atmega328 DIP package.
You need to do two things for the proper function of the microcontroller in the breadboard. There are other solutions exist. I always prefer this one as easy.

connect 16MHz crystal with 22p(two) capacitor with the corresponding crystal pin(pin 9 &10). The crystal circuit is straightforward. Searching google might help.
Pull the Reset Pin with VCC using a 10k resistor.

Don't forget 0.1uF caps on the VCC and AVCC pins to Gnd. AVCC must also have power on it, either direct to the VCC pin, or thru a filter (small inductor)


text:
How many sensors can be used in arduino for my project?
I'm doing a project on water purity finder. I dont know which arduino board can be used for the project. It uses upto 15 sensor modules excluded display, WiFi module. Can you tell me which board is better for my project.

It depends on what kind of sensors you're using. If you use I2C based sensors, and you can configure each with a separate I2C address, you could theoretically drive up to 128 of them. I say theoretically since you might not be able to push the signal across an I2C bus with that many devices on it. You could certainly manage 15 of them however.
The Mega 2560 has tons of I/O lines, so that might be a good choice if you need separate single lines for each sensor.
If you need a separate analog input for each of your sensors, you'd need to use an Arduino with at least 15 separate analog inputs. The Arduino Mega 2560 has 16, so that would work.
If you need 4 bit binary inputs, you'd need 4*15 or 60 inputs. The Mega 2560 has 54 digital inputs, which would not be enough for that situation.
You might also be able to use some sort of signal multiplexer and enable one sensor at a time.
Tell us which type of sensor you're using and we can provide more concrete help.


text:
Arduino MKRZero malfunctioned after trying to load a program
I have an Arduino MKRZero that I tried to load the following program into:
#include <FastLED.h>

#define NUM_LEDS 60
#define ledPin 4;

AudioFrequencyMeter meter;
CRGB leds[NUM_LEDS];

void setup() {
  Serial.begin(9600);
  meter.setBandwidth(70.00, 1500);
  meter.begin(A0, 45000);
  FastLED.addLeds<WS2812B, ledPin, RGB>(leds, NUM_LEDS);
}

void loop() {
  float frequency = meter.getFrequency();
  Serial.println(analogRead(A0));
}

After which, the Arduino IDE said:
"Couldn't find a Board on the selected port. Check that you have the correct port selected.  If it is correct, try pressing the board's reset button after initiating the upload."
And windows gave this message:

The board is dead for all I can tell. The light still comes on when I connect it to my computer and when press reset, windows makes the "you just plugged something in" sound, but it doesn't work. Can anyone tell me what happened?

Maybe the board was dead before you programmed it? The LED is probably fed by the 5V supply. As long as this supply is not shorted, the LED will shine, but not tell anything about the rest of the electronics.

@Huisman No, I used the board to only light up the led before including the bit with the frequency meter. That worked just fine.

Did you change the baud rate of the serial port you were using to communicate with the device?

@Tyler I don't know what that means. No, I didn't do anything like that.


text:
Use of progmem in ESP8266 vs AVR and also how to handle large dynamic strings
This is a somewhat tricky question dealing with implementation and best-practices of the ESP8266. I'd ideally hope that it's answered by people with in-depth knowledge on the problem.
As you are hopefully aware, the Arduino (AVR) platform requires the use of the PROGMEM or F() instructions to avoid copying all strings to RAM. The ESP8266 platform also provides a PROGMEM instruction, but is memory-mapped.
I thus have several questions about what the PROGMEM instruction actually does on the ESP8266.
For the next few questions, until otherwise marked, I am referring to character-array-style C strings, not the Arduino String type.

Storage of constant strings: If I were to declare a string (global, for now) on the ESP8266, would it be read from flash only when it's accessed, or will it always take up RAM (like it would on the AVR. Assume that in this case I do NOT declare it as PROGMEM; I wish to find out what the default behavior is on the ESP8266)?
Local Constant Strings: What happens with strings that are used inside a function? I am fairly sure that they ALSO exist in RAM, at least in AVR. Does the ESP8266 do this too, or does it (potentially) store it in flash until it is read (it is fine if it ends up inside a cache somewhere, as long as it can be evicted if needed)?
Use of String(F("mystring")): If I wrap a PROGMEM string in this manner, does this truly convert the string into a RAM-based string only when this line is reached, or does this for some reason initialize the String() early (and consume the RAM anyway)? Do the systems differ in this behavior?
If I define several instances of the above (as in, the identical wrapped string shown above appears several times, perhaps in different functions), do all of them point to the SAME F() instance (since they are identical) or does it get duplicated since it's part of code rather than a referenced variable? On ESP8266? On AVR?
On the ESP8266, I discovered that the server.on() function for the built-in webserver read F()'d constant strings just fine, but failed to work once the file grew beyond the size of the RAM. It was clearly stored correctly, but it could not be read. I thus conjecture that the method was making a local copy to RAM, even if the file was stored in Flash. There was also a on_P version that worked after that point (I believe I used PSTR rather than F at this point as well, since -- correct me if I am wrong -- the two are not compatible). Is this the real point of PROGMEM on ESP8266? That the data is only stored in Flash, but it also tells the function reading it to make as few copies as possible or chunk it?

I am also curious what happens with large strings that aren't constant. The web server can return data that was passed via querystring, for instance, which in my case can be quite large. If I copy that data to a string (and then into a function), does it pass the heap pointer directly, or does each String make a new copy? I am concerned about fragmentation or other fun ways of running out of RAM even if one copy should in theory fit.
Does doing something like bool myFunction(String &str){...} help? Some sort of way to actually ensure that it's the same string, rather than copying (and can I do String &myStr=server.arg(...) -- is a return value different from an assignment)? It's confusing for me, since strings are clearly passed by value, despite being a complex datatype with dynamic memory somewhere in there. So, did they override the assignment operator (and/or the one that handles reference passing, since I think there's more than one) to duplicate the string as pass-by-value of a basic type would normally do, or do they share pointers (and thus memory) as a class passed-by-value would normally do?

On the ESP8266 flash is a very special case. Because the ESP8266 itself does not have any flash, but instead uses an external SPI-connected flash chip, accessing it is not an easy or technically obvious operation.
Reading from the flash chip is slow. Very very slow (by comparison to reading RAM).  Because of this where possible certain things are copied into RAM. Also, there are different sections of RAM that are dedicated to different purposes.

dram0 - This is your "Data" RAM. It's where your variables and such are stored (80kB total).
iram1 - Instruction RAM. It's here that interrupt routines need to be stored for rapid execution (32kB).
icache - Instruction cache. 16kB of data that is cached when reading from the flash chip. Executed code usually gets copied here.

Normally when you execute code the block of code that the instructions you are executing are copied from flash into the icache memory block and then executed. This is reasonably fast (reasonably in that there may be brief delays while copying the data from flash, but fast when actually executing. I don't know how efficient the cache is, whether it's split into different blocks that are loaded in the background by the memory controller as needed, but it seems to be a pretty efficient system that is used in practice).
Because of this disassociation of the CPU and flash string constants, unless specified otherwise, will be copied into dram0 during startup. This makes it very fast and simple to get at the data. Anything that you don't specify as PROGMEM will get copied into dram0. Note that you don't get all 80kB of the RAM to play with since the SDK uses a portion of it. You only get about 50kB at most (station mode - softap mode will use more).
Now... what does PROGMEM do on the ESP8266 then?  Well, it adds an attribute to the definition that tells the linker to place the data in a specific section in flash (.irom.text.<filename>.<line>.<number>). This prevents it being copied into dram0 at startup.
So how do you get at it? That's where the *_P variants of the string functions (and certain overloaded functions in the Arduino core) come into play.
The whole of the flash chip is mapped (or can be, depending on register settings) into the ESP8266's memory map (address 0x40200000). Which means that it's possible to get directly at the data. However since this access doesn't go through the icache RAM block it's slow. Very very slow. About 12x slower by some accounts. Also because data can be in different locations within the chip the addresses of your string data can't be directly hard coded. There has to be some form of "it's over there" redirection when reading the data (for example if you use OTA updates you get two distinct blocks of flash where your code can be stored - the currently executing code and the previously executing version). The *_P variants of the string functions take that into account and look up where in flash the current code is located before reading from it.
So to summarise: Not using PROGMEM gives you fast access to your string data at the cost of RAM, and limits the size of the data you can use. Using PROGMEM removes the size restriction, doesn't use RAM, but is considerably slower.
To specifically answer your questions:

The string data gets copied to RAM at startup.
The string data gets copied to RAM at startup.
The string data gets loaded from flash (using *_P variants of functions) when the String object is constructed (RAM is allocated on the heap at that moment in time). The RAM is freed when the String object is destroyed (goes out of scope).
The compiler has recently had an update that will deduplicate constant PROGMEM strings.
As mentioned above *_P copies directly from flash and is slow, but has no size limitation.

That was very helpful. Annoying that it's not a Harvard system but has the same end effect... :D The one thing I'm still not sure on was when the web server read the PROGMEM'd web page without need for the _P function. But given that it has that option, I'd suspect it streams the data from flash for the latter, and the former makes a RAM copy first, which of course failed because the page is very large.

@RDragonrydr A function doesn't  have to have _P to read from flash - that's just a naming convention in the C library. The web server has multiple overloaded functions that accept different data types - one of which is a "flash string".

Yeah, that's what I had noticed. I figure it's a fair warning that they seem to have optimized the _P version, though. The other works, right up until you try to serve a really big page and it abruptly fails, probably due to an inability to allocate a buffer somewhere. I had to switch to the dedicated progmem version despite the compatibility because of that.

Does string de-duplication happen at all? I saw this (https://forum.arduino.cc/index.php?topic=194603.0) and wondered if that has been implemented for either system or if the "compiler changes" mentioned would have been added.

@RDragonrydr I have just run some tests and yes, it looks like it does now do string deduplication for const char *foo PROGMEM variables.  I just made a little sketch and with two differing strings ("this is foo" and "this is bar") they end up pointing to different locations. With both strings having "this is foo" in them they both point to the same address.


text:
Arduino encrypted Radio communication
Is there any way or library to communicate two Arduino devices with encrypted connection using modules NRF24L01 or "433Mhz RF" ? Similar encryption like CCMP in Wi-Fi network.

There is no answer at all.

Ups, the question, if this answers your question was added automatically. Your original was closed because it needs more focus. You asked the exact question again, so this question will also be closed

Please read both questions, and you will see the difference...

I have done so. Both question are exactly the same. Besides exchanging one "wireless" with "Radio" in the title. The rest is exactly the same.

Please compare.

New Question: Is there any way or library to communicate two Arduino devices with encrypted connection using modules NRF24L01 or "433Mhz RF" ? Similar encryption like CCMP in Wi-Fi network.
Old Question(updated, but it's already closed):What is the best way/library to communicate two Arduino devices with encrypted connection using modules NRF24L01 or "433Mhz RF" ?

When I google "Arduino encryption library" I find this about an AES library for example. Would that help you?

Ah, ok, now I'm seeing. You already edited your old question to replace the "best way", that was critisized in the comments.

you asked a yes/no question that has an answer of yes ... that seems kind of pointless to me

ESP-NOW offers an encrypted mode at a lower performance rate.

Communicating and Encryption are to completely separate things. How you communicate (with what device) has no relevance to encryption. True, there are devices that can themselves encrypt data, but they tend to be higher-end or geared towards a specific purpose (such as WiFi).
What you send is just data. What that data consists of is entirely up to you.  If you want your communications encrypted then send encrypted data before sending it and decrypt it after receiving it.
Of course, you have to then consider such things as sharing of keys, etc.
There are numerous ways of encrypting data, but one of the easiest to implement on Arduino is AES, for which there is a library here.


text:
how to get serial data to wait until a certain length is reached
I have a code that loops through 2 different serial inputs on the arduino mega, and sends them to serial constantly:
int RFIDResetPin = 13;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);
}

void loop() {

  char tagString1[13];
  int index = 0;
  boolean reading1 = false;
  boolean reading2 = false;
  ///////////////////////////////////////
  //this reads from the reader installed
  //on serial1, which is pin 19
  //////////////////////////////////////
  while (Serial1.available() > 0) {

    int readByte1 = Serial1.read(); //read next available byte

    if (readByte1 == 2) reading1 = true;
    if (readByte1 == 3) reading1 = false;

    if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
      tagString1[index] = readByte1;
      index++;
    }
  }
  Serial.println(String("Reader 7: ") + tagString1); //the tag itself

delay(1);
  clearTag(tagString1); //Clear the char of all value
  resetReader(); //reset the RFID reader
  //////////////////////////////////////////////////
  // This bit reads from serial2, located on pin 17
  /////////////////////////////////////////////////
  while (Serial2.available() > 0) {

    int readByte2 = Serial2.read();

    if (readByte2 == 2) reading2 = true;
    if (readByte2 == 3) reading2 = false;

    if (reading2 && readByte2 != 2 && readByte2 != 10 && readByte2 != 13) {
      tagString1[index] = readByte2;
      index++;
    }
  }
  Serial.println(String("Reader 8: ") + tagString1);

  clearTag(tagString1);
  resetReader();
}

void resetReader() {
  ///////////////////////////////////
  //Reset the RFID reader to read again.
  ///////////////////////////////////
  digitalWrite(RFIDResetPin, LOW);
  digitalWrite(RFIDResetPin, HIGH);
  delay(150);
}

void clearTag(char one[]) {
  ///////////////////////////////////
  //clear the char array by filling with null – ASCII 0
  //Will think same tag has been read otherwise
  ///////////////////////////////////
  for (int i = 0; i < strlen(one); i++) {
    one[i] = 0;
  }
}

when not scanning anything, the serial monitor outputs this:
Reader 1:
Reader 2:
Reader 1:
Reader 2:

When I scan a tag, lets say on reader 1, I get this:
Reader 1: 000004f5
Reader 2:
Reader 1: 000004f5
Reader 2:

it is not possible to scan more than a single scanner at a time. Is it possible to get the first line to wait until a certain number of characters have been scanned (indicating a tag has been scanned), and then output to the serial monitor?After that initial run, the code will loop as I showed above. any help is appreciated.

Your dcode doesn't match your output (e.g. "Reader 7: ") At 9600 baud, you could have lots of time between characters and do simultaneous reads. Try reading the bytes from the separate ports into separate buffers bytewise, and then only acting when you fill up a buffer.

I've tried that in the past, the problem is that I don't get any output at all, including the Reader names. I want them to appear at all times, even when there is no tag. I only want the first line to wait until a tag has been scanned

It looks like index is shared between the tags, and you do a 150ms reset cycle and clear each cycle, Per Bra1n's answer, do consider a state machine, and maybe use a index1 and index2 to track the number of bytes you've read on each, and separate the reporting into something conditional on having a "certain number of characters have been scanned"

@jsotola I have no problem receiving from multiple serial ports at once (or functionally at once), as I explained in the question.  I currently have 8 of these system working properly together. I just need this modification on the first one, to initiate certain functions in a different code. I appreciate the thought.

@daveX that definitely seems like something worth investigating, thank you

So it works for 8 readers?  It looks like if you try to read more readers per loop(), index could go well above 13 and do something ugly.  Maybe clear index before the while loops?

sorry for the late reply! It's not that it works for 8 readers, on the arduino mega there is a max of 4 com ports (not including software enabled ports). on each arduino, I am running the code above, with different reader numbers. eg arduino 1 has readers 1 and 2, arduino 2 has readers 3 and 4. thankfully, I was able to solve my problem using a more downstream method. this prints to a MATLAB code, and I worked it out over there

I would use a programming concept called a state machine. For example an integer variable called State could be used to track the current status which could for example be WAITING_FOR_DATA or RECEIVING_DATA or DATA_COMPLETE and only print when DATA_COMPLETE. I'm sure there are plenty of examples you could find with an appropriate search.

this sounds like a good idea, I'll do some research. Thanks very much

Better use an enum type for State instead of an int (and using a better name, like UartState, or UartState1, UartState2 if you need)

1.prefer using Serial.readStringUntil(); OR Serial.readString() that way its much easy to manipulate.
2.use a static variable in loop function which stores the string or use a global variable to save char array tagString1 before going in println function same goes with the second reader that way the println will show the previous scan until a new scan is not done.
3.print both the tagstrings in the end of the code one after another


text:
Managing configurations via EEPROM by writing it with the hex file
I've been looking into I2C bootloaders for an ATTINY coprocessor on a board I'm developing, and I ran into a bit of a snag. I have the need to detect what board the main processor's code is running on, since there are a number of write-only peripherals I can't probe for presence or configuration (WS2812-series LEDs and a SSD1306 screen, among a few others), and I was going to manage that via a configuration blob stored on the ATTINY.
Unfortunately, this was coded into the firmware, and pushing out any sort of update for the coprocessor would then require that I build, label, and provide each version, and then have the user choose the correct one.
So, the solution would seemingly be EEPROM, since that can be set to persist over programming attempts (there's even a fuse setting to keep it, although in the other case how the AVR knows if it's been programmed [in the era of bootloaders] I'm not sure).
The issue is now that I need a way to set the EEPROM configuration when I create the original program, and then have future updates not touch it. The existing way is that I add a stub to my code that checks if there's a config and sets it (unfortunately per-unique-board-design, so I'd need lots of different copies again) and then never touches it again. Future firmwares could then just not include any stub at all.
However, this annoys me, especially since if something goes wrong it could mess up the EEPROM.
Does anyone know of a way to use a ICSP programmer to set EEPROM, ideally as part of the firmware upload?
I am using a usbasp with PlatformIO to do the chip programming, so I should have enough access on the first burning to change the EEPROM. Does anyone know how I could add in an EEPROM configuration to go with the flash one?
Some thoughts I have had:

Somehow modify/append the hex file to include data that goes to EEPROM and then burn it
Add a script to PlatformIO that lets me edit/compile/upload/whatever to EEPROM (I do not speak Python, so I'd need help)
Use an existing feature of PlatformIO/the build process/the AVR toolchain to set an EEPROM configuration (I have to suspect there is one, but Googling does not seem to have pointed one out)
Somehow do this with AVRDude

AVRDUDE can program EEPROM. I usually do this as part of the firmware burn - the operator can pick which config block should go into the board while running the programming cycle. In some cases the EEPROM info is even generated programmatically during the cycle to contain dynamic info like unit serial number and commision date.
Here is an example command line that will program the file filename.hex into EEPROM...
avrdude -c stk500v2 -P COM6 -p atmega328p -U eeprom:w:filename.hex:i

The AVRDUDE write command (U) has many options to do almost anything you want...
-U memtype:op:filename[:format]
Perform a memory operation. Multiple ‘-U’ options can be specified in order to operate on multiple memories on the same command-line invocation. The memtype field specifies the memory type to operate on. Use the ‘-v’ option on the command line or the part command from terminal mode to display all the memory types supported by a particular device. Typically, a device’s memory configuration at least contains the memory types flash and eeprom. All memory types currently known are:
(...)
MEMTYPE:
eeprom
The EEPROM of the device.
(...)

OP:
w
read the specified file and write it to the specified device memory

(...)

FILENAME:
The filename field indicates the name of the file to read or write. The format field is optional and contains the format of the file to read or write. Possible values are:

i
Intel Hex

s
Motorola S-record

r
raw binary; little-endian byte order, in the case of the flash ROM data

e
ELF (Executable and Linkable Format), the final output file from the linker; currently only accepted as an input file

m
immediate mode; actual byte values specified on the command line, separated by commas or spaces in place of the filename field of the ‘-U’ option. This is useful for programming fuse bytes without having to create a single-byte file or enter terminal mode. If the number specified begins with 0x, it is treated as a hex value. If the number otherwise begins with a leading zero (0) it is treated as octal. Otherwise, the value is treated as decimal.

a
auto detect; valid for input only, and only if the input is not provided at stdin.

d
decimal; this and the following formats are only valid on output. They generate one line of output for the respective memory section, forming a comma-separated list of the values. This can be particularly useful for subsequent processing, like for fuse bit settings.

h
hexadecimal; each value will get the string 0x prepended.

o
octal; each value will get a 0 prepended unless it is less than 8 in which case it gets no prefix.

b
binary; each value will get the string 0b prepended.

The default is to use auto detection for input files, and raw binary format for output files.

Note that if filename contains a colon, the format field is no longer optional since the filename part following the colon would otherwise be misinterpreted as format.

As an abbreviation, the form -U filename is equivalent to specifying -U flash:w:filename:a. This will only work if filename does not have a colon in it.

Any of these files types can be used depending on what kind of data you are writing to the EEPROM and how it is being generated.
More info here...
https://www.pololu.com/docs/0J67/5.8

Can you elaborate on how I'd make the hex file that goes to EEPROM (for that matter, does it support other types of file and how does that work) or how I might generate the file on-the-fly as listed? Adding a build date or similar would probably be a good idea...

AVRDUDE supports Intel Hex, Motorola S-Record, and raw binary files. Arduino uses Intel Hex as far as I know.

@RDragonrydr answer updated with an excerpt from the AVRDUDE documentatio showing  all the kinds of data use can use.


text:
How does the ssd1306 handle different screen sizes?
I noticed that if I have two SSD1306 displays, the 128x32 display will lose every other row if written in x64 mode, and the 128x64 display will show blank horizontal lines if written in x32 mode. How does this physically work, and can I expect this to be a reliable feature?
I would have thought that half the screen would get cut off somehow, but it appears that it must interlace the data instead (which seems a lot more complicated). Yet there's also some sort of configuration to the driver chip to make it do this (It seems to be the 0xDA command, but I'm not clear how/why it has these options).
Can I expect that, at least if I use the same driver library, that using the wrong screen will always have this behavior? I was planning to use it to help the user detect what screen they have.

What does your own efforts reveal? What does the data sheet say? Did you look into the driver's source? You can answer most of your questions yourself with some web recherche and reading.

I looked up the datasheet, and there is some sort of muxing going on, but I didn't really understand it much, and some of it is library/implementation specific. As apparently mentioned below, it's a convention thing apparently...

The SSD1306 does not handle different sizes, it's ever only handling it's maximum size 128x64. But one can decide to only use less pins of the driver for a smaller display.
The SSD1306 has 128 segment pins, which activate the current column, so that the states of the 64 common signal pins will be used by the display for that column. For smaller display sizes there are just some pins of the SSD1306 left unconnected. They get set like all the other pins, but they are not connected to anything, thus the information gets lost.
For accommodating that, the library sets the pixel according to the size by not using every second row (aka common signal) for half size displays. That's why you get horizontal black lines, when using a 128x64 display with the library in 128x32 mode. The library thinks, that every second row is not connected either way and thus sets these pixels to black. The 128x32 display is loosing every second row when used with the library in 128x64 mode, because every second row is not connected.
Note, that nor the library neither the SSD1306 know about how the display is connected. You need to tell the library this, by setting the mode, and it will control the SSD1306 accordingly. So there is no feedback about the display, that you could use.

Can I expect that, at least if I use the same driver library, that using the wrong screen will always have this behavior?

Yes and no. The library handles it this way, because it is the common way to leave out every second pin for displays of half size. But it comes down to the manufacturer to decide this. We cannot guarantee, that nobody will ever connect the SSD1306 in a different way to a display.
For most manufacturers you will be good. If you simply plan to provide the displays for your user, so that they can change them their selves, you can be sure. If the user should be able to use her/his own display, purchased anywhere else, you might run into problems (though rarely).

I'd be providing the screens, so that part at least is easy. The worrying part is how do I know if the ones I'll be buying are wired normally...

By trying, just as you already did

...Thanks? That's not really the most encouraging...

Depending on where you are buying them, you might be able to get this information from the reseller/manufacturer. You will be fine in most cases. When you have found a reseller, that is selling the correctly wired modules, just buy the modules from him. There is no study, how many modules are wired that way,but I think it will be the wast majority of cases