text:
Expected signature for ATmega328P is 1E 95 0F; I can not burn bootloader on my arduino Uno
well...
the problem starts from the time that I accidentally touched the crystal on my arduino and all of a sudden everything messed up; the leds on arduino turned on and off while being touched, and after that I was unable to program it...
after a lot of searches, I decided t burn bootloader again...
so I got a USBasp and wired it to arduino and tried to program it using programmer or burning bootloader...
but...
It is not posible because of the following ERROR:
**Arduino: 1.8.15 (Windows 10), Board: "Arduino Uno"

avrdude: warning: cannot set sck period. please check for usbasp firmware update.

avrdude: Expected signature for ATmega328P is 1E 95 0F

         Double check chip, or use -F to override this check.

Error while burning bootloader.**

I tried changing that 0xF in config file to 0x14, because of the difference between ATmega328 and ATmega328p...
but still no progress...
I will be very glad if someone can help me run this UNO...
by the way, is it possible that the crystal which I touched with hand is ruined or interrupted and all of these stuff is because of that?

What crystal? Is it a genuine Arduino or a cheap Chinese POS?

its a 16mHz smd crystal...

and I dont think it to be chinese...

The crystal by the ATMega328P chip or the crystal by the USB interface chip?

the one by the ATmega

Then if it's a real Arduino it's not a crystal but a ceramic resonator. But there's always a chance you zapped the chip with static. Did you feel a shock when you touched it?

no, nothing like a zap...just sth like a touch screen that when I touch it, things change like leds

Any chance you could take a short video?

Or upload it to google photos and share the link.

https://drive.google.com/file/d/1u4wfHMXPAMI16Mm7IDgOGQIH4MAds16J/view?usp=sharing

Ok, so it's not a genuine Arduino. It's just the TX and L LEDs that light up. The L could be being controlled by a sketch that is triggered from a floating input. The TX LED is connected to the CH340G chip and no one really know what goes on with those things.

I was thinking that there must be sth wrong with fuse bits and boot loader...so, reprograming it should have worked, but well...it is not working...any suggestion?

It's more likely the CH340G chip has died. They're known to be very sensitive.

thats really a bad news...but anyhow...thanks for the time you put on this...I do appriciate it... ;)

You could try a "loopback" test to see if the USB interface is working or not.  1. Connect RESET to GND. 2. Connect pin 0 to pin 1. 3. Connect the Arduino to the PC. 4. Open the serial monitor in the IDE with the right port selected. 5. Type something. You should see what you type echoed back to you.

well...I did as you said...nothing happens...i an not see the message I type in response...it fade...and when I press ENTER, for a moment RX and TX leds on arduino blink...just this...

It sounds like the CH340G may be dead then. You can try using an external USB to UART adapter connected to the TX/RX pins and bypass the CH340G to keep using your board. Treat it like a "breadboard arduino" but with the chip still on the PCB.

I would use it for a mechanical template and purchase a new one. At this point we do not know what all failed. If you have the time and skill set go for it.

Well a couple of options:

Plug the Arduino with USB, do you see a Serial PORT? If you do there is a good chance the USB CHIP is ok.
Try programming the Arduino with a 12v High Voltage Programmer and burn a 8Mhz Internal oscillator bootloader and see if it works, if it does, the the crystal is damaged.
Another alternative, e to use a 16mhz crystal and put it in parallel with that one, see if you can flash it like that, or just desolder that one and replace with a new one, doesn't matter if it's the same freq, you still be able to burn a bootloader, hopefully choose a osc that is supported by the bootloaders (8, 12, 16, 20) for example


text:
I can change value of only one register on 8-Bit Register integrated circuit (74hc273 / DM74LS273)?
First, please be patient, I'm not electronical person. I am learning Arduino and electronics for hobby and this is my fist time with integrated circuits.

Situation: I'm want to extend the Arduino Nano pins (De/Multiplexer) and keep the state (High/Low) of the new pins until I decide to change it again. For keep the states I think that D-type Flipflop memory-based system can help .
Question 1: On this system can  I change only one bit with a unique signal or need to set all bit states ?
Example (reference image):

Memory, previous state: Q0=0, Q1=1, Q2=1, Q3=0
Arduino: Set pin17 (D2) to High -> Memory: Waiting new data.
Arduino: Set pin16 (D3) to High -> Mux: Pass the value to memory at D0
Memory: Read 1 on D0 (this is my doubt. D1, D2 and D3 don't matter ?)
Arduino: Set pin17 (D2) to LOW -> Memory: Save new data
Memory, new state: Q0=1, Q1=1, Q2=1, Q3=0 ? or Q0=1, Q1=0, Q2=0, Q3=0 ?

Question 2: Are this correct ?
Question 3: Are there a more efficient way to do this?

Notes:

I used a simulator to diagramed the memory based on this datasheet: https://pdf1.alldatasheet.com/datasheet-pdf/view/8337/NSC/74273.html It seems that it is possible, but I want to be sure.
My currently solution is use separated flipflops, but I want to simplify it.
Connections on reference image are simplified.
Sorry about the poor diagram, I don't know programs for beautiful electronical diagrams.
Sorry about typos, not-native English person here.

I don't want to answer in a comment, but have you heard of the 74HC595 chip? That lets you set up 8 outputs using only 3 pins from the Arduino, and they can be chained. That looks simpler than your proposal.

Or if you want even fewer outputs used you could consider an I2C IO expander like the MPC23017.

feeding demux into the latch will not let you set output pins to various states

There is a simple and cheap component that can do what you want, the 74HC259 addressable latch. Essentially it's demux and an 8-bit latch in which the bits are individually addressable.

Look at the data sheet of the '273: You cannot set its flip-flops individually. All or none, that's it. Use another IC.

A lot of thanks for your comments. Really appreciate your time and patience.

Question 1 and Question 2: I was wrong, this is not the correct way. @jsotola and @the_busybee, thanks for the clarification
Question 3: @Nick_Gammon and @Majenko I think you are right, using i2c are more efficient ways to do. But, the @StarCat proposal is more compatible with my current solution. 74hc259 allows me set the state one by one and keep it until I change it again.

source: Stack Exchange

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

sort: votes


text:
Reprogram By Address: Arduino Node Array
Let me just start off by saying that this is the first time I've attempted a project at this scale. I'm not sure that I'm even taking the right approach on this.
I'm attempting a project inspired by Daniel Rozin. This is basically an array of small stepper motors representing display pixels, where it's lighter when pointing towards a reference light and darker as it's points away. Each Arduino controls two steppers through two ULN2003 drivers. These nodes will be given instructions by a raspberry-pi via i2c or spi.
My question is this: One of my goals is to reprogram the ATmega328Ps through the raspberry pi without taking down the entire display and reprogramming each of the nodes individually. I would expect my code to go through a number of iterations, and reprogramming these individually sounds like a nightmare. Is it possible to reprogram these nodes by address from the raspberry-pi? Is this a problem that should be tackled using some standard mechanism?
Here is what I'm currently thinking about. And I'm not an expert here. I could be way off base. I don't know... According to this writeup, when the application starts, the bootloader is looking for a series of byes to kick off the reprogramming process. What I'm thinking about is forking the arduino bootloader project and defining a different expected series of bytes for each node.

thank you for responding, @jsotola. I've edited my question to try and make it a little clearer... The question is specific about programming multiple Arduinos... I would expect the code to go through a number of iterations and the idea to pulling the display down and programming them individually sounds like a nightmare.

I would consider a WiFi/BT platform that supports OTA updates--it's unclear how the nodes would be symchronized from the description. Note that such a node can be very cheap, on the order of 5-10 dollars, and in the end, a matrix display like this needs little in the way of smarts.

Is is really worth it doing all this work just to reprogram them easier? As I understood the Arduinos will just move the motors to a specific position like commanded by the Pi. Thats a rather easy code. Normally one would do the development with only very few Arduinos (main code with only one, testing communication with maybe 3). Scaling to a full display can be done later, when the Arfuino code doesn't really chamge anymore. Also you didn't specify how exactly the Arduinos are connected to the Pi

If your question is how to address the individual Arduinos from Linux (which is, I guess, what the Raspberry Pi will be running), see this answer.

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


text:
Not able to control servo motor using ESP32 board when RGB LED is used
I'm new in using ESP32 boards. For some reasons, the servo motor is not working when RGB LED code is used. I have looked everywhere and I did not see any solution for this. Any help is appreciated.
Here is the code I'm using:
#include <ESP32Servo.h>
#include "BluetoothSerial.h"

#define LEDC_CHANNEL_R 0
#define LEDC_CHANNEL_G 1
#define LEDC_CHANNEL_B 2
#define LEDC_TIMER 0
#define LEDC_BASE_FREQ 5000 // Frequency in Hz
#define LEDC_RESOLUTION 8  // 8-bit resolution (0-255)

const int redPin = 18;
const int greenPin = 19;
const int bluePin = 21;
Servo indexServo;
BluetoothSerial SerialBT;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  indexServo.attach(14,1000,2000);
  Serial.begin(115200);
  SerialBT.begin("ESP32_BT_Test");

  ledcAttachChannel(redPin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_R);
  ledcAttachChannel(greenPin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_G);
  ledcAttachChannel(bluePin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_B);
}

void loop() {
  indexServo.writeMicroseconds(1000);
  delay(1200);
  indexServo.writeMicroseconds(2000);
  delay(1200);
  ledcWrite(redPin, 255);
  ledcWrite(greenPin, 0);
  ledcWrite(bluePin, 0);

  delay(50);
}

If I comment out these lines:
  /*ledcAttachChannel(redPin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_R);
  ledcAttachChannel(greenPin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_G);
  ledcAttachChannel(bluePin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_B);*/

  //ledcWrite(redPin, 255);
  //ledcWrite(greenPin, 0);
  //ledcWrite(bluePin, 0);

The servo motor moves back and forth without any problem.
I even tried analogWrite() funtion for the led and the same problem occurred.
Servo is connected to pin 14 and powered via an external power supply. RG&B pins of led is connected to pins 18,19, and 21. The wiring is correct because both led amd servo is working fine individually. Problem occurs only if the code for both led and servo is running.
I'm not able to find what is the issue here. Any help will be much helpfull.
Thankyou

please edit your post ... add information about the electrical connections

The issue stems from how the ESP32 handles its PWM channels. I see that you are trying to use the same timer/channel for the the servo library and LED PWM, which ends up in a conflict. Also I'd recommend a pin definition where you have the pins for the LED defined. The key is proper timer and channel management for the ESP32's PWM system.
Try this code:
#include <ESP32Servo.h>
#include "BluetoothSerial.h"

// PWM Channels for RGB LED
#define LEDC_CHANNEL_R 1  // Changed from 0 to avoid conflict
#define LEDC_CHANNEL_G 2
#define LEDC_CHANNEL_B 3
#define LEDC_TIMER 1      // Changed timer
#define LEDC_BASE_FREQ 5000
#define LEDC_RESOLUTION 8

// Pin Definitions
const int redPin = 18;
const int greenPin = 19;
const int bluePin = 21;
const int servoPin = 14;

