text:
Nodemcu Lolin v3 Timeout error
I am getting the Arduino console error "the selected serial port serial.serialutil.SerialTimeoutException: Write timeout
does not exist or your board is not connected". I recently upgraded to esp8266 version 3.0.2 and cannot upload a simple blink led sketch to my board. Does anyone know how to resolve this? I would like to be able to use the latest core although downgrading to version 2.7.4 allows me to upload sometimes.
Arduino Code:
#define LED_BUILTIN 2

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
                                // but actually the LED is on; this is because
                                // it is acive low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}

Console output:
Arduino: 1.8.13 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"
Executable segment sizes:
ICACHE : 32768           - flash instruction cache
IROM   : 231724          - code in flash         (default or ICACHE_FLASH_ATTR)
IRAM   : 26793   / 32768 - code in IRAM          (IRAM_ATTR, ISRs...)
DATA   : 1496  )         - initialized variables (global, static) in RAM/HEAP
RODATA : 876   ) / 81920 - constants             (global, static) in RAM/HEAP
BSS    : 25608 )         - zeroed variables      (global, static) in RAM/HEAP
Sketch uses 260889 bytes (24%) of program storage space. Maximum is 1044464 bytes.
Global variables use 27980 bytes (34%) of dynamic memory, leaving 53940 bytes for local variables. Maximum is 81920 bytes.
esptool.py v3.0
Serial port COM4
Connecting...
Traceback (most recent call last):
File "C:\Users\ab\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2/tools/upload.py", line 66, in
esptool.main(cmdline)

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 3552, in main
esp.connect(args.before, args.connect_attempts)

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 519, in connect
last_error = self._connect_attempt(mode=mode, esp32r0_delay=False)

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 499, in _connect_attempt
self.sync()

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 438, in sync
timeout=SYNC_TIMEOUT)

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 376, in command
self.write(pkt)

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 339, in write
self._port.write(buf)

File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/pyserial\serial\serialwin32.py", line 325, in write
raise SerialTimeoutException('Write timeout')

serial.serialutil.SerialTimeoutException: Write timeout
the selected serial port serial.serialutil.SerialTimeoutException: Write timeout
does not exist or your board is not connected
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Are you sure that you have the correct COM port selected?

Yes, since downgrading the core to 2.7.4 allows me to upload.


text:
Exception 29 when trying to display NTP time on an LED
I'm currently working with a "WEMOS D1 R2 & mini" and am trying to call the time from an NTP server and display it onto an OLED display. I've been stuck on an error code that I can't seem to work around and was hoping for some pointers in the right direction. I've used an exception decoder to try an understand it but it's not really helping.
The error in the exception decoder:
Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
PC: 0x4020d032
EXCVADDR: 0x00000000

Decoding stack results
0x40202d64: ESP8266WiFiSTAClass::status() at C:\Users\XXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp line 563
0x4020292e: digitalClockDisplayOled() at C:\Users\XXX\Documents\Arduino\possible_fixed_clock/possible_fixed_clock.ino line 40
0x40202970: loop() at C:\Users\XXX\Documents\Arduino\possible_fixed_clock/possible_fixed_clock.ino line 35
0x4020512c: loop_wrapper() at C:\Users\XXX\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\core_esp8266_main.cpp line 125

The code I'm using:
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET -1
#define OLED_SCREEN_I2C_ADDRESS 0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Defining constants
const char *ssid     = "XXX";
const char *password = "XXX";
const long offset = 3600;
// Background stuff
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", offset);
void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  timeClient.begin();
}

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

void digitalClockDisplayOled() {
  display.clearDisplay();
  display.setCursor(0,0);
  display.print(timeClient.getHours());
  printDigitsOled(timeClient.getMinutes());
  printDigitsOled(timeClient.getSeconds());
  display.display();
}

void printDigitsOled(int digits){
  display.print(":");
  if(digits < 10)
    display.print('0');
  display.print(digits);
}

What is this error code actually telling me, and what kind of implementation could I use to fix it?

That error is an access violation. The fact that it happens inside a system function indicates that you probably have some memory corruption. Try removing code (e.g. remove the display output) until it works.

source: Stack Exchange

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

sort: votes


text:
Is possible to use ESP-NOW in LR mode (long range) simultaneously with WIFI STA (to connect to internet over wifi)
I am building esp-now gateway with mqtt but need long distance (200 meters).
I try to use LR mode but when I enable de LR mode I lost connection with WiFi.
Is licit to make use of LR and STA at the same time?

Are you able to use ESP-NOW at all together with Wifi? I thought this is mutual exclusive, since the same hardware is used for both

Yes but not in LR mode

you can use both by switching back and forth, but adding a 2nd ESP tied to serial is probably better to avoid message delivery delays.

you can easily use both ESPnow and WiFi - you just configure it as WiFi.mode(WIFI_MODE_APSTA);
no need to switch between AP and STA
And I have not experienced any delays for my gateway - sending MQTT message over WiFi to MQTT broker takes 6ms

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


text:
Is possible to use heap_trace_init_standalone() on arduino framework with esp32?
I need to trace memory leak but I can't find a way.
on IDF you can use heap_trace_init_standalone but there is not present on arduino framework.

If you add #include <esp_heap_trace.h> (and define CONFIG_HEAP_TRACING) at the top of your sketch, the method should be available.
It is defined in esp32\tools\sdk\esp32\include\heap\include\esp_heap_trace.h


text:
Arduino esp32 randomly corrupted variable
Every so often my variable gets corrupted. Sometimes it happens several times in a row and other times it doesn't happen in several hits.
I put these logs to rule out that any of the operations interfered. But as you can see just between one log and another, the data is dirty.
This runs on an ESP32 with arduino as framework and this procedure comes from a freeRTOS dequeue.
log:
[D][RC_msgRouterProcessCommand.cpp:60] _cloudRXServiceWorker(): Mensaje desencolado:
 topic: iot/riego/prueba/valvula/1
 payload: {
  "controlRemoto": true,
  "modulo": 11,
  "slot": 1,
  "status": 1
}
[D][RC_msgRouterProcessCommand.cpp:61] _cloudRXServiceWorker(): running on core >>>> 0
[D][RC_msgRouterProcessCommand.cpp:62] _cloudRXServiceWorker(): 1 >>>>>>>>>>>>>>>>>>>>>> {
  "controlRemoto": true,
  "modulo": 11,
  "slot": 1,
  "status": 1
}
[D][RC_msgRouterProcessCommand.cpp:63] _cloudRXServiceWorker(): 1-1 >>>>>>>>>>>>>>>>>>>>>> {
  "controlRemoto": true,
  "modulo": 11,
  "slot": 1,
  "status": 1
}
[D][RC_msgRouterProcessCommand.cpp:64] _cloudRXServiceWorker(): 1-2 >>>>>>>>>>>>>>>>>>>>>> {
  "controlRemoto": true,
  "modulo": 11,
  "slot": 1,
  "status": 1
}
[D][RC_msgRouterProcessCommand.cpp:65] _cloudRXServiceWorker(): 1-3 >>>>>>>>>>>>>>>>>>>>>> ��@)�?
[D][RC_msgRouterProcessCommand.cpp:66] _cloudRXServiceWorker(): 1-4 >>>>>>>>>>>>>>>>>>>>>> ��@)�?
[D][RC_msgRouterProcessCommand.cpp:67] _cloudRXServiceWorker(): 1-5 >>>>>>>>>>>>>>>>>>>>>> ��@)�?
[D][RC_msgRouterProcessCommand.cpp:69] _cloudRXServiceWorker(): 2 >>>>>>>>>>>>>>>>>>>>>> ��@)�?
[D][RC_msgRouterProcessCommand.cpp:71] _cloudRXServiceWorker(): 3 >>>>>>>>>>>>>>>>>>>>>> ��@)�?
[D][RC_msgRouterProcessCommand.cpp:72] _cloudRXServiceWorker(): Item count: 5
[D][RC_msgRouterProcessCommand.cpp:73] _cloudRXServiceWorker(): 4 >>>>>>>>>>>>>>>>>>>>>> �^�?
[D][RC_msgRouterProcessCommand.cpp:76] _cloudRXServiceWorker(): Item @ index 0 : iot
[D][RC_msgRouterProcessCommand.cpp:76] _cloudRXServiceWorker(): Item @ index 1 : riego
[D][RC_msgRouterProcessCommand.cpp:76] _cloudRXServiceWorker(): Item @ index 2 : prueba
[D][RC_msgRouterProcessCommand.cpp:76] _cloudRXServiceWorker(): Item @ index 3 : valvula
[D][RC_msgRouterProcessCommand.cpp:76] _cloudRXServiceWorker(): Item @ index 4 : 1
[D][RC_msgRouterProcessCommand.cpp:78] _cloudRXServiceWorker(): 5 >>>>>>>>>>>>>>>>>>>>>> �^�?
[D][RC_msgRouterProcessCommand.cpp:93] _cloudRXServiceWorker(): CASE: RC_HW_TYPE_VALVULA
[D][RC_msgRouterProcessCommand.cpp:94] _cloudRXServiceWorker(): XXXXXXXXXXXXXXXXXXXXXXXXXXX �^�?
[E][RC_msgRouterProcessCommand.cpp:223] _get_valve_typeByPaylod(): _get_valve_typeByPaylod. deserializeJson Json:
 �^�?
[E][RC_msgRouterProcessCommand.cpp:228] _get_valve_typeByPaylod(): Fallo la deserializacion del json
[E][RC_msgRouterProcessCommand.cpp:229] _get_valve_typeByPaylod(): Error: InvalidInput

