text:
ESP8266 constantly crashes in malloc-related "check_poison_neighbors(unsigned short)" when networking happens
My project involves a bunch of peripherals, but most importantly for this project, a request to an NTP time server is done using the standard NTPClient library. Suddenly, after modifying some seemingly unrelated parts of the code involving SdFat, the ESP8266 started crashing each time in the same place, somewhere deep within the networking firmware.
I have now had this problem with multiple variations, but every time, the crashing function was something that the Exception Decoder calls check_poison_neighbors(unsigned short). It appears to be nested in some memory allocating functions (guessing by the malloc names).
Below is the entire output of ESP Exception Decoder from one of the crashes.
Exception 3: LoadStoreError: Processor internal physical address or data error during load or store
PC: 0x40100fb5: check_poison_neighbors(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc/umm_local.c line 52
EXCVADDR: 0x40010059

Decoding stack results
0x4010109d: umm_malloc_core(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 422
0x4022cae4: mem_malloc at core/mem.c line 210
0x4010131c: umm_malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 511
0x4010017c: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_main.cpp line 177
0x4010134b: umm_poison_malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\umm_malloc/umm_poison.c line 155
0x4010072e: malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\heap.cpp line 228
0x4022cae4: mem_malloc at core/mem.c line 210
0x40226984: pbuf_alloc_LWIP2 at core/pbuf.c line 284
0x4022443c: dns_send at core/dns.c line 777
0x402245f7: dns_check_entry at core/dns.c line 1096
0x40224b11: dns_gethostbyname_addrtype at core/dns.c line 1502
0x40208a0c: wifi_dns_found_callback(char const*, ip4_addr const*, void*) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp line 707
0x40224b68: dns_gethostbyname at core/dns.c line 1530
0x40208b80: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&, unsigned int) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp line 623
0x4020e554: operator new(unsigned int) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\abi.cpp line 39
0x40209b3f: WiFiUDP::begin(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 83
0x4010072e: malloc(size_t) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\heap.cpp line 228
0x4022cae4: mem_malloc at core/mem.c line 210
0x4020e554: operator new(unsigned int) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\abi.cpp line 39
0x40209b3f: WiFiUDP::begin(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 83
0x40208c00: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\ESP8266WiFiGeneric.cpp line 605
0x402095bc: WiFiUDP::beginPacket(char const*, unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 140
0x40209b3f: WiFiUDP::begin(unsigned short) at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\libraries\ESP8266WiFi\src\WiFiUdp.cpp line 83
0x40209db1: NTPClient::sendNTPPacket() at C:\Users\USERNAME\Documents\_H\Arduino\libraries\NTPClient\NTPClient.cpp line 174
0x40209df1: NTPClient::forceUpdate() at C:\Users\USERNAME\Documents\_H\Arduino\libraries\NTPClient\NTPClient.cpp line 76
0x40209e93: NTPClient::update() at C:\Users\USERNAME\Documents\_H\Arduino\libraries\NTPClient\NTPClient.cpp line 99
0x40205317: setup() at PROJECT_MAIN_FILE.ino line 173
0x4020e7e4: loop_wrapper() at C:\Users\USERNAME\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.7.1\cores\esp8266\core_esp8266_main.cpp line 194

Lines 170-173 in my main project file read:
// start ntp client
timeClient.begin();
timeClient.update();
yield();

The code before that ensures that a WLAN (WiFi) connection has been established, which I also confirmed from the ESP internal debug output to the serial port.
This is one of the lifecycle serial logs:
SDK:2.2.2-dev(38a443e)/Core:2.7.1=20701000/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
# SD ok.
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 2
cnt

connected with ACCESS_POINT_NAME, channel 11
dhcp client start...
wifi evt: 0
ip:192.168.178.76,mask:255.255.255.0,gw:192.168.178.1
wifi evt: 3
# Display ok.
# Waiting on WLAN
# WLAN connected.
[hostByName] request IP for: europe.pool.ntp.org
[hostByName] Host: europe.pool.ntp.org IP: 212.92.16.193
:urn 48
:urd 48, 48, 0
# Checking status...

 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld

The lines starting with "#" are my own logging output which confirms external hardware and WLAN connectivity. Note the [hostByName] lines, which are triggered by the NTP client's DNS lookup. Somewhat randomly, on some resets they will not show up and I will get the above exception and stack trace, and other times, like shown in this serial log, they do show up and the ESP8266 resets without causing an explicit exception and stack trace log. Weird.
I have checked multiple solutions and reflashed the firmware etc. Flash is 415660 Bytes (39%) and global variables 32848 Bytes (40%). Any help would be appreciated.

cause 4 is watchdog reset

If you're corrupting memory, the crash will most likely not happen where you cause the problem, it will happen in other code that's working with the damaged area of memory. If you can cut your program down to at the smallest program that still demonstrates the problem, someone may be able to point out the issue to you.  You might even find it yourself.

Thanks. I have found a wrong allocation inside some other code, fixing that leads to new poison errors I may be able to track futher.


text:
esp32 board crashes
I try to connect sensors to esp32 board. when connecting a sensor, for example, DHT11, but it happens with others as well the board enter into a loop of boots with the following error
19:36:37.440 -> rst:0x10 (RTCWDT_RTC_RESET),boot:0x13(SPI_FAST_FLASH_BOOT)
19:36:37.440 -> flash read err, 1000
19:36:37.440 -> ets_main.c 371
19:36:37.772 -> ets Jun  8 2016 00:22:57

I tried to upload the board with led connected between the Vout and the GND and same thing happens.
any idea? where is the problem? blink catch with led connected between GND and a pin work fine.
I attach the board picture
many thanks,
Gilad

does the board work correctly when no sensors are connected?

"I tried to upload the board with led connected between the Vout and the GND", what is that for? Are you connecting an LED between Vcc and GND without a resistor?

@jsotola, Yes without sensors it works fine, can connect to wifi, upload data to firebase and blink led

@hcheung with a resistor. I thought to debug if the problem is with the sensor or the connection to Vout-GND. I connect the Vout to the CLK pin in the picture

I don't see a Vout on the board in the picture and the description of your setup is not very clear to me. Make sure you're not connecting pins carrying 5V directly to any pins of the ESP32 (which is a 3.3V device). Could you describe how you connect the sensor or show a schematic?

A flash read error might occur when you have the wrong partition scheme selected. Try with board type "ESP-dev-module" and a 4MB partition scheme.

source: Stack Exchange

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

sort: votes


text:
Global variable changes its value when loop starts again
I have a problem with the global variable calibrationValue. It is initially set with the correct value and is also displayed correctly in the output. As soon as the loop function is restarted, the value of the variable is wrong, although it is not rewritten. Can someone help me please?
The following values are printed in the image:

new AI value
wrong calibrationValue (!)
sumOfValues (needed for calculation of calibrationValue) correct
numValues (needed for calculation of calibrationValue) correct
Text and calibrationValue (correct!)

    int op_mode_Pin = 7;                      // Digital input Pin which transmittes the op_mode_Ardui
    int op_mode_Ardui;                        // Operator Mode of Arduino
    int returnValue1 = 12;                    // First digital return value for transmitting box weight
    int returnValue2 = 13;                    // Second digital return value for transmitting box weight

    int sensorPin = A0;                       // Select the input pin for the potentiometer
    long weightValue = 0;                     // Variable to store the value from the sensor
    long calibrationValue = 0;                // Value which is filled in calibration progress
    int numValues = 50;                       // Number of taken values for calculating an average
    int thresBoxWeight = 300;                 // Weight for separating heavy and light boxes

    unsigned long sumOfValues;                // Sum of the taken values
    unsigned long aveOfValues;                // Average of the values

    char stringBuffer[30];                    // Buffer for combining string and variables

    void setup() {
      // Initiate serial communication to screen
      Serial.begin(9600);

      // Initiate some variables
      //weightValue = 0;
      //calibrationValue = 0;
      //numValues = 50;
      //thresBoxWeight = 300;

      // Set the Input Pins for op_mode_Ardui
      pinMode(op_mode_Pin, INPUT);            // sets the digital pin 7 as input

      // Set the Output Pins for Box declaration
      pinMode(returnValue1, OUTPUT);          // sets the digital pin 12 as output
      pinMode(returnValue2, OUTPUT);          // sets the digital pin 13 as output

    }

    void loop() {
      Serial.println(analogRead(sensorPin));
      Serial.println(calibrationValue);
      // Reset of Sum and Average variables for next cycle
      sumOfValues = 0;
      aveOfValues = 0;
      op_mode_Ardui = digitalRead(op_mode_Pin);

      if (op_mode_Ardui == HIGH){
        for (int i=0; i<numValues; i++){
          weightValue = analogRead(sensorPin);                                                  // read the value from the sensor
          sumOfValues = sumOfValues + weightValue;                                              // Build the sum of all values
        }
        Serial.println(sumOfValues);
        Serial.println(numValues);

        calibrationValue = sumOfValues / numValues;
        sprintf(stringBuffer, "Calibration accomplished with value: %d", calibrationValue);     // Combine text and variable to output
        Serial.println(stringBuffer);                                                           // print text and variable to screen
        delay(3000);
      }
    }

This:
sprintf(stringBuffer, "Calibration accomplished with value: %d", calibrationValue);

is a buffer overflow: the function sprintf() is writing a 40-byte
string into a 30-byte buffer. Whatever happens to lie in memory right
after the buffer will be overwritten by sprintf(). Apparently this
happened to be calibrationValue. You should use
snprintf() rather that sprintf(), as the former is designed to
prevent this kind of overflows.
Or better yet, stick with Serial.print[ln]():
Serial.print("Calibration accomplished with value: ");
Serial.println(calibrationValue);

Edit: You may notice that 13108 is the same as 0x3334, which on a
little endian architecture is stored in memory as 0x34 0x33. These are
the ASCII codes for "43", which is part of what sprintf() wrote past
the end of the buffer.

it's interesting that the buffer overflow in stringBuffer overwrites a variable defined further up in the file. In most compilers your globals get allocated in memory roughly in the order you declare them. (Optimizing compilers on 32 and 64 bit platforms might do some re-ordering to make variable sized structures fit in less memory while honoring word/longword/double alignment, but most Arduinos are 8 bit devices where there's no such thing as word alignment.)

It worked. I never thought that an overflow could affect global variables. Thank you.

On a real mode machine like an Arduino, a buffer overflow stomps whatever is in RAM. Global variables, data on the heap, whatever. And there's nothing stopping it.

@DuncanC: I don't know how the linker decides on the allocation order. I tried compiling the OP's code with avr-g++ 7.3.0, as shipped with the Arduino IDE 1.8.13, and the .bss section contains timer0_fract, timer0_millis, timer0_overflow_count, stringBuffer, sumOfValues, calibrationValue and Serial, in this order. If I remove -flto from the compiler's command line, I get a different allocation starting with stringBuffer, aveOfValues (which was optimized out with -flto), sumOfValues, calibrationValue

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


text:
SSD1306 allocation failed when adding a constant
I am trying to get this code working:
#include <Button.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RTC_DS1307 RTC;

// when I remove this part it works...
int mode = 1;
const String periodicSystem[60] = {
    "H", "He", "Li", "Be", "B", "C", "N", "O",
    "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S",
    "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr",
    "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge",
    "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb",
    "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
    "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd"
};
/////////////////////////////////////////////////////////////////////

Button button1(7);

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

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // This will reflect the time that your sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  display.display();
}

void loop() {
  DateTime now = RTC.now();
  if(button1.pressed()) {
      display.clearDisplay();
      display.setTextSize(1); // Draw 2X-scale text
      display.setTextColor(WHITE);
      display.setCursor(10, 0);
      display.print(now.second());
      display.display();
  }
}

Whenever I try to add the constant periodicSystem, I get the error SSD1306 allocation failed over Serial. The error also goes away when I remove the part with button1.pressed(). Basically I am not able to add the constant periodicSystem and read out a digital pin at the same time. To me it seems to be some sort of memory issue (I am only adding the constant, I am not doing anything else with it), but my IDE tells me I am only using 52% of the available storage. What am I doing wrong?
Here is my wiring (in reality I am using a 128x32 display, I didn't have the correct part for Fritzing; my display is labeled SDA, SCK, VCC, GND instead of SDA, SCK, VDD, GND; the RTC Module I am using is a DS1307 AT24C32 RTC Module):

Hint: Consider a more memory efficient storage for the string table. Using Arduino String for this is a very very very bad idea. Use character strings and put the whole table in program memory. Ref. https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

Your display needs 624 bytes of RAM for its internal buffer (128 * ((32 + 7) / 8)). The periodicSystem array needs a massive 360 bytes of RAM just for the objects. That doesn't include the memory used to store the actual string data, which by my reckoning is 168 bytes.
So far we're up to 624+360+168 = 1152 bytes of a maximum of 2048.  Over half way and we haven't touched on the serial buffers or other objects that you're using.
An array (const or otherwise) of String objects is by far the least efficient way possible of storing constant string data on an Arduino. You're using 528 bytes of RAM to store what could be stored in 121 bytes of flash.
Personally I would store the data thus:
const char periodicSystem[] PROGMEM = "H HeLiBeB C N O F NeNaMgAlSiP S ClArK CaScTiV CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY ZrNbMoTcRuRhPdAgCdInSnSbTeI XeCsBaLaCePrNd";

Each symbol consists of exactly two bytes, and the PROGMEM forces it to stay in flash and never be copied to RAM.
You can get the two bytes of each symbol with:
char b1 = pgm_read_byte(periodicSystem + (i * 2));
char b2 = pgm_read_byte(periodicSystem + (i * 2) + 1);

Then either print them separately, or combine them into a C string:
char symbol[3] = { b1, b2, 0 };

That will include the space character, of course. So you could remove that if you like:
if (symbol[1] == ' ') symbol[1] = 0;

Theoretically you could also change the spaces in the original data to be character 0 if you like - depending on what you do with it, it shouldn't cause any issues:
const char periodicSystem[] PROGMEM = "H\0HeLiBeB\0C\0N\0O\0F\0NeNaMgAlSiP\0S\0ClArK\0CaScTiV\0CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY\0ZrNbMoTcRuRhPdAgCdInSnSbTeI\0XeCsBaLaCePrNd";


text:
How to send signal ONCE when within constant range of sensor?
I am working on a project to have a open/close a solenoid at certain ranges (using HC-SR04 ultrasonic sensor).
#include <NewPing.h>2

#define Relay1 7
#define Relay2 8

NewPing SonarRight(12, 11, 400);

void setup() {
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
}

void loop() {

  unsigned int uS1 = SonarRight.ping();
  delay(50);

  if (uS1 / US_ROUNDTRIP_CM > 15)
    digitalWrite(Relay1, HIGH);
    delay(100);
    digitalWrite(Relay1, LOW);
    delay(1000);

  if (uS1 / US_ROUNDTRIP_CM < 5)
    digitalWrite(Relay2, HIGH);
    delay(100);
    digitalWrite(Relay2, LOW);
    delay(1000);
}

I got the sensor to ping correct and the distances are reading accurately.  I have it to where once sensor reads that the object is more than 15cm away, the solenoid opens but it keeps clicking open until the object goes back to the dead zone (5-15cm).  Same thing when less than 5cm.  Essentially what i am trying to accomplish is to have the solenoid fill up a tank when the water level get low.  So when the water drops 10cm (x>15) the solenoid opens and then once the water is replenished (x<5), the solenoid closes.
How do i go about doing this without sending a constant OPEN/CLOSE to the solenoid?  Is there a way to make a loop to have it send a the signal only once until it exits that defined range?
Please note that i have not actually used it for its intended purpose im supply moving an object back and forth to simulate water distance.
Thanks

You have to add a (global) variable that stores the last send command (to open/close).
When you send a command, you save it in the global variable.
And you only send a command when it is different than the command send the last time, so only CHANGES are sent.
The best way to do this is to make a specific function, e.g. SetSolenoid(bool open);
#define SOLENOID_OPEN  TRUE
#define SOLENOID_CLOSE FALSE

bool _currentSolenoidStatus = false; // Assume closed

In your loop:
...
if  ... condition when solenoid should be be opened
{
    SetSolenoid(SOLENOID_OPEN);
}
...
if  ... condition when solenoid should be be closed
{
   SetSolenoid(SOLENOID_CLOSE);
}

Function to open/close solenoid open (only when changed):
bool SetSolenoid(bool status)
{
    if (_currentSolenoidStatus != status)
    {
        // Send status to solenoid
        _solenoidStatus = status;
    }
}

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


text:
Tinyduino I/O line voltage level
Does anyone know what the I/O line voltage level is on the Tinyduino?
Tinyduino
I want to run a MAX7219 LED array with it, like this one:
LED Array

Whatever your power supply voltage is. If you run it from 5V you get 5V IO. If you run it from a 3V coin cell you get 3V IO.

So if I want to use 5V I/O (for the Max7219) and I want portable 3.7V lithium power, then I need a boost circuit to get it to 5V?  At least that's what I take from your answer.

That's correct.

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


text:
: Failed to open /dev/ttyACM0 (port busy)
I am trying to work with the (new) sparkfun razor IMU 9dof, I wrote a silple sktetch to calibrate the magnetometer:
#include <SparkFunMPU9250-DMP.h> // Include SparkFun MPU-9250-DMP library
#include <Wire.h> // Depending on your Arduino version, you may need to include Wire.h
MPU9250_DMP imu; // Create an instance of the MPU9250_DMP clas
void setup() {
  Serial.begin(115200);

  Serial.println(F("Adafruit 10 DOF Board AHRS Calibration Example")); Serial.println("");

  if (imu.begin() != INV_SUCCESS){
    while (1) {
    Serial.println("Failed to initialize MPU-9250, loop forever");
   }

  }

 imu.setGyroFSR(2000); // Set gyro to 2000 dps

 imu.setAccelFSR(2); // Set accel to +/-2g

 imu.setLPF(5); // Set LPF corner frequency to 5Hz

 imu.setSampleRate(100); // Set sample rate to 10Hz

imu.setCompassSampleRate(100); // Set mag rate to 10Hz
}

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

  // Print the sensor data
  Serial.print("Raw:");
  Serial.print(imu.ax);
  Serial.print(',');
  Serial.print(imu.ay);
  Serial.print(',');
  Serial.print(imu.az);
  Serial.print(',');
  Serial.print(imu.gx);
  Serial.print(',');
  Serial.print(imu.gy);
  Serial.print(',');
  Serial.print(imu.gz);
  Serial.print(',');
  Serial.print(imu.mx);
  Serial.print(',');
  Serial.print(imu.my);
  Serial.print(',');
  Serial.print(imu.mz);
  Serial.println();

  delay(50);
}

To be sure the Arduino IDE can access to dev/ttcACM0, I did   sudo chmod 666 /dev/ttyACM0
I can dowload successfully but when I want to open the terminal I got the following error:
Erreur d'ouverture du port série « /dev/ttyACM0 ». (Port busy) (see attached screenshot)
More over when I entered dmesg on the console, I can see the following messages:
[   94.133923] usb 3-2: USB disconnect, device number 2
[   94.133978] cdc_acm 3-2:1.1: urb 12 failed submission with -19
[   94.135862] cdc_acm 3-2:1.1: urb 13 failed submission with -19
[   94.136059] cdc_acm 3-2:1.1: urb 14 failed submission with -19
[   94.136257] cdc_acm 3-2:1.1: urb 15 failed submission with -19
[   94.136457] cdc_acm 3-2:1.1: urb 2 failed submission with -19
[   94.136656] cdc_acm 3-2:1.1: urb 3 failed submission with -19
[   94.136852] cdc_acm 3-2:1.1: urb 5 failed submission with -19
[   94.137048] cdc_acm 3-2:1.1: urb 6 failed submission with -19
[   94.138841] xhci_hcd 0000:03:00.0: WARN Cannot submit Set TR Deq Ptr
[   94.138843] xhci_hcd 0000:03:00.0: A Set TR Deq Ptr command is pending.
[   94.931853] usb 3-2: new full-speed USB device number 3 using xhci_hcd
[   95.316578] usb 3-2: New USB device found, idVendor=1b4f, idProduct=9d0f
[   95.316581] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[   95.316582] usb 3-2: Product: SFE 9DOF-D21
[   95.316584] usb 3-2: Manufacturer: SparkFun
[   95.320306] cdc_acm 3-2:1.0: ttyACM0: USB ACM device
[  858.774849] usb 3-2: USB disconnect, device number 3
[  904.529058] TCP: wlp1s0: Driver has suspect GRO implementation, TCP performance may be compromised.

Does anyone outhere experienced such issue?
Thank you for your help
Fabrice

Remove the modemmanager package.

Also you should add your user to the group which owns serial devices - the chmod trick would have to be repeated every time you reboot or replug the board.  Finally, you can use lsof | grep ttyACM to see which process is holding the port (might possibly need to run lsof as root, but try it first as yourself)

Just to odd simple things out first: have you closed all serial monitors in other instances?

sudo apt-get purge modemmanager
It helps me for linux user and for many other peoples.
Now I am playing with stm32f103 and opening port was painfull.
That  was problem only for stm32 chip. Arduino nano was working without problems.
Before I need reopened few times port to initiate communication.
That was painfull. After finding that solution now Arduino ID is working without problems.
 I am not sure if deleting modemmanager will have impact for my system.

I solved following serial port related problems in ubuntu 18.04 as follows:
Problem 1 :  Cannot open /dev/ttyACM0: Permission denied
Solution  :  Grant permissions to read/write to the serial port with this terminal command --->  sudo chmod a+rw /dev/ttyACM0
Here replace tty port with your respective ubuntu port.
Problem 2 : Failed to open /dev/ttyACM0 (port busy)
Solution  : This problem appears when serial port is busy or already occupied. So kill the busy serial port with command ---> fuser -k /dev/ttyACM0. Here replace tty port with your respective ubuntu port.
Problem 3 : Board at /dev/ttyACM0 is not available
Solution : In this case, your serial port in tools menu will be greyed out. I googled a lot for this, but  none of  solution worked for me. Atlast I tried different arduino board and usb connector and it was working for me. So, if you are having old arduino board (can be solved using required drivers) or defected arduino board then only this problem arises.

You need to be part of the dial out group. Try this:
Type 'groups', is 'dialout' there ?
sudo usermod -a -G tty yourUserName
Example sudo usermod -a -G tty gil
Log off and log on again for the changes to take effect.
This has consistently worked for me and is now in some of the Arduino install packages.

When I had this problem I discovered that running ps x showed a lot of tasks involving temporary mount files. So I closed Arduino, ran sudo rm -rf /tmp/.mount_arduin* and restarted Arduino. The device attached successfully.


text:
Mega attachInterrupt on pins 18 or 19 require EIFR bit set first (to clear it)?
Experimenting with external interrupts on a Mega. Pins 2 and 3 work with standard
attachInterrupt(digitalPinToInterrupt(iPin),ISR,FALLING);
coding and call my ISR. With pins 18 and 19 I had to add
EIFR = 4;

for pin 19, and
EIFR = 8;

for pin 18 before calling attachInterrupt(...) to get them to work. Why?
BTW, I'll add this table that I filled in by trial and error for anyone interested in Atmel (AVR) external interrupt numbers to Arduino external interrupt numbers (I won't list the AVR chip pin numbers)
AVR INT      5 .  4 .  3 .  2 .  1 .  0
EIFR (Dec)  32 . 16 .  8 .  4 .  2 .  1
Arduino Pin  3 .  2 . 18 . 19 . 20 . 21
Arduino INT  1 .  0 .  5 .  4 .  3 .  2

I know writing a 1 to the EIFR bit for the appropriate interrupt clears the interrupt. When I reset the Arduino without clearing interrupts on pins 2 and 3 it's fine. If I don't clear 18 and 19 after a reset, it throws the interrupt right away. (Yes, I should OR the EIFR with the bit I want to change but I'm just playing) Didn't try 20 and 21 because I'm using them for comm.

It's not that pins 18 or 19 are faulty, you are just lucky the other ones worked.
As I mention on my page about interrupts* you are recommended to always write 1 to the appropriate EIFR bit before enabling interrupts because it (the interrupt condition) may have been set in the past.
I checked the source for attachInterrupt in the file WInterrupts.c and there is no mention of the EIFR register, therefore attachInterrupt never affects that register.

* Also see my answer: How do interrupts work on the Arduino Uno and similar boards?

Wow! I know where I'll be spending the next few hours. Thanks!


text:
Unsure how to get pressure data from MCP3424
I am having trouble reading data from an MCP3424 chip, specifically the one from this website:
https://uk.rs-online.com/web/p/general-purpose-adcs/6696086/
I have a pressure transducer that connects to the MCP3424 chip. The chip is then connected to a NodeMCU 1.0. Schematics are attached.
The pressure transducer comes from here:
https://www.edwards.com/gb/devices/pressure-monitoring/transducer?WT.ac=eu_truwave
It is run into a 9-pin VGA adapter
I am new to this kind of stuff, and I do not know what code is needed on the NodeMCU to read the data coming in from the pressure transducer via the MCP3424 chip. My code currently contains code from here:
https://github.com/bersch/MCP3424
My code is set to upload the error message I am getting from the MCP3424 to a spreadsheet so I can read the error. The error I get is "i2c". I am not sure what that means. I have tried contacting the author of the code but I have not received a response in a few weeks. I simply want to read the pressure I am getting from the pressure transducer from the MCP3424 chip.
Some useful information about the MCP3424 chip can be found here:
http://ww1.microchip.com/downloads/en/DeviceDoc/22088b.pdf
If anyone can provide any guidance, code, or helpful advice, that would be extremely appreciated.
Link to my post on the arduino forum, which includes my code, is here:
https://forum.arduino.cc/index.php?topic=588831.0
Thank you.

my bet is on a wrong I2C address. run the I2C scanner sketch and adjust any hard-coded value on the sensor demo sketch once you identify the module. If it doesn't show up un the scanner, try adjusting the wires.

I ran the i2c scanner and all I get is a bunch of unknown errors at every address...what does this mean about the board?

It means it's hooked up to the MCU wrong, you forgot the I2C pullups (sometimes they can be ignored, sometimes not) or it doesn't have enough voltage/current. It's possible the module or board is defective, but that's a lot rarer than user error.


text:
Attempting to read random string from SD card
I was wondering if anyone knew how to read in a random string from a file named "PhraseList.csv" or "PhraseList.xlsx" (whatever is easier)? There is a list of 10k.
#include <SD.h>
#include <SPI.h>

File myFile;

void setup()
{

 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // re-open the file for reading:
  myFile = SD.open("PhraseList.xlsx");
  if (myFile) {
    Serial.println("PhraseList.xlsx":);

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening Phrase List");
  }
}

void loop()
{
    // nothing happens after setup
}

what is random string? ......... what does this mean? There is a list of 10k.

Reading an individual string from a list in a file is not a simple operation. Well, it's "simple", but takes a lot of work.
It's not possible to say "Get me line number 2984 from the file" with a normal text file.  You, instead, have to get each line in turn, discarding the ones you don't want, until you get to line 2984.
A better way would be to create custom "indexed" file format with a file header structure describing the rest of the file.  That header structure would contain (amongst other possible things) the offset within the file of each string it contains.
For example you may choose to have the simplest arrangement - a list of 32 bit integers (4 bytes each), each one a simple offset from the start of the file for the string that corresponds to the same number, and have the strings NULL terminated in the file.
Such as:
00000000: 0c000000 17000000 22000000 53747269  ........"...Stri
00000010: 6e67206f 6e650053 7472696e 67207477  ng one.String tw
00000020: 6f005374 72696e67 20746872 656500    o.String three.

The idea with this now is you can seek in the file to "String no * 4" and read 4 bytes as an unsigned long (arranged little endian, like the Arduino uses), then use that value to do another seek. From there you can read bytes until you hit \0, at which point you know you have finished the string.
In the example above the string "String one" is located at offset 12 within the file.  That's 0x0C in hexadecimal, or 0x0c 0x00 0x00 0x00 as a little-endian 32-bit integer.  That's the first 4 bytes in the file.  So you read those, interpret them as a 32-bit integer (12), then seek to that location in the file to get your string.
void readString(int num) {
    // Seek to the index entry
    myFile.seek(num * 4);

    // Read the index entry
    unsigned long offset = 0;
    myFile.read(&offset, 4);

    // You might want to add some sanity checking here

    // Seek to where the index points to
    myFile.seek(offset);

    // Read each character until you get a NULL.
    char c = myFile.read();
    while (c > 0) {
        Serial.write(c);
        c = myFile.read();
    }
    Serial.println();
}


text:
What is the proper wiring for relay module?
I want to know the recommended wiring for relay. I am setting it up as NO.

Where should I connect the relay, the hot wire or the ground wire?
Where should I connect the wire going to bulb, NO or C pins of relay? Where should I connect the wire going to AC, NO or C?

For that setup it doesn't matter in the slightest.

ALWAYS switch the hot wire with the relay (or any switch), never the neutral wire. This prevents a hazardous voltage being present at the bulb, when the switch/relay is turned off. Important safety measure for electricians.

@chrisl good point. I added that bit to my answer. It's an important safety measure for non-electricians as well. (Electricians should know better)

@chrisl While that may be good in principle, in practice it's generally irrelevant. At least in countries with non-polarized sockets, like the USA and most of Europe and Asia. That is, pretty much anywhere except the UK and India...  There's no "Hot" (I HATE that word!) or neutral wire in an appliance.

A relay is a simple switch controlled by an electromagnet coil. The "NO" (normally open) side is off until you apply power to the coil. The "NC" (Normally closed) side is on until you supply power to the coil, at which point it turns off. Switches don't have polarity. If you connect the common into one part of a circuit and the "NO" side into the other, it doesn't matter which goes where.
Edit:
As another poster pointed out, you should wire the relay so it switches the hot leg from the plug, not the neutral (Assuming you're in the US or another country with polarized plugs.) That is much safer, since it means when the relay is off, the lamp is only connected to the neutral line. If, instead, you wire the relay to switch the neutral leg then the lamp will ALWAYS be connected to hot, and if somebody touches the wires they could get a shock.
Important:
What does matter is how you power the relay. If you try to drive a simple relay directly from a logic pin, it will likely damage or destroy the Arduino.
If you're using a "digital" relay that takes a constant 5V source, and a logic level control, such relays have built in transistors and protection diodes that prevent the relay coil from destroying solid state electronics.
If you're using a simple relay, you'll need an appropriate transistor to boost the current to the coil, as well as a "flyback diode" to protect the transistor from back-EMF when the coil is disconnected.

Connect the bulb to the NO pin of the relay.
Image source from: https://ncd.io/relay-logic/

One point: In the US, polarized AC plugs are almost universal. The smaller blade is connected to the black, hot wire, and the wider blade is connected to the white, neutral wire. It's the convention to connect the outer threaded part of an Edison lightbulb socket to the neutral and the inner "tab" on the socket to the hot.

That's because users are more likely to accidentally touch the outer part of the socket while screwing in bulbs, and if your house is wired correctly you shouldn't get a shock from the neutral wire (where you will get a shock from the hot wire if you touch it, or touch metal that's in contact with it.)

@DuncanC - Regarding this part of your comment: "..you will get a shock from the hot wire if you touch it...". That is not always true. The only time you could get a shock is if another part of your body is touching the neutral or ground potential at the same time. I just did a simple experiment before posting this. While standing on a dry, hardwood floor with shoes on, I took a pair of stainless steel nail clippers and inserted the "nail file part of it" into the hot 120VAC side of the receptacle. Nothing happened. I didn't feel anything. Nothing happened in the neutral side either.

Fair enough. I should have said "You CAN get a shock..." You have to be at least partially grounded. If you're isolated from ground you won't pass any current. Note that if you're standing on a damp concrete floor, or have your other hand on a grounded metal object, you could be killed.


text:
How to wire L293D chip to a nodeMCU?
How do I wire an L293D motor controller chip to a nodeMCU?
I have tried to follow the instructions from this tutorial: lastminuteengineers.com
One problem. I don't have a 5v pin?
Are there any alternative ways to wire this?
All of the other tutorials i see, only say to use a special other motor driver board with an L293D embedded in it, and with extras connected to the board.

why would you need a 5 V pin? ... you can't power the L293D from the nodeMCU anyway

Yeah. can you wire Vcc1 and Gnd (pin 5) (L293D Breakout) on the L293D to an external source, and not the NodeMCU?

I figured it out. I am putting a logic level converter On the 3v pin to step it up to 5v


text:
Where is the Arduino IDE log file located? Not the Serial Monitor
"An error ocurred while uploading the sketch"
I'm having this specific error when uploading a sketch to my board and the IDE doesn't specify the problem correctly.
It's version is 1.8.13 for Windows 10.
I would like to get a file with detailed information about the IDE's error. Where should I look for it?

Turn on verbose errors in preferences. It will display more errors. And use the scroll bar in the output panel to scroll back to see the error. There is no log file.

If there is no log file, this response seems like a proper answer.

There is no log file. Instead you need to turn on both "compilation" and "upload" under the "Show verbose output during:" option in Preferences.
This will give you far more information about any errors in the output scroll pane at the bottom of the IDE.
On Linux if you run the IDE from the command line you get large amounts of logging on stdout. There may be a way of doing the same from Windows.


text:
Is this circuit risky for an Arduino Uno?
I will show a connection diagram between my Arduino Uno and a DSC HS2032 panel (alarm system).
The DSC panel uses 12V and I don't know the voltage fluctuation.
The yellow and green are RX/TX ports.
Github file: https://github.com/taligentx/dscKeybusInterface/blob/master/examples/Arduino/KeybusReader/KeybusReader.ino
DIAGRAM (I assume the vertical "+--+" means a simple "OR" connection):
  DSC Aux(+) --- Arduino Vin pin

  DSC Aux(-) --- Arduino Ground

                                 +--- dscClockPin (Arduino Uno: 2,3)
  DSC Yellow --- 15k ohm res ----|
                                 +--- 10k ohm resistor --- Ground

                                 +--- dscReadPin (Arduino Uno: 2-12)
  DSC Green ---- 15k ohm res ----|
                                 +--- 10k ohm resistor --- Ground

I need to make sure this diagram is SAFE, and will not overheat or do something risky to my Arduino.
Why is this circuit not going to burn my Arduino if it is using 12V?

There is a schematic editor built in to the question editor, you know... No need for dodgy ASCII art...

The vertical +-+ is not an or, but an and. You need to connect both. These are pulldown resistors

@Majenko I also think that dodgy ASCII art is disgusting, but I took it "as it is" from the Github file which I don't own.

That circuit is fine as long as the input signals don't go above 12.5V.  You can protect it further by adding a 5.2V zener diode across each of the signals as they enter the Arduino:

simulate this circuit – Schematic created using CircuitLab

Why is this circuit not going to burn my Arduino if it is using 12V?

Because it uses a voltage divider to reduce the voltage to 4.8V.

This is perfect. May I connect the grounds into the Arduino's ground? Sorry about my lack of knowledge and thank you.

Not only "may" you - you must. https://majenko.co.uk/blog/importance-sharing-grounds

Yes, adding a zener diode will offer further protection to your Arduino, and is a very good idea. (Voted). If I read the specs right that 1N4733A diode can dissipate a watt of power? (https://www.jameco.com/Jameco/Products/ProdDS/36097VIS.pdf)

No idea, that's just the default in the editor.

The Arduino also has clamping diodes inside the MCU, that will clamp the voltage to VCC (+0.6V).

Yeah, but they can only take about 1mA before burning out. Should be fine at 12V with the 15kΩ resistor if the ground should get disconnected, but it's still abusing the diodes.


text:
Bootloader problem on Arduino Uno?
Since today, my Arduino Uno (using Arduino IDE version 1.8.13) lost the capacity to store a sketch upon physical disconnection (does not include button reset).
This means, the sketch works properly but when I unplug it and plug it back again, the Arduino will act as if I uploaded a blank sketch by blinking 3 times fast repeatedly.
To check this, I tried several examples like "Blink" on Windows 10 and Ubuntu and repeats the error.
I feel there is something wrong with the bootloader or something like that, but I'm finding hard to understand some concepts.
Does anyone recognizes what is happening on the Arduino? What can I do to address the problem?
Summary:

Uploads fine.
Works fine.
Resets fine.
Hard-resets INCORRECTLY (can't plug and unplug and expect the program will still work).
Keeps working good until loss of power.

did you ask this same question several hours ago?

What happens if you use just a simple USB wall wart to power the Arduino?

@thebusybee Just tried, and the same thing happens

@jsotola I did but it was unaccurate to the point that nobody would answer, sorry about that.

Hm, strange.I would expect that a reset by the button has the same effect as a power cycle. Sorry, I have no idea currently.


text:
Write a Struct using ArduinoBLE library
Hello I'm trying to send some Structs such as:
typedef struct __attribute__ ((__packed__)) myohw_command_set_mode {
    myohw_command_header_t header; ///< command == myohw_command_set_mode. payload_size = 3.
    uint8_t emg_mode;              ///< EMG sensor mode. See myohw_emg_mode_t.
    uint8_t imu_mode;              ///< IMU mode. See myohw_imu_mode_t.
    uint8_t classifier_mode;       ///< Classifier mode. See myohw_classifier_mode_t.
} myohw_command_set_mode_t;

To another device via BLE using the Arduino BLE library.
I have the services and characteristics all set up correctly.
My problem is that arduino BLE .writeValue() function expects some specific formats and i'm not quite sure the best way to convert this struct to one of them.
  int writeValue(const uint8_t value[], int length);
  int writeValue(const void* value, int length);
  int writeValue(const char* value);
  int writeValue(uint8_t value);
  int writeValue(int8_t value);
  int writeValue(uint16_t value);
  int writeValue(int16_t value);
  int writeValue(uint32_t value);
  int writeValue(int32_t value);

What format should i use? And what is the best way to cast the Struct to the format?
Thanks,

What format should i use?

int writeValue(const uint8_t value[], int length);

And what is the best way to cast the Struct to the format?

writeValue((uint8_t *)&myStruct, sizeof(myStruct));

Thank you for the help!


text:
Arduino Modbus Slave Library Needed
We are building a circuit based on ATMega328* that :

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

The circuit should be connected as a ModBus Device (Slave) to an existing
Modbus network with several other devices on an RS485 interface.
The circuit should communicate all these calculated values and alarms
as well as some other info, like peak/max values with date and
time stamps that were recorded at their time of occurrence, to the
Modbus Master. We have the freedom of allocating the register numbers
and their formats etc. (Modbus Map) to the controller's vendor (SAUTER).
For example we tell them Register 30001 is the current sensor x,
30002 is voltage sensor y, etc.
We think that sending time stamps (of certain events) will be based on
"agreed-upon" coding of register values (MM, DD, YYYY, etc.) and the
same for alarms (to be sent as hex codes).
We have searched for libraries and got really confused from the
multitude of libraries out there, as well as the lack of documentation -:)
Can you please kindly help us :
select the proper Arduino Modbus Slave Library that :

Has MAX485 support,
Assigns Modbus registers to any arbitrary variables,
Issues Exception Responses to Modbus requests (e.g. non-existing registers
or un-supported Function Codes.
Complies to Modbus Standards
Has a manual !!

We found the "yaacov" library on Github but it assigns registers directly to "Pins".
Also we looked at its "issues" and one of them was very serious : in which frames
coming from the Master with corrupted CRC gets responded to and causes collision
with other slaves. We dont like that ! as it indicates that the library was not tested
in true industrial environment.
We also found that the Library at :
https://electronhacks.com/2014/04/arduino-modbus-plc-rtu/
somewhat fits to our requirements, however it lacks the RS485 support, and more
important, it has no documentation.
We really appreciate any kind support.

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

Thank you.

The ATmega328 will be probably replaced with a larger CPU ... then you will back to searching for a livrary

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

https://drive.google.com/file/d/0Bx5wWRfN_z7oMDlZMDhWbXM2VFU/view
The library is based on the original one written by Jason Vreeland [CodeRage]
Released 3/7/2010 under GNU license
and was used (and possibly modified) by "jhottell" on electronhacks.com :
https://electronhacks.com/2014/04/arduino-modbus-plc-rtu/
The major difference is the use of RS485.
I have written code and tested it on an "UNO" which worked perfectly with more
than one ModBus Slave Simulator under windows, including DAQ Factory which
is a professional package used in actual industry.

This is an awesome Modbus slave and Master Library
Required this library <ModbusRtu.h>
#include <ModbusRtu.h>
unsigned long TIME = 0;
unsigned long LASTTIME = 0;
unsigned long INTERVAL = 5000;

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

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

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

void loop() {

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

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

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

    au16data[i] = 1;

    TIME = millis();
  }

  slave.poll( au16data, 16 );
}


text:
Stream esp-32 camera to RMTP server like YouTube
I am doing research for a project in which I need to play with camera streams. After multiple hit and trails and googling I am not getting even close to the solution for streaming ESP-32 Camera stream to my own RMTP server directly.
Already tried solutions:
1) I have tried re-streaming of ESP-32-cam with Raspberry pi, that works well but not something I am looking for
2) ESP-32-cam: Record and FTP transfer with time triggers (Not tried but believed that it is not a good approach).
Please note: I am not looking at the solution in which ESP-32 cam acts as stream server and browser can connect to it like : https://www.hackster.io/BnBe_Club/9-rtsp-video-streamer-using-the-esp32-cam-board-8832b4
I have already tried it and it works well but not for the usecase which involves streaming to RTMP server without restreaming.
On google, I found a similar thread : https://forum.arduino.cc/index.php?topic=634605.0
The guy with solution is not interested in sharing it.
may be some modification required in below code MAY BE
ref: https://github.com/espressif/esp32-camera
static esp_err_t stream_handler(httpd_req_t *req){
  camera_fb_t * fb = NULL;
  esp_err_t res = ESP_OK;
  size_t _jpg_buf_len = 0;
  uint8_t * _jpg_buf = NULL;
  char * part_buf[64];

  res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
  if(res != ESP_OK){
    return res;
  }

  while(true){
    fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Camera capture failed");
      res = ESP_FAIL;
    } else {
      if(fb->width > 400){
        if(fb->format != PIXFORMAT_JPEG){
          bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
          esp_camera_fb_return(fb);
          fb = NULL;
          if(!jpeg_converted){
            Serial.println("JPEG compression failed");
            res = ESP_FAIL;
          }
        } else {
          _jpg_buf_len = fb->len;
          _jpg_buf = fb->buf;
        }
      }
    }
    if(res == ESP_OK){
      size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
      res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
    }
    if(res == ESP_OK){
      res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
    }
    if(res == ESP_OK){
      res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
    }
    if(fb){
      esp_camera_fb_return(fb);
      fb = NULL;
      _jpg_buf = NULL;
    } else if(_jpg_buf){
      free(_jpg_buf);
      _jpg_buf = NULL;
    }
    if(res != ESP_OK){
      break;
    }
    //Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
  }
  return res;
}


text:
Can Only Upload Arduino Sketch Once to Custom Mega2560 Board
I created a custom Arduino based off the Mega2560 R3. It uses the ATMega16U2 uC as the USB interface between ATMega2560 uC and the PC.
The bootloader on the 2560 is uploaded by using an Arduino Micro via ArduinoISP. I followed this tutorial from Instructables on uploading the bootloader/firmware for the 16U2 except I modified some parts for the 2560 instead of the UNO. Here is my added section in the /program Files (x86)/Arduino/hardware/arduino/avr/boards.txt
unorestore.name=MEGA2560 16U2 Restore Firmware
unorestore.bootloader.tool=arduino:avrdude
unorestore.bootloader.low_fuses=0xff
unorestore.bootloader.high_fuses=0xd9
unorestore.bootloader.extended_fuses=0xf4
unorestore.bootloader.file=Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex
unorestore.bootloader.unlock_bits=0x3F
unorestore.bootloader.lock_bits=0x0F
unorestore.build.mcu=atmega16u2
unorestore.build.f_cpu=16000000L
unorestore.build.board=uno.build.board=AVR_MEGA2560
unorestore.build.core=arduino:arduino
unorestore.build.variant=standard

The problem is after I upload a sketch (with a size say over 10 kB), I can't upload any new sketch and get this timeout error message instead as shown below. Not even a simple blink sketch. The TX and RX LED connected to the 16U2 uC that flashes during an sketch upload doesn't even blink once.

The only way I can get it take another sketch is to "re-flash" the bootloader on the 2560 uC via ArduinoISP. The TX and RX led now flashes during the sketch upload. Of course, this is a huge hassle as I don't want to do "re-flash" the 2560 bootloader every time I want to upload a sketch.
I don't have this problem on my Elegoo Mega2560 R3 clone board so I'm thinking it might be something wrong with my 16U2 firmware/bootloader. Anyone have any idea what else might be causing this?

Why are you compiling for the atmega16u2?

the first upload after flashing the bootloader doesn't require a reset to bootloader. following uploads require a reset before upload. does your auto-reset circuit work?

@Majenko that is the selection for burning the bootloader onto the ATMega16U2 via ArudinoISP.

@Juraj I never heard of this before. I pretty much copied the official schematic. Is the reset the same as pulling the reset pin on the 2560 to ground before the sketch upload?

You shouldn't be uploading a bootloader to the 16U2. You install the CDC/ACM firmware over DFU. Are you sure you aren't installing the 16U2 bootloader onto the Mega2560?

@Majenko I burned the "MEGA2560 16U2 Restore Firmware" to the ATMega16U2 uC and burned the "Arduino/Genuino Mega or Mega 2560" to the ATMega2560 uC. Both done via ArduinoISP. I double checked that I didn't get them flipped.

@Majenko I originally tried to use the ATmel Flip to flash the hex files for the Mega2560 to the 16U2. But for some reason, it won't accept the it but will accept the hex files for the UNO. So if I went with it, I'd have the computer recognize my mega as a uno

What exact file is it you are having to re-flash? The 16U2 CDC/ACM firmware or the ATMega2560 UART bootloader?

@Majenko the official hex file for the ATMega16U2 for the Mega2560 R3: "Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex". It can be found here: https://github.com/arduino/ArduinoCore-avr/tree/master/firmwares/atmegaxxu2

@Majenko The "Arduino-COMBINED-dfu-usbserial-atmega16u2-Mega2560-Rev3.hex" file is what I burned to the 16U2 but can't be done via Atmel Flip software. The Arduino Mega2560 bootloader is what I have to re-flash in order to upload a new sketch as of now.

Ok. So why tell us all about the 16U2 when the problem bootloader is the 2560 one? It sounds like there may simply be a problem with your reset circuit rather than your firmwares. Try hitting reset on the board when attempting your second upload.

@Majenko I wasn't sure if it might be something to do with the 16U2 so I just put that info out there. I tried the reset to ground before hitting upload and it worked! I wonder what causing the reset issue. In the boards.txt file, the bootloader fuse line is "mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8" which is the correct default, isn't it?

That would make no difference. Please show us your schematic and board so we can examine the reset circuit for ourselves.

@Majenko Here is the EasyEDA share link: https://easyeda.com/salesagriculex/lcmr-v5 I'm comparing my schematic to the official eagle schematic right now to see if I missed anything.

I'm finding it hard to find my way around your schematic. I hate the modern way of having components with little labelled stubs instead of drawing proper nets linking things together. You can follow nets. You can't follow a little arrow and a name. And that EDA can't seem to do a simple search. So far all I have found for RST D7 on the 16U2, RESET on the 2560 and a pin on the ICSP. Are there other places where RST exists on that schematic?

Following the traces in the PCB layout editor it would appear not. Ok. I see a problem here.

@Majenko that should be all the RESET connections. I noticed on the official eagle schematics, there is circle between the REST net and the RESET pin on the 2560 chip.  The RESET pin on the 2560 also have the upper line above it.

Your RESET circuit is wrong.

You have no pullup resistor on the RESET pin of the ATMega3560.
You have an extraneous pulldown resistor on the D7 pin of the 16U2.

That means your 16U2 will not be able to trigger a reset of the ATMega2560 to run the bootloader.
Remove the pulldown on D7 of the 16U2 and add a 10kΩ pullup to the RESET pin of the ATMega2560. Without that pullup:

The chip may not run properly as RESET is floating (it may have an internal pullup, I can't recall)
The capacitor linking the 16U2 D7 and RESET of the ATMega2560 won't be able to generate a proper reset pulse. This will be exacerbated by the 1kΩ pulldown.

On the Mega2560 reference schematic RN1A is the pullup in question.

Thanks a lot for your find! Really appreciate it! I'll add the pull up resistor RN5A. As for the pull down resistor on D7 of the 16U2, it's from RN3D on the reference schematic. I'll remove that then. It said it's for USB Boot En.

I think that means it's for enabling DFU mode on the 16U2 - it may be related to why you can't use flip?

I was able to use the Flip software to upload the Uno hex file to a fresh new 16U2 but it can't just for the mega hex file. It said it was too large. Anyways, I added the pullup resistor and removed the pulldown resistor and it works now! I can upload a new code without having to re-flash the bootloader. You saved a huge amount of time for me. Would you accept a small tip via paypal if that's allowed? It's not much but as a way of thanks for your time.

Wow. If you really want to, sure. There's a "donate" link on UECIDE.org that goes to me if you really want to.

Majenko, I don't see a schematics in the question

@Juraj the link to it was posted under the comments of the original question post. The schematic itself has been turned private since the issue was solved.


text:
Accessing raspberrypi.local from Nodemcu
Currently I am trying to access a rest API from NodeMCU. The API is hosted on my local LAN on a Raspberry pi 3 b. The Raspberry pi is accessible on LAN using the raspberrypi.local domain address.
But the problem is I am unable to access the raspberrypi.local address form NodeMCU.
It is unable to just resolve the address.
Can anyone please help me resolve this issue?

In order to access the API, your NodeMCU needs to know the IP address your Pi has at this time. There are several ways to resolve raspberrypi.local to the actual IP. Assuming the NodeMCU got its IP assigned by your WiFi hotspot, it also received a DNS server IP. This is where the NodeMCU would ask first. However, if this DNS server is hosted by your internet provider, it obviously would not know what to respond when asked for your raspberrypi.local.
Another way, especially for .local domains, is mDNS. NodeMCU has a module to do that.
If you work with this a lot, consider running a local development network with your own DHCP/DNS combo. dnsmasq is a good place to start. Lots of tutorials online. The Pi can host that for you.


text:
DF Robot W5200 Ethernet Shield for an Arduino Uno not working?
I've been working on using an ethernet shield for my Arduino Uno for a couple weeks now. I've been going through the problems one by one and now realise that there seems to be nothing transmitting. Running code similar to DHCPAddressPrinter results in nothing, and any web server I set up does not work at all. Can anyone please help? Running the code below results in an output of "Baud rate set!" and nothing else. One thing to note is that the MAC address I am using is from going into the command prompt and using the MAC address listed from ipconfig /all, as there is no sticker on the ethernet shield itself.
    /*
    DHCP-based IP printer

     This sketch uses the DHCP extensions to the Ethernet library
     to get an IP address via DHCP and print the address obtained.
     using an Arduino Wiznet Ethernet shield.

     Circuit:
     * Ethernet shield attached to pins 10, 11, 12, 13

     created 12 April 2011
     modified 9 Apr 2012
     by Tom Igoe

     */

    #include <SPI.h>
    #include <EthernetV2_0.h>

    // Enter a MAC address for your controller below.
    // Newer Ethernet shields have a MAC address printed on a sticker on         the shield
    byte mac[] = {
      /*MAC Address here*/ };

    // Initialize the Ethernet client library
    // with the IP address and port of the server
    // that you want to connect to (port 80 is default for HTTP):
    EthernetClient client;

    void setup() {
     // Open serial communications and wait for port to open:
      Serial.begin(9600);
      Serial.println("Baud rate set!");

      // start the Ethernet connection:
      if (Ethernet.begin(mac) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        // no point in carrying on, so do nothing forevermore:
        for(;;)
        Serial.println("FAIL");
          ;
      }
      // print your local IP address:
      Serial.print("My IP address: ");
      for (byte thisByte = 0; thisByte < 4; thisByte++) {
        // print the value of each byte of the IP address:
        Serial.print(Ethernet.localIP()[thisByte], DEC);
        Serial.print(".");
      }
      Serial.println();
      Serial.println("Loop");
    }

    void loop() {

    }

run the WebClient example sketch

Don't use the MAC address of your computer read from ipconfig output. It creates a conflict on LAN. Use the MAC address from examples.
To troubleshoot Ethernet shield, use the Ethernet library newest version 2.00. It supports W5100, W5200 and W5500 and has better diagnostic in examples.
And to troubleshoot, always connect the LAN cable to router or switch, not to computer, because direct connection to computer requires manual setup of addresses (no DHCP).


text:
How do I know if my Arduino is connected to my LEDs?
I have an Arduino Uno and a string of WS2811 LEDs. I am still trying to get started on this project, which is creating a Stranger Things wall. I've installed FastLED and uploaded the sample program "Blink" to the Arduino, which appears to upload correctly. However, the lights don't blink.
Notes:
 - When I plug the string of lights into a power source (when disconnected from the Arduino), they briefly light up red and then turn off. I don't know if this means there's something wrong with the power setup. (I don't know if they are supposed to stay on.)
 - Here's a photo of my connection from the Arduino to the LEDs

Here's the setup I'm trying to follow.

Thanks in advance for any help!

The FastLed Blink sketch uses pin 3 as the data pin. Did you change that to 6?

THANK YOU. These noob roadblocks can be so silly. I'm off and running now!

Great. Just in time for Halloween. Make sure you don't plug it in "upside down" q-;

Haha - I'll be careful :)

i was going to say; a flash and red is a good sign, sounds like the pin config is just off...

The sample code sets the data pin to 3, but I was using 6. Noob mistake.


text:
Connecting 12V WS2811 RGB LEDs to Arduino Uno & 5V Power Source (Breadboard needed?)
I have an Arduino Uno, 12V WS2811 RGB LEDs (from Mokungit), a 5V power source, and DC power connector. I do not have a breadboard and hope I don't need one.
This is almost exactly what I need to follow this tutorial to build a Stranger Things wall. The LED strip listed shares the same name as the one I have, but the wiring is different.
Here's a photo from the Instructables site:

However, the wires coming from my strip don't match up to the instructions, and I can't seem to figure out how to get these bad boys burning.

Thanks to anyone who can help me get started!

This image, from here, shows which pins are what:

Note the flat key next to the 12 V and GND pins. In addition:

the GND wire has a black broken line printed along it;
the data line is in the middle.

If you trust the image then you should be able to wire them up correctly.

That picture is for a 5 Volt rgb led strip. You have to use a 12 Volt power supply for your led and power the uno with another 5volt source. A computer power supply would be great for supplying power both 5 Volt and 12 Volt.

The signals are clear on the bulb pcb. Take a multimeter in continuity mode and probe to see which pins on the round connector is DI, GND and +12v.
Then connect DI to the arduino. +12v to the strip. GND from the Arduino, LED strip and your +12v source should all be conected together.

Do you know where in the Arduino I should connect the DI?
I don't see how I can connect the +12V to the strip. The the round connector is the only one available.

You know how to use a multimeter in continuity test mode ? You need to probe each pins on the round connector with the pins on the 1st LED PCB to see which is which.
Once you know that you will know where to connect the Arduino and your +12v.
If you don't have a matching female round connector, I would cut it and use the direct wires. Or solder wires on the 1st LED PCB.

I don't know how to use a multimeter in continuity test mode. Also, I don't think I have a PCB. I assume this is nowhere nearly as straight-forward as the wiring in the Instructables instructions, eh?

Before launching into an electronics project I really suggest that you learn the basics like using a multimeter (and buy one, even a cheap one, if you don't have one). Here is a quick 2m video on how to do a continuity test with a multi-meter: https://www.youtube.com/watch?v=OOK8np4t40c
Without this basic skill you will not be able to complete your project.

Thanks for the tip. I needed neither a multimeter nor the skills to use one in order to complete the project as it was described on the Instructables site. I should probably get one and learn how to use it, but I need to complete this today. Perhaps I won't be able to. It seems odd that having a different version of WS2811 would change the steps required so significantly.

Welcome to the world of electronics and proprietary connector pinout.
Without testing which pins is which on the round connector, you have 2 chances out of 3 of applying +12v on the wrong pin and burning your entire LED strip.


text:
How to set SPI speed for ATmega1284P?
I am using MightyCore and platformio. My config file looks like this
My fuses are set as:
E:FD
H:D6
L:8F

I have controller running at 16 MHz and SCK frequency is 8 MHz.
My display is showing white color and that is it. I know to make it function properly I have to use 1 MHz SPI clocking.
If I program CKDIV8 fuse my controller doesn't start. I dunno why, kind of black magic going on there for me. My lack of knowledge is not helpful there.
I tried to use the following tricks:
Setting SPI speed using TFT library
// earlier in main.cpp
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// later in setup()
tft.setSPISpeed(1000000); // has no effect on SCK

Trying to set it directly via SPI class instance:
// in setup()
SPI.setClockDivider(SPI_CLOCK_DIV128); // no effect

Or statically:
// in setup()
SPIClass::setClockDivider(SPI_CLOCK_DIV128); // still no effect

Also I tried to pass DEFAULT_SPI_FREQ build flag with frequency preset.
I ran out of ideas.
Schematic is here:

is setSPISpeed after init?

"If I program CKDIV8 fuse my controller doesn't start." How are you determining this?

@Juraj  no. It was before. I placed it after and it works now.

@timemage I have some pin manipulations later in setup() and they aren't happening.

why would you place it before? init initializes SPI and then of course sets the default value.

Per this issue setSPISpeed has to be made after initR like this:
tft.initR(INITR_BLACKTAB);
tft.setSPISpeed(1000000);

init initializes SPI and of course sets the default value. you can change it only after that

@Juraj I have no idea what was going on in Adafruit engineers head. The display fails to init @ 8 MHz because SPI is too fast for it. It has to be initialized at 1 MHz then it supposed to function properly.


text:
Help with the Arduino Wire I2C Communication with MAX16826 LED Controller IC
I'm trying to read and write to this MAX16826 LED controller evaluation board through I2C. There is no specific library for this IC so I have to use the Wire library and the datasheet to try to communicate with it. My use of this library is limited and my test code doesn't seem to work. While I wait for the MAXIM tech support, I thought I'd ask here.
According to the IC datasheet, the 7-bit address is 0x58 while the 8-bit read and write addresses are 0xB1 & 0xB0 respectively. I was able to detect the 7-bit address using the i2c_scanner example sketch but after a while, it seems to lose communications with it. Attached below is a picture of what I meant.

My code tries to read and write to the MAX16826's register 0x00 by following along the Wire API and the datasheet. However the results I got out of the register from Wire.requestFrom() was 255 when it should be 0. Not sure what's exactly going on. I read through the Wire API but still not sure how to detect the ack bits from the slave IC.
Here are the relevant key information from the datasheet:

Here is my Arduino test code. I did remove parts that were extra and unnecessary for simplicity purposes:
#include <Arduino.h>
#include <Wire.h>

#define MaxAddr 0x58        //7-bit address
#define MaxAddrRead 0xB1    //8-bit read address
#define MaxAddrWrite 0xB0   //8-bit write address
#define enPin 12            //Arduino pin for IC enable

//protoype function declarations
void basicWriteTest();
void basicReadTest();

void setup() {
  Serial.begin(115200);
  Wire.begin();
  //enable the MAX16826 IC
  pinMode(enPin, OUTPUT);
  digitalWrite(enPin, HIGH);
  //wait for the serial monitor to be opened
  while (!Serial);
  delay(1500);
  //function to write to register 0x00
  basicWriteTest();
}

void loop() {
  //function to write the value at register 0x00
  basicReadTest();
  delay(1500);
}

void basicWriteTest(){
  Wire.beginTransmission(MaxAddrWrite);
  //write to register 0x00
  Wire.write(0x00);
  //write the value 0x00 to that register
  Wire.write(0x00);
  Wire.endTransmission();
}

void basicReadTest(){
  Wire.beginTransmission(MaxAddrRead);
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.requestFrom(MaxAddrRead, 1);
  if (Wire.available() <= 1){
    uint8_t data = Wire.read();
    Serial.println("Data = " + String(data));

    float mV = float(316) - 1.72 * (data & 0x7F);
    float mA = mV/2.2;

    Serial.println("mV = " + String(mV));
    Serial.println("mA = " + String(mA));
  }else{
    Serial.println("Failed to get read on MAX!");
  }
}

You should be using the 7bit address for beginTransmission/requestFrom

@Mat how would I write the final bit for read or write then?

The library does it. Check the docs (parameter descriptions) for those two functions.

Check your pull up resistors.

@Gil I have a 10K pull up resistor on both the SDA and SCL line so I highly doubt that's the problem.

That is a bit light, try using 4.7K pull up resistors one for SCA and one for SCL I think your problem will go away. Without a schematic or knowing how long the wires are I cannot be sure. If you are operating on 3V3 go to something in the 3K range.


text:
Return photo stacking rail to start
In isolation (73 years old) and trying to get my macro photo stacking rail to return to start without a limit switch.  I know the number of steps taken, so it is just a matter of reversing the motor.  My code (copied and pasted from other sites) works like a dream (10 steps, fire an IR camera trigger) and continues up to when I want to return (line 73) taking 100 shots or steps however many I want - no problem.
I started a void return loop (and terminated the loop) but the coding has me beat.  I have attached my code (might look terrible, but it works).  Can anyone help out this old guy and give me the code to counter clockwise 1000 steps?
Thanks fellas
David
[code]
#include <AccelStepper.h>
#include <MultiStepper.h>

int smDirectionPin = 2; //Direction pin
int smStepPin = 3; //Stepper pin
int Distance = 0; // records the number of steps we have taken
byte numRepeats = 0;
byte maxRepeats = 100;
int smFirePin = 13;  //Trigger pin
#define fire 13

 void setup(){
  /*Sets all pin to output; the microcontroller will send them(the pins) bits, it will not expect to receive any bits from thiese pins.*/
  pinMode(2, OUTPUT);  //Direction Pin
  pinMode(3, OUTPUT);  //Step Pin
  pinMode(13, OUTPUT);  //LED pin
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(13,LOW);
  pinMode(smDirectionPin, OUTPUT);
  pinMode(smStepPin, OUTPUT);

  Serial.begin(9600); //Open Serial connection for debugging
}

void loop(){
   if (numRepeats < maxRepeats) {
   move1Step();
   Distance = Distance + 1; //record this step to see if we are et the end of our move

  if (Distance == 10)
  {
 if (digitalRead(2) == LOW)
 {
  digitalWrite(2 , LOW);
 }
 else
 {
  digitalWrite(2, LOW);
 }
 Distance = 0;
 numRepeats ++;
 delay(3000);
{
    trigger();
}
   }
 }
}
void move1Step() {
  digitalWrite(3, HIGH);
  delayMicroseconds(750);
  digitalWrite(3, LOW);
  delayMicroseconds(750);
}
// Power on the IR trigger circuit to fire the camera
void trigger()
{
    delay(1000); // wait for vibration to settle
    digitalWrite(fire, HIGH); // take the picture
    delay(2000); // wait for that to happen
    digitalWrite(fire, LOW); // disable the IR circuit again
}

// Advance the motor by one step
void step()
{
  digitalWrite(step, HIGH); //Trigger one step forward
  delay(1);
  digitalWrite(step, LOW); //Pull step pin low so it can be triggered again
  delay(1);
}

  void return();

{
  digitalWrite(smDirectionPin, HIGH);
  /*Slowly turns the motor 1600 steps*/
  for (int i = 0; i <200; i++){
    digitalWrite(smStepPin, HIGH);
    delayMicroseconds(700);
    digitalWrite(smStepPin, LOW);
    delayMicroseconds(700);
  }

  while(1) { }
}

[/code]

code, such as this, makes no sense ... if (digitalRead(2) == LOW) { digitalWrite(2 , LOW); } else { digitalWrite(2, LOW); } ... that whole block can  be replaced by digitalWrite(2, LOW);

return is a reserved word, so you should rename the function to, for example, returnHome. You also need to remove the ; at the end of that line of code.

Plus your indentation is a mess. Pick an indentation style and then follow it religiously.  As it is the code is quite hard to read.

Gerben has provided a solution, your observation have been noted and accepted, thanks

I cleaned up your code a bit. Removed duplicate and unused code. I used a for-loop to make it run for 100 repetitions.
Feel free to let me know if you have any more questions, or if there are things that aren't clear.
// You aren't using these libraries, so I commented them out
//#include <AccelStepper.h>
//#include <MultiStepper.h>

int smDirectionPin = 2; //Direction pin
int smStepPin = 3; //Stepper pin
int smFirePin = 13;  //Trigger pin

byte maxRepeats = 100;

void setup()
{
  /*Sets all pin to output; the microcontroller will send them(the pins) bits, it will not expect to receive any bits from thiese pins.*/
  pinMode(smDirectionPin, OUTPUT);  //Direction Pin
  pinMode(smStepPin, OUTPUT);  //Step Pin
  pinMode(smFirePin, OUTPUT);  //Fire pin
  digitalWrite(smDirectionPin, LOW);
  digitalWrite(smStepPin, LOW);
  digitalWrite(smFirePin,LOW);

  Serial.begin(9600); //Open Serial connection for debugging
}

void loop()
{
  digitalWrite(smDirectionPin, LOW); // set stepper motor to run forwards

  for( byte i=0; i<maxRepeats; i++ ) // run the following section 100 times
  {
    //move 10 steps forward
    for( byte j=0; j<10; j++ )
    {
      move1Step();
    }

    // wait and take a photo
    delay(3000);// there is already a delay in the `trigger` function, so this like could be removed
    trigger();
  }

  // return the stepper motor to the starting position
  digitalWrite(smDirectionPin, HIGH); // set stepper motor to run in reverse
  for( byte i=0; i<maxRepeats; i++ ) // run the following section 100 times
  {
    //move 10 steps backwards
    for( byte j=0; j<10; j++ )
    {
      move1Step();
    }
  }

  // Do nothing
  while(1){ }
}

void move1Step()
{
  digitalWrite(smStepPin, HIGH);
  delayMicroseconds(750);
  digitalWrite(smStepPin, LOW);
  delayMicroseconds(750);
}

// Power on the IR trigger circuit to fire the camera
void trigger()
{
    delay(1000); // wait for vibration to settle
    digitalWrite(smFirePin, HIGH); // take the picture
    delay(2000); // wait for that to happen
    digitalWrite(smFirePin, LOW); // disable the IR circuit again
}

Gerben, I will follow your advice on deleting the delay, you should publish this, many in micro photography would be grateful, works like a charm. Fantastic.

If you delete the delay, you might have to increase the delay(1000). As currently it waits 4 seconds to prevent any movement from vibrations. You'd have to see how short the values can be, or just be a bit more patient. Glad it helped you.


text:
Out of two logically similar sketches, one works while the other does not
I am currently making a project involving a self balancing bot & found this code online:
#include "PID_v1.h"
#include "LMotorController.h"
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

#define MIN_ABS_SPEED 20

MPU6050 mpu;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

//PID
double originalSetpoint = 178.57;
double setpoint = 178.57;
double movingAngleOffset = 0.1;
double input, output;
double Kp = 50;
double Kd = 1.4;
double Ki = 60;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft = 0.6;
double motorSpeedFactorRight = 0.5;
//MOTOR CONTROLLER
int ENA = 5;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 10;
LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
    mpuInterrupt = true;
}

void setup()
{
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    // (115200 chosen because it is required for Teapot Demo output, but it's
    // really up to you depending on your project)
    Serial.begin(115200);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately

    // initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();

    // verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    // load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(262);
    mpu.setYGyroOffset(-29);
    mpu.setZGyroOffset(-10);
    mpu.setXAccelOffset(-2109);
    mpu.setYAccelOffset(394);
    mpu.setZAccelOffset(1341); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0)
    {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();

        //setup PID

        pid.SetMode(AUTOMATIC);
        pid.SetSampleTime(10);
        pid.SetOutputLimits(-255, 255);
    }
    else
    {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
}

void loop()
{
    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize)
    {
        //no mpu data - performing PID calculations and output to motors

        pid.Compute();
        motorController.move(output, MIN_ABS_SPEED);

    }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024)
    {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    }
    else if (mpuIntStatus & 0x02)
    {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        #ifdef LOG_INPUT
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180/M_PI);
        #endif
        input = ypr[1] * 180/M_PI + 180;
        Serial.println(input);
   }
}

The repo is linked to https://github.com/kurimawxx00/arduino-self-balancing-robot
My code is as below:
    /* For documentation purposes
 *
 * #define MPU6050_INTERRUPT_FF_BIT            7
 * #define MPU6050_INTERRUPT_MOT_BIT           6
 * #define MPU6050_INTERRUPT_ZMOT_BIT          5
 * #define MPU6050_INTERRUPT_FIFO_OFLOW_BIT    4
 * #define MPU6050_INTERRUPT_I2C_MST_INT_BIT   3
 * #define MPU6050_INTERRUPT_PLL_RDY_INT_BIT   2
 * #define MPU6050_INTERRUPT_DMP_INT_BIT       1
 * #define MPU6050_INTERRUPT_DATA_RDY_BIT      0
 *
  */

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "PID_v1.h"
#include "LMotorController.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include <Wire.h>
#endif

#define MIN_SPEED 20

#define DEBUG_BUILD

MPU6050 mpu;

// Variables for MPU status and control
bool isDMPReady = false;
uint8_t dmpStatus; // 0 if initialization succeeds
uint16_t dmpPacketSize; // default = 42
uint16_t fifoCount;
uint8_t fifoBuffer[64];
uint8_t mpuIntStatus;

// Variables for calculated data from DMP
Quaternion q; // // holds QUAT_W, QUAT_X, QUAT_Y, QUAT_Z from FIFO
int16_t gyro[3]; // Holds rotation
VectorFloat gravity; // holds gravity vector calculated from DMP
float ypr[3]; // 0 = yaw, 1 = pitch, 2 = roll

// PID data
double setPoint = 178.57;
double input = setPoint, output;
double Kp = 50;
double Kd = 1.4;
double Ki = 60;
PID pid(&input, &output, &setPoint, Kp, Ki, Kd, DIRECT);

// Motor config
const int inA = 6;
const int inB = 7;
const int inC = 8;
const int inD = 9;
const int enA = 5;
const int enB = 10;
const double motorCorrectionA = 0.6;
const double motorCorrectionB = 0.5;
LMotorController motorController(inA, inB, inC, inD, enA, enB, motorCorrectionA, motorCorrectionB);

// =================================================
// ===         Interrupt Service Routine         ===
// =================================================
volatile bool mpuInterrupt = false;
void dmpDataReady() {
    mpuInterrupt = true;
}

// =================================================
// ===              Program Setup                ===
// =================================================
void setup() {
    // join the I2C bus
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.begin(115200);
    while(!Serial);

    // Initialize mpu
    Serial.println(F("Initializing I2C Devices: "));
    mpu.initialize();
    dmpStatus = mpu.dmpInitialize();

    // Gyro and accel offsets
    mpu.setXGyroOffset(262);
    mpu.setYGyroOffset(-29);
    mpu.setZGyroOffset(-10);
    mpu.setXAccelOffset(-2109);
    mpu.setYAccelOffset(394);
    mpu.setZAccelOffset(1341);

    // Verify initialization
    #ifdef DEBUG_BUILD
        Serial.println(F("Testing MPU Status: "));
        Serial.println(mpu.testConnection() ? F("MPU6050 initialization success!") : F("MPU6050 initialization failed!"));
        Serial.println(dmpStatus == 0 ? F("DMP initialization successful!") : F("DMP initialization failed!"));
    #endif

    if(dmpStatus == 0){
        // Enable DMP
        mpu.setDMPEnabled(true);

        attachInterrupt(0, dmpDataReady, RISING);

        // Get interrupt byte
        mpuIntStatus = mpu.getIntStatus();

        // Get DMP packet size ; default = 42B
        dmpPacketSize = mpu.dmpGetFIFOPacketSize();

        // Verify DMP initialization
        #ifdef DEBUG_BUILD
            Serial.println(mpu.getFIFOEnabled() ? F("FIFO Enabled!") : F("FIFO Not Enabled!"));
            Serial.println(mpu.getXGyroFIFOEnabled() ? F("FIFO X Gyro Enabled!") : F("FIFO X Gyro Not Enabled!"));
            Serial.println(mpu.getYGyroFIFOEnabled() ? F("FIFO Y Gyro Enabled!") : F("FIFO Y Gyro Not Enabled!"));
            Serial.println(mpu.getZGyroFIFOEnabled() ? F("FIFO Z Gyro Enabled!") : F("FIFO Z Gyro Not Enabled!"));
            Serial.println(mpu.getAccelFIFOEnabled() ? F("FIFO Accel Enabled!") : F("FIFO Accel Not Enabled!"));
            Serial.print(F("DMP Packet Size: "));
            Serial.println(dmpPacketSize);
        #endif

        isDMPReady = true;

        // Setup PID
        pid.SetMode(AUTOMATIC);
        pid.SetSampleTime(10);
        pid.SetOutputLimits(-160, 160);
    }
    else{
        Serial.println(F("DMP Error!!!"));
    }
}

// =================================================
// ===            Main Program Loop              ===
// =================================================
void loop() {
    // Do nothing if DMP initialization failed
    if(!isDMPReady) return;

    while(!mpuInterrupt && fifoCount < dmpPacketSize){
        pid.Compute();
        motorController.move(output, MIN_SPEED);
    }

    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    fifoCount = mpu.getFIFOCount();

    if(mpuIntStatus & 0x10 || fifoCount == 1024){
        mpu.resetFIFO();
        Serial.println("FIFO Overflow");
    }
    else if(mpuIntStatus & 0x02){
        while(fifoCount < dmpPacketSize) fifoCount = mpu.getFIFOCount();

        mpu.getFIFOBytes(fifoBuffer, dmpPacketSize);
        fifoCount -= dmpPacketSize;

        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        // TODO: implement complementary filter
        input = ypr[1] * 180 / M_PI + 180; // Supposing at upright position, pitch is 180 degrees

        #ifdef DEBUG_BUILD
            Serial.print("Yaw/Pitch/Roll: ");
            Serial.print(ypr[0] * RAD_TO_DEG);
            Serial.print("\t");
            Serial.print(ypr[1] * RAD_TO_DEG);
            Serial.print("\t");
            Serial.println(ypr[2] * RAD_TO_DEG);
        #endif
    }
}

I am using the exact same libraries and classes as in the repo. Yet my code does not work at all, the motors move erratically. All the physical connections are ok since the code from the repo works flawlessly. I've no idea why this is happening. Help is very much appreciated.

Given that both libraries are the same.
The two sketches seem to set up the motorcontroller quite differently. Changing an "input pin" and "enable pin" around, would lead to errratic motor behaviour.
```
LMotorController motorController(ENA, IN1
LMotorController motorController(inA, inB
```
To me, an input pin would be an PWM signal to drive the speed of the motor.
An enable pin, would enable/disable the whole driver (both left/right).
But it's hard to tell, also, if the above sketch is working, why not use the above sketch and adjust that?

Oops! Totally missed that there. Should pay more attention to the header files :D

Another thing I noticed while tinkering, interrupts from the MPU6050 can only be caught by the Uno when serial comm is set to 115200 baud rate or higher. Anything lower causes the MPU interrupts to be never caught. Maybe this is a particular problem of my board (it's a cheap chinese one), but maybe this will help someone out somehow. :)


text:
Detecting pulsed LED
I am trying to use an Uno to detect if an LED is on or not. Sounds simple, but I am tearing my hair out on this one, here is why.... This is a model railway application and I want to detect an LED being lit on the control panel showing how a route (points/turnouts) is set. The LED is lit by a point position indicator (www.blocksignalling.co.uk/index.php/points-position-indicator-ppi4-dc) which works perfectly but the LEDs are not permanently on when lit, even though they appear so, they are pulsed at around 8khz. I tried using opto isolators triggering an digital input on the Uno. They all happily detect 'no light' and the pin goes HIGH, but when the led is lit, the pin flucuates between 0 and 1 so not a true or stable LOW. I also made my own opto using a TCRT5000 with the leds pointing at eachother encased in shrinkwrap, using standard breadboard set-up which worked perfectly when powering the transmitter from the Uno, but same result when powered from the LED. Anyone out there got any ideas please?

use a CDS sensor; they are slow enough that 8khz is no problem.

why don't you detect the state of the switch that operates the LED??

Yes, the point motor (solenoid) is triggered by the switch, but though a capacitance discharge unit (CDU) which fires a momentary high current that would damage the Uno.  The PPI detects this high value and lights the corresponding low voltage LED.

Count HIGH values read for example in 2 ms. It should be zero if the LED is not lit and more then zero if it is lit.

Good thought, the one thing I can rely on is the HIGH value stays there when it should be, so counting a fixed number of responses and if all HIGH then assume HIGH, anything else, assume LOW. Thank you.

Why not connect a low pass filter to the LED, and measure the DC level coming out? Will certainly be higher when on than when off.  Resistor from anode to analog input pin, and capacitor to Gnd.

Use a photoresistor (also called LDR).
Connect the photoresistor between Vcc and an analog input and place it physically next to the LED you want to monitor.
In your arduino code simply monitox the analog input value. When the LED will be on the photoresistor will have a lower resistance andyou will read a higher analog voltage.

good thought, I would need to add another LED in series to the one in the control panel as that doesn't show any light under the panel.


text:
Serial.write is synchronous
I have a good experience of the real(/critical)time world, but I'm new with Arduino.
I noticed that Serial.write is synchronous. If the buffer size is >64 (the USART size) it lasts the time of the physical transmission minus 64char.
It is obvious with simple tests as : Serial.write (char64) comes back in 1 millisec if the USART buffeur is empty and comes back in 64*10/baudrate if USART buffer is full.
Does anyone has written an asynchronous Serial.write?
If not who can help me to write it? That is to say have the docs on the USART, the interrupts and soon? Basically, the point is to fill the buffer, get an interrupt when it is free to fill it again.
Thanks for contacting me.

you can test before write with availableForWrite()

Until the buffer is full, Serial.write is asynchronous.  You just have to avoid filling the buffer up.
Fortunately, there is the function Serial.availableForWrite() which returns the number of bytes available in the buffer. You can use that to see if there's room in the buffer for what you want to send, and if there is then send it (i.e., just placing it in the buffer).
By re-writing the UART handing to call your own interrupt routine to send a byte as and when needed you are basically doing exactly the same as the Arduino's HardwareSerial class is doing - just with your own buffer instead of the one in the HardwareSerial class.
There is no hardware buffer in the Arduino. It only has a single byte shift register for sending UART data. Any buffering has to be done in software, so either you implement that yourself, or use the existing buffering, or only ever generate and send one byte at a time, which is fairly useless.
If you really want to re-write it then all the information you need is in the datasheet for the MCU on your chosen development board.

The terms "synchronous" and "asynchronous" when applied to situations like this are better replaced with "blocking" and "non-blocking", since "synchronous" and "asynchronous" when applied to serial communications imply different styles of data transmission, not software implementation.

Thank you for your answer, very clear and very helpful.
Based on it I will use both of your suggestions :
1 Test first before write.
2 As the buffer size is software, extend it from 64 to 85 to be able to send a NMEA0183 phrase at once, and only wait if the next comes to soon.
I agree synchronous/asynchronous can be miss-understood because of data transmission protocol. But you get it!

I checked, the HardwareSerial.h starts with #if !defined(SERIAL_TX_BUFFER_SIZE) that is to say it can be defined outside before (just what I need). But where shall I place my #define SERIAL_TX_BUFFER_SIZE xx ? Is it in the Arduino Sketch itself or in some .h file? If this size is >256 a special mode is used. Does it improve performances or not? I guess each Serialx (on Mega) has its private TX and RX buffers. Have all the TX buffers the same size? Or shall I adjust each? Thank you in advance.

I believe they are all the same size. You want to place the define at the top of the HardwareSerial.h file so that HardwareSerial.cpp etc pick it up.

Thanks to Majenko I have the pieces of a gloabal solution. I just summaries and share :
The Serial.availableForWrite() gives the available space left free in the Serial TX buffer.
It your string is shorter the Serial.write will be passing, if not blocking (until enought free space).
You can adjust the size of this TX buffer (default is 64) in HardwareSerial.h. Take care buffersize larger than 256 (255 available) result in a longer processing time for Serial.write.
If you have Serial, Serial1, ... the size will be the same for both and ofcourse the buffers are seperated.
I noticed thas Serial.flush is blocking long (80ms). This is to take into account for time critical issues.
Enjoy

If you change the TX buffer size, please note that it should be a power of two. Otherwise the processing time for HardwareSerial::write() and the TX ISR will be much longer. The performance penalty for sizes larger than 256 is small in comparison.

Thank you for this Edgar. I've been throught the multiple layers of C++ code for the Serial.xx down to the HardwareSerial.xx. I wanted to implement a very simple and quick SerialTXClear to clear out the TX buffer queue, but I feel I'll miss layer. Where shall I find the doc on theses multiple layers?

I am not aware of any software layer other than the files you mentioned.