Servo indexServo;
BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32_BT_Test");

  // Setup LED PWM
  ledcAttachChannel(redPin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_R);
  ledcAttachChannel(greenPin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_G);
  ledcAttachChannel(bluePin, LEDC_BASE_FREQ, LEDC_RESOLUTION, LEDC_CHANNEL_B);

  // Setup Servo
  ESP32PWM::allocateTimer(0); // Use timer 0 for servo
  indexServo.setPeriodHertz(50); // Standard 50Hz servo
  indexServo.attach(servoPin, 1000, 2000);
}

void loop() {
  // Servo movement
  indexServo.writeMicroseconds(1000);
  delay(1200);
  indexServo.writeMicroseconds(2000);
  delay(1200);

  // LED control
  ledcWrite(redPin, 255);  // Red
  ledcWrite(greenPin, 0);  // Green
  ledcWrite(bluePin, 0);   // Blue

  delay(50);
}

I changed the LED channels to start from 1 instead of 0 (servo typically uses channel 0), used different timer for LED PWM and allocated timer for servo using ESP32PWM::allocateTimer(0) (you can read more about it here: https://madhephaestus.github.io/ESP32Servo/classESP32PWM.html)
Furthermore: I added proper servo frequency setup with setPeriodHertz(50) (don't overdo it). If you still have an issue, than it might be the ESP-IDF version.

Thank you, this was the solution. Now everything works properly.


text:
2.4" TFT LCD is only showing white screen, but the touch functions still work
Hi (Sorry for the long post).
The other day I finally found a code that worked on my standard 2.8" TFT LCD by Simkeim, but then I pressed the bottom left corner too hard and the screen went white. The code is a calculator code and it worked because the screen showed the numbers and the screen saver, but when I pressed the screen nothing happened. After the screen went white, I "opened" it and saw no damage to the screen. I have tried a bunch of example sketches and now the touch functions work, but nothing is displayed on the screen. The LCD does not have any wires, it just plugs in the board. When I upload a sketch, the backlight changes brightness a bit, and there is a slight line on the left side of the screen, when the code uses dark colors, I can press two parts of the screen and the screen goes dark (except for a small part of the left side).
Could the screen be damaged by pressure?
This is what the LCD looks like:

It's dead, Jim.

what do you mean by opened it?

I just took the top part of the LCD off to see the screen, and it had no damage.

but then I pressed the bottom left corner too hard and the screen went white. Meh. It should be quite obvious what happened to it.


text:
How to gradually increase and decrease the speed of a motor using IR remote
I am making an IR controlled helicopter and I have the very basic part of the code done, but I don't know how to make the motor gradually increase speed. I want the motor to gradually increase speed when you hold the button on the IR remote and hold its speed when you stop pushing the button. And the same for when the helicopter goes down.
Here is the code:
   #include <IRremote.h>
   #include <Servo.h>
   #define enA 9
   #define enB 11
   #define in1 6
   #define in2 7
   #define in3 4
   #define in4 5

   Servo ball1;

   int IR_RECEIVE_PIN = 2;
   IRrecv IrReceiver(IR_RECEIVE_PIN);
   decode_results results;

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

     ball1.attach(10);

     pinMode(in1, OUTPUT);
     pinMode(in2, OUTPUT);
     pinMode(in3, OUTPUT);
     pinMode(in4, OUTPUT);
   }
   void loop() {
     if (IrReceiver.decode(&results)) {
       switch (results.value) {

         case 0xFFA857:
           Serial.println("case: UP");
           digitalWrite(enA, 255);
           digitalWrite(in1, HIGH);
           digitalWrite(in2, LOW);
           break;

         case 0xFFE01F:
           Serial.println("case: DOWN");
           digitalWrite(enA, 120);
           digitalWrite(in1, LOW);
           digitalWrite(in2, LOW);
           break;

         case 0xFF18E7:
           Serial.println("case: FORWARD");
           ball1.write(90);
           break;

         case 0xFF10EF:
           Serial.println("case: LEFT");
           digitalWrite(in3, LOW);
           digitalWrite(in4, LOW);
           break;

         case 0xFF5AA5:
           Serial.println("case: RIGHT");
           digitalWrite(in3, HIGH);
           digitalWrite(in4, LOW);
           break;

         case 0xFF48B5:
           Serial.println("case: BACKWARD");
           ball1.write( ? ); // I need help on the direction of the linear servo
           break;
       }

       Serial.println(results.value, HEX);
       IrReceiver.resume();
     }
   }

It is the same code I used to control a RGB LED (But modified). Would it be possible to upload this code to an IC? I already programmed my UNO as an ISP, but there seems to be a problem. Also, I am using a linear servo for the pitch of the helicopter, can someone please show me how to change the direction of a linear servo? I have one that is similar to the Pico linear servo.

Should each case statement have a matching break statement?

Yes, I removed them when I was trying something, but I added them back now... Thanks!

Properly indenting your code would make it much easier to follow.

Okay, I indented it...

Every time you receive an "up" code increase the speed. Every time you receive a "down" code decrease the speed. IR doesn't (usually) have a concept of "press" and "release", only "press" and it sends the code repeatedly while it's pressed.

Mhh, normally you don't see IR controlled flight models, because it is too unreliable and it won't work in direct sunlight (because the IR light from the sun already saturates the sensor, so that it cannot see the signal from the sender). Are you sure, that you want to use IR? A good RF sender and receiver (like in other flight models) are nornally way better

Hi chrisl, thank you! I will see if I can get an RF sender and receiver... I used IR because it is all I have now, but I will look into your idea. Thanks again!

You could separate reading the controls and taking actions and there are several ways of doing that, one example shown below where the switch() can be used to read all commands and according to the value call one or more atomic functions. For instance, one function to change speed and another one to change direction, and perhaps calling several functions in a row for more complex tasks like take off and land (I have no idea how those helicopter projects works).
On each case you do the validation, min and max allowed values, dependencies on other factors and alike.
void loop() {

  if (IrReceiver.decode(&results)) {

    switch (results.value) {

      case 0xFFA857: // up
        verticalSpeed = verticalSpeed + verticalSpeedStep;
        if (verticalSpeed > maxVerticalSpeed) verticalSpeed = maxVerticalSpeed;
        setVericalMotor();
        break;

      case 0xFFE01F: //down
        verticalSpeed = verticalSpeed - verticalSpeedStep;
        if (verticalSpeed < 0) verticalSpeed = 0;
        setVericalMotor();
        break;

    }
  }
}

void setVericalMotor() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(enA, verticalSpeed);
}

As for your question regarding the servo, they usually run from 0 to 180 degrees, so tey anything in that range as the "reverse" for 90 degrees for Forward (normally that should be 0 or 180).

Thank you for the help!!

I have not worked with verticalSpeed before, and the compiler says it is not declared in a scope along with verticalSpeedStep, and maxVerticalSpeed... Could you please help me?

The code I showed you is not a complete program, just an idea how to design your program and as part of it you have to declare the variables.  As you are new to programming I suggest you follow one of the many getting started with Arduino tutorials you can find on arduino.cc and many other websites.

Okay, thank you!


text:
arduino nano with lora only runs once if connected to battery
this code works perfectly if connected with usb cable. but as soon as i connect my Arduino nano with battery (two 18650 batteries in series connected to VIN) it runs loop only once. it sends only 0 to another LoRa module (3.3v) and i assume it runs loop only once. blink works without a problem.
#include <SPI.h>
#include <LoRa.h>

int counter = 0;

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

  Serial.println("LoRa Sender");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);

  // send packet
  LoRa.beginPacket();
  LoRa.print(counter);
  LoRa.endPacket();
  counter ++;
  delay(3000);
}

Edit
battery pack voltage is 7.01v.
connections I've tried so far:

2x 18650 -> VIN = Does not work
2x 18650 + regulator -> 5v = Does not work
2x 18650 + regulator -> USB = Does work
USB -> USB = Of course works

when I say it works I mean it Arduino powers up and LoRa module sends data but only once and looks like loop is running only once.

it works if i connect usb cable with a power bank. but wont work if i power with regulated 5v on 5v pin

voltage on vin pin is 7.01v

A diagram of how you have all this wired together may be relevant.

are you powering the lora with the nano's 5v pin? iirc, Vin goes through an LDO, USB is fed directly.

no. i'm powering lora from 3v3 as vcc for lora is not 5v tolerant

If you measure the "5V" pin does the measured value read appear to be lower in the working scenarios and higher in the failing scenarios?

@timemage when in working condition 5v output reads 4.48 but when using regulator and its failing 5v pin is constantly at 5.05v

What exact Lora module do you have?

Again, it would be nice to looking at how you have it set up.  You didn't mention any proper signal level conversion, so I'm going to assume there isn't any.  My best guess is one of the signals being produced by the Lora module is near the edge of being correct on the ATMega328P.
In comments I asked:

If you measure the "5V" pin does the measured value read appear to be
lower in the working scenarios and higher in the failing scenarios?

The reason for the question is that the logic levels of the ATmega328P are dependent on its VCC, what we're nominally calling "5V".

when in working condition 5v output reads 4.48 but when using
regulator and its failing 5v pin is constantly at 5.05v

By operating the 328P closer to 3.3V (when you're at 4.48), you're lowering the threshold voltage needed for the Lora's signals to reliably register as a HIGH on the Nano's pins.
You will likely need proper level conversion between the Nano and Lora module, but that will depend on the exact module.  Keep in mind that if your module says it has "5V tolerant" data pins, that doesn't mean it produces logic levels acceptable to a 5V Arduino Nano; it just means the module will accept 5V signals at its own inputs.

shouldn't according to datasheet, read ATmega328p operating at 5V everything above 3 V as HIGH?

In a roundabout way it does say that. I assume you're talking about the 0.6 * VCC for VIH low spec. I'm aware of that. I can't tell if you genuinely think this is relevant and not understood or you're just screwing with me. On the assumption that you're running at exactly 5V and you have a VIN(min) of 3V, you are still talking to a 3.3V device, nominal, which may not even be operated at exactly 3.3V. Taking the RFM95W as an example, VOH(min) is 0.9 * VCC, or 2.96V at 3.3V VCC.  Even if the figure were slightly above 3V, they are still operating with no margin to speak of.

yes it is possible


text:
Update the ESP to espduino via NodeMCU Flasher
I am using Cactus Micro Rev2 and I'm trying to communicate with ESP via Mega32U4. I guess I have to update to espduino to be able to program the ESP side.
And I don't know current ESP firmware version. I tried firmware update (https://github.com/AprilBrother/espduino/tree/master/esp8266/release) via esptool but it gave connection error. And I can't erase flash it still gives an error. This time I tried via nodeMcu flasher:

Screenshot:

It succeeds. But when I uploaded the basic serial communicate sketch to ESP and Mega32U4 side, I still don't get a response.
ESP side sketch:
{
Serial1.begin(115200);
}

void loop()
{
Serial1.println(“Hello”);
delay(1000);
}

MEGA32U4 side sketch:
String character = Serial1.readString();
Serial.println(character);
}

Believe me, I don't know exactly where I went wrong. I wrote more descriptive, but I was asked to ask one question. In short, how exactly can I update to espduino via NodeMCU flasher?