code fragment:
void RC_msgRouter::_cloudRXServiceWorker(){
    log_d("iniciando worker cloudRXService running on core >>>> %d",xPortGetCoreID());
    msg_t mensaje;
    while (true)
    {
        if(xQueueReceive(QfromCloud, &mensaje , queueSpeed / portTICK_PERIOD_MS)){
            log_d("Mensaje desencolado:\n topic: %s\n payload: %s", mensaje.topic,mensaje.payload);
            log_d("running on core >>>> %d",xPortGetCoreID());
            log_d("1 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            log_d("1-1 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            log_d("1-2 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            log_d("1-3 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            log_d("1-4 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            log_d("1-5 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            StringSplitter *splitter = new StringSplitter(mensaje.topic, '/', -1);  // new StringSplitter(string_to_split, delimiter, limit)
            log_d("2 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            int itemCount = splitter->getItemCount();
            log_d("3 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            log_d("Item count: %d", itemCount);
            log_d("4 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);
            for(int i = 0; i < itemCount; i++){
                String item = splitter->getItemAtIndex(i);
                log_d("Item @ index %d : %s", i,item);
            }
            log_d("5 >>>>>>>>>>>>>>>>>>>>>> %s",mensaje.payload);

Chances are there's something happening in some other thread that is corrupting (or even destroying entirely) your payload.

Thx @Majenko that was the problem.

Hope you delete that dynamically allocated StringSplitter somewhere later, otherwise it'll eventually run out of memory. Is it even needed to have it allocated like this? Something like StringSplitter splitter { mensaje.topic, '/', -1 }; should be just fine and it's managed automatically

@KIIV I add    delete splitter;
Thx for your suggestion.

The problem was that a task with higher priority interrupts the process. I increased the priority to this task and the problem is solved.
xTaskCreatePinnedToCore(_cloudRXServiceTask, "_cloudRXServiceTask", 2048, this, 20, &_cloudRXServiceWorker_handle,0);


text:
passive buzzer is drawing 500mA
I am having a ridiculously hard time trying to make a passive buzzer work correctly on my Seeeduino XIAO.
Here is the buzzer module :

Here is how I believe it works, assuming the SOT23 smd is a PNP transistor? :

I plugged VCC to a +5V rail, GND to the ground rail, and I/O pin to my Seeeduino XIAO's pin 2 (aka "A2 / D2" :

When I write DigitalWrite(2, LOW), I can mesure about 0.4V on pin 2, while DigitalWrite(2, HIGH) reads about 3.3V (I assume the 5V rail feeding my Seeeduino XIAO's VCC gets converted to 3v3 through an internal regulator)
I understand I have to oscillate the signal to make this module buzz (remember it is a passive buzzer, or a transducer, whatever it is called), or simply use the tone() method, and I eventually managed to make this beep on and off every 1 second successfully during 10 seconds, but what bothers me is that I can NOT turn this module OFF after 10 seconds as a test in my sketch. It stops beeping after 10 sec as expected (ìf (millis() < 10000) { doBeep(); } , but it still draws massive current and gets hot after that delay. It's like the PNP transistor never turns off? I tried both digitalWrite HIGH and LOW but no success.
This is driving me crazy. What am I doing wrong?

You're right that it's a PNP transistor - the SS8550 to be precise.
And therein lies the problem.
When running at 5V to "make no current flow" through the base the voltage at the base has to be higher than 4.4V (5v - 0.6v), and since you're controlling it from a 3.3V microcontroller that can never happen. So you are right in thinking it never turns off - it never does.
Even when you're "beeping" it it's not turning fully off, so the beep sounds you make will be reduced accordingly.
You should power the board from 3.3V instead of 5V so the PNP can turn off fully. If that is not possible then switching the GPIO pin to INPUT mode will prevent it from driving the PNP thus allowing it to turn itself off.

Thank you for the explanation. Adding an AMS1117 3.3v did solve the issue. The buzzer was shy indeed. Knowing all this, I will probably prefer a logic level converter.


text:
how to change a const char*
At the top of my arduino sketch, I have the following :
// softAp
const char *softApSsid = "abcdefg";
const char *softApPassword = "123456";

Those are the DEFAULT ssid and password to connect to the soft AP. The soft AP is start in the setup() such as :
WiFi.softAP(softApSsid, softApPassword);

according to the github repo, that function indeed requires "const char*" as parameters (source: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp#L97)
Further in my sketch, I want to let the user edit the ssid and password. I wrote a function that reads the first byte of the eeprom. If it equals 255, we use the default credentials, if it equals to 1, it means the user set custom credentials, so we will use those to spawn the soft AP.
I wrote this :
void getSoftApAuth() {
  bool isDefaultSoftApAuth = 255 == EEPROM.read(0);

  if (! isDefaultSoftApAuth) {
    softApSsid = "";
    softApPassword = "";

    int i = 1;
    while ('\0' != EEPROM.read(i)) {
      softApSsid += char(EEPROM.read(i));
      i++;
    }

    i = 65;
    while ('\0' != EEPROM.read(i)) {
      softApPassword += char(EEPROM.read(i));
      i++;
    }
  }
}

void setSoftApAuth(const char* ssid, const char* passphrase) {
  EEPROM.write(0, 1);

  // ssid
  int positionOfSsid = 1;
  int lengthOfSsid = strlen(ssid);
  for (int i = 0; i < lengthOfSsid; i++) {
    EEPROM.write(positionOfSsid + i, ssid[i]);
  }
  EEPROM.write(positionOfSsid + lengthOfSsid, '\0');

  // passphrase
  int positionOfPassphrase = 65;
  int lengthOfPassphrase = strlen(passphrase);
  for (int i = 0; i < lengthOfPassphrase; i++) {
    EEPROM.write(positionOfPassphrase + i, passphrase[i]);
  }
  EEPROM.write(positionOfPassphrase + lengthOfPassphrase, '\0');

  if (EEPROM.commit()) {
    Serial.println("Successful EEPROM write");
  } else {
    Serial.println("Failed EEPROM write");
  }
}

void resetSoftApAuth() {
  EEPROM.write(0, 255);

  if (EEPROM.commit()) {
    Serial.println("Successful EEPROM reset");
  } else {
    Serial.println("Failed EEPROM reset");
  }
}

this does compile but crashes and throws exceptions when I run the chip. I believe the issue is in getSoftApAuth() where i try to concatenate the string such as softApSsid += char(EEPROM.read(i));. I print the value of softApSsid in the Serial Monitor and it outputs garbage. I replaced everything with "String" type, and this time it outputs correct username/password stored in the eeprom, but it wont start the soft AP, I believe because I am now trying to pass String instead of const char* to the WiFi.softAP() function as I said earlier (it starts the soft AP with factory default SSID like ESP-AABBCCDDEE appending the MAC address and without any password).
So, basically, how can I modify my softApSsid down in my code, while i declared it at the top as a const char*, knowing it feeds a function that takes (exclusively?) a const char* (WiFi.softAP())
Or is there an other approach / design pattern to achieve this? That is to say: having default credentials hard-coded, but allowing the user to define custom credentials (and storing/retrieving them from the eeprom).
Thanks. Please be indulgent as I am mostly a webdev and not yet comfortable with the strongly typed languages (let alone pointers / references ...)

the esp8266 remembers the SSID and the password by itself. no need to use emulated eeprom for this. once you use beginAP(ssid, pass), next beginAP() will use the stored values (if you use WiFi.persistent(true))

that function indeed requires "const char*" as parameters

There seems to be a misunderstanding here. The method signature is:
bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* psk,
    int channel, int ssid_hidden, int max_connection);

Within this signature, the word const means the method makes the
promise not to modify the ssid nor the psk strings. If you were
implementing the method, you would indeed be required to honor the
constness of these strings. As a user of the method, however, you are
perfectly allowed to provide a modifiable string. You are not bound by
any constness requirement. And indeed, you have to use modifiable
strings if you want your user to be able to change them.
The simplest way to handle this situation is:
char softApSsid[MAX_SSID_LENGTH] = "abcdefg";
char softApPassword[MAX_PWD_LENGTH] = "123456";

Note that you have to allocate enough room to store the longest strings
you may need. Whereas 8 bytes would be enough to store "abcdefg",
it may not suffice for other ssids.
Also note that C strings cannot be grown with the += operator. They
are just arrays of characters and should be written to as such:
i = 0;
do {
    char c = EEPROM.read(1+i);
    softApSsid[i++] = c;
} while (c != '\0');

Edit: answering this comment:

Some research on SO also suggested the following:
const char *password = myString.c_str();
where myString is of String type.

Indeed. The c_str() method of the String class lets you directly
access the C string buried within a String object, if you promise not
to modify it (hence the const). Growing a String is easy, as the
+= operator takes care of handling the memory.
I would, however, advice against any unnecessary use of the String
class, as it involves lots of heap memory allocation, especially if you
build a string one character at a time with +=. This is not really
friendly to your device's memory. See The Evils of Arduino
Strings for details.

Thank you for the clarification and the detailed response. I learned something. Some research on SO also suggested the following: const char *password = myString.c_str();  where myString is of String type. I will try it both later today at home and accept the answer eventually.


text:
5v hall current sensor with a 3v3 mcu
current sensor (5v) with a 3.3v MCU
I am trying to make a hall effect current sensor (ACS712ELCTR-20A-T) work with a 3.3v MCU.
The current sensor is powered with 5v. I specifically choose this sensor because I need to measure current up to 7A powering a led strip. I know INA219 is easier to use (i2c) but it can only read up to 3A.
My ACS712 has a sensitivy of 100mV/A according to the datasheet.
Here is my code :
void getCurrent() {
  //float acs_rest_voltage = (float) (analogRead(currentPin) * (3.3 / 1023));
  float acs_value = 0.0, acs_sum = 0.0, acs_rest_voltage = 2.5;

  for (uint8_t i = 0; i < 11; i++) {
    acs_sum += analogRead(currentPin);
    delay(3); // wait for the ADC to settle
  }
  acs_value = acs_sum / 11;

  float currentRaw = ((((acs_value) * (3.3 / 1023.0)) - acs_rest_voltage) / 0.100);

  //current = 2.178956044 * currentRaw - 0.2223241758; // linear regression calibration
  current = currentRaw;

  if (current < 0.0 || current > 321.0) {
    current = 0.0;
  }
}

it reads 11 samples, averages them, applies a formula, and returns the current.
The returned current value is so inaccurate that I even tried to apply a linear regression calibration formula.
The wiring is quite simple :
ACS712 has VCC to 5v rail.
MCU (seeeduino xiao) has vcc to 3.3v through a LDO voltage regulator (AMS1117).
So ACS712 and MCU share the same ground.
ACS712 data out pin goes to MCU analog pin (I believe adc is 10 bits) through a voltage divider. I assumed DOUT could output up to 5v so i divided accordingly so the MCU can get 3.3v max data.
This did not work great (inaccurate values).
I was so desperate that I even tried plugging the ACS712 data OUT to the MCU directly. Since my current wont reach more than 10A, i'm confident it wont output more than 3.3v (it outputs 100mv/A)
Here are 2 schematics of 2 options I tried :

The voltage measured at ACS712 data out when current is zero is 2.5v
When i increase the current (higher brightness on led strip), here is something weird : the voltage I read with my DMM decreases when the amps increases... ? ? ?
I must be doing something wrong, either circuit or code (or both)

swap the contacts on the ACS712. it is intended to measure AC with the output oscillating around 2.5 V

@Juraj I'm afraid I already tried it as well. Believe it or not, it behaves the same : voltage read at the DMM decreases as the current increases

you can "overclock" an INA219 by adding two more 0.1ohm resistors in parallel with the module's built-in one, then multiplying any read current values by 3.

@dandavis I will give it a try. How accurate would it be ?I think the problem is the ACS712 chip, I measure voltage at OUT pin with a DMM for currents at 0A, 1A, 2A, 3A : the response is non-linear.

The output of 2.5V for 0A is as specified by the datasheet. For increasingly negative currents the voltage will decrease. For increasingly positive currents it will increase. So these symptoms by themselves don't really indicate a problem. Through I would expect the direction of voltage change to switch between positive and negative depending on the direction of the current through the sensing inputs. Are you sure, that this doesn't change, when you swap the input current contacts?

the ina would be very accurate, and can be calibrated to near perfection. the precision would be 1/3rd of the pre-modification value, which is still pretty good for many things.

@chrisl You are right. It increases when I switch the inputs. I am confused now because I tried it many times already. Anyways, I really think the acs712 chips are potatoe. The 100mV/A claim is wrong. Quiescent voltage reads 2.5V, when I increase to 1A it wont read 2.6V at my DMM, neither would it read 2.7V when my PSU outputs 2A. Worst : the change is not even something I could translate into something like y=ax+b. The problem with the INA219 is that it is a shunt, not a hall effect, so I can not power the INA with the same power source it reads.


text:
why is my char array empty
following sketch will run totally fine and as expected :
#include <Wire.h>

#include "SparkFun_External_EEPROM.h"
ExternalEEPROM ExtEEPROM;
char username[33] = "";
char password[65] = "";

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Wire.begin();
  #define EEPROM_ADDRESS 0b1011000 // 0x58
  ExtEEPROM.setMemorySize(256000/8); // 256kbit = 32kbyte
  ExtEEPROM.setPageSize(64); // 64 byte page size.
  ExtEEPROM.enablePollForWriteComplete();
  ExtEEPROM.setPageWriteTime(10); // max. ms for AT24C128
  if (ExtEEPROM.begin(EEPROM_ADDRESS, Wire) == false)
  {
    Serial.println("No memory detected. Freezing.");
    while (1);
  }
  Serial.println("Memory detected!");

  String uuu = "myusername";
  String ppp = "mypassword";

  uuu.toCharArray(username, sizeof(username) - 1);
  ppp.toCharArray(password, sizeof(password) - 1);
  Serial.print("password=");Serial.println(password);
  ExtEEPROM.put(0, username);
  //delay(100);
  ExtEEPROM.put(0 + sizeof(username), "greatnewpassword");
}

void loop() {
  char xxx[33] = "";
  ExtEEPROM.get(0, xxx);
  Serial.print("xxx=");Serial.println(xxx); // prints the username

  char yyy[33] = "";
  ExtEEPROM.get(0 + sizeof(username), yyy);
  Serial.print("yyy=");Serial.println(yyy); // prints the password
  delay(1000);
}

However, if I replace ExtEEPROM.put(0 + sizeof(username), "greatnewpassword"); to ExtEEPROM.put(0 + sizeof(username), password);, then yyy prints empty in the serial monitor. Why?

Try doing a serial print of password to see if the toCharArray call did what it was supposed to do.

OT: Don't write any_boolean == false, use !any_boolean. If you think think, you should make sure that anyone understands, then I'd recommend (any_boolean == false) == true. :-D

OT: sizeof is an operator, not a function, so use sizeof variable. However, its operand can be a type, and then it needs parentheses for syntactIcal reasons. This leads to this ubiquitous bad habit to write it as a function.

Are you sure you are putting the actual array password, rather than a pointer produced by its decay (like char *foo = password; ExtEEPROM.put(..., foo);)?

256kbit is not 256000 bits. It's 256 * 1024 bits, or 262144.

problem seems to be the lib I am using. I think it can not handle data overlapping page size.
if I replace from this
char username[33] = "";
char password[65] = "";

to this:
char username[16] = "";
char password[16] = "";

everything works fine as it saves and reads from the EEPROM via I2C.

the conversation has been moved to chat.

As Majenko already mentions:

.get() and .put() should only be used for atomic, self-contained,
types like int or float, not pointers like char *.

Not sure what atomic means here, but you may .put and .get any data type, especially a struct.
struct EPROMData {
  char username[33];
  char password[65];
};
EPROMData data {"myusername","mypassword"};

void setup() {
   ...
   ExtEEPROM.put(0,data);
}
void loop() {
   EPROMData d;
   ExtEEPROM.get(0,d);
   Serial.print("user="); Serial.println(d.username);
   ...
}

Sure, if the data type is a pointer or a String object (containing a pointer only), you won't be happy with .put / .get

By atomic I mean "it is a thing complete in itself". A struct is complete. An int is complete. A char * is not complete since it doesn't contain the data, it is only a pointer to it. So it's not "atomic". Same goes for a String object, since the object doesn't contain the string data, only a pointer to allocated memory that contains the string data.

.get and .put are being passed a char pointer, not the contents of a char array. Thus you're not writing the content of the string but the address in memory where it's being stored.
With a string literal that is fixed and never changes, so what you write and what you read are fine. With a variable though the address could be anything, and storing the address of some RAM where a string is stored is pointless.
.get() and .put() should only be used for atomic, self-contained, types like int or float, not pointers like char *.
Instead you need to be using the .read(address, buffer, size) and .write(address, buffer, size) functions to read and write the contents of your char arrays.

In the OP's code, get() and put() are being passed actual arrays, not pointers. As the arrays are being passed by reference, they do not decay to pointers.


text:
A strange bug in my Arduino ALU
I have discovered a strange error in my Arduino. It's not in the code. I think it's a hardware bug in the ALU of the microcontroller, maybe in clone only.
So there is a variable called feedLimit and its value is 30, which doesn't really matter.
When I print the answer of feedLimit301000 using this command Serial.println(feedLimit*30*1000)
The answer printed on the serial monitor is 30528, which is obviously incorrect. But when I print feedLimit*30000, the answer is correct (300000). The answer should be the same in both cases but it's not. I have attached the code as well as a screenshot of the output.
Can somebody please let me know if this is a bug in Arduino or something else? I have never experienced this kind of bug at the hardware level.
Thanks.
int interval, interval2;

int feedingTime = 3; //Must feed once every 3 minutes
int feedLimit = 30;  //If fed 10 times or more within feedingTime span, the fiesh dies
int dieAfter = 30;   //Will die if its not fed in 10 minutes
int feedCounter = 0; //Counts how many time fed in feedingTime span

void setup() {
  Serial.begin(9600);
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  Serial.println(feedLimit);
  Serial.println(feedLimit*60*1000);
  Serial.println(feedLimit*60000);
}

Not a bug. You're working with integers on an 8 bit microcontroller. The maximum they can hold is 32767.

This is not a bug. It's just that you are working with signed 16 bit integers on an 8 bit microcontroller. The maximum an int can store is 32767, and literals are 16 bit signed by default.
Your three prints are:
  Serial.println(feedLimit);

Print 30.
  Serial.println(feedLimit*60*1000);

Multiply  feedLimit by 60 = 1800. Multuply 1800 by 1000 = 1800000. Fit 1800000 into 16 bit signed = 30538. Also works the other way: preprocessor multiplies two 16 bit ints to create a new 16 bit int constant: 60 * 1000 = 60000, which is too big to fit in an int and truncates to 27232. Multiply by 30 = 30538 when truncated to 16 bits.1
  Serial.println(feedLimit*60000);

Multiply 30 by 60000. 60000 is too big to store in an int so it is implicitly promoted to a long. 30 * 60000 = 1800000. The result is a long because you have an implicit long in your calculation.
You have to take care with big numbers on small microcontrollers and keep in mind the limits of each variable type, along with what the default data type for literals is.

char: -128 to +127
unsigned char / byte: 0 to 255
int: -32,768 to +32,767
unsigned int: 0 to 65,535
long: -2,147,483,648 to 2,147,483,647
unsigned long: 0 to 4,294,967,295

You can force literals to be a specific data type by adding a suffix to them:

L: Long
UL: Unsigned long

(There are others too but less often used).
So your first (failed) calculation can be fixed by forcing one of the values to be a long:
  Serial.println(feedLimit*60*1000L);

1: It seems avr-gcc isn't clever enough to do this, instead it's always treating each operation separately, and each time it works from int-to-int using two 8-bit registers to represent each value or result.

This was very helpful. Thank you :)

Alternatively, one can use the types with explicit sizes: int8_t, int16_t, int32_t etc. These will have the expected size regardless of what CPU is used.

I don't think that a folded constant of 60000 is truncated to 27232. Did you check that in compiled code?

@thebusybee It seems avr-gcc isn't clever enough to fold 60 * 1000 as constants into a single 60000 constant. Instead it does individual mul calls at runtime - <variable> * 60 followed by <result of previous> * 1000. And at each stage it's working with just 2 8 bit registers per value (or just 1 in the case of 60 of course, it's not that stupid) and all results go into two registers every time. Everything truncates and truncates again. But it doesn't think to coalesce literals like that though...

Re “It seems avr-gcc isn't clever enough to fold 60 * 1000 as constants into a single 60000 constant”: It can't do that: that would break the rules of the language about implicit typing. But it is clever: it notices feedLimit doesn't change and folds feedLimit*60*1000 into 30528. No runtime mul calls.

@EdgarBonet Not according to the output of avr-gcc -S in my tests. There was a long list of mul instructions to get the result.

Mmm... weird. The avr-g++ 7.3.0 shipped with Arduino 1.8.15 does the optimization. Did you compile with -Os -flto?

@EdgarBonet No, I didn't. I wouldn't expect -flto to have any effect since there's no linking. -Os might but who knows? It doesn't really matter anyway, since the exact "why" is irrelevant. Whatever the compiler decides to do or doesn't decide to do, it's still 16 bit integers unless there's a good reason for it to promote to long.

@Majenko last night I also had trouble trying to replicate what you saw in folding. But my thoughts on it were more that regardless of what it does, you're asking it to do something undefined and it's hard to have expectations of the optimizer in such cases. I would have tested -fwrapv to check for a change. But, no original problem, no test. As you said not ultimately relevant. About the only thing I thought to add is that the literal's specified base affects whether unsigned types are considered candidates. E.g. 32768 is long, but 0x8000 is unsigned int with 16-bit systems.


text:
How to prevent an alarm which checks minutes from going off many times within one minute?
How do I prevent an alarm, which checks if the current time matches an alarm time in hours and minutes, from going more than once within one minute?
I am using the DS3231 RTC module and RTClib from adafruit. I want to check if the current time equals to the alarm time, then set the alarmFlag variable. I want to clear alarmFlag when a button on pin D5 is pressed.
The code below works fine as long as I don't press the button within about a minute from the start of the alarm. If I press the button within about a minute from the start of the alarm, the alarmFlag will be 0 for one loop() cycle, but then (almost immediately, I don't have much in loop()) will be back to 1. I want for the button to stop the alarm completely, so it fires again only on the next day.
uint8_t alarm[2] = {19, 30}; // hour (24), minute

// other code ...

void loop() {

  currTime = rtc.now();

  // check if current time matches alarm time
  // if it matches, it matches for a whole minute, which is the problem here
  if (!alarmFlag && alarm[0] == currTime.hour() && alarm[1] == currTime.minute()) {
    alarmFlag = true;
  }

  // clear alarmFlag on button press (this is a shortened version, excuse the lack of debouncing/other stuff)
  if (digitalRead(5) == HIGH) {
    alarmFlag = false;
  }

}

Notes:

I can not use the RTC's built-in alarms because I need them elsewhere.
I don't want to just add currTime.seconds() == 0 to the first if statement, because that would skip the alarm if the loop() cycle takes more than a second.
I know that the way I detect a button press in the example code is suboptimal, I wrote a better way to deal with this in my main code, but I don't want to clutter up this question.

Have you tried adding the current seconds to your first if statement? Something like this: alarm[2] == currTime.seconds(). Oh, and maybe this too: uint8_t alarm[3] = {19, 30, 0};.

store the minute when the alarm triggered ... do not trigger alarm if stored minute equals current minute ... or use another flag to signify that an alarm already raised

You might want to read about "finite state machines" because this is what you have here. Granted, a really simple one, but this knowledge will be valuable in your future life as a developer. You will need at least 3 states: armed, triggered, muted. The transition conditions and how to implement it is left as an exercise for you.

Make your alarmFlag have three states, 0 for false, 1 for alarming, 2 for muted.

@MarkLossner But you actually made a comment...

As suggested by the busybee, this is a textbook application of the
concept of finite state machine. Below is a state diagram that
hopefully captures the desired behavior. Its meaning is hopefully
obvious at first sight.

Here your alarmFlag is replaced by the TRIGGERED state. Please note
that, with this state machine, the only way to turn the alarm off is to
press the button. If nobody is there to press it, is goes on forever.
This kind of issue is quite obvious when looking at the state diagram,
less so when looking at the code. This is why it is advisable to draw a
state diagram before you start coding. If this behavior is a not
desirable, you may add an extra transition out of the TRIGGERED state,
which would happen on a timeout.
It is also worth noting that, with this state machine, pressing the
button multiple times in quick succession has the same effect as
pressing it once. In other words, there is no point in debouncing the
button.
For implementing this in C++, I suggest you follow the steps of this
tutorial on finite state machines.

If you add a delay(60*1000) to your button press function, then you will essentially have a cool off period before the alarm is checked again.  The alarm cannot go off again during that delay;
For non-blocking code, you could store the time you pushed the button, and then check that time before checking it's the alarm time.
    //code to add to your button press
    lastbuttonpress = millis();

    //code to add before your alarm check
    if (lastbuttonpress - millis() > 60*1000) {
        //do your alarm check
    }

does it mean you can't stop the alarm until it runs one minute?

no, the alarm would be stopped immediately on button press.  These recommendations only prevent the alarm from being triggered again within one minute of the alarm being silenced

but the time for the end of the problem is known and why have a 4 byte variable instead of a 1 byte bool and wait more than necessary


text:
Why analogRead's value decreases when I decrease the value of resistor?(I use digitalWrite(high) to positive terminal of resistor)
Basically, my circuit contains only 1 resistor(like the basic LED circuit).
I tried to know what is the actual voltage of digitalWrite(High). I don't understand why the value of analogRead does not fix to 1023 but instead decreases when I decrease the value of the resistor. Moreover, the value comes to zero when my resistor value comes to 1 ohm. Really appreciate any helps here.

if you open a valve on the left side the pressure on the right side falls.

This blog post of mine will help you understand what is happening: https://majenko.co.uk/blog/our-blog-1/what-exactly-is-a-gpio-pin-10

A digital output pin can only provide a specific current: 20mA max recommended, 40mA absolute max. When you get near and over that these values the voltage will go down, as the internal driver hardware cannot provide enough current to hold the voltage.
With the resistor you are providing a direct current path to ground. For high values of R it doesn't make much different (as the current through the resistor to ground is lower than the max current of the digital pin drivers max current). When you lower R the current through it to ground gets bigger. Thus the digital pin driver has to provide more current to hold the voltage. When it gets too low the driver cannot provide enough current, the voltage will fall.
With R at 1Ohm you are basically shorting the digital output pin to ground as 1Ohm really isn't much resistance. At 5V (which is the output voltage of the Uno) you will get U/R = 5V / 1 Ohm = 5A current through it. The driver cannot provide this. In real life the pin driver would most likely be killed by this current draw.

As a complement to chrisl's answer, it is worth noting that the
datasheet of the microcontroller (here the ATmega328P), under a section
named “Typical characteristics”, has a subsection named “Pin Driver
Strength”. This subsection has some typical voltage-vs-current curves
showing that:

the curves are not quite linear, although the non-linearity is small
at 5 V supply voltage
they depend strongly on temperature
near ambient temperature, the pin behavior is close to an ideal
voltage source in series with a 25 Ω resistor.

The curves go only up to 20 mA, as the behavior for higher currents
is not characterized.
From this, you can guess the voltage reading you expect. For example, if
you use a 470 Ω resistor (which is safe), the output pin resistance
and the external resistor make a voltage divider. The expected voltage
you read is
(5 V) × (470 Ω) / (470 Ω + 25 Ω) = 4.747 V


text:
Power supply for Seeeduino Xiao
The Seeeduino Wiki claims that it can run on 3.3V/5V. It doesn't specify if it can step down higher voltages. I am looking to power the XIAO using a battery. It usually uses a USB-C cable which can provide 5V. Will I need to step the voltage down, or does it behave like a normal Arduino Nano and automatically step down the voltage?

Have you successfully used a 6v powersupply to power up the XIAO? I asked on Seeeduino Xiao forum and they said 5V is maxium, if higher it will damage the board.

Hey @NeungChung, I was looking into this as part of a project, but ended up finding out that I didn't need to use the XIAO anymore, so unfortunately I can't answer your question. Did they provide any details as to why this is the case? I'd say that the answer below is pretty detailed.

If you scroll down on that page you link to you can see the power circuit. It uses an XC6206 voltage regulator which has a maximum input voltage of 7V and a dropout voltage that could be as high as 680mV.
So you can feed between about 4V and 7V in to the VIN pad and it will step it down to 3.3V. Anything below 4V and you will go "out of regulation" though the system may still run down to lower voltages. If you go above 7V you will blow it up.

Thanks a lot! A 6V power supply will work perfect.

Make sure it's a regulated 6V supply. Unregulated power supplies tend to output voltages much higher than their published voltage under very low load. You might well exceed your 7V "do not exceed" voltage limit at the low current draw of a microcontroller.

@DuncanC The OP specifies a battery...

@Majenko initially they mentioned a battery, but their last post said a "6V POWER SUPPLY." I took that as a change of plan.

@DuncanC Whereas I take "power supply" to be any source of power, including batteries.

You quoted a value from ABSOLUTE MAXIMUM RATINGS table. Values from ELECTRICAL CHARACTERISTICS apply for normal operation, which limits the input voltage to 6V.

A batch of 60 XAIO ESP32C3's will not power on using a 3.3V DC supply applied to pins 3V3 and GND. They only power on using a 5V input applied to pins 5V and GND.
The test rig was a bench DC power supply.
The XIAO ESP32C3 seems to power on as low as 4.1V DC applied to the 5V pin.
No external component is required, just a direct connection from the bench power supply to the 5V pin. Therefore the posts somewhere on the internet about needing a diode in the path of the positive supply do not appear to be necessary.
Note that the ESP32C3 were not programmed, ie. they arrived from the factory and were powered without downloading any code to them. Thus the posts about sleep mode are not applicable as the 3.3V and 5V behavior should then be identical, but they are not.


text:
Can Bluetooth HC-05 Module detect other modules and relay data back to phone?
I want the following to happen:

The HC-05 is paired to a phone. The module is called "Amy". The module is worn, say, as a wristband by a person.
Amy passes another wristband-with-HC-05-module called "Bob".
Amy inquires about Bob, and if the RSSI signal received is strong, it relays the name "Bob" to the phone which will somehow store the information in an app.
The HC-05 will pass many other modules, each with different usernames. A list of names will be stored by the phone app.
All other HC-05 modules, i.e. Bob and co. , would be doing the same thing with their own phones.

How feasible is this?

From your last question I thought you wanted to go with BLE beacon.  Why now normal old bluetooth?

@chrisl I didn't realise that the HC-05 wasn't a BLE device. I am still researching things, and my choice of module isn't set in stone - I am still looking for better options. All I am interested in regarding this question is whether the module can be paired to a phone, but still collect information from inquiring into other nearby devices. I assume the answer would be the same for both Bluetooth and BLE? (Also both Bluetooth and BLE modules can provide an RSSI value, which is the important thing).

Correction - BLE devices give off RSSI, but not Bluetooth. BLE devices can be used as iBeacons. I have settled on the HM-19 Bluetooth 5.0 module. A phone acts as an iBeacon scanner.


text:
ESP8266 CCLOCK Odd behavior
I'm trying to write some extremely fast code for the ESP8266, so I'm trying to figure out how to time things.  I've discovered CCLOCK, a register that reflects the number of clock cycles since startup. (https://github.com/esp8266/Arduino/issues/4632#issuecomment-380632906, and other references.) In testing it out, though, I've encountered some weird behavior.  Consider the following code:
static inline volatile uint32_t asm_ccount(void) {
    uint32_t r;
    asm volatile ("rsr %0, ccount" : "=r"(r));
    return r;
}

char outgoingPacket[4];

...

void loop() {

  // ... some stuff ...

  uint32_t startTime = asm_ccount();
  uint32_t stopTime = asm_ccount();
  uint32_t elapsed = stopTime-startTime;

  outgoingPacket[0] = (elapsed >> 24) & 0xff;
  outgoingPacket[1] = (elapsed >> 16) & 0xff;
  outgoingPacket[2] = (elapsed >> 8) & 0xff;
  outgoingPacket[3] = elapsed & 0xff;
  Udp.beginPacket(targetUdpIp, targetUdpPort);
  Udp.write(outgoingPacket, 4);
  Udp.endPacket();
}

(On my computer, I have basically the following Java code running to receive these messages:)
    while (true) {
      DatagramPacket packet = new DatagramPacket(buf, buf.length);
      socket.receive(packet);

      byte[] data = packet.getData();
      StringBuilder sb1 = new StringBuilder();
      StringBuilder sb2 = new StringBuilder();
      for (int i = 0; i < packet.getLength(); i++) {
        sb1.append(String.format("%8s", Integer.toString(((int) data[i]) & 0xFF, 2)).replace(' ', '0'));
        sb2.append(String.format("%2s", Integer.toString(((int) data[i]) & 0xFF, 16)).replace(' ', '0'));
      }
      System.out.println(sb1 + " " + Integer.parseInt(sb2.toString(), 16));
    }

(Yes, it's a little hacky, I know, but the results have seemed correct.)
Now, most of the time, the output looks like
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1

But about 5 times in 77000, I'll get lines like
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000110101000 424
00000000000000000000000000000001 1
00000000000000000000000000000001 1
...
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000010010100001 1185
00000000000000000000000000000001 1
00000000000000000000000000000001 1
...
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000010001001100 1100
00000000000000000000000000000001 1
00000000000000000000000000000001 1

I ran the code for 1 minute 4 seconds, and got 3 counts of 424, 1 of 1100, and 1 of 1185.  It seems particularly odd that 424 would show up three times.
Given that, as far as I understand, the relevant lines of code (the two calls to asm_ccount) would have been compiled to a given set of instructions, I'd have expected it to take exactly the same number of cycles every time.
Why is this not happening?
Is it interrupts?  Something something caching?  Does that register not actually work as claimed or as I understand?  Have I done something dumb in the transmission or logging code?  Something else?

You've got interrupts running and interrupting your code.  Those take some cycles to run.

aHAH!  I think you're right.  When I disable interrupts around the critical code, its timing becomes almost perfectly stable.  ...But then it stops working after a few dozen loops, so I guess I can't do that, haha.  If you want to make your comment an answer, I'll accept it.

You've got interrupts running and interrupting your code. Those take some cycles to run.


text:
Recommendations For High Capacity Microcontrollers
For a new project I'm working on, I'm turning an old Casio Personal Mini into a Speak & Spell (with possibly other functions). However, the speech library I plan on using is Talkie, and it takes up quite a bit of program space. I've been trying to look around for some microcontrollers I could use that have high program storage capacity, but I really don't know much about what I should look for, nor how to find ones that are compatible with the Arduino boot loader. Would any of you have any good suggestions? I'd probably need one with over 256KB of program storage.

Personally I always recommend the PIC32, but ... it's not the bootloader you want to care about. It's what will work with this "Talkie" library, whatever that is. If it's doing sound reproduction then it's probably going to have very specific non-portable requirements. So the only people that can recommend anything would be the author(s).

In a comment, Juraj wrote:

the ATmega MCUs are similar so a port to Arduino Mega should be
possible

This seems indeed to be very much the case.
Looking at the source code of the library, it appears it uses
timer 2 for generating the PWM signal and timer 1 for
scheduling the samples. These timers are almost identical between the
ATmega328P of the Uno and the ATmega2560 used in the Arduino
Mega 2560. The only relevant difference between these boards, as
far as the library is concerned, is the output pin, which is the “OC2B”
pin of the microcontroller:

on the Uno, OC2B is digital pin 3
on the Mega, OC2B is digital pin 9

So my guess is that the library should work on the Mega with just this
tiny change:
--- a/Talkie/talkie.cpp
+++ b/Talkie/talkie.cpp
@@ -71,7 +71,7 @@ void Talkie::say(uint8_t* addr) {
        //
        // Enable the speech system whenever say() is called.

-       pinMode(3,OUTPUT);
+       pinMode(9,OUTPUT);
        // Timer 2 set up as a 62500Hz PWM.
        //
        // The PWM 'buzz' is well above human hearing range and is

Also, make sure you plug your headphones on pin 9 rather than
pin 3.
If you try this and it works, please report that either here or directly
to the author of the library. It should then be easy to modify the
library to support both boards out of the box.

Edit: If you download Talkie through the Arduino library manager,
you will get this version, which does supports the Arduino
Mega 2560.


text:
arduino due: how to read more than one byte at a time in serial uart with tfmini liar sensor
I'm trying read tfmini lidar sensor from arduino due board with uart. Here i can read only one byte at a time using serail.read() method but i need to read 9 byte at a time and store it in array. Means i don't want to repeat loop again and again to store byte by byte.

Serial is only one byte. If something send multiple bytes then you have to read each individual byte.

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

Majenko, That means i have to repeat the loop untill a would not get the last data!!!

You would have to repeat a loop. Not necessarily "the" loop. But it depends how "blocking" you are happy for your code to be.

Do we have any UART interrupt in arduino due board?

Yes but it is being used by the UART reception code. You do know the bytes get placed into a buffer, and you can read them any time you like, don't you?

No, i don't know, may you please share UART reception code to read data from the UART interrupt.


text:
Why ATMEGA328P U-TH doesn't answer to USBasp but work fine with Arduino as ISP?
I ordered ATMEGA328P AU from China recent but I got "ATMEGA328P U-TH". which seem super problematic.
I try to use USBasp to burn bootloader but it fail and show error message as shown.
avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
     Double check connections and try again, or use -F to override
     this check.

which I believed many people face same situation as mine. Then I accidentally found the solution by using Arduino as ISP which successfully birn bootloader. After that I can use USBasp to upload sketch or burn bootloader.  I don't understand what happen here.
Note: I solder ATMEGA328P U-TH in SMD package to Arduino UNO clone.

If you want to upload a sketch via any other interface than ISP, the atmega needs a bootloader.
The bootloader basically is a piece of software which is stored in a dedicated flash section, the "bootloader section". Code stored in this bootloader section has the special ability to write to parts of flash memory where the actual program is stored (this is called the "application section").
In general, a program can not overwrite its own flash section, so the bootloader and the application need to be stored in different sections/partitions.
In principle, a bootloader can do whatever a normal sketch could do: toggle pins, access eeprom, read UART/I2C/etc... and as it can also write to the "application section", you can make it read data from any interface and transfer it to the application section.
This is what happens if you upload code via USBasp (Arduinos have a USB-to-UART converter on board).
But of course, this requires that a bootloader is installed.
avrdude: error: program enable: target doesn't answer. 1 - this might sound misleading, what it actually means is, that the bootloader doesn't answer. That makes sense, as the device doesn't have a bootloader.
When there is no bootloader, the only way to upload code is to use ISP, which doesn't need any software to function. It's a hardware functionality that Atmel implements in silicon.
A code upload via ISP works in (almost) any case.

Both usb-asp and Arduino as ISP is the programmer which be able to upload sketch either bootloader. In my question it do the same job to uploader but the chip not answer to usbasp but it work fine with arduino as isp.
my inspectation is is about factory setting clock speed of the chip the corelate to programmer clock speed. but still no clue.

I think bootloader only use with stk500  Serial UART protocol  upload.


text:
non asssign variable using by for in loop() can remeber last value. what happen here?
I modify this code from my friend and it look strange.
void setup() {
    Serial.begin(115200);
    Serial.println("reset");
}
void loop() {
    for (int d; d <= 32767; d++) {
      Serial.println(d);
      delay (1000);
    }
}

for some reason when you press reset, the variable will keep counting from last value as shown.

this not gonna happen when you put these block in setup()
I know that not good idea to use varible in for loop without assigned the value, but I belived it must have a interesting reason for this.
For my hypothesis, the variable value just allocate with same address in memory. when this code run in setup() some how the complier detect this situation and assign 0 as initial value. but when in the loop() some how the compiler don't assign new value to the memory address and it get old value from last time the program was run before resetted. I still need further explanation.

This code behaves normally for me - 'd' starts at 0 for every reset. Is this the complete and exact code that made the output example?

@JRobert, yes I use Arduino UNO with Arduino 1.1.13

I think you missed a compiler warning (I did, too!) - notice that you are using 'd' uninitialized. On each re-entry to the loop() function, loop()'s stack will be in the same place in memory. The for-loop doesn't initialize 'd', but the boot loader did zero RAM for your first run. 'd' happens to occupy the same memory location on each entry to loop(), so the old value (just before reset) is still in place. Since the for-loop didn't re-initialize it... :)
The fix is:
for (int d=0; d <= 32767; d++) {

Update:
That begs the question: Why did your run fail as expected, while my run appeared to execute normally? My guess is different bootloaders, one that does, and one that doesn't, initialize SRAM on a reset that doesn't result in an upload.

Wow, never think that was firmware problem. I doesn't need the fix I want the explanation.

I can't confirm that the difference between your runs and mine is due to firmware, but there's no question that 'd' was being used without initialization.

old IDE, old AVR toolchain


text:
How Arduino IDE work with ESP32?
I understand how compiler compile our code to make binary code. Then we can use avr gcc to upload bin code to atmega chips via programer (USB ISP) or via USB serial (required bootloader).
I'm using ESP32 for a while and notice they work in difference way. As far as I know

It  not required Arduino  bootloader.
It not reset when re-open serial monitor.
It use external memory chip.
It have boot and reset button
The USB Serial connect to ESP32 and we can upload bin code with it. (maybe the only way)
In IDE it run python scrip (esptool.py)
I wonder how the process going and how each element work for its part for completely understand the process.

avr gcc is the compiler ... it does not do the code upload

Arduino IDE is one possible way of getting code onto the ESP32. There’s lots of info available about using Arduino IDE with ESP32 (e.g., https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/). There are also other IDEs that will work see https://randomnerdtutorials.com/getting-started-with-esp32/ for a list.

@RowanP That one confuse me. so with one bootloader  esp32 can work with all environment??? or the system not required bootloader at all???

@Mlab Explaining that’s beyond my expertise. I know that it uses a boot loader, and that it’s compatible with several environments. I’ll pass the baton to someone with deeper expertise.

Its more like the programming environments/IDEs are made compatible with the bootloaders (not other way round). For the Arduino IDE you need to install the ESP32 core, which includes the upload tool for its bootloader, making the Arduino IDE compatible with the bootloader of the ESP32. There are many other IDEs, which can be made compatible. I think only the native ESP IDE from Espressif is specifically made for ESPs

The ESP32 has a bootloader that uses serial embedded in its internal ROM. Whether that bootloader runs or not depends on the state of certain IO pins when the ESP32 starts up.
Those states are controlled by a small circuit that is triggered by the serial control lines (DTR and RTS).
On the Arduino there isn't that requirement, and the bootloader always runs when the chip resets, so a much simpler circuit is used to trigger a reset using just the DTR signal.
So for an Arduino whenever the serial port is opened the DTR signal resets the board. But for the ESP32 the RTS signal also has to be asserted along with the DTR signal in the right sequence to both set the correct IO pins and to reset the chip.
Whether the target device has internal flash or an external flash chip makes no difference. It is the bootloader's job to get the data into that flash. The AVR chips have a way of interfacing with the internal flash (ISP) to program it without a bootloader, but the ESP32, as it has external flash, doesn't need that (you can interface directly with the flash chip if you so wish).
The software on the PC that communicates with the bootloader has to speak the "language" the bootloader expects. Each family of chips has its own bootloader (some don't even have a bootloader, but that's another story) which speaks its own language. On the AVR chips that's usually a variant of the STK500 protocol, and the program avrdude is what communicates with it to send the program to flash. On the ESP32 (and the ESP8266 too) it's esptool.py that does the job. On chipKIT boards it's pic32prog. On Digipark it's micronucleus. There's as many upload programs as there are families of boards. Some programs, like avrdude and pic32prog are more flexible and can also talk to hardware programmers (USBASP, PICkit2 etc), but in general the upload program is written specifically for a particular bootloader.

So all ESP32 have build-in bootloader right? means I don't need to re-install it ever? I never see someone done that before

@Mlab That is correct. It is getting more common to have a bootloader in ROM instead of (or as well as) having a hardware programming interface. The Arduino Due also has its bootloader in ROM, as do many other high-end ARM chips. It's common to have the bootloader operate in multiple modes, including booting off SD card (like the Pi does) depending on settings on certain IO pins.

That really anewer my question. I just self learner. By missing that information make my life a hard time figured out how things work. Thank to you.


text:
How to connect more than one arduino serial port together
The idea is to connect more than 1 arduino slave to master as shown in schamatic

simulate this circuit – Schematic created using CircuitLab
The problem is TX slave can not just combine to master RX.
It need to done some trick like tri-state buffer to make slave TX one at time.
Anyway, avr port can config as tristate buffer.
(Q1)Is there any software solution to done this?
Second If I connnect TX to RX for half-duplex communication (using 1 data line). How to make Rx stop listenning to its self while transmiting data?

Diodes and a resistor.

Two resistors--that's it! I just added my answer.

You can do it with two diodes and a resistor:

simulate this circuit – Schematic created using CircuitLab
You'll still have to implement some system to prevent collisions, but electrically that will be sound.

Does it have programing solution?

Tip magically turn the shave devices into open drain? No. Not unless you have the ability to reprogram the slaves and write your own implementation of software serial that emulates open drain.

Will something like Serial.end() and oinMode(x,INPUT) trick work?  or I need to write my own Serial library?

On the slave devices, yes, that would work - but would also disable serial reception. To prevent collisions you need the master to tell a slave it can send, which means reception needs to be working, or you need to implement some other form of signalling architecture (and that would most likely need more changes to your hardware). It's simplest to just add those diodes and a resistor and do it properly - or not use Serial at all and use a proper bus system like I2C.

Without the diodes or some form of direct control over when each slave can send a collision could be fatal to one or both of the slaves. It could cause a dead short circuit (one sends a 1 and the other a 0 at the same time) which could burn out the IO pins.

This approach you have keeps the Rx line always pulled to 5V except when a Tx line from a Slave goes LOW. I had to look it up to ensure that idle is in fact HIGH and not LOW, and yep, it is: https://learn.sparkfun.com/tutorials/serial-communication/all#wiring-and-hardware -- see the diagram under "Hardware Implementation", and also: A signal at the VCC level (3.3V, 5V, etc.) indicates either **an idle line**, a bit of value 1, or a stop bit. So, yes, this solution would definitely work, although I think I prefer my 2-resistor solution I've posted here over this solution.

Sparkfun's explanations are excellent. I'm grateful they and Adafruit, in addition to Arduino of course, exist.

For this scheme to work, you need to make sure that at most one slave
drives its TX at any given time. You will have to devise some protocol
by which the master addresses one slave, and then only that slave
responds. The problem is:

both slaves must have their serial ports turned on in order to notice
when they are addressed by the master
an active serial port keeps its TX pin in a low impedance state,
actively driving it HIGH when not transmitting data.

The best way out of this dilemma is to modify the hardware, as per
Majenko’s answer. If, for whatever reason, you cannot do that
modification, there may be a software-only solution, but only if the
underlying hardware allows you to turn off the serial transmitters of
the slaves, while keeping the serial receivers active.
The Arduino API dos not allow you to keep the serial transmitter active
while the receiver is disabled: the functions Serial.begin() and
Serial.end() control the transmitter and the receiver as a whole. You
may be able to do that by accessing the hardware at a lower-level. You
didn't state what kind of Arduino you are using. Assuming you have
something similar to an Uno, you can disable the transmitter with:
UCSR0B &= ~_BV(TXEN0);

and enable it again with:
UCSR0B |= _BV(TXEN0);

If you want to use the Arduino API for serial communication, you will
have to disable the transmitter right after Serial.begin():
const uint8_t TX_PIN = 1;

void setup() {
    pinMode(TX_PIN, INPUT_PULLUP);  // valid when transmitter is off
    Serial.begin(9600);             // enable serial port
    UCSR0B &= ~_BV(TXEN0);          // disable transmitter
}

But beware that then it will be enabled for a sort time (no more than a
few microseconds), right before you disable it. This may cause a short
if one slave boots while the other is transmitting data.
One problem with this kind of software-only solution is that bugs do
happen, and with your circuit, a bug in the protocol handling can burn
your hardware. If you can manage to at least add some protective
resistors, as in Gabriel Staples’ answer, that should keep you safe.

You can use a single-pole dual throw switch. a simple switch that can switch lines between multiple slaves.
Limitation: The salve will not be able to create a request unless the master has selected its corresponding lines.
Master has to actively ask for the data or send commands to the slaves. Slaves may not be able to initiate the communication (when not selected)

Appreciate for your participation but I prefer software solution first.

Update Nov. 2020: my answer below, though a bit insightful and with many correct statements, is wrong. My schematic below will indeed prevent the Arduinos from damaging each other, but it will not allow proper communication. Majenko's answer here is right. Use his schematic, but read my answer below as well for additional insight and ideas.

ORIGINAL ANSWER:
You can do it with 2 resistors, as shown below. That's it! Super simple!
Electrical explanation:
The goal is simply to protect the two Tx pins from killing each other. Without the resistors one Slave might be writing output LOW while the other Slave is writing output HIGH, which is a dead short--damaging both devices. Simply putting a 1k resistor in series with each Tx pin like this prevents that dead short. Now, if one Tx pin is HIGH while the other is LOW, you get current flow from one into the other through a total of 2kOhms, which means the current will be only I = V/R = 5V/2000 Ohms = 2.5mA, which isn't a problem, as each pin can handle 40mA max and 20mA~30mA continuous safely. Also, a 1k resistor isn't much load, so you should still get good serial throughput even at fairly high baudrates.

simulate this circuit – Schematic created using CircuitLab
The code:
The communication code will be done as normal with Serial.print() or Serial.write(), Serial.read(), etc. Nothing special about the code, except you should make an effort to keep the slaves from talking at the same time to prevent data corruption from slave to master. So, you should have Master request data from a Slave, and a Slave should only talk when it knows the other Slave is not talking (ex: it should only talk when spoken to). The Master coordinates the communication. In this way, this is like SPI: the Master is in charge and tells each Slave when to talk. Since both Slaves are always listening, just use an "ID" to indicate which slave is being spoken to. If a Slave doesn't see it's ID, it should ignore the message.
Ex:
Request a new temperature reading from Slave 1:
Serial.println("1:T");

Now, wait until you get the full response from Slave 1, then send out a request for...let's say, some current reading, from Slave 2:
Serial.println("2:C");

The exact communication codes are up to you--your imagination is the limit.
Again, both slaves see both messages, but they look at the number at the beginning and only reply if it's their number. Doing this technique, you could connect nearly infinite Slaves all on the same line, just adding a 1k resistor to each Slave's Tx line before the junction where they all connect back to the Master's Rx line.
Pretty cool. I never thought of doing this before until you asked the question. Good question.

You hardware setup can prvent damage but I wonder if one slave send no data (given High signal)  will the data get voltage divider effect that divide signal amplitude to half?

@Mlab: Indeed. A “silent” TX actively pulls the line HIGH. That's why you need the diodes.

@EdgarBonet  that why I seraching for solution to make A “silent” TX become high impedance. it should be possible by software some how.

I think my answer is wrong, and needs the diodes due to idle Tx being actively driven (low impedance) HIGH. I'll update my answer as soon as able. I measured the impedance of a HIGH Tx line at something like 26 Ohms early this morning.

26 Ω is the expected resistance of an ATmega pin configured as OUTPUT. C.f. the datasheet section on pin driver strength.


text:
Arduino Nano 33 Sense won't upload
When I try to upload an example code from the Arduino_LSM9DS1 Library it either jumps ports so the upload cannot complete or spits out some red text and never completes the upload, just gets stuck on uploading.
The red text is:
processing.app.debug.RunnerException
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
    at processing.app.SketchController.upload(SketchController.java:732)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$UploadHandler.run(Editor.java:2047)
    at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port 'COM5'.
    at processing.app.Serial.touchForCDCReset(Serial.java:107)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
    ... 5 more
Caused by: jssc.SerialPortException: Port name - COM5; Method name - openPort(); Exception type - Port busy.
    at jssc.SerialPort.openPort(SerialPort.java:164)
    at processing.app.Serial.touchForCDCReset(Serial.java:101)
    ... 6 more

I'm not that new to Arduino but I've never looked into uploading (I guess I should) and am struggling to get it to work.
Any help is appreciated, thanks

but you can upload Blink? or did this happen after uploading the Arduino_LSM9DS1 exmple? did you try double reset to activate the bootloader?

With the bootloader active it will still sometimes jump ports either during or after uploading

yes, they do that. is is because the USB is handled by the MCU, not by a separate chip (which would not reset)

ok, so the board should be fine to use


text:
send configuration commands with arduino
I am using ublox zed F9P multi GNSS module. I have to program it for its configuration messages. Like I have to run a specific configuration of my receiver with the help of Arduino. I know arduino parse the GNSS sentences but can anyone tell me how to write code for ublox configuration commands such that that command can change setting of the receiver upon burning it in Arduino. Also, that code should retain in the receiver even if arduino is disconnected (closing arduino IDE console). Please help

you write the code using the Arduino IDE

yes code will be written in arduino IDE.

You would send the commands over the same serial channel that you read the data from.

can you give some example of sending these hex bites into Arduino? It will help me

Here you find a standard library from arduino.
https://www.arduino.cc/reference/en/libraries/sparkfun-ublox-arduino-library/
You can find the documentation here:
https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library


text:
Reduce time between two consecutive SPI transfers on ESP32
I'm trying to drive an external DAC via SPI interface using ESP32 chip. But I cannot achieve the desired speed (>1M transfers/sec, each transfer consists of 16bits). The reason is not the SPI speed itself, which could be set as high as 40MHz, but the time delay between two consecutive SPI transfers.
A sample code is as follows:
#include <SPI.h>

void setup()
{
    Serial.begin(115200);
    SPI.begin();
    SPI.beginTransaction(SPISettings(40000000,MSBFIRST,SPI_MODE0));
}

void loop()
{
    unsigned long tstart=micros(),count=0;

    byte data[18]={0,1,2,1,3,1,0,1,2,1,3,1,0,1,2,1,3,1};

    while(micros()-tstart<1000000)
    {
        for(byte i=0;i<9;i++)
          SPI.transfer16(0b0101010110101010);
        count+=9;
    }

    Serial.println(count);
}

The output shows that ESP32 can do approximately 694,800 transfers/sec, still far away from my requirement of 1M transfers/sec. However, theoretically, using a 40M SPI bus, each transfer only takes 16/40M sec, which should enable a >2M transfers/sec speed, so the difference must originate from the time delay between two consecutive SPI transfers.
I know that these delays can possibly be canceled by transferring more data in a single transfer command. However, the interface of DAC requires me to pulse SYNC once (set it high and then low) before each SPI transfer, which is not possible if I use a single SPI transfer command.
I have searched for solutions online and found two related problems:
The one here suggests disabling all MUTEX commands in esp32-hal-spi.c/h. It seems reasonable, but I see no effects, probably because the compiler has already deleted those codes in optimization.
Another here suggests using RMT to replace SPI, but suffer from timing issues.
I think there is also room for improvement as I only need to output data, and I access SPI on a single thread, so the solution can be thread-unsafe.
So I'm here to ask, is there any way to accelerate the SPI transfers? Thanks a lot in advance!

How are you accounting for the time needed to call micros, do the subtraction, do the comparison, check the while condition, handle the for loop, and add to count?

@Delta_G, I've checked, checking micros() and adding count takes way less than a microsecond. 95%+ of time is still consumed on SPI.transfer(), which takes 1us+ on each call.

What DAC are you trying to drive?

@Majenko DAC108S085 manufactured by TI

I am not familiar with the SPI peripheral in the ESP32, but it looks like you can 1) confgure it to automatically assert the CS pin (for /SYNC) for each transaction, and 2) user DMA to stream large amounts of data quickly. How you would do all that I have no clue, but you'd be using ESP-IDF functions not Arduino functions to do it. And that's way beyond the scope of this site.

@Majenko thanks for your reply! I'm currently trying to (ab)use I2S interface to emulate SPI. would update if I succeeded. DMA seems not a good solution though, as preparing DMA takes time as well...

I know this is an old post, but did you managed  to solve it @Wjx ? I'm currently facing the same issue for a different DAC.

@ChecheRomo I2S brought even more issues, I wouldn't recommend that. I currently think it's just a hardware limitation. However, ESP32-S3 added a synchronization module, so you might be able to bit-bang SPI if you want and it might work. According to my experience, RMT modules are pretty responsive and can have delay of <5us.


text:
Arduino MKR GSM 1400: Can I tell from code if the power has tripped
Is there a way to tell if an Arduino MKR GSM 1400 has lost power and has to rely on the connected battery?
Ideally, I'd like to do this without adding additional circuitry. Alternatively, can I connect VIn to an analogue input pin?
On the schematic, there are two lines that seem promising. One named VBATT\2.4B that go into PB09 of U1 via a voltage divider and another named VBAT\1.4B. Also the BQ24195L is an I2C device which would probably be connected the the main micro controller.
What I need to do is to send an SMS as soon as the incoming power is lost to notify a user that the power supply has tripped. Does anyone have any code samples?

did you succeed with this? Looking at the suggested library, the (misnamed)  function 'isBattConnected()' returns the DPM_STAT bit from the SystemStatusRegister. I think that this indicates when there is a draw of current from the battery, but I'm not 100% sure about that when I read the spec sheet: (https://www.ti.com/lit/ds/symlink/bq24195l.pdf section 8.3.2.2 Dynamic Power Management) Can you share anything you figured out?

It did work, yes. I'm going to have to dig out the code for this, but yes, there is a call to see if I power was lost and it worked perfectly.

Any chance to know how you managed to solve the issue? Which method of the library did you use?

@Kylix This is now from some time back, but I did end up using https://github.com/arduino-libraries/Arduino_BQ24195 and it worked quite well for me. I checked PMIC.isPowerGood() in loop and then took action whether this came back true or false. I hope that helps.

VBATT/2.4B is used for measuring the batter voltage using the internal ADC of the MCU. It can't really tell if the battery is being used or not - except by maybe monitoring it over time and see if the voltage goes up or down.
However the BQ24195 is where all your hope lies.  It has a status register that can tell you all sorts of things.
For example it can tell you if there is incoming power, and what that incoming power is coming from (a USB host, a USB power adaptor, or operating in OTG mode). It can also tell you what the battery is doing - if it's charging, or not for example.
A quick google search throws up this library specifically for the purpose.


text:
How .data + .text section can be = How much flash the final program will consume
I could not understand one point related with Arduino code.
Let's say i have following code
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
}

void loop()
{

}

When i compile above code for Arduino Uno. Arduino IDE gives.

Sketch uses 1478 bytes (4%) of program storage space. Maximum is 32256
bytes. Global variables use 192 bytes (9%) of dynamic memory, leaving
1856 bytes for local variables. Maximum is 2048 bytes.

I examine the generated file with avr-size.
.data                         26   8388864
.text                       1452         0
.bss                         166   8388890
.comment                      17         0
.note.gnu.avr.deviceinfo      64         0
.debug_aranges               208         0
.debug_info                 6150         0
.debug_abbrev               2721         0
.debug_line                 2239         0
.debug_frame                 504         0
.debug_str                  1770         0
.debug_loc                  1908         0
.debug_ranges                 80         0

As you can see .data + .text = consuming program storage space. Then i checked this document. https://courses.cs.washington.edu/courses/csep567/04sp/pdfs/avr-libc-user-manual.pdf. It says about avr-size
Note:
The avr-size program (part of binutils), coming from a Unix background,
doesn’t account for the .data initialization space added to the .text section, so in
order to know how much flash the final program will consume, one needs to add
the values for both, .text and .data (but not .bss), while the amount of pre-allocated
SRAM is the sum of .data and .bss.

Then, i check contents of .data section with
avr-objdump.exe -s -j .data <my.elf>

Then I got
Contents of section .data:
 800100 00000000 ff005f00 8c004c01 bd009b00  ......_...L.....
 800110 af00666f 6f000d0a 0000               ..foo.....

I'm confused, what above quote really means ? "foo" stored in .data section, but why i need to add this section to .text section in order to calculate how much flash consumes ?

Where do you think those string literals are stored?

@KIIV in SRAM ?

SRAM is volatile, meaning it can't remember anything without being powered

Just to expand on what JRobert said, variables which are initialized, and other literals (eg. the word "foo" in your example) have to come from somewhere, and thus are stored in program (flash) memory and copied into RAM as part of the C++ initialisation.
However, uninitialised variables do not take up flash memory. Compare:
char foo [1000];
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
  Serial.print (foo);
}

void loop()
{
}

This reports for the Uno:
Sketch uses 1498 bytes (4%) of program storage space. Maximum is 32256 bytes.
Global variables use 1192 bytes (58%) of dynamic memory, leaving 856 bytes for local variables. Maximum is 2048 bytes.

However if you initialise that global variable foo, like this:
char foo [1000] = { 1, 2, 3, 4, 5 };
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
  Serial.print (foo);
}

void loop()
{
}

Now the flash takes 1000 more bytes:
Sketch uses 2498 bytes (7%) of program storage space. Maximum is 32256 bytes.
Global variables use 1192 bytes (58%) of dynamic memory, leaving 856 bytes for local variables. Maximum is 2048 bytes.

This clearly shows that, since uninitialised variables at global scope are set to zero, the compiler has generated code to do just that. However initialised variables have to be copied from flash into RAM.
A very useful technique when using these chips with not much RAM is to use the "F" macro, which effectively tells the compiler to copy strings directly from flash, rather than into RAM, thus saving RAM space. For example:
Serial.println (F("Hello, world"));

In this case the string "Hello, world" still has to be in flash, but doesn't have to be copied into RAM, thus saving precious memory for other purposes.

Putting initialised arrays into flash
I've got a lengthy discussion about using PROGMEM for storing data, other than just literal strings for printing on my forum.
This example code here shows how you can store messages in PROGMEM (flash memory) and retrieve them at runtime. It uses pgm_read_word to read the pointers, and then strcpy_P to copy the string from PROGMEM into RAM, so it can then be printed.
const int NUMBER_OF_ELEMENTS = 10;

const char Message0000 [] PROGMEM = "Twas bryllyg, and ye slythy toves";
const char Message0001 [] PROGMEM = "Did gyre and gymble";
const char Message0002 [] PROGMEM = "in ye wabe:";
const char Message0003 [] PROGMEM = "All mimsy were ye borogoves; And ye mome raths outgrabe.";
const char Message0004 [] PROGMEM = "\"Beware the Jabberwock, my son! \n The jaws that bite, the claws that catch!";
const char Message0005 [] PROGMEM = "Beware the Jubjub bird, and shun\n The frumious Bandersnatch!\"";
const char Message0006 [] PROGMEM = "He took his ";
const char Message0007 [] PROGMEM = "vorpal sword in hand:";
const char Message0008 [] PROGMEM = "Long time the manxome foe he sought - ";
const char Message0009 [] PROGMEM = "So rested he by the Tumtum tree, \n And stood awhile in thought.";

const char * const messages[NUMBER_OF_ELEMENTS] PROGMEM =
   {
   Message0000,
   Message0001,
   Message0002,
   Message0003,
   Message0004,
   Message0005,
   Message0006,
   Message0007,
   Message0008,
   Message0009,
   };

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

  unsigned int count = 0;

  for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
    {
    char * ptr = (char *) pgm_read_word (&messages [i]);
    char buffer [80]; // must be large enough!
    strcpy_P (buffer, ptr);
    Serial.println (buffer);
    count += strlen (buffer) + 1;
    }   // end of for loop

  Serial.print (F("String memory used = "));
  Serial.println (count);

  }  // end of setup

void loop () { }

This particular example doesn't use much RAM:
Sketch uses 2220 bytes (6%) of program storage space. Maximum is 32256 bytes.
Global variables use 188 bytes (9%) of dynamic memory, leaving 1860 bytes for local variables. Maximum is 2048 bytes.

Thanks for your contribution.

The values of your initialized-data (.data) are stored in flash together with your code. The initialized-data gets copied to RAM after every upload, reset, or power-up, before your code starts executing.

That's why the F("macro") and overloaded methods in Arduino core exists to avoid this RAM "spam". However Atmega4809 doesn't need it as it has all memories mapped into single address space. Or ARM based boards doesn't need this.

@JRobert, Interesting behavior. So everything in the .data segment eats from the flash area, right?

@embeddedstack, the flash memory in MCU is the 'hard drive'

Yes - the .data segment contains the variables for which you have specified initial values. Those values have to be stored in non-volatile memory to initialize the variables in RAM before execution begins.


text:
AfMotor Shield Library does not work with template programming
I am able to move motors using AfMotor Shield Library. ( https://github.com/adafruit/Adafruit-Motor-Shield-library )
Like :
AF_DCMotor insertionMotor(1);
AF_DCMotor pumpMotor(2);

void setup()
{
  insertionMotor.setSpeed(255);
  pumpMotor.setSpeed(255);
  insertionMotor.run(RELEASE);
  pumpMotor.run(RELEASE);
  insertionMotor.run(FORWARD);
  pumpMotor.run(FORWARD);
}

But if I want to write it like this, only the motor with the template expansion that I called last works.
enum class direction {
  FRW = 0x01,
  BCKW,
};

template<int n, direction type>
class Motor : public AF_DCMotor {

public:

  Motor() : AF_DCMotor(n) {
    setSpeed(255);
    run(RELEASE);
    run(type);
  }
};
Motor<1, direction::FRW> fanMotor;
Motor<2, direction::FRW> pumpMotor;

Only the pumpmotor is running. Or if I call the fanMotor after the pumpMotor, it still works.If I remove pumpmotor and leave only fanMotor, the fanMotor also works. Is there something I overlooked?

Your code gives me a compiler error: in
run(type);

the run() method expects a uint8_t, but it is given a direction.
Adding an explicit cast to uint8_t makes it compile.
Now, as a general rule, I would advice you to never touch the hardware
in a constructor. The problem is, if you create a global object (like
you are doing here), the constructor gets called before main(), thus
before the Arduino core has had a chance to initialize the hardware. If
your constructor touches any hardware register, this may conflict with
the initialization the core is going to perform right at the start of
main().
The usual idiom for doing any hardware initialization is to define in
your object a method called begin(), and call it from setup():
template<int n, direction type>
class Motor : public AF_DCMotor {
public:
  Motor() : AF_DCMotor(n) {}

  void begin() {
    setSpeed(255);
    run(RELEASE);
    run((uint8_t) type);
  }
};

Yes you should do casting. (static_cast maybe more suitable). But it is not related about my problem.
Also with these lines, the constructor gets called before main()
AF_DCMotor insertionMotor(1);
AF_DCMotor pumpMotor(2);


text:
What component do I need (power)
I want to power my board using a 9v battery. I also want to power a component in my circuit from the same power source (9v battery) but ONLY when my board sends a signal (say from D1 pin).
What component allows me to restrict power this way? I don't want to activate the component through signal, but actually power it after the signal is sent.

A P-channel MOSFET driven by an N-channel MOSFET in the 9V connection? An N-channel MOSFET in the ground signal? A relay in either signal? There's lots of ways of achieving it - the best depends on what the "component" is you're controlling.

Having done further research and changing my search terms, it seems I can use a transistor as an electrical switch. I these methods and update with progress.

Are you using a 9V block battery? I hope not, because these are really only for low power applications. Otherwise you will drain it very fast and it might not be able to peovide enough current, depending on your components

Transistor was the component I was looking for, NPN. It is a 9v block battery, the circuit is only powered for minutes at a time, I'm only testing circuitry rather than running a finished product for the time being

You should use a MOSFET transistor, not a conventional transistor. Those have significant ON resistance, and waste a fair amount of power as heat. MOSEFETs have capacitive inputs and very low ON resistance, so are a better choice for efficiently switching power, particularly in battery-powered applications where you have to limit your average mA of power consumption. You'd also be better off using a switching regulator, as the built-in regulator in an Arduino is a linear regulator, which wastes any excess voltage as heat.


text:
Monitor two baud rates
I am using different codes which set different values of baud rate through the Serial.begin() function.
I have an Uno using Serial.begin(9600) connected to an ESP8266 ESP-01 module
SoftwareSerial WiFiBoard(2, 3);
WiFiBoard.begin(115200)

Both of them are printing and reading from Serial, but when I use Arduino IDE Serial Monitor, I'm only able to display the content of the 9600... Am I missing a setting somewhere?
Also, when I configure both of them to use the baud rate 9600, I still only see the Uno information

You can't have two different baud rates on the same serial connection. That is illogical.

My understanding is that by using the SoftwareSerial library, a new Serial connection is used

That is a completely separate serial connection. Nothing at all to do with the serial monitor.

Oh ! That makes a lot more sense now... So is there a way to actually monitor the two boards ?

Your PC only sees what the Arduino sends through Serial. If you want it to see something from somewhere else then you have to actively read that data from that "other place" and send it to your PC through Serial.

That makes so much sense now.. So I still can chose a different baud rate for the WiFiBoard, I can still write and read from it, but in order to display it in the serial monitor, I need to basically Serial.print(WiFiBoard.read()) ?

In short, yes.  Better: while (WiFiBoard.available()) { Serial.write(WiFiBoard.read()); }

Perfect, thank you!

Your computer can not see what is going over the WiFiBoard serial connection because that connection has nothing at all to do with the connection to your computer.
If you want your computer to see what is being received on that port you must read the data from that port then send it to your computer.
It doesn't (much) matter about the difference in baud rates (only that if one sends too much data too fast for the other to forward it you will lose some data).
It's common to use something like:
while (WiFiBoard.available()) {
    Serial.write(WiFiBoard.read());
}

That will forward anything received from the WiFi board over the serial port to the computer.


text:
Get client information on BLE
So I'm working on a personal project using bluetooth abilities to start a BLE server and want to automatically retrieve a client's information after it's connected: ID so I can keep track of clients, but brand/make, serial.. and other information would be good as well.
My ServerCallback class looks like this
class ServerCallbacks: public BLEServerCallbacks
{
  void onConnect(BLEServer* pServer)
  {
    deviceConnected = true;
    BLEDevice::startAdvertising();

    String deviceID = "XXXXX";

    Serial.print("new device ");
    Serial.print(deviceID);
    Serial.println(" connected");

  };

  void onDisconnect(BLEServer* pServer)
  {
    deviceConnected = false;

    String deviceID = "XXXXX";

    Serial.print("device ");
    Serial.print(deviceID);
    Serial.println(" disconnected");

    pServer->startAdvertising(); // restart advertising
  }
};

so, what is your actual problem and what is your question?

@jsotola How to retrieve client information after it's connected to the server. Multiple central devices will be querying this information and so I want to track who did and who did not


text:
L298N Motor Driver with Nodemcu/ESP32
I have seen a lot tutorials on L298N motor driver with nodemcu and ESP 32, which are 3.3v logic boards where the motordriver is a 5v logic board, now in Arduino while doing speed control 255 means 5v or even a high means 5v but in nodemcu/ESP32 this means 3.3v, so my question is how it will work ?

It's not a question of voltage. You make a basic mis-assumption:

in Arduino while doing speed control 255 means 5v

No, it doesn't.  255 means "Provide a logic HIGH signal all the time".
128 means "Provide a logic HIGH signal 50% of the time".
The 255 (or whatever number) is the "duty cycle" of a PWM signal. That is a digital signal that can be LOW or HIGH which is switching on or off rapidly. The duty cycle defines the ratio of ON time to OFF time.
You're not providing a voltage - you're providing an ON/OFF signal.
As long as the HIGH voltage of that signal is above the threshold of the receiving device (the L298N in this case) then it will see it as an ON/OFF signal.
According to the datasheet for the L298 the HIGH logic threshold (VIH) is 2.3V. That means anything above 2.3V is seen as ON and anyting below that is seen as OFF (actually there is hysteresis, so it has to drop below 1.5V to switch to OFF).
So your 3.3V from the NodeMCU is above that ON threshold, so the ON/OFF PWM signal is received properly as such.
Incidentally, it's because of this PWM signal that motors make a whining sound when they start up slowly. Because of this most proper motor drivers run the PWM at above 25kHz instead of the 500-ish Hz of the Arduino, so that whine is above the threshold of human hearing.

Explained with awesomeness!  :


text:
Issue with different ways of powering
I have a project to make where I have to read tags out of 5 RFID Readers and when every tag is in correct reader to open a relay. The schematic is the same with Annaane's with the difference I have 5 Readers, so I didn't make one.
I also have made the board that i have attached so I can connect all the common pins together (MISO, MOSI, SCK, RESET, 3.3V and GND)
The SDA SS pins are connected directly to pins 3-7 of Arduino.
My code works just fine when powering arduino through my Laptop's USB port but since it have to be installed somewhere I tried the following ways to power it:

USB coming from a Xiaomi 5v Phone Charger to Arduino's USB port
USB coming from this to Arduino's USB Port. It is being powered from a 12v 1amp power supply from and old router.
The 12v 1amp power supply from and old router.
L7805CV and it's suggested circuit from the datasheet

My problem is that none of these ways seem to work properly. What I mean is that I cant get readings from the Readers as it should do. I have an LED which lights up when it read a tag but at these cases it only lights up only on some of the readers. The strange part is that when I am charging my laptop and powering arduino through its usb port it doesnt work either.
Any help please?

On your board I see much of what seems to be flux residuals from soldering. Maybe you should clean that up. Depending on the flux, you might get unwanted connections there. I personally use the lighter fluid of my zippo.

This flux is there because I used to have a 5V regulator (L7805CV) but I desoldered it because id didnt seem to work properly. I dont think that this is the issue.

I am suspecting noise. Can you test once with a Power bank if you have access?