The Cactus Micro Rev2 board has ATmega32u4 with LiliPad bootloader as main MCU and esp8266 as WiFi adapter.
The esp8266 UART is connected to 32u4 Serial1. The Serial on 32u4 is connected to computer over USB.
To bridge the esp8266 to computer you can use the SerialPassthrough sketch from Communication section of base Arduino IDE examples in File menu.
The manufacturer of the board made a sketch for the ATmega32u4 which sets the esp8266 to bootloader mode and bridges the esp8266 to USB.
The esp8266Programmer.ino sketch is basically a SerialPassthrough sketch with reset of the esp8266 to bootloader mode in setup().
Select "Arduino LiliPad USB" in Arduino IDE the upload the esp8266Programmer.ino sketch to the 32u4.
With the esp8266Programmer.ino in 32u4 you can upload to esp8266 with Arduino IDE or esptool.py.
If you want to communicate with the application (firmware or sketch) in esp8266, use the SerialPassthrough sketch from Arduino IDE examples (because the esp8266Programmer sketch always sets the esp8266 to bootloader mode).
For successful upload from IDE or esptool.py over the esp8266Programmer sketch, the reset before uploading must be suppressed. In IDE it is the "Reset method" option (select no_dtr), for esptool.py it is the --before no_reset option.

Let us continue this discussion in chat.

The board has an esp-03. First, we uploaded esp8266programmer.ino and then uploaded the esp sketch from IDE. Our esp settings must be like this:

Flash Size: "1MB (none OTA)
Flash Mode: "DIO"
Reset method: "no dtr
(aka ck)"

We uploaded our sketch. The Atmega sketch must have this two lines of code in the setup() function:
digitalWrite(program_pin, HIGH); //Set GPIO to boot into programming mode
digitalWrite(enable_pin, HIGH); //Enable ESP-03 module

The serial baud rate must be less than 74880. This way, the problem will be solved. Thanks to @Juraj for the support.


text:
How real-time is an arduino (react to sensor)?
New to arduino here, sorry for asking what may be a trivial question.
I need to simulate an industrial machine at home. It operates in a cyclic motion, creating an event for every rotation / cycle. Imagine a turntable or wheel with a marker in one place.
What I would like is:

Have a physical wheel which I turn one rotation every 300 msec. This is the length in time of a cycle.
Read a marker on this wheel using a sensor, such as Sick or Omron. I have this already. Sensor can be PNP or NPN, providing a closed or open connection. I can go via an optocoupler if needed.
Once a signal is seen, the arduino should send a (sequential) string using RS232 to a PC. Approximately 90 characters.  It is not needed to wait for response.

My question is: would be time for arduino to do this be relatively constant - ie, send out the data at approximately same point in the cycle. Example: signal read at "12" on the clock, data sent around "5".
If possible, what sort of Arduino would I be looking at ?
Or do I need something more real-time for such project, like a PLC ?

You are asking for two different things: latency of your system and the jitter

You’re talking about responding to a an approximately 3.33Hz signal that you can monitor with a simple edge-triggered interrupt using a microcontroller running at almost six million times that frequency. You should be perfectly fine, even factoring in the few hundred instructions to send the serial data.

one rotation every 300 msec.

300 ms is a very long time for an Arduino, even for an AVR-based
one, like an Uno.
I did a little experiment. I generated (with an Arduino...) a periodic
signal consisting of a 96 µs-wide negative pulse repeating every
300 ms. I sent that signal to an Arduino Uno running the following
code:
const uint8_t sensor_pin = 3;

// 90-byte message.
const char message[] = "Korem ipsum dolor sit amet, consectetur "
        "adipiscing elit sed do eiusmod tempor incididunt\r\n";

void setup() {
    pinMode(sensor_pin, INPUT_PULLUP);
    Serial.begin(9600);
}

void loop() {
    if (digitalRead(sensor_pin) == LOW) {
        Serial.write(message);

        // Wait until the signal rises again.
        while (digitalRead(sensor_pin) == LOW)
            continue;
    }
}

This is not the nicest way to do edge detection, but for this simple
test it will do. You may notice that I am not using interrupts for
capturing the pulse: 96 µs is long enough to be captured with this
simple digitalRead(). I then captured the input and output signals
with a dual-channel pocket oscilloscope. Here is a screen capture:

The cyan trace at the top is the received pulse. The yellow trace below
is the output of the serial port. The negative pulse on this trace that
is almost coincident with the received pulse is the start bit. Then the
signal rises to transmit the first data bit, which is a 1 (that's
why I chose “K” rather than “L” as the first letter).
What you can see in this capture is that the latency of the Arduino is
tiny at this scale: a small fraction of the duration of the start bit.
What you cannot see is the jitter, which is quite large in relative
terms, but still small compared to the time scales relevant to you. In
short, the delay between the falling edge on the input and the falling
edge of the serial port start bit fluctuates roughly between 10 and
20 µs. Yes, those are microseconds. This delay is roughly
20,000 times shorter than the rotation period. If the signal is read at
“12” on the clock, the start bit fires at 12 hours with
0 minutes and 2 seconds.
Note that, on the other hand, the time needed to send the message at
9600 b/s is 93.6 ms, a significant fraction of the rotation
period. And I didn't look at the behavior of the USB-to-serial converter
chip, which is another can of worms...

There's no reason why the serial port speed can't be increased. I'm always using 115200 as baud rate, and never had any problems.

@PMF: The OP has a very good reason to not increase the serial port speed: he wants to simulate an industrial device that speaks at 9600 b/s.

Note that a 90 char message will probably exceed the output buffer size of the (chip being used on the) Arduino. There's obviously ways around this (send a few bytes, delay, send a few more...) but there's both a risk of determinate overrun here (the last message hasn't yet been written when the wheel comes round to its trigger point) and an indeterminate overrun (interrupts are still being serviced when the wheel comes round). The first case will be easy enough to recognise but the second less so... and might be enough to cause problems if this is being used for e.g. ignition timing.

@EdgarBonet I see nothing in the question that specifies the speed of the actual device he wants to simulate. But if the message was, in fact, to long to be transmitted within a time slot, that would be the same for the real system as well.

@MarkMorganLloyd: The output buffer of the chip in question is one byte deep. Two bytes if you count the shift register holding the remaining bits of the byte being transmitted. And yet, the code I posted has no issues reliably sending the whole message: Serial.write() is smarter than you think. There is no risk of overrun as long as the input pulses are spaced more than 93.6 ms apart, and they only come every 300 ms.

@EdgarBonet Thank you kindly, but HardwareSerial.h demonstrates precisely how smart it is: either 16 or 64 bytes depending on the type of chip/board. I assure you that it IS possible to overrun that.

@MarkMorganLloyd: My point is, even with this 64-byte internal buffer, Serial.write() reliably sends a 90-byte string if asked to.

@EdgarBonet Not in all cases in my experience. However /my/ point is that if the ISR is still clearing the buffer at the time that the next revolution pulse arrives it is likely to result in indeterminate jitter... unless of course it's attached to a higher-priority interrupt, which I suspect is unlikely (and which is definitely not the case in your posted example).

@MarkMorganLloyd: Re “Not in all cases in my experience”: If Serial.write() does not send reliably 90 bytes when asked to, you have a bug in your code. Probably one that is corrupting memory. Re “if the ISR is still clearing the buffer..”: In this case, a new message is due while the previous one has not been sent completely. Of course there will be extra jitter! There is no way around this. Fortunately for the OP, the messages take 93.6 ms to send and are sent every 300 ms.

@EdgarBonet I disagree. However I think I was using Serial.print() etc. when I discovered this rather than Serial.write() (and that I can't remember the precise symtoms), and I would caution that even in the Serial.write() case if it can't fit the data into the available buffer then it's likely to pause the main loop (with an effect on any hardcoded delay) rather than magically allocating more storage space. However your point about a 90-byte message occupying roughly 90 mSec at 9600 BPS is of course a good one.

@MarkMorganLloyd: You are right about the pause. In this instance, Serial.write() takes 26 ms to complete. I did not mention that in the answer because I believe the OP is not going to be concerned about that, as his main concern was whether there would be a latency in the hundreds of milliseconds.

TLDR: any Arduino is probably sufficient for your purpose when done properly.
I'll assume a proper HIGH/LOW binary signal from the sensor, HIGH when it "sees" the marker, LOW when it doesn't.
What could go wrong?

You use digitalRead() to get the state of the digital input. Depending on the pulse width, you might not catch the high state. Use interrupts instead.
Sending the data over Serial port takes longer than a turn of the machine. 90 bytes at 9600 bit/s needs (90 bytes * 10 bits/byte / (9600 kbit/s) = 93ms. In 300ms, there's enough time to send the 90 bytes. And 9600 bit/s is quite slow: you can probably use 115200 bit/s on short or shielded wires.
"Approximately 90 characters": calculate everything for the maximum data that will eventually be sent
Getting the data on Arduino side takes too long. You didn't give details on where those 90 bytes come from. Asking 90 devices to each give you a byte of data might not be possible in 300ms.
Receiving the data on the PC side (or whatever) might be delayed, because it is buffered. Especially USB to Serial adapters have no guaranteed timing. Doing the math for USB devices is hard.
Threading on the PC side: due to the OS Thread scheduling, the application that shall receive the data might not get CPU time for several milliseconds, 16ms (1/64s) is quite common. Doing the math is impossible (try running 8 real time threads that do something else and your PC is basically frozen)
Processing on the PC side: unknown
Displaying: after processing until a signal is displayed on the screen, that may take another 16 ms (at 60 Hz refresh rate).

would be time for Arduino to do this be relatively constant

Relatively: yes. It certainly depends on the implementation (the Arduino C++ code).
If the data to send is hard coded 90 characters, I would expect the complete signal has been sent at before the 4 o'clock mark (94ms /300ms * 12 hours ~ 3 hours) . I see the problem more on the receiving side (see points 5., 6., 7. and 8.).

what sort of Arduino would I be looking at ?

I don't know all of them, but an Uno will certainly work. If you only have that one digital input, even smaller ones are probably ok. Just start with an Uno or what you have available and see how it goes.

do I need something more real-time for such project, like a PLC?

I don't see a need for a PLC in your project.

Your answer is also useful, but I had to accept the other once for providing exact measurements.  As this would just be a simulation the 90 characters would be just fixed text and an increasing counter, so no delay getting input from anywhere. The receiving end is well capable of handling the input.  Unfortunately switching to 115k is not possible due to the actual machine being simulated.

@MyICQ: accepting the other answer is ok. I am not overly happy with the digitalRead() decision of that answer - probably because I had too many issues with digitalRead() not working reliably enough in my projects. Anyway, if the suggested code is roughly what you need, that's a fine answer.

What would be the alternative to digitalRead() ? I am new to Arduino, and somehow the event of sending serial string should be triggered ?

@MyICQ: note that I accidentally calculated with kbits/s instead of bit/s, so I was off by a factor of 1000. OMG! See the new calculation. The whole data is sent at around the 3 o'clock mark

@MyICQ: use digitalRead() as suggested by Edgar. Later you can try https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

I am not a huge fan of digitalRead() either, but it has the benefit of simplicity, and it is newbie-friendly. If the stuff was really time-critical, I would use interrupts. With care, because printing to Serial from interrupt context has its issues. 2. 90 bytes at 9600/8N1 should take 93.75 ms (do not forget the start and stop bits). At the Arduino-rounded “9600 bps” speed it takes 93.6 ms.


text:
ESP32-CAM, Failed to connect to ESP32
I am trying my ESP32-CAM for project but I am having problems with uploading script/code to the ESP. I am using CP2102 to connect ESP and my laptop. I tried connecting it to 3.3V and even 5V but none seem to be working as I always get the same error:
"A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header"

Did you connect GPIO0 to Ground when powering up the ESP32Cam, before starting the upload?

Yes, I connected it exactly like this :
https://i1.wp.com/randomnerdtutorials.com/wp-content/uploads/2019/12/ESP32-CAM-FTDI-programmer-5V-supply.png?w=750&quality=100&strip=all&ssl=1
Don't know if it helps but when I connected it of the two LEDs on this USB-UART (TXD and RXT) only TXD was blinking.

i bet the 3.3v isn't strong enough to power the ESP32

Well as I said, I tried 5V too, meanwhile I tried using Arduino Mega as "programmer" so I could be sure it isn't in UART-USB and it did the same thing. I am wondering if the ESP isn't damaged, any ideas how to test it?

For future references.
So after some time I was finally able to upload my code into ESP32-CAM. I don't know if I had just bad luck with "faulty" ESP but here is what helped me.

Don't use CP2102, it just doesn't work for me, use other programmer or Arduino as I did.

If you have been using scheme like this scheme and wasn't able to fix your problem try to connect all other things that need GND on some breadboard and use just one GND pin from ESP. I noticed that GNDs on ESP has (or atleast mine have ) 0.5V difference between them. Right now I am using the GND pin that was connected to IO0 as "main" GND and its works.

Hope this helps someone and thanks for all replies.

Thanks for posting your solution. Please note that whatever your problem was, it might very well come down to power supply issues. In my experience, not all commonly available USB Serial->TTL converters are powerful enough for an ESP32Cam (either at 3.3V or 5V), especially once the ESP32 is starting up, connecting to Wifi and powering up its camera.


text:
How to know if GPS module is dead?
I can't make function the NEO-6M-0-001 GPS module, this is the third one that already bought! I'm using an ATmega2560 as microcontroller for obtaining the data from the module and seems that the module never initializes.
I bought an USB-UART converter for checking if there is something that I did wrong (soldering, bad wiring, burned circuit, etc.). I connected the the module to the converter, opened the serial monitor to see what is happening and this is what I found:
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,15,02,,,23,05,,,23,07,,,21,12,,,22*78
$GPGSV,4,2,15,13,,,22,16,,,22,17,,,23,18,,,22*70
$GPGSV,4,3,15,19,,,22,20,,,22,21,,,22,24,,,22*74
$GPGSV,4,4,15,26,,,22,27,,,22,50,,,27*7C
$GPGLL,,,,,,V,N*64

Seems that the data is missing, or I have to some how initialize the module. This is happening with the three modules. In the picture you can see the antenna that I'm using, I'm outdoors testing it. By the way, its true that without antenna the gps could be damaged?

I really appreciate if someone could help, thank you.

Are you indoors? Do you have a suitable antenna attached? It can take a long time to connect to the satellites, so you need to be patient.

I went outdoors, I'm attaching a picture of the antenna. Its true that I did'n  wait so much.

This is pretty much what Majenko is saying, but just to be more explicit: Empty fields are normal for not having acquired a fix.

@timemage I went outside and I'm getting nothing, the quantity of satellites changes from 1 to 10 without getting a fix. Maybe something wrong at hardware level?

If it difficult to say. Just to warn you, without some fairly Arduino specific stuff in the question it's liable to get closed, although I'm not sure where the right place to ask it is. Thoughts are: make sure the power going to the GPS is clean. I'm don't know (or remember really) what all of the ramifications of that number going to 10 are.  I know you only need 3 for a 2D fix, but I've seen GPS report quite a pile of satellites before getting a proper fix.  If you have at least three for a two or three minutes solid, then I'd worry more.

to reiterate what's already been said, you need good visibility of the sky to get a strong signal and it can take a long time to get a fix especially with a weak signal

You are probably not waiting long enough. It can take a good 15 minutes for a satellite to send all its orbit data that the module needs to triangulate its position. So that's your wait time you need to account for. Your phone cheats by going online and downloading that data from an online database.

"Trilaterate", I think.  It can take while to download WAAS information, to get a good fix. I can't remember the last time, if ever, I saw a GPS take anything like 15 minutes to get an initial crude (within 50 meters or so) fix outside.  It seems like if you don't get one within about 3 minutes, you're just not going to.

I’m voting to close this question because its not about Arduino but about a GPS module

Well, I waited. Like 1 hour with every single GPS module. I have 2 conclusions: I'm in the wrong place (even though I went outside and is clear), or the GPS modules are obsolete by now and I have to buy newer versions. Thank you all by your help!

You are getting correctly formed NMEA sentences from the GPS module, so it looks like it is working ok. The $GPGGA sentence says: no fix and zero satellites. An uncovered place outside (no trees) should be sufficient. So it looks like an antenna problem.


text:
Arduino Due generate 400KHz sine waze
I new in Arduino environment.
Found some code generate sine wave but frequency between 14kHz to 84kHz. URL is https://www.instructables.com/SineWave-Generator-for-Arduino-DUE/
I need to generate sine waze 400kHz frequency.
Output should be on DAC0 or DAC1.
Any one can help to solve my problem.

Sorry, but how should we help you with that? You didn't give us any information. Show the code, that you have found. And also provide a detailed description of what your actual problem is.

I get some sample for generate sine wave in this link
I need to generate sine wave with frequency 400KHz. Base on link above, I dont have any idea how can I write code to get freq 400KHz.
Sorry I new student to learn arduino. @chrisl

Please add this information to your question by editing it. It should be able to stand for itself, without important information in the comments. I'm no expert in the Due (never used it), but I don't think that will work for you. The sketch is just pumping out the samples by software as fast as it can. For the 84kHz it only uses 20 samples. So for 400kHz you would have only about 4 samples. Thats not really a sine wave anymore. Maybe a pure hardware wave generation would be better.

Googling gave me for example this site, which explains how to generate a sine wave using a 555 timer chip. They seem to go up to 250kHz. By changing the values of the components further, you might get to 400kHz. Though this is not my expertise field. You could ask a question about this at electrical stackexchange

For the STM32 there is app note AN4566 about Extending the DAC performance by disabling internal output buffer and using external one, and then they can go several times higher than usual 1Msps, but I'm not sure if microchip's SAM3X8E has this possibility too

The Due's DAC can go up to, and I quote direct from the datasheet:

Up to 350ksps conversion rate

That means you can set up to 350,000 data points on your waveform per second. With two datapoints (giving you a square wave or, more realistically, a waveform with a sharks fin shape) the maximum you could get is (350,000/2) 175kHz.
Given that you stipulate you want a sine wave you're going to need many more than just 2 data points in your waveform. Assuming a (reasonable) minimum of 32 data points (more would give a smoother waveform) you'd be looking at a maximum frequency of about 10kHz. Sacrificing waveform fidelity you could increase that, but the higher you go the less and less it resembles a sine wave.

I think you may be overestimating the capabilities of the Due DAC. My understanding and experimentation is that waveform generating code (e.g., https://forum.arduino.cc/t/funkgenie-a-wavetable-based-function-generator/214938) can generate consistent output waves up to “a few kHz”. After which the wave shapes suffer from distortion.
If wave shape is not critical (though you did mention you specifically needed a sine wave) you may be able to push further using PWM outputs (e.g., https://forum.arduino.cc/t/due-high-frequency-waveform-up-too-500khz/423392).
However, I think you may need to design a suitable electronic circuit to generate the wave you’re seeking. That may be a topic for the Electrical Engineering stack exchange though? There is an introduction to wave generation circuit options going up into the RF frequencies here.


text:
On a custom ESP32-based PCB, I can' flash anymore after the first successful firmware flash
I have designed and manufactured a custom PCB, with an ESP32 chip on it.
I use my FTDI cable to upload my firmware.
I have no problem to flash my firmware, and it runs with no problem. So far so good.
But then, any successive attempts to flash again is a dead end as it results into a timeout (of course I still press the boot button on my PCB).
If I take a new PCB, the first flash is OK but I cannot do it again.
Note: to make thing as simple as possible, I simply use the Arduino IDE and my do-nothing code as my firmware replacement:

void setup() {
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  Serial.println("Yo from SDL!");
}

// the loop function runs over and over again forever
int _loop = 1;

void loop() {
  Serial.print("Loop #");
  Serial.println(_loop++);
  Serial.println();
  delay(3000);
}

[UPDATED] Here is the schematic regarding the ESP32 and the GPIO0, GPIO2:
The schematic of the PCB regarding the boot loader
Do you have any clue?!

Have you properly wired in the GPIOs that trigger the bootloader mode?

@Majenko I did wired the boot loader pin and added a button to turn the chip to boot loading mode. To make it clear, I successfully  download the firmware in the chip the first time. But after that I cannot update.

A "blank" chip will be in bootloader mode by default IIRC. Can you share your schematic and board design?

@Makenlo Oh, I see, I might have screwed up the boot loader schematics? let me share this part with you in a few moment

@Majenko I have uploade the schematics of the PCB regarding the boot loader

IO2 needs to be connected to a pulldown resistor (your buzzer FET has a pulldown on its input which does the job, which is fortunate). I would consider moving the buzzer elsewhere and keeping IO2 just for the pulldown resistor if possible.
IO0 needs a pullup resistor.
You need some way of resetting the ESP32 through pulling the EN pin low when you want to reprogram it.
Both IO0 and the EN pin are usually controlled through a combination of the DTR and RTS pins of the USB to UART adapter to do the resetting automatically. Without that you will have to manually hold IO0 LOW while briefly pulling EN low to reset the chip.

as per the doc the io0 as an internal pull-up: do we really needs to add an external one?  (“Each strapping pin is connected to its internal pull-up/pull-down during the chip reset. Consequently, if a strapping pin is unconnected or the connected external circuit is high-impedance, the internal weak pull-up/pull-down will determine the default input level of the strapping pins.”)

@StéphanedeLuca Interesting - that I did not know. Still, it's good to be explicit in these things I think to avoid uncertainty. But if the internal one works then that's fine. You still need to toggle EN though ;)

So IO0 was OK. But I screwed up the EN (it was attached to a pull up). And how @Majenko pointed out, EN must be briefly set to low. Thanks a lot


text:
Measure voltage in 14 points 0 - 60 volts (14s LiPo battery) with single ADC
I wish to measure 14S battery voltage on each cell with single ADC.
I guess I need some ADC built-in or external (I2C), voltage divider and switch chip that will allow me to select one of 14 pins to measure.
Am I correct?
Could you advice what switch chip should I use?
or Should I build that curtuit myself with 2 74HC595 and mosfets? (not sure if that will ever work)

You may want to search on the term “analog multiplexer”.

I would do it manually (but then I am a bit sadistic like that).
The circuit for one cell is pretty simple, and you just need to replicate it 14 times. A P+N pair of MOSFETs to switch a battery channel on and off, and a pair of resistors to make a voltage divider. You can keep the "lower" of the resistors common between all channels if you like to reduce the number of components and complexity, but once you have 14 channels the complexity will become pretty silly anyway.  Here's an example with just 3 channels:

simulate this circuit – Schematic created using CircuitLab
You would need to size RA|RL, RB|RL and RC|RL (etc) accordingly to get the right voltage ranges for the ADC input, and keep the output impedance low enough (<10k) for the ADC to handle it properly. You may want a couple of different load resistors (RL) for different groups of cells.
All the N-channel MOSFETs could be replaced by a 4-to-16 decoder with open-collector outputs (such as, if you can get it, the 74xx159), which would also protect against switching on multiple channels at once, which you never want to do.
Note that this arrangement gives you the voltage of the first cell, the voltage of the first two cells, the voltage of the first three cells, etc. To get the voltage of just the third cell (for example) you will need to subtract the voltage of the lower cells.


text:
How to debug an error which occures after a long time only?
I've got an ESP32 with an CO2 sensor attached. The Arduino script I'm using is quite old and worked for sending them over LoraWAN to TTN and is stable. I added an Wifi-Client to read data more frequently when an Wifi is near. The data get send over to my server via MQTT. Now after some time the device stops sending; I think it's just a few hours working. (I used libraries)
Now my question -  how do I find the problem? I mean it has something to be the memory, doesn't it? The code is quite long so I would prefer to find the actual problem on my own - but how? My idea was to send debug messages by MQTT, hooking up a client to save all the MQTT messages so I can view the last messages the device sent. (I'm not even sure if the device fully stops or just loses connection etc). This whole thing sound like a tedious problem as I'd have to wait a few hours after every code fix I'd have implemented..
Thank for any help!

Without any detail to work with, there's not much help I can give. If your sensor is being read periodically, take out the delay so you're spamming output as quickly as possible. Hopefully, you'll get to the error more quickly that way. Remove every call to malloc() in your code - it leads to unavoidable fragmentation problems. Without more info, there's not much more I can suggest.

@Sniggerfardimungus Okay I understand that. - I'm not using malloc in my code.

@Juraj I'm using a String indeed to concat several values, then I convert this to an chart array. On every sensor refresh the string gets re-set again.

Add Serial.println(ESP.getFreeHeap()); to your sketch and monitoring the value the first step for debugging.

@wernersbacher there’s a relevant post regarding use of strings you should have a look through. https://arduino.stackexchange.com/questions/85157/using-string-instead-of-c-string-yet-another-attempt-to-touch-a-loaded-issue (Arduino strings are a bit of a rite of passage in the Arduino world - causes a lot of discussion. The referenced answers are a solid intro to the issues and resolutions)

@wernersbacher If you're doing string concatenation, you may not be allocating, but the concatenation methods are. If you're doing much of this, particularly if you're slowly growing a string over time, I'd say there is a strong possibility that you're fragmenting memory. What String library are you using and exactly what function are you using to do concatenation?

report to the server more often to make it fail sooner. I would also bet on Strings. I have some older stuff I should but never have rewritten that also hangs after a long time; I have it reboot the ESP every few hours to avoid it, and it reboots in seconds, so i never miss my 5-min reporting interval (which is why i've never gotten around to rewritting the strings)...

I'm using a String indeed to concat several values. If you using String.concat, take a look at this answer from me on how it could create the problem and how to avoid it.


text:
1.) How do I delay a servo motor from turning in a loop? 2.) How do I make a servo motor's change in position dependent on temperature?
I'm super new to the c++ programming world (currently taking the class now) and I'm in need of some assistance with some coding that's way beyond my knowledge at the moment. I have to write a code for Arduino interfacing with servo motor, ezButton, water-proof sensor and ada fruit motor shield.
the project entails building a moveable arm that holds a hot metal post that needs to be submerged into water for cleaning, BUT before it can be submerged I need to give the metal time to cool so it doesn't fracture. (Question 1, how do I delay the servo motor from moving to allow the metal to cool.) After the metal is submerged for cleaning, the servo motor needs to move back to the starting position ONLY if the temperature is less than 50 degrees Celsius. (Question 2, how do I make the servo motor dependent on temperature.)

#include <OneWire.h>
#include <DallasTemperature.h>
#include <AFMotor.h>
#include <Servo.h>
#include <ezButton.h>

#define ONE_WIRE_BUS 2
#define LOOP_STATE_STOPPED 0
#define LOOP_STATE_STARTED 1

OneWire oneWire (ONE_WIRE_BUS);
DallasTemperature sensors (&oneWire);

ezButton button(7);
int loopState = LOOP_STATE_STOPPED;

Servo name_servo;
int servo_position = 0;
int Celsius = 0;

void setup() {
  sensors.begin();
  Serial.begin(9600);
  name_servo.attach (10);

  button.setDebounceTime(50);
 }

void loop() {
  button.loop();

if (button.isPressed()) {
    if (loopState == LOOP_STATE_STOPPED)
      loopState = LOOP_STATE_STARTED;
    else // if(loopState == LOOP_STATE_STARTED)
      loopState = LOOP_STATE_STOPPED;
  }

if (loopState == LOOP_STATE_STARTED) {
    sensors.requestTemperatures();
    Celsius = sensors.getTempCByIndex(0);
    Serial.print(Celsius);
    Serial.print(" C  ");
    delay(1000);

//ADD COOLING PERIOD (3min)

  for (servo_position = 0; servo_position <=180; servo_position +=1){
      name_servo.write(servo_position);
      delay(10);
      ;
   }

// ADD CONDITIONAL STATEMENT (if temp < 50, motor returns from 180 to 0)

  for (servo_position=180; servo_position >= 0; servo_position -=1){
      name_servo.write(servo_position);
      delay(10);

    }
  }
}

how do I delay the servo motor from moving to allow the metal to cool ... press the button when the metal is cool

@jsotola yes that true but, The project is supposed to be a push button operation that you can walk away from after loading in the metal post. I guess the key is efficiently, the operator can go finish/do other tasks while this program is running

do this with pencil and paper ... write down in great detail how the program should behave ... if the description is very detailed, then it will translate into code almost directly

write a simple state machine ... use flags to interface the button and the temperature sensor to the servo control code ... all code would be in loop() ... do something like this read remperature ... if below 50 then dipDone = true ... if below 100 then okToDip = true .... read button ... if pressed then doDip = true ....... next comes the logic that controls the servo ... if doDip and okToDip and notDippingAlready then start servo ... etc. etc.


text:
How to use the M117 temperature sensor from mysentech?
Anyone can help me decode the temperature of the M117 chip from mysentech.com?
I tried things, but I get a constant raw value of 0xFFFF, which becomes 1 once 2's complemented is applied.
The chip shows up at the expected address (TEMP_SENSOR_ADDRESS is 0x45) during a scan operation of the I2C bus.

    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
    // Select data register
    Wire.write(0x00);
    // Stop I2C Transmission
    Wire.endTransmission();
    delay(300);

    // == Request for the raw temp 2 bytes
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 2);
    const size_t count = Wire.available();
    log("%d bytes available", count);

    if (count!=2) {
        *ready = false;
        warn("I2c temp is not available");
    }
    else {
        *ready = true;
        // Get the raw data as the 16-bit big endian (MSB-LSB)
        byte data0 = Wire.read();
        byte data1 = Wire.read();
        const uint16_t raw = data0<<8 | data1;
        const int sign = raw>>15 == 1 ? -1 : 1;

        // Get the raw temperature as a 2's complement of the 16-bit (MSB-LSB) value
        const int16_t c2Raw = ~raw + 1;

        // Apply scale and offset
        temperature = sign * float(c2Raw)/256.0 + 40;
        log("raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C",
            raw, raw,
            c2Raw, c2Raw,
            temperature
        );
    }

[UPDATE | SEPT. 2nd 2022]
Following the discussion I had with @jsoleta, my current code is as follows. But still getting FFFF AC. AC being the correct CRC for FFFF.
Coud it be the result of a wiring issue of the component on our custom PCB?
The logs:
b5725|—|  Thermometer: Command: Writing to register command 0xCC44
b5725|—|  Thermometer: Command byte 0: cc
b5725|—|  Thermometer: Command byte 1: 44
b5725|—|  Thermometer: Command: register transmitted 2 bytes
b5725|—|  Thermometer: 3 bytes available
b5725|—|  Thermometer: Actually read 3 bytes: ff ff ac
b5725|—|  Thermometer:  CRC matched: computed: ac == read: ac
b5725|—|  Thermometer: raw: ffff (65535) | Raw 2's complement  0001 (1) | temperature: 39.996094°C
b5725|—|  Thermometer: raw: ffff (65535) | temperature: 39.996094°C
b5725|—|  Thermometer: Transmitting board temperature 40.0°C over the RS-485 bus (raw is 799 - 0x031f)

The updated code:
loat I2cThermometer :: readTemperature(bool *ready) {
    float temperature = 0;

    log("Command: Writing to register command 0xCC44");
    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);

    // Select data register 0x00, config 0x01

    const uint16_t command =
        0xcc44  // Wait for temperature measurement
        //0xf32d    // Read status
        //0x611d    // Measurement result set alarm
    ;
    byte * data = (byte*)&command;
    Wire.write(data[1]); log("Command byte 0: %02x", data[1]);
    Wire.write(data[0]); log("Command byte 1: %02x", data[0]);

    // Stop I2C Transmission
    const auto readCount = Wire.endTransmission();
    log("Command: register transmitted %d bytes", readCount);
    delay(15);
    // == Request for the raw temp 2 bytes + CRC
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 3);   // 2-byte data + 1-byte CRC
    const size_t count = Wire.available();
    log("%d bytes available", count);

    if (count!=3) {
        *ready = false;
        warn("No temp data is not available");
    }
    else {
        *ready = true;

            // Get the raw data as the 16-bit big endian (MSB-LSB)
            byte data[3];
            const size_t r = Wire.readBytes(data, sizeof data);
            log("Actually read %d bytes: %02x %02x %02x", r, data[0], data[1], data[2]);
            const byte crc = MY_CRC8(data, 2);
            if (crc != data[2]) {
                warn("CRC mismatch: computed: %02x != read: %02x", crc, data[2]);
            }
            else {
                success("CRC matched: computed: %02x == read: %02x", crc, data[2]);
            }
            const uint16_t raw = *(uint16_t*)data;

            const int sign = raw>>15 == 1 ? -1 : 1;

            // Get the raw temperature as a 2's complement of the 16-bit big engdian (MSB-LSB)
            const int16_t c2Raw = ~raw + 1;

            // Apply scale and offset
            temperature = sign * float(c2Raw)/256.0 + 40;
            #if LOG_LEVEL >= LOG_LEVEL_DEBUG
            log("raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C",
                raw, raw,
                c2Raw, c2Raw,
                temperature
            );
            #endif

        #if LOG_LEVEL >= LOG_LEVEL_DEBUG
        log("raw: %04x (%d) | temperature: %f°C",
            raw, raw,
            temperature
        );
        #endif

        writeBoardTemperatureMessage(temperature);
    }

    if (!(*ready)) {
        #if LOG_LEVEL >= LOG_LEVEL_INFO
        log("Temperature is not ready %d°C", temperature);
        #endif
        return temperature;
    }

    #if LOG_LEVEL >= LOG_LEVEL_INFO
    log("Temperature is %d°C", temperature);
    #endif

    return temperature;
}

don't think 0xFFFF, which becomes 1 once 2's complemented ... instead think 0xFFFF, is 1111111111111111.  I'm not reading any zeros

Not saying that FFFF is 1, but  that two complement of FFFf becomes 1. The raw value is the 2 complement of the 16-bit we read.

Ok, I found something weird. My code do work if I request the sensor every 4 seconds at max. But if the frequency is below that, it won't work.
Will replace the sensor, rolling back to TMP112, as before.

WARNING: I have no way to test/verify the parts of this that directly apply to your chip.

Issue conversion command
This device does not appear to follow the common write-register-address followed by read-register-value scheme. Instead, it seems in order for the device to  sample and convert temperature at all you must first issue  a command to perform the conversion. You're not doing that, so that seems to be the principal problem. You're reading whatever the value is prior to every having asked for a conversion an the datasheet says indicates this is indeterminate. So 0xFFFF is plausible and unremarkable for a value you'd get not having already requested conversion.
Issuing the conversion command (again, I'm not able to test this):
void request_temperature_conversion() {
  Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
  Wire.write(0xCC);
  Wire.write(0x44);
  const auto check_me = Wire.endTransmission();
  delay(15); // Ensure a completed conversion.
}

Read result
To read the result of value of the most recent conversion:
uint16_t read_u16_temperature() {
  const auto read_count = Wire.requestFrom(
    TEMP_SENSOR_ADDRESS,
    3 // the actual transaction includes an 8-bit as well as 16-bit sample
  );
  uint8_t temp_payload[2];  // 2 because i'm going to ignore the CRC.
  Wire.read(temp_payload, sizeof temp_payload);

  return uint16_t(temp_payload[0]) << 8 | temp_payload[1];
}

int16_t read_s16_temperature() {
  int16_t r;
  const uint16_t u = read_u16_temperature();
  memcpy(&r, &u, sizeof r);
  return r;
}

Together
Again, I can't really test this.
request_temperature_conversion();
temperature =
  sign
  * float(read_s16_temperature()) / 256
  + 40;

You probably can and should avoid the use of the floating point type.  If you're logging this data and transmitting this data to somewhere else to be logged, you may be better off transmitting/storing the raw values which can be (re)interpreted later rather than having different versions of your sketch potentially affecting how a calculation is done on the values.
Manufacturer's documentation
The website you have linked to has a datasheet in Chinese. You may get some use out of you machine translate it to English (or whatever). Google Drive is capable of this. Probably more useful are the archives of sample code intended for STM32.  That's where all the information came from, including crucially the use of 0xCC44 command to prompt conversion. The 15ms delay is also lifted from what I read in the STM32 sample code in the rar archive from the site; I didn't put much thought into its significance or how the part behaves if you don't wait long enough. You should read through it, because there's more about configuring the chip, the CRC, etc.

Thanks for the answer. Unfortunately, I had already tried CC44, but I made some adjustments according your input to my code but this still gives 0xFFFF raw value. The CRC I got is 0xAC (I did not yet checked it is ok though). Regarding the data sheet, I had already translated it from the Chinese. I'm gonna work with the STM version thy give on the site.

I modified some old CRC8 code I had for the generator polynomial and initial values the datasheet specifies (0x31 and 0xFF respectively) and it confirms that 0xAC is the correct CRC for 0xFFFF. Also verified their 0xBEEF, 0x92 example CRC.  So you getting a well formed  inbound I2C read. If I have cause to edit some of this may make its way into the answer.

I confirm that AC is the right CRC for FFFF. Current prog code seems now correct but still no result beyond the FFFF (I am going to update the question accordingly-. Could it be the result of something's wrong in the wiring of our custom PCB?

Since you're getting a correct CRC an I2C wiring problem seems unlikely to me. If there is such a problem, then it's not likely the sort of problem that can't be mitigated by lowering the I2C data rate. We're now well off discussion the answer written. If I see something new in the question that I can respond to I will. If you're trying to talk to me directly, I can often be found on libera.chat


text:
Serial comm UART1 works on Arduino but makes ESP32 continuously reboot
This comm sketch simply read incoming bytes from the UART 1 where a device is attached.
It works normally on a real Arduino device.
But on ESP32, it makes it continuously reboot with the following messages:
([UPDATE] Note that there is no reboot on ESP32 is I use Serial2 instead of Serial1)
9:13:19.676 -> ets Jun  8 2016 00:22:57
19:13:19.676 ->
19:13:19.676 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
19:13:19.676 -> configsip: 0, SPIWP:0xee
19:13:19.676 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
19:13:19.676 -> mode:DIO, clock div:1
19:13:19.676 -> load:0x3fff0018,len:4
19:13:19.676 -> load:0x3fff001c,len:1216
19:13:19.714 -> ho 0 tail 12 room 4
19:13:19.714 -> load:0x40078000,len:10944
19:13:19.714 -> load:0x40080400,len:6388
19:13:19.714 -> entry 0x400806b4
19:13:19.786 -> Yo! from serial UART 18/19
19:13:19.786 -> SbmDi⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮@D@⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
@%cGuru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
19:13:19.823 -> Memory dump at 0x400e90f4: ffffffff ffffffff ffffffff
19:13:19.823 -> Core 1 register dump:
19:13:19.823 -> PC      : 0x400e90f8  PS      : 0x00060530  A0      : 0x800d1529  A1      : 0x3ffb1f80
19:13:19.823 -> A2      : 0x3ffbfe88  A3      : 0x3ffbfe6c  A4      : 0x0001c200  A5      : 0x0800001c
19:13:19.823 -> A6      : 0x00004e20  A7      : 0x00000000  A8      : 0x800d0c4f  A9      : 0x3ffb1f60
19:13:19.857 -> A10     : 0x3ffbfe6c  A11     : 0x3f40013b  A12     : 0x0800001c  A13     : 0x00000009
19:13:19.857 -> A14     : 0x00000009  A15     : 0x00000000  SAR     : 0x00000016  EXCCAUSE: 0x00000000
19:13:19.857 -> EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffbd
19:13:19.857 ->
19:13:19.857 -> ELF file SHA256: 0000000000000000
19:13:19.857 ->
19:13:19.857 -> Backtrace: 0x400e90f8:0x3ffb1f80 0x400d1526:0x3ffb1fb0 0x400860ed:0x3ffb1fd0
19:13:19.891 ->
19:13:19.891 -> Rebooting...

Here's my code:
#include <Arduino.h>

#define SbmDisplaySerial Serial1

void setup() {
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  Serial.println("Yo v0.0.1! from serial UART 18/19");

  SbmDisplaySerial.begin(9600, SERIAL_8N1);//, 16, 17);

  Serial.print("SbmDisplaySerial is ");
  Serial.println(SbmDisplaySerial);
}

int _loop = 1;

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("Loop #"); Serial.println(_loop++);
  delay(1000);

  if (!SbmDisplaySerial.available()) {
    delay(2000);
    Serial.println("No byte avail from the UART, looping…");
    return;
  }

   int b = 0;

   Serial.print("Synching with message limit (waiting for 0xA5 (165) header byte): ");
   int i=0;
   do {
     delay(10);
     b = SbmDisplaySerial.read();
     Serial.print(b);
     Serial.print(" ");
     if (i%128==0) Serial.println();
      i++;
   }
   while(b!=0xa5);

  Serial.println("Ok, packet started!");
  Serial.print("Received bytes: ");
  Serial.print(b);
  Serial.print(" ");

  int soc = 0;
  int voltage = 0;
  int current = 0;
  int capacity = 0;

  for(int i=1; i<16; i++) {
    b = SbmDisplaySerial.read()&0xff;

    Serial.print(b);
    Serial.print(" ");

    switch(i) {
      case  0: Serial.print("Header byte 0xA5");
        voltage = 0;
        current = 0;
        capacity = 0;
      break;
      case  1: soc = b; Serial.print("(SoC: ");  Serial.print(soc); Serial.print("%) "); break;

      case  2: voltage = b<<8; break;
      case  3: voltage |= b;  Serial.print("(");  Serial.print(float(voltage)*0.01); Serial.print("V) "); break;

      case  4: capacity = b<<24; break;
      case  5: capacity = b<<16; break;
      case  6: capacity = b<<8; break;
      case  7: capacity |= b;  Serial.print("(");  Serial.print(float(capacity)*0.001); Serial.print("A.h) "); break;

      case  8: current = b<<24; break;
      case  9: current = b<<16; break;
      case 10: current = b<<8; break;
      case 11: current |= b;  Serial.print("(");  Serial.print(float(current)*0.001); Serial.print("A) "); break;

      //case 12: current = b<<8; break;
      //case 13: current = b<<8; break;
      //case 10: current |= b;  Serial.print("(TOA: ");  Serial.print(float(current)*0.001); Serial.print("Seconds) "); break;
    }

    if (!SbmDisplaySerial.available()){
      delay(2000);
      Serial.print(" No more byte prior reaching 16 bytes, looping…");

      break;
    }
  }

  Serial.println("Waiting for next packet");
  delay(10000);

}

[UPDATE]
When ran on Arduino, I get typical logs as follows:
11:20:18.217 -> Yo v0.0.1! from serial UART 18/19
11:20:18.217 -> SbmDisplaySerial is 1
11:20:18.217 -> Loop #1
11:20:19.204 -> Synching with message limit (waiting for 0xA5 (165) header byte): 0
11:20:19.204 -> 0 0 0 0 165 Ok, packet started!
11:20:19.275 -> Received bytes: 165 28 (SoC: 28%) 4 251 (12.75V) 0 0 54 248 (14.07A.h) 255 255 0 0 (0.00A) 0 0 0 0 Waiting for next packet
11:20:29.263 -> Loop #2
11:20:30.266 -> Synching with message limit (waiting for 0xA5 (165) header byte): 0
11:20:30.266 -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 165 Ok, packet started!
11:20:30.508 -> Received bytes: 165 28 (SoC: 28%) 4 251 (12.75V) 0 0 182 0 (46.59A.h) 0 0 0 0 (0.00A) 0 0 0 0 Waiting for next packet

Serial.println(SbmDisplaySerial); how is that supposed to work?

You simply read: "10:46:23.574 -> SbmDisplaySerial is 1" but you can ignoire, it's pure logging message.

The problem is that SbmDisplaySerial (or any Arduino Serial object) is not equal to "1", but an object with all kinds of properties that you can't simply "print". I don't know why the Arduino (AVR) allows this, but the Serial implementation of the ESP32 might not handle this gracefully. Why don't you try leaving this Serial.println() statement out and see if it makes a difference?

FYI, I've tried your code on my own ESP32 and it does not crash. What Arduino IDE and ESP32 Core version are you using?

@StarCat This is used to know the state of the connection (see https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/). And anyway, If I remove it it makes no change to the game.

Can you post a schematic, not a frizzy picture.

Here is what I've ended up with: I dropped Serial1 as I did not find anyway to make it run and I switched to Serial2, where everything works as expected.

#define SER1_RX 35
#define SER1_TX 32

void setup()
{
    Serial.begin(115200);                       //
    Serial.setDebugOutput(1);

    // For Serial1, be sure to set the communication port.
    Serial1.begin(115200, SER1_RX, SER1_TX);    // set the communication port
}


text:
Poor man's serial sniffer: reading Serial.print logs of an Arduino esp32 dev kit from another
(I use ESP32 dev kits with Arduino api.)
My dev kit 1 is running my firmware; and I want to measure the current it draws, therefore I don't like to plug the USB in.
As I need to read the logs from the dev kit 1, I want to plug another dev kit that collects the log from the first through the UART.
The dev kit 1 firmware is as it is, but on the dev kit 2, I wrote such a thing:
#include <Arduino.h>
#include <Hardware.h>

HardwareSerial Reader();

void setup() {
    Serial.begin(115200);
    Reader.begin(115200, SERIAL_8N1, 16, 17);

}

void loop() {
    while(Reader.available()) {
        Serial.print(Reader.read());
    }
}

The wiring is as follows:

Dev kit 1
Wiring
Dev kit 2 (sniffer)

TXD
<=>
RXD (16)

RXD
<=>
TXD (17)

GND
<=>
GND

But this doesn't work, that is I can't see anything on the dev kit 2 serial on my computer.
Any idea?
[UPDATE] As suggested by @juraj, I simply wire TX to TX, RX to RX and GND to GND and removed the Serial.begin(115200) from the firmware running on dev kit 1.
Dev kit 2 firmware is as simple as:

void setup() {
  Serial.begin(115200);
  //Serial.printf("Serial2 logger RX (%d)<=>TX & TX(%d)<=>RX @ 115200 bauds", RX, TX); Serial.println();
}

void loop() {
  static unsigned lastHeartbeat = 0;

  const unsigned now =millis();
  if (now-lastHeartbeat > 4000) {
    lastHeartbeat = now;
    Serial.println("Heartbeat");
  }
}

Note that on dev kit 1, I commented out the line Serial.begin(115200).
No kit 1 logs appears on my computer.
The wiring of this setup:

But this doesn't work is not a useful description of any problem ... what were you expecting to happen? ... what actually happens?

As you just want to forward the serial data, don't use print() but write() in your sketch. Otherwise print() will interpret the data before sending and you just want to forward the raw data. With TXD and RXD I guess you mean (depending on the notation) TX0 and RX0 (or U0_TXD and U0_RXD), so GPIO1 and GPIO3 on the firmware board?

yep, TXD is TX0 is GPIO1 and RXD is RX0 is GPIO3. I could craft a macro to transform the prints in write, but then it should be easier to hook an ISR and write to the pins myself. What do you think?

Serial.write(Reader.read());

if you just wire RX to RX and TX to TX the CH340 on the dev board will read it directly and send to USB. upload Blink or any other sketch without Serial.begin into the esp32

HardwareSerial Reader(); should be HardwareSerial Reader;

@juraj I tried this but nothing is received. The USB logger do not show any logs. I update the question with a simple board wiring photo, just in case I did something wrong.

I finally managed to make it work.
The final wiring:

Kit 1
kit 2

The firmware to spy
The firmare that spys

RXD
17

TXD
16

GND
GND

The spying firmware uses Serial2

#define USE_READER true

#if USE_READER
#define USE_SERIAL2 true

#if USE_SERIAL2
    #define TX 17
    #define RX 16
    #define Reader Serial2
#else
    #include "SoftwareSerial.h"
    #define TX 12
    #define RX 13
    SoftwareSerial Reader;
#endif
#endif

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

#if USE_READER
  Serial.printf("Serial logger RX (%d)<=>TX & TX(%d)<=>RX @ 115200 bauds", RX, TX); Serial.println();

  #if USE_SERIAL2
  Reader.begin(115200);
  #else
  Reader.begin(115200, SWSERIAL_8N1, RX, TX, false);
  #endif
  #endif
}

void loop() {
  static unsigned lastHeartbeat = 0;

  const unsigned now =millis();
  if (now-lastHeartbeat > 4000) {
    lastHeartbeat = now;
    Serial.println("Heartbeat");
  }

  #if USE_READER
  if (Reader.available()) {

    Serial.write(Reader.read());
  }
  else {
    #endif

    //Serial.print(".");
    delay(500);

    #if USE_READER
  }
  #endif
}

The spied firmware
You leave it as it is. Don't remove Serial.begin(115200);.
The breadboard photo:


text:
Azure IoT times out while trying to send a message from an ESP32
I am looking for a working example of an ESP32 sending telemetry data to Azure IoT hub. I find nothing working around the internet: below is the code I am trying to make it working.
As you can see in the logs, after a successful connection to the WiFi, followed by a successful connection to IoT Hub, the message has been accepted by the drive, but it is never sent successfully: Sound kinda timeout.
I posted the full Arduino SW for you to try.
[UPDATE]
You need to install the ESP32MQQTClient lib from Microsoft that you'll find right there: https://platformio.org/lib/show/5462/ESP32%20Azure%20IoT%20Arduino
Bottom note: IoT Hub is fully configured and working, and device is provisioned and the connection string is OK.
And the logs are as follows:
11:36:50.573 -> mode:DIO, clock div:1
11:36:50.573 -> load:0x3fff0018,len:4
11:36:50.573 -> load:0x3fff001c,len:1216
11:36:50.609 -> ho 0 tail 12 room 4
11:36:50.609 -> load:0x40078000,len:10944
11:36:50.609 -> load:0x40080400,len:6388
11:36:50.609 -> entry 0x400806b4
11:36:50.881 -> ============ Starting connecting WiFi.
11:36:51.513 -> ......
11:36:54.011 -> ============ WiFi connected
11:36:54.011 -> IP address:
11:36:54.011 -> 192.168.1.20
11:36:54.011 -> Info: Initializing SNTP
11:36:54.999 -> Info: SNTP initialization complete
11:36:54.999 -> Info: IoT Hub SDK for C, version 1.1.23
11:36:58.050 -> Info: >>>Connection status: connected

11:36:58.050 -> ============ start sending events.
11:36:58.083 -> Info: >>>IoTHubClient_LL_SendEventAsync accepted message for transmission to IoT Hub.

11:37:08.066 -> Error: Time:Fri Nov 19 10:37:08 2021 File:/Users/stephanedeluca/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/AzureIoT/src/Esp32MQTTClient.cpp Func:SendEventOnce Line:316 Waiting for send confirmation, time is up 10006

11:37:08.099 -> Info: >>>Re-connect.

11:37:08.099 -> Error: Time:Fri Nov 19 10:37:08 2021 File:/Users/stephanedeluca/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/AzureIoT/src/az_iot/c-utility/pal/src/tlsio_openssl_compact.c Func:tlsio_openssl_destroy Line:213 tlsio_openssl_destroy called while not in TLSIO_STATE_CLOSED.

11:37:08.136 -> Info: >>>Confirmation[0] received for message tracking id = 0 with result = IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY

11:37:08.136 -> Info: Initializing SNTP

11:37:09.109 -> Info: SNTP initialization complete

11:37:09.109 -> Info: IoT Hub SDK for C, version 1.1.23

11:37:09.470 -> Info: >>>IoTHubClient_LL_SendEventAsync accepted message for transmission to IoT Hub.

11:37:10.911 -> Info: >>>Connection status: connected

11:37:18.134 -> Error: Time:Fri Nov 19 10:37:18 2021 File:/Users/stephanedeluca/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/AzureIoT/src/Esp32MQTTClient.cpp Func:SendEventOnce Line:316 Waiting for send confirmation, time is up 10049

11:37:18.134 -> xxxxxxxxxxxx Failure sendind data: {"batteries":{"0":{"current": 1234.5}}}...

#include <WiFi.h>
#include "Esp32MQTTClient.h"

// Please input the SSID and password of WiFi
const char* ssid     = "XXX";
const char* password = "XXX";

/*String containing Hostname, Device Id & Device Key in the format:                         */
/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"                */
/*  "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>"    */
static const char* connectionString = "XXX";
static bool hasIoTHub = false;

void setup() {
  Serial.begin(115200);
  Serial.println("============ Starting connecting WiFi.");
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n============ WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  if (!Esp32MQTTClient_Init((const uint8_t*)connectionString))
  {
    hasIoTHub = false;
    Serial.println("============ Initializing IoT hub failed.");
    return;
  }
  hasIoTHub = true;
}

void loop() {
  Serial.println("============ start sending events.");
  if (hasIoTHub)
  {
    char buff[128];

    // replace the following line with your data sent to Azure IoTHub
    snprintf(buff, 128, "{\"batteries\":{\"0\":{\"current\": 1234.5}}}");

    if (Esp32MQTTClient_SendEvent(buff))
    {
      Serial.println("============ Sending data succeeded");
    }
    else
    {
      Serial.printf ("xxxxxxxxxxxx Failure sendind data: %s...", buff); Serial.println();
    }
    delay(5000);
  }
}

Could you add code from the library file that is generating the error? It might help us understanding where the error is.

@krystof18 Sure, here is the Microsoft Esp32MQTTClient repository https://platformio.org/lib/show/5462/ESP32%20Azure%20IoT%20Arduino

The problem is probably in IoTHubClient_LL_SendEventAsync function, but I can't find where it is, it is there somewhere, but I don't have time to crawl thru all files, If you find the file where it is, it will be really helpfull.

@krystof18 Ok. My colleague tells you in a few minutes.

@krystof18 The function is at line #1006 in file https://github.com/VSChina/ESP32_AzureIoT_Arduino/blob/master/src/az_iot/iothub_client/src/iothub_client_ll.c


text:
How to use ESP32 ESP32 config flag in platformio?
I build my ESP32 project from platformio and I'd like to change CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT in order to reduce the RAM footprint.
I don't get how to do that: should I modify my platformio.ini?

If you are using arduino-esp in platformio, then you have to build the sdk yourself.

Simply put, you have to update your platformio.ini as assumed in the question as follows (see last line):
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    adafruit/Adafruit NeoPixel@^1.10.0
    plerup/EspSoftwareSerial@^6.13.2
    miwagner/ESP32CAN@^0.0.1
    nilsminor/TMP117-Arduino@^1.0.2
    lbernstone/Tone32@^1.0.0
board_build.partitions = no_ota.csv
build_flags = -DCONFIG_MBEDTLS_DYNAMIC_BUFFER


text:
Why do I read my own transferred data during my RS485 serial comms?
I am writing a RS485 serial communication firmware for the ESP32 (the minimal code is at the end of the question you can paste it as an Arduino INO or in platformIO main.cpp file).
It is quite simple: it asks for commands on a regular basis, say command ID 0x92, in the form of 0xA5 0x40 0x92 0x08 etc.on 13 bytes and the master is expected to send the response back in the form 0xA5 0x01 0x92 0x08 etc.as a 13-byte packet as well. So far so good.
As you certainly noticed A5 is a constant header, 0x40 is used to ask the master (whilst 0x01 marks an incoming message) and 0x92 is the message ID we are interested in.
The logs are as follows, and as you can see, my reading portion of code received my own sent message followed by the response.
I am trying to understand why: a design flow in my code? flush() does not actually flush? or whatever I should do to fix it?
18:38:14.936 -> Starting RS485 serial comm @ 9600 SWSERIAL_8N1
18:38:14.936 -> #1: Asking for command 00
18:38:14.936 -> Writing command:
18:38:14.936 -> =====> a5 40 00 08 00 00 00 00 00 00 00 00 ed …
18:38:16.946 -> Asking for command 90
18:38:16.946 -> Writing command:
18:38:16.946 -> =====> a5 40 90 08 00 00 00 00 00 00 00 00 7d …
18:38:18.963 -> Asking for command 91
18:38:18.963 -> Writing command:
18:38:18.963 -> =====> a5 40 91 08 00 00 00 00 00 00 00 00 7e …
18:38:20.986 -> Asking for command 92
18:38:20.986 -> Writing command:
18:38:20.986 -> =====> a5 40 92 08 00 00 00 00 00 00 00 00 7f …
18:38:22.977 -> Received some bytes as follows:
18:38:23.011 -> <===== a5 40 92 08 00 00 00 00 00 00 00 00 7f a5 01 92 08 00 01 ff 01 fa 01 03 d6 15
18:38:23.011 -> Let ask once more!

And the code I wrote is as follows:
/// RS 485 test lab for ESP32
/// Minimal firmware for testing the SBM IoT RS485
/// Created by Sdl on Friday January 7th 2021 10:43am @ Will's N Hoagland Blvd in Kissimme, FL, USA

#include "SoftwareSerial.h"

#define RXD GPIO_NUM_19
#define TXD GPIO_NUM_18

#define PACKET_HEADER_LENGTH 4
#define PACKET_LENGTH 13

// == Software serial bound to TX RX 18/19
SoftwareSerial s(RXD, TXD, false);

/**
 * Computes the check sum
 * @param {[uint8]} data The data buffer
 * @param {Number} length The number of bytes
 * @returns The ine-byte checksum
 */
uint8_t checksum(uint8_t *buffer) {
  const int length = PACKET_LENGTH - 1;

  uint8_t checksum = 0;
  for (int i=0; i<length; i++) {
    checksum += buffer[i];
  }
  return checksum&0xff;
}

// == Build the remote master
#define MASTER 0x40

int messageCount = 0;

/// Sneds a message whose ID is the given [id]
void sendMessage(uint8_t id) {
  Serial.printf("Asking for command %02x", id); Serial.println();

  uint8_t command[PACKET_LENGTH] = {
    //Head  Master, Id: Soc   Length    Data 1, 2,    3     4     5     6     7     8     cs
    0xA5, MASTER, id,     8,        0x00,   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  send(command);
}

void send(uint8_t *buffer) {
  const int length = PACKET_LENGTH;

  // == Compute command checksum
  buffer[PACKET_LENGTH-1] = checksum(buffer);

  //digitalWrite(TXD, HIGH); //enable sending

  // == Write command
  Serial.println("Writing command: ");
  Serial.print("=====> ");

  for(int i=0; i<length; i++) {
    Serial.printf("%02x ", buffer[i]);
  }
  Serial.println("…");

  //size_t count =
  s.write(buffer, length);

  // == Disable transmitter
  s.flush();
  s.drain();

  //digitalWrite(TXD, LOW); //back to receiving
  //log("sent %d bytes", count);

  delay(2000);
}

uint8_t commands[] = {
  0x00,
  0x90,
  0x91,
  0x92,
  0x93,
  0x94,
  0x95,
  0x96,
  0x97,
  0x98,
  0xD8,
};
int commandsCounter = 0;

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

  // == Start comms
  Serial.println("Starting RS485 serial comm @ 9600 SWSERIAL_8N1");
  s.begin(9600, SWSERIAL_8N1, RXD, TXD, false, 256);

  Serial.printf("#%d: ", ++messageCount);

  for (int i=0; i<4; i++) {
    sendMessage(commands[i]);
    commandsCounter++;
  }
}

void loop() {

    // == Now wait for reading

    if (s.available()) {
      Serial.println("Received some bytes as follows:");
      Serial.print("<===== ");

      int i=0;
      int messageId = 0;
      while(s.available()) {
        uint8_t b = s.read();
        Serial.printf("%02x ",b);
      }

      Serial.println();

      // == Ask again
      Serial.println("Let ask once more!");
    }
    else {
      Serial.println("No bytes to read: ask for the SoC");
    }

    // == Wait for 5 secs
    delay(5000);

    // == Ask BMS for message
    Serial.printf("#%d: ", ++messageCount);
    sendMessage(commands[commandsCounter++]);

    // == Loops thru the commands vector
    if (commandsCounter>=sizeof(commands)) commandsCounter = 0;

}

Not sure this is the case here, but I have seen a number of RS232 level shifters that cause this behavior. Try disconnecting everything from the TX/RX pins and test that you don't get echo in that case.

@PMF Oh really? That counts for one direction to search! Thanks!

How did you wire the “transmit enable” and the “receiver enable” pins of your transceiver?

If you keep your receiver enabled while sending, of course you will receive your sent message. The RS485 serial communication is a bus, there are no separated lines for the different directions.

Is it 2- or 4-wire RS485 (half/full-duplex)? Which transceiver do you use?


text:
Cannot change pointer for port in main loop
I am testing on an Arduino UNO. I want to use timer1 and interrupts to create various LED patterns. The LEDs may span multiple ports i.e PORTB and PORTD. I want to use a "volatile uint8_t*" pointer to store whether to toggle a pin on PORTB or PORTD i.e have the pointer store &PORTB or &POINTD. And then use it as necessary. However, once set, I cannot seem to be able to change the pointer in the loop.
Some more details:
I'm using timer1 in CTC mode (clear on compare match) and making use of both OCR1A and OCR1B interrupts.
When output compare A interrupt matches, the led is turned on and a flag is set for the main loop to change leds.
When output compare B interrupt matches, the led is turned off.
The switch statement works and the led pins can be changed i.e next_led and current_led, however, the next_port and current_port statements are ignored in the main loop.
The led pin change works when changing from case 3 to case 1 (when they are both PORTB), but when changing the next_port variable to PORTD this is completely ignored.
At the very beginning of the code, if I initialize current_port and next_port with &PORTD, then just PORTD led will light up and the main loop will not change the current_port and next_port variable to &PORTB.
I have tried using volatile uint16_t* for the next_port and current_port and that doesn't work, either.
What am I doing wrong?
int red_led = 9;    //PORTB 1
int green_led = 10; //PORTB 2

int led3 = 5;       //PORTD 5

volatile uint8_t current_led = 1; //port number of led
volatile uint8_t next_led = 1;

volatile uint8_t *current_port = &PORTB;
volatile uint8_t *next_port = &PORTB;

int counter = 0;
volatile int change_led_flag = 0;
volatile uint8_t led_state = 1;

uint16_t ocr1a_val = 10000-1; //determines period. 16MHz clock, Prescaler=8, 10000-1 ticks = 5ms period (200Hz)
uint16_t ocr1b_val = 9900-1; //determines duty cycle (99% for 10000 ticks)

void setup() {
  pinMode(red_led, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(led3, OUTPUT);

  TCCR1A = 0;
  TCCR1B = 0;

  //set CTC mode
  TCCR1B |= (1<<WGM12);

  //set OCR1A value
  OCR1A = ocr1a_val;
  //set OCR1B value
  OCR1B = ocr1b_val;

  //set pre-scaler to 8
  TCCR1B |= (1 << CS11);

  //enable output compare interrupts
  TIMSK1 |= (1 << OCIE1A);
  TIMSK1 |= (1 << OCIE1B);

  sei();
}

void loop() {
  if(change_led_flag == 1){
  change_led_flag = 0;
  current_led = next_led; //set the current led to what was just turned on
  current_port = next_port; //this statement doesn't do anything.
  switch (led_state) {
    case 1:
      led_state = 2;
      next_led = 2;
      next_port = &PORTB; //this statement doesn't do anything
      break;
    case 2:
      led_state = 3;
      next_led = 5;
      next_port = &PORTD; //this statement doesn't do anything
      break;
    case 3:
      led_state = 1;
      next_led = 1;
      next_port = &PORTB; //this statement doesn't do anything
      break;
    } //end switch statement
  } //end if

} //end loop()

//turn on next_led and set change_led_flag
ISR(TIMER1_COMPA_vect){
  *next_port |= (1 << next_led); //turn on led
  change_led_flag = 1; //set flag to update next led
}

//turn off current_led
ISR(TIMER1_COMPB_vect){
  *current_port &= ~(1 << current_led); //turn off led
}

I get the error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'volatile uint16_t* {aka volatile unsigned int*}' in initialization
volatile uint16_t *next_port = &PORTB;

Welcome to SE/Arduino! Please take the [tour] to learn how this site works. If you have any additional information, please [edit] your question, don't post a comment. It will not be read, this is not a forum. -- However, please reduce your program to the most simple example, where you change just the port pointer and use it to access the ports. -- If that does not work generally, you can fall back to use Arduino functions like digitalWrite() or use an enum and a switch, for example.

I don't know this is your problem, but it is a problem in any case.
The pointer itself, not just what it points to, would also need to be volatile qualified. That is:
volatile uint8_t *volatile current_port = &PORTB;
volatile uint8_t *volatile next_port = &PORTB;

The volatile after the pointer declarator (the *) determines the volatile quality of the pointer itself.  The volatile that you already had prior to the declarator is just qualifying what is pointed-to, the port in this case, which is needed for similar reasons.
Without the pointer itself being volatile, you can't expect to changes to it to be reflected correctly between the ISR contexts and the normal main line of execution that runs setup, loop and and most everything else.  The compiler/optimizer may assume since it can't see any way to get to code that can change the value that the value is therefore not changing.  ISR dispatches are outside its field of view.
Also in the when you update next_port outside of the ISR, you probaly should make sure interrupts are off while you update it:
noInterrupts();
next_port = &PORTB;
interrupts();

Because the pointer value is a two-byte address, if you don't disable the interrupts while assigning it your ISR can be dispatched midway through the assignment when the pointer object isn't yet valid.  I say should above, because in your situation the addresses that happen to be used for ports may all have the same upper byte value. It's a good habit to be in regardless.

Thank you so much! Adding the extra volatile fixed the code. (This is the first time I've used a volatile pointer that itself is volatile!)
You make some good points on the non-atomic assignments. It's probably a good idea to put the next_led assignment within that no interrupt block as well, so that the ISR won't dispatch with a mismatched led and port. Thanks again!