title: Working with pulseIn() and millis()

text:
# Question
Title: Working with pulseIn() and millis()
I'm trying to use `pulseIn` with elapsed time using `millis()`, I don't want to use interrupts instead of `pulseIn` (I need `pulseIn` because I need accurate pulse time), the elapsed time doesn't need to be very accurate, so to calculate the elapsed time I've added to the elapsed time the time the arduino is blocked, The problem is the calculated elapsed is very inaccurate, I suspect it sometimes never enters `if(elapsed > 1000*60*2)`, Why is that? How can I fix that?

Thanks.

**Code**

```
unsigned long startTime = 0;
unsigned long elapsed = 0;
unsigned int val = 0;
uint32_t time_wait_pulse = 0;

void setup(){
  startTime = millis();
}

void f(){
  uint32_t time = 0;
  time += pulseIn(pin, LOW);
  if(time > 0) {
   ...
   time_wait_pulse += time;
  } else {
   time_wait_pulse += 1000000; //default pulseIn timeout (micros)
  }
}

void loop(){
    elapsed = millis() - startTime + (unsigned long)(time_wait_pulse/1000);
    if(elapsed > 1000*60*2){
      val++;
      startTime = millis();
      time_wait_pulse = 0;
    }

     noInterrupts();
     f();
     interrupts();
}

```

# Answer
> 3 votes
`millis()` is using interrupts to work. When deactivating interrupts for your function `f()`, you prevent that the value returned by `millis()` can actually change in that time.

So if the interrupt associated with `millis()` occurs during the execution of `f()`, you will lose time in your measurement and it will be inaccurate. It will get worse the more time the code spends with interrupts off vs on. `micros()` will still be updated without interrupts on (since it directly reads the register of Timer0), but it will still lose time after about 500ms, since then it cannot compensate for multiple overflows in that time period.

The way to go forward depends on your requirements. Is it really needed, that you disable interrupts for the `pulseIn()` measurement? What accuracy do you get in both cases (interrupts on vs off) and what accuracy do you need? If you absolutely need to turn off interrupts, only do it for the shortest time (only around `pulseIn()`). You can built your own time keeping analog to `millis()` using a 16bit Timer (you didn't specify what Arduino you are using), which would give you way more time, that the microcontroller can spend without interrupts on before loosing time in the measurement.You can also use a different prescaler to further increase this time, though sacrificing precision for it.

# Answer
> 1 votes
You can time reasonably long intervals using Timer 2 (on the Atmega328) as described in my page about timers.

The example there is this:

```
void startTimer1 ()
  {
  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  // zero it
  TCNT1 = 0;
  TIFR1 |= bit (TOV1);  // clear overflow flag
  // start Timer 1
  TCCR1B =  bit (CS10) | bit (CS12);  //  prescaler of 1024
  }  // end of startTimer1

unsigned long getTimer1Reading ()
  {
  unsigned long elapsed = TCNT1;
  if (TIFR1 &  bit (TOV1))
     elapsed += 65536;
  return elapsed;
  }  // end of getTimer1Reading

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

  }  // end of setup

void loop ()
  {
  Serial.println ("Starting ...");
  Serial.flush ();

  startTimer1 ();

  delay (7560);
  float secs = (1.0 / F_CPU * 1024) * getTimer1Reading ();

  Serial.print ("Time taken = ");
  Serial.print (secs);
  Serial.println (" seconds.");

  } // end of loop

```

The code above uses Timer 1 to time an interval up to 8.388 seconds. It users a prescaler of 1024, which means each "count" of timer 1 is 1/16e6 * 1024 of a second (0.000064 seconds, or 64 µs). Since it can count up to 65536 we can time 0.000064 * 65536 = 4.194304 seconds. Then the timer overflows, but we can test the "overflow flag" and know the overflow occurred. That lets us time up to 8.388608 seconds before we miss the fact that there was a second overflow.

This code works even if interrupts are off, because the timing is done by the hardware timer.

Output on my Uno:

```
Starting ...
Time taken = 7.56 seconds.

```

---
Tags: c, millis, pulsein
---


# Question
Title: Arduino resets or stuck during run, only when DC motors are connected
I'm using an arduino connected to 2 DC motors through L298N. the arduino is powered by a 9V battery, and the L298N is powered by 4 AA batteries. there's also a switch that starts the movement.

I've added print statements to debug, one in the setup, one in the start of the loop, and two before and after running so i know when the motors start and how long they run. I also print the state of the switch. this is what i get:

```
1                          // switch state. 1  means off.
loop                       // start of loop statement
1
loop
0                          // switch state changed to on
0                          // added another switch check after the if
Forward for: 5 seconds     // motors on
setup                      // reset for some reason
loop                       // start of loop
0                          // switch still on
setup                      // another reset
loop
0
0
Forward for: 5 seconds     // motor starts again
setup                      // another reset
loop
0
0
Forward for: 5 seconds     // stuck with the motors on, no more resets

```

its not always this bad, sometimes it runs once or twice correctly (for five seconds) and then off. some times it gets stuck on without reseting. also, sometimes it starts reading the switch value as 1 after a few seconds of reading the correct value, even though the switch wasen't moved. also, when I remove one of the motor batteries so they don't get power everything works great. What causes the reset and the freezing? How can I fix that?

this is my code:

```
#include <Arduino.h>
int RightSpeedPin = 5;
int Rdir2 = 6;
int Rdir1 = 7;
int led = 13;
int LeftSpeedPin = 10;
int Ldir2 = 8;
int Ldir1 = 9;
int SwitchPin = 4;
int ReadVal;
int baseSpeed = 230;
int Stime;
int Etime;

void go(int d) { // d = 1 will move, d = 0 will stop
  analogWrite(RightSpeedPin, (d == 1 ? 230 : 0));
  analogWrite(LeftSpeedPin, (d == 1 ? 255 : 0));
}

void forward(int t) {
  Serial.print("Forward for: ");
  Serial.print(t / 1000);
  Serial.println(" seconds");
  digitalWrite(Rdir1, HIGH);
  digitalWrite(Ldir1, HIGH);
  digitalWrite(Rdir2, LOW);
  digitalWrite(Ldir2, LOW);
  digitalWrite(led, HIGH);
  Stime = millis();
  while (millis() < Stime + t) {
    go(1);
  }
  go(0);
  Etime = millis();
  Serial.print("ran for ");
  Serial.println(Etime - Stime);
  digitalWrite(led, LOW);
}

void spin() {
  digitalWrite(Rdir1, LOW);
  digitalWrite(Rdir2, HIGH);
  digitalWrite(Ldir1, HIGH);
  digitalWrite(Ldir2, LOW);
  Stime = millis();
  while (millis() < Stime + 100) {
    go(1);
  }
  go(0);
}

void setup() {
  // put your setup code here, to run once:
  pinMode(Rdir1, OUTPUT);
  pinMode(Rdir2, OUTPUT);
  pinMode(RightSpeedPin, OUTPUT);
  pinMode(LeftSpeedPin, OUTPUT);
  pinMode(Ldir1, OUTPUT);
  pinMode(Ldir2, OUTPUT);
  pinMode(SwitchPin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  Serial.println("setup");
}

void loop() {
  Serial.println("loop");
  ReadVal = digitalRead(SwitchPin);
  Serial.println(ReadVal);
  if (!ReadVal) {
    delay(500);
    Serial.println(ReadVal);
  // starting situation- both motors heading forward
    // running for 5 secs
    forward(5000);
    delay(1000);
    spin();
  }
}

```

and this is my scheme:

# Answer
> 2 votes
The L298 has a pair of darlington bipolar transistors in each motor lead. This will cause a voltage drop of at least 1.4V on each lead or 2.8V to the motor, starving it of power. This voltage drop is burnt up as heat which your battery is supplying. A 9V smoke alarm battery is a bad choice for powering an Arduino even though many place show using it as a power source. Take a look at this link, it has some nice graphs showing just how much the voltage drop will be. https://www.powerstream.com/9V-Alkaline-tests.htm The maximum current draw of the Arduino R3 is in the range of 200mA. Try connecting several 9V batteries in parallel and if the problem disappears should the 9V battery.

# Answer
> 1 votes
When brushed motors are involved I usually think of arc suppression caps across the motor terminals, 100 mF or larger cap across the motor power supply, solid common (GND) connections. Sparking motor commutators can cause all sorts of problems.

---
Tags: arduino-uno, motor, switch, reset
---


# Question
Title: Powering a NodeMCU as well as a GSM module
I'm trying to connect a GSM module(sim800L) with a NodeMCU to execute remote operations. But the GSM module cannot be powered using the NodeMCU. So, what are the other ways to power the board as well as the module. Also I want to connect directly to a wall power supply instead of using a battery.

# Answer
After a bit of researching, I have found the following solution:-

A DC-DC buck converter (such as the LM2596) can convert a 12 V 2A rated power supply down to 4 V (the value is adjustable) which can then be used to power the module.
> 1 votes

---
Tags: esp8266, power, nodemcu, gsm
---


title: Arduino IDE equivalent to DataView?

text:
# Question
Title: Arduino IDE equivalent to DataView?
I am working on a project with Bluetooth commands between various devices. I would like to try and convert a string to a DataView Object on Arduino, so I can send it over BLE, much like this function written in Javascript:

```
function str2DV(str) {
  var buf = new ArrayBuffer(str.length);
  var bufView = new Uint8Array(buf);
  for (var i=0, strLen=str.length; i<strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  var DV = new DataView(buf);
  return DV;
}

```

Is this possible with Arduino? I have yet to find a solution....

# Answer
There is no use for a DataView in the Arduino environment. In the JavaScript language, a string and an array of bytes are two very different things. That's why you need something like this `str2DV()` function to convert between them. In C++, they are one and the same thing: no need to convert. Sometimes the type `uint8_t` (also named `byte`) is used in preference of `char` for storing binary data, but you can just typecast between these types. The typecast typically compiles to zero machine instructions, as the underlying data representation is the same.

For example:

```
extern some_lib_function(const uint8_t *buffer, int buffer_length);

const char *my_message = "Hello, World!\n";
some_lib_function((uint8_t *) my_message, strlen(my_message));

```

If your string is in the form of a `String` object, rather than a plain C-string, then use the `c_str()` method to get the plain string back:

```
String my_message = "Hello, World!\n";
some_lib_function((uint8_t *) my_message.c_str(), my_message.length());

```
> 4 votes

---
Tags: arduino-ide, bluetooth, buffer
---


# Question
Title: How do I use a transmitter and receiver to send string messages conditionally to a receiver?
I'm working on a project to build a plant monitor that works from the outside with Arduino that picks up light and water values from it's environment then uses a nRF24L01 with an antenna and I've come across a roadblock in the code with using a transmitter and receiver, heres the code fully below.

Appreciate any help, been stuck for weeks trying to figure this out.

Transmitter Code

```
/*
 * NAME: <Mario Ronci>
 * Healthy Plant Monitor  V2  T
 *
 *
 */

 //** **/
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
//create an RF24 object
RF24 radio(9, 8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

int ldrValue;
int sensorPin = A0;    // select the input pin for the Water Comparator
int sensorValue = 0;
int light_threshold = 650;
int water_threshold = 850;
String dark_message = " ALERT:Plant is Dark!";
String bright_message =" Brightness Achieved! ";
String water_message1 = " Plant has enough water.";
String water_message2 = " Need Water...!";
String healthy_message = "Plant is Healthy!";
String unhealthy_message = "Unhealthy...!";
//String engineerinfo = "Mario Ronci 2023";

void setup() {

  pinMode(LDR, INPUT);
  pinMode(POT, INPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  Serial.begin(9600);
  Serial.println(engineerinfo);
  // put your setup code here, to run once:
radio.begin();
  //set the address
  radio.openWritingPipe(address);
  //Set module as transmitter
  radio.stopListening();

}

//This checks if the plant is getting enough light,//
//by taking a acceptable or unacceptable light value
//from a LDR and prints the value to the serial monitor
//and if the light value is acceptable

void ldrCheck(int device, int duration1,int duration2){

ldrValue = analogRead(device);

if(ldrValue >= light_threshold)

{
  messageLight = light_message + String(ldrValue);
  sendByteMessage(); // Call the function to send the byte message
   delay(duration1);// Wait for some time before sending the next message

}

if(ldrValue < light_threshold){
  messageLight = dark_message + String(ldrValue)
  byte messageBytes[message.length() + 1]; // Create a byte array to store the message
  delay(duration2);
}

void sendByteMessage() {
  byte messageBytes[message.length() + 1]; // Create a byte array to store the message

  // Convert the string message into a byte array
  message.getBytes(messageBytes, message.length() + 1);

  // Send the byte array through the transmitter
  radio.write(&messageBytes, sizeof(messageBytes));
}

}

////This checks if the plant is getting enough water,//
//by taking a acceptable or unacceptable hydration value
//from a LDR and prints the value to the serial monitor
//and if the hydration value is acceptable , the yellow LED will turn on
//and blink, if it's not it will print a message to the serial monitor
//to alert you

//********* Note replace POT with hydrometer code*********//
void potCheck(int device,int duration3){

potValue = analogRead(device2);

if(potValue > water_threshold)
{
  Serial.print(potValue);
  Serial.println(water_message1);

}

else{
  Serial.println(water_message2);

}

}

//This checks if the plant is getting enough water and light
//, if it's not it will print a message to the serial monitor
//to alert you and if it is getting enough it will print a
//message to the serial monitor telling you the plant is healthy

void healthyCheck(int led_4,int duration4,int duration5){

if((ldrValue >= light_threshold) && (potValue > water_threshold)){
digitalWrite(led_4, HIGH);
Serial.println(healthy_message);
delay(duration4);
}

else{
digitalWrite(led_4,HIGH);
delay(duration5);
digitalWrite(led_4,LOW);
delay(duration5);
Serial.println(unhealthy_message);

}

}

void loop(){

//This calls the function/method

//in loop call transmitter

ldrCheck(LDR, 1000,100 );
sendByteMessage(LDR)
potCheck();
healthyCheck(2000,800);

}

```

Receiver Code

```
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

//Create an rf24 object

RF24 radio(9,8) ; //CE,CSN

//address through which two modules communicate.

const byte address[6]  = "00001";

void setup() {

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

 radio.begin();

 //set the address
 radio.openReadingPipe(0, address);

 //set module as receiver
 radio.startListening();

}

void loop() {
  //Read the data if available in buffer

  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.print(ldrValue);
    Serial.println(light_message);
  }

```

**What specifically do you need help with?**

I'm trying to modify original code to work with the transmitter and receiver functionality before I had code that used leds meaning the plant monitor would turn on certain colored LEDs based on condition.Now in V2 of this project i decided to do away with the LED's and make the goal to have communication between the componets from the outside to send messages about the plant status inside where another arduino would print to the serial monitor

I need help with having the transmitter code work with the conditional statements atm I'm confused where to insert the each piece of code so the transmitter sends a message to the receiver and prints in the serial monitor.It should work as the componets take inputs from the environment like the ldr, then that value is stored and applied to if statment , if x is this value then send this message and then the transmitter sends the message to the receiver that prints it to the serial monitor

**What have you tried?**

I've tried to create a seperate variable for the message I want to send along with the analog sensor values from the ldr.( I've not gotten to the hydrometer yet I only got the wiring for it done) Turn the ldr from int to a string and then call the variable in the byte message function within a function for checking for ldr values. Then in the receiver code i tried testing by writing Serial Print for each value but It's not working and I think its because the value is out of scope.Not in the same sketch.

**What do you think the problem is?**

I think it may be the order of the code and or syntax,maybe if I put the transmitter code outside of the ldr check function it would work, but im not sure. Could also be that the datatypes are strings and ints and changing that to the bytes isn't as straightfoward as I thought.

The actual build and components

Master ( transmitter ) takes inputs from the environment using a Ldr and hydrometer both water and light values and sends it to the slave microcontroller the receiver, wiring is correct.

Slave ( receiver) processes the values from the transmitter and prints them in the serial monitor the messsage it recieves will depend on conditions such as light value thresholds and water value thresholds in simple terms if the light or water values exceed a certain value or are below a certain value it will send a different message for each situation.

# Answer
I figured the issue out.

1. code was a mess but after troubleshooting it for a while the if statements didn't make sense and had no good flow to them plus too complicated. I had copied and pasted some code without making sense of it.
2. It worked when I focused on one component like @jstola said. The photoresistor only and so the main thing is to add the conditional then turn string into a byte message and then void loop sends byte message to receiver arduino. Then the next part there were symbols appearing in the serial monitor and that was weird. So I experimented with the char data type instead of string and worked. Also use chatgpt as well for some syntax help.

Now I have base to work from. So next is to tackle the hydrometer.

**Transmitter Code - with photoresistor only**

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(9, 8); // Create an instance of the RF24 object

const byte address[6] = "00001"; // Set the pipe address

int ldrValue;
int sensorPin = A2;    // Select the input pin for the LDR
int light_threshold = 650;
String light_message = "Plant has enough light :";
String dark_message ="Alert: Plant is Dark! :" ;
String water_message1 = " Plant has enough water.";
String water_message2 = " Need Water...!";
String healthy_message = "Plant is Healthy!";
String unhealthy_message = "Unhealthy...!";

void setup() {

  pinMode(sensorPin, INPUT);
  radio.begin();
  radio.openWritingPipe(address);
  radio.stopListening();

}

void loop() {
  ldrCheck(sensorPin, 1000, 100);
}

void ldrCheck(int device, int duration1, int duration2) {
  ldrValue = analogRead(device);

  if (ldrValue >= light_threshold) {
    String message = light_message + String(ldrValue);
    sendByteMessage(message);
    delay(duration1);
  }
  else {
    String message = dark_message + String(ldrValue);
    sendByteMessage(message);
    delay(duration2);
  }
}

void sendByteMessage(String message) {
  byte messageBytes[message.length() + 1];
  message.getBytes(messageBytes, message.length() + 1);
  radio.write(&messageBytes, sizeof(messageBytes));
}

```

**reciever Code - with photoresistor only**

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(9, 8); // Create an instance of the RF24 object

byte address[6] = "00001"; // Set the pipe address

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, address);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    char message[32] = ""; // Create a character array to store the message
    radio.read(&message, sizeof(message));
    processMessage(message);
  }
}

void processMessage(char* message) {
  String receivedMessage = String(message); // Convert the character array to a String
  Serial.println(receivedMessage);
  delay(1000);
}

```

result:

Video
> 2 votes

---
Tags: arduino-uno, programming, nrf24l01+, code-review, convert
---


# Question
Title: STM32 "black pill" won't enter DFU mode reliably
I'm following the standard process to put an STM32 "black pill" (STM32F401CC) into DFU mode so that I can upload from the Arduino IDE over USB:

1. Hold down boot0.
2. Press and release rst.
3. Release boot0.

When the board is not in a circuit this works somewhat reliably but not 100%. While breadboarding with only a few connections it becomes very unreliable and sometimes won't work at all.

The USB serial device set up by my Arduino sketch works fine, it is only DFU mode that does not want to work.

When it fails to enter DFU mode I see the following error in the Arduino upload process:

```
      -------------------------------------------------------------------
                        STM32CubeProgrammer v2.13.0
      -------------------------------------------------------------------

An error occurred while uploading the sketch
Error: Target device not found
Establishing connection with the device failed

```

I'm using Arduino on Ubuntu 20.04 and when it fails I see in `/var/log/syslog`:

```
Apr 27 13:26:08 smurfenaar kernel: [79594.279257] usb 1-3: USB disconnect, device number 10
Apr 27 13:26:08 smurfenaar kernel: [79595.078232] usb 1-3: new full-speed USB device number 11 using xhci_hcd
Apr 27 13:26:09 smurfenaar kernel: [79595.192387] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.413389] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.636370] usb 1-3: new full-speed USB device number 12 using xhci_hcd
Apr 27 13:26:09 smurfenaar kernel: [79595.751435] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79595.973367] usb 1-3: device descriptor read/64, error -71
Apr 27 13:26:09 smurfenaar kernel: [79596.082540] usb usb1-port3: attempt power cycle
Apr 27 13:26:10 smurfenaar kernel: [79596.462407] usb 1-3: new full-speed USB device number 13 using xhci_hcd
Apr 27 13:26:10 smurfenaar kernel: [79596.462674] usb 1-3: Device not responding to setup address.
Apr 27 13:26:10 smurfenaar kernel: [79596.666550] usb 1-3: Device not responding to setup address.
Apr 27 13:26:10 smurfenaar kernel: [79596.874414] usb 1-3: device not accepting address 13, error -71

```

When it is successful I see:

```
pr 27 13:22:33 smurfenaar kernel: [79379.772197] usb 1-3: new full-speed USB device number 9 using xhci_hcd
Apr 27 13:22:33 smurfenaar kernel: [79379.899601] usb 1-3: New USB device found, idVendor=0483, idProduct=df11, bcdDe
vice=22.00
Apr 27 13:22:33 smurfenaar kernel: [79379.899605] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Apr 27 13:22:33 smurfenaar kernel: [79379.899607] usb 1-3: Product: STM32  BOOTLOADER
Apr 27 13:22:33 smurfenaar kernel: [79379.899609] usb 1-3: Manufacturer: STMicroelectronics
Apr 27 13:22:33 smurfenaar kernel: [79379.899611] usb 1-3: SerialNumber: 3466365E3135

```

and I can also see it with the `lsusb` command:

```
Bus 001 Device 052: ID 0483:df11 STMicroelectronics STM Device in DFU Mode

```

# Answer
> 2 votes
I found this solution in the stm32duino forums:

> Tying A10 to GND successfully makes it enter DFU bootloader mode 100% of the time (though just not leaving PA10 floating is probably sufficient)
>
> **Hypothesized Explanation**: In the last paragraph of Sec 4.3 of AN2606 (the STM bootloader manual), it states:
>
> > It is recommended to keep the RX pins of unused bootloader interfaces (USART\_RX, SPI\_MOSI, CAN\_RX and USB D+/D- lines if present) at a known (low or high) level at the startup of the bootloader (detection phase). Leaving these pins floating during the detection phase might lead to activating unused interfaces.
>
> PA10 is the RX pin for USART\_1. I believe that since PA10 is floating, the bootloader senses traffic on USART\_1, and believes that's the interface it should use, and thus turns off USB. By tying PA10 to GND, the bootloader doesn't sense UART traffic and correctly enables USB.

While I followed the advice of tying it to ground I assume tying it to ground via a high resistance value would work too and should allow you to keep using PA10 for something else. After tying PA10 to GND I find entering DFU mode is 100% reliable, even when the board is in a circuit.

# Answer
> 0 votes
I recently purchased two **"WeAct V3.0 STM32F411" Black Pill boards** on eBay. I've purchased many boards & other electronic items from this seller in the past without any issues. This eBay seller is very highly rated: 99.8% positive feedback with \>1 million items sold. However, I cannot confirm whether these boards are "genuine" WeAct boards since I did not purchase them directly from WeAct.

Both of my Black Pill boards can be programmed with ST-LINK V2 using the standard 3 (or 4) wire SWD interface pins. No problems.

However, both boards initially failed to enter USB DFU programming mode after resetting boards with the `BOOT0` button pressed. Then I tried grounding pin `A10` as suggested above. **This totally fixed DFU programming**. Now both boards program perfectly every time via DFU mode.

The only downside is the requirement to press `BOOT0` \+ `NRST` buttons on board to initiate DFU programming mode prior to uploading with Arduino IDE.

---
Tags: uploading, error, stm32
---


# Question
Title: Unable to upload sketch to Lolin S3 Pro (ESP32-S3)
I'm trying to upload a simple sketch to the new Wemos Lolin S3 Pro but unfortunately I can't seem to get it to work. I get the following error message:

```
    Connecting......................................

A fatal error occurred: Failed to connect to ESP32-S3: No serial data received.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
Failed uploading: uploading error: exit status 2

```

The following board is causing problems: https://www.wemos.cc/en/latest/s3/s3\_pro.html

It seems that there is no USB to UART chip and also no boot button. As board I selected the "LOLIN S3 Pro" in the Arduino IDE and under Platformio I had selected the "lolin\_s3". I have also tried it under platformio with the following build flags but unfortunately without success:

```
build_flags = -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1

```

I am really perplexed what could be the cause?

Btw: I bought 3 of these boards and all 3 have the same issue.

# Answer
OK I managed to solve it although I find its a little bit annoying it seems that you need to always set this board in download mode manually. (Press and hold boot and click reset button once).

If you are using Arduino IDE use the following options:

* USB CDC On Boot -\> Enabled
* Upload Mode -\> Hardware CDC / UART0

If you are using PlatformIO use the following build flags:

```
build_flags = '-DARDUINO_USB_MODE=1' '-DARDUINO_USB_CDC_ON_BOOT=1'

```

Also a good source: https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/tutorials/cdc\_dfu\_flash.html
> 2 votes

---
Tags: serial, esp32, usb, uploading, uart
---


# Question
Title: Are intel hex files converted into a binary format before they are written to Atmega's flash?
I have been going through some resources on bootloaders, programmers, etc (I'm very new to this specific subject) and how they work with the Atmega chips and Arduino board programming. My research may have been shallow but none of the online articles/blogs/forum posts that I have been through mentioned that the .hex file (in intel hex ASCII format) needs to be converted to any other kind of binary format. It did seem odd to me though that one would directly write ASCII plain text into an MCU's flash. Also, when using AVR Burn-o-Mat (a GUI front end for avrdude) I did notice a couple of times that the number of bytes being flashed was significantly less than the actual size of the hex file. Most recently I went through this library on github which converts intel hex into a binary format. So am I right in saying that the hex file needs to be converted to binary? So for instance, does avrdude basically do this before sending the binary stream to the bootloader (when uploading a sketch via the IDE)?

# Answer
Yes, the hex codes in the .hex file are read in by avrdude (or other programs) and written to the MCU in binary. A small microprocessor would not be able to read ASCII format commands.

See my answer about What happens when code is uploaded using the bootloader?

---

(Following on from some comments)

> I did notice a couple of times that the number of bytes being flashed was significantly less than the actual size of the hex file

I think there is some confusion here, because of the different way numbers can be represented, or stored. Just for example, the number which we know as "twenty" could be written (in a file) as:

* 20 (decimal)
* 00020 (decimal with leading zeroes)
* 0014 (hex)
* 0024 (octal)
* 10100 (binary digits)

Now a program like Avrdude could read numbers in any of those formats, internally convert them to "binary" and send a single byte, being that binary number, to the MCU for placing into a program memory byte.

The .hex format, which the Arduino system produces as part of the compilation process, uses lines in this format:

```
Line format:
  :nnaaaatt(data)ss
  Where:
  :      = a colon
  (All of below in hex format)
  nn     = length of data part
  aaaa   = address (eg. where to write data)
  tt     = transaction type
           00 = data
           01 = end of file
           02 = extended segment address (changes high-order byte of the address)
           03 = start segment address *
           04 = linear address *
           05 = start linear address *
  (data) = variable length data
  ss     = sumcheck
            * We don't use these

```

The above from comments in my file https://github.com/nickgammon/arduino\_sketches/blob/master/Atmega\_Hex\_Uploader/File\_Utils.ino

**Example**: Optiboot in all its glory (only 512 bytes):

```
:107E0000112484B714BE81FFF0D085E080938100F7
:107E100082E08093C00088E18093C10086E0809377
:107E2000C20080E18093C4008EE0C9D0259A86E02C
:107E300020E33CEF91E0309385002093840096BBD3
:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E6000A2D0813461F49FD0082FAFD0023811F036
:107E7000013811F484E001C083E08DD089C08234E0
:107E800011F484E103C0853419F485E0A6D080C0E4
:107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000102F00270E291F29000F111F8ED06801E7
:107EB0006FC0863521F484E090D080E0DECF843638
:107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160
:107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80000AD08FE07ACF813511F488E018D01DD067
:107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0009093C60008958091C00087FFFCCF809118
:107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F0E098E1908380830895EDDF803219F02E
:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:047FF000FF270994CA
:027FFE00040479
:0400000300007E007B
:00000001FF

```

So, a line in the .hex file will start with a colon, then a length, then an address, then a transaction type, then some variable amount of data, and then a sumcheck. These are stored in the file in hexadecimal notation.

The very first thing we can deduce from this is that the file size will be over double the amount of memory that is programmed. For example, to program "AB" in hex, this would take two bytes in the .hex file ("A" followed by "B") but these would be converted into the equivalent one-byte "binary" number, which would end up in the MCU memory.

Then, because of the colon, the transaction type, the line length, and the sumcheck, the file will be somewhat longer still, than double the number of bytes to be programmed into the MCU. That is the file layout overhead.
> 4 votes

---
Tags: arduino-mega, avrdude, hex
---


title: USB OTG and ESP32-S2

text:
# Question
Title: USB OTG and ESP32-S2
I have an ESP32-S2-DevKitM-1 which is supposed to able to act as USB HID device.

But whatever I try using either ESP-IDF or Arduino-IDE, I can't get any data from it.

I ran this esp-idf example.

I also ran the arduino example.

I connected GPIO20/19 to D+/D- of a USB cable.

When I plug in that cable, my host computer logs:

```
usb 1-6: new full-speed USB device number 93 using xhci_hcd
usb 1-6: device descriptor read/64, error -71
usb 1-6: device descriptor read/64, error -71
usb 1-6: new full-speed USB device number 94 using xhci_hcd
usb 1-6: device descriptor read/64, error -71
usb 1-6: device descriptor read/64, error -71
usb usb1-port6: attempt power cycle
usb 1-6: new full-speed USB device number 95 using xhci_hcd
usb 1-6: Device not responding to setup address.
usb 1-6: Device not responding to setup address.
usb 1-6: device not accepting address 95, error -71
usb 1-6: new full-speed USB device number 96 using xhci_hcd
usb 1-6: Device not responding to setup address.
usb 1-6: Device not responding to setup address.
usb 1-6: device not accepting address 96, error -71
usb usb1-port6: unable to enumerate USB device

```

The esp-idf example fails to send, because `tud_mounted()` is false, and the arduino-ide example fails on `SendReport(): not ready`.

How can I get the ESP32-S2 to talk USB with my host computer?

# Answer
> -1 votes
This problem went away when I replaced my DIY USB cable connection with an Adafruit USB-C breakout board.

I checked all the connections of my cable, but somehow it would not work, until I replaced it.

---
Tags: esp32, usb, hid
---


title: are 4AA batteries (6V) power my arduino

text:
# Question
Title: are 4AA batteries (6V) power my arduino
I'm actually new to using arduino , and trying to make a simple car, using two dc motors, a l298n and an arduino, the problem is that a 9v battery doesn't seem enough to just power the l298n and one dc motor , but in the internet some people use an 4AA battery which is 6v and power the arduino 4 dc motors and the l298n so how ?

# Answer
> 2 votes
I understand you situation completely as I had also previously experienced the same problem. 9 V batteries are not enough to get the job done.

Therefore, I suggest you to use two 3.7 V Batteries. These batteries are a great alternative and had solved my problem. I hope it will do the same to you.

# Answer
> 1 votes
The name Arduino refers to dozens if not hundreds of different board and processor designs. Since a specific board / processor was not asked about we can only talk in generic terms.

Almost all Arduinos run at either 5 Volts or 3.3 Volts and contain a regulator to convert a wide range of Voltages to this value. That said, these regulators need a minimal drop between the input voltage and the desired regulated voltage in order to operate. Some require less and are referred to as LDO or Low Drop Out regulators.

As a worse case, consider if this Arduino does not use an LDO regulator and operates at 5 Volts. The difference between the 6 Volt input and Arduino operating Voltage is only 1 Volt. Further, consider if the batteries were not fresh and were only supplying, say, 5.5 Volts. Finally, consider if one or both motors started drawing heavy current from the batteries causing a further drop in Voltage. Any of these cases could cause the Arduino to reset / behave unexpectedly.

Consider trying to use the 9 Volt battery to power the Arduino and the 6 Volt battery to power the motors.

# Answer
> 0 votes
To properly answer your question instead of taking a SWAG as I did would Be for you to post links giving technical information on each of the hardware devices and which Arduino you are using.

Nine Volt (smoke alarm) batteries do not have enough power to properly power an Arduino. Use some larger cells. There are so many places that show this improper configuration, it just will not last if it even works for a short while. Great for the battery manufacturers.

You can also purchase a SEPIC converter for a few bucks, this is a combination Buck/Boost converter. You set the output voltage you want and it will maintain it as long as you're getting the minimum voltage from the battery, even if the battery is at 3.5V and the output is at 5V. The input will range from about 3V to 30V and it will maintain its setpoint. This range is dependent on the device you pick.

The L298N is about the worce choice you can make for the motor driver. It has darlington bipolar outputs, that drop about 1.4 volts per lead or 2.8 - 3.2 volts to the motor depending on the load. That voltage drop is burnt up as heat and is doing nothing useful. Purchase an H-Bridge that is large enough to drive the motor that has MOSFET outputs, you will be much happier with that.

For batteries use whatever is convenient, the SEPIC converter solves that problem. Best to pick them to power the motor and use the SEPIC to power the Arduino Vin pin at about 7.5V. Doing it via the Vin is not as efficient as doing a 5V direct but you get the additional filtering on that input circuit. A lot depends on which Arduino we are talking about. Since you did not mention one I am assuming either a UNO or Nano.

---
Tags: arduino-uno, motor, battery, robotics, l298n
---


# Question
Title: Where to store struct used for driver initialization
I'm doing a small project with ESP32 board. When initializing a driver, multiple structs are passed to initialization functions. I know that there are two ways to store such structs:

1. Storing structs on heap (with `calloc` or `malloc`)

```
adc_continuous_config_t cfg = calloc(1, sizeof(adc_continuous_config_t));

cfg->sample_freq_hz = 4500;
cfg->conv_mode = ADC_CONV_SINGLE_UNIT_1;
cfg->format = ADC_DIGI_OUTPUT_FORMAT_TYPE;

adc_continuous_config(*handle, cfg);
free(cfg);

```
2. Storing structs on stack

```
adc_continuous_config_t cfg = {
    .sample_freq_hz = 4500,
    .conv_mode      = ADC_CONV_SINGLE_UNIT_1,
    .format         = ADC_DIGI_OUTPUT_FORMAT_TYPE1,
};

adc_continuous_config(*handle, &cfg)

```

I was wondering which approach is encouraged.

# Answer
> 2 votes
You seem to be initializing this struct with constants. In such a case, I would use neither the heap nor the stack, but a third option: the “read-only data” section of the program. At global scope:

```
const adc_continuous_config_t cfg = {
    .sample_freq_hz = 4500,
    .conv_mode      = ADC_CONV_SINGLE_UNIT_1,
    .format         = ADC_DIGI_OUTPUT_FORMAT_TYPE1,
};

```

**Rationale**: The constants you are using to fill the struct have to be stored somewhere in the flash when the program is not running. Although I do not know the details of the machine language of the ESP32, it seems to me the compiler has only two options to compile your example code. It could say:

* load a CPU register with the immediate value `4500`
* store that register at the address of `cfg->sample_freq_hz`
* load a CPU register with the immediate value `ADC_CONV_SINGLE_UNIT_1`
* etc.

Then the values are stored as immediate operands of machine instructions. The other option would be to store an anonymous version of the initialized struct in the read-only data section of the program, and issue a `memcpy()` to initialize the allocated space at run time.

If you instead store the initialized struct as a global constant, it will go straight into the read-only data section of the program (like in the second compiler strategy), and you will use it from there. No extra copy needed. No extra machine instruction for initializing space allocated on the heap or stack.

**Caveat**: I assume `adc_continuous_config()` expects its second parameter to be of type “pointer to `const` data”. If it expects it to be a pointer to modifiable data, then this will not work.

---
Tags: esp32, memory
---


# Question
Title: Best way to send a boolean (1/0) to a windows application in real time?
I have an arduino mega connected to a light sensor that reads the status of a machine's indicator light. I have a C++ application that controls the machine, and I would like the arduino to send the application the status of the indicator light in real-time so that the application can control the machine.

Essentially, I just want to constantly send a "1" or "0" through the serial monitor to a C++ application. What would the best way to do this be? I am confused as to the difference between `serial.Write()` and `serial.Print()`, what is more optimal for this application?

# Answer
> 4 votes
It might sound like a good idea to send "0" or "1" in real time, for a fast response, but that might be counter-productive.

For one thing, you are spamming serial data which could slow down the receiving machine slightly. For another, if the sampling rate is faster than the baud rate, then the sending buffer will fill up, and the data being sent will be "old". Say the buffer size is 64 bytes, then the data being sent (and therefore received by windows) could be 64 bytes ago, and not real time.

I would suggest sending a "1" (with Print rather than Write) when the light is on, and then nothing until you detect that the light is off, then send a "0". And ditto for the transition back to being on. Thus the serial data flow merely indicates transitions and not the current state. This greatly reduces the amount of data, and makes it much less likely you will lose some or it will be out of date.

And just in case, send the current state (0 or 1) every second or so, just in case the listening end has only just been turned on.

# Answer
> 4 votes
I agree with both previous answers. Nick Gammon gives excellent advise on how to handle this situation, and Rohit Gupta gives you the gist of `write()` v.s. `print()`. I would like to elaborate on this `write()` / `print()` distinction though.

These methods of the Arduino API can be confusing, as they have many different signatures.

## write()

Let's look at `write()` first, as it is the simplest of them:

```
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);

```

These are meant to send a single byte and an array of bytes respectively. You can send *arbitrary bytes*, which is usually termed “binary data”. Note that any data, including text, is binary data: the term *binary* here simply means that there is no restriction on the bytes you can send.

```
size_t write(const char *buffer, size_t size);

```

This is the same as the previous one, for the case when the buffer is of type “array of char”. It can still send arbitrary data.

```
size_t write(const char *str);

```

This is a version for sending C-strings, i.e. NUL-terminated buffers. This one cannot send a zero byte, as that byte is interpreted as a string terminator. It is thus inappropriate for sending binary (in the sense of “arbitrary”) data. For this reason, I believe the inclusion of this overload is a mistake made by the designers of the API, and I would avoid it in preference of `print()` which, for this type of argument, *does exactly the same thing*.

Note that, in every instance, `write()` takes the data you give it and sends it as-is. There is no attempt at formatting it in any manner.

## print()

As stated by Rohit Gupta, `print()` is meant for sending text. If you have some data to send that is text to start with (like a literal string), `print()` sends it as-is, and is thus quite similar to `write()`. This is the case for the following overloads:

```
size_t print(const String &);  // sends a String object
size_t print(const char[]);    // sends a C-string
size_t print(char);            // sends a single character

```

Then you have some overloads for printing various kinds of numbers. All of these involve a binary-to-text conversion. The two remaining overloads, which involve `__FlashStringHelper` and `Printable`, are a bit too technical and I will not discuss them here.

## Comparison

All the statements below do the same thing, they send "A" through the serial port:

```
Serial.write(65);        // sends a byte with binary value 65
Serial.write('A');       // the ASCII code of 'A' is 65
Serial.print('A');       // a char is print()ed by sending it as-is
Serial.print(char(65));  // 'A' is a shortcut for char(65)
Serial.print("A");       // a one-character string

```

All the statements below send "65" through the serial port:

```
Serial.write(54); Serial.write(53);    // send two binary values
Serial.write('6'); Serial.write('5');  // ASCII('6') = 54...
Serial.write("65");       // sends text in a pre-formatted buffer
Serial.print("65");       // same
Serial.print(65);         // print() does the number-to-text conversion
Serial.print(int('A'));   // same

```

As a general rule, I recommend to always use `print()` for sending text, and use `write()` only for sending data that is not (reliably known to be) text.

# Answer
> 2 votes
`Serial.write` sends binary data, whereas `Serial.print` sends ASCII data. So it depends on whether you want Windows to receive ASCII 0 and 1 or binary 0 and 1.

I would suggest that you use print and send ASCII data.

---
Tags: serial, arduino-mega, sensors
---


title: Smoothing hx711 readings with atmega328

text:
# Question
Title: Smoothing hx711 readings with atmega328
I am making a 50kg weighing scale using **HX711 ADC**. My project includes **Atmega328** along with **74HC595** for driving 5 7segment displays(multiplexed). I am using the function `scale.get_units()`to fetch the data and the values are very well displayed on the 7segments. The problem I am facing is the readings on the 5th digit (right most 1's) are unstable. Now, if I use `scale.read_average(5)`, **my display scanning gets slow**. I was wondering if there is a way to average the readings in a loop like the conventional way. I tried it but with no luck! It keeps showing random added numbers. Any help would be highly appriciated. Below is the code inside the loop. Let me know if full code is needed. Thanx in advance!

```
if (scale.is_ready()) {
    weight = scale.get_units();
    finalWeight = weight * 1000;
}
for (int i = 0; i < 10 ;i++) {
    sum += finalWeight;
}
average = sum / 10;
if (average < 0) {
    break_number(0);
} else {
    break_number(average);
}
display_number();
delay(1);

```

# Answer
> 1 votes
First of all, this code:

```
for (int i = 0; i < 10 ;i++) {
    sum += finalWeight;
}
average = sum / 10;

```

does not average multiple readings. Instead, it takes the single reading stored in `finalWeight`, multiplies it by ten (by means of successive additions), then divides it by ten to get back the same value.

If you want to reduce the noise, you have to take multiple readings and average them. The reading-taking code must thus be inside the loop. A simple option may be like this:

```
void loop() {
    sum = 0;
    for (int i = 0; i < 10; i++) {
        while (!scale.is_ready()) {}  // wait for the scale to be ready
        sum += scale.get_units();
    }
    weight = sum / 10;  // compute the average
    display(weight);    // and display it
}

```

Note that I have simplified things a bit by removing the scaling factors. You can take this as simple inspiration and adapt to your specific needs.

The code above has one problem though: as the code is blocking while waiting for the scale to be ready, the display is not refreshed. You could fix this by explicitly refreshing the display within the waiting loop:

```
void loop() {
    sum = 0;
    for (int i = 0; i < 10; i++) {
        while (!scale.is_ready()) {  // wait...
            display(weight);         // ...while refreshing the display
        }
        sum += scale.get_units();
    }
    weight = sum / 10;
    display(weight);
}

```

This should work, but I would however suggest instead a third approach: write *non-blocking code*. This is code that never blocks: instead, if something can be done *right now*, it does it. If not, it moves along:

```
void loop() {
    if (scale.is_ready()) {  // if something useful can be done NOW:
        sum += scale.get_units();
        count++;
        if (count >= 10) {
            weight = sum / count;  // update the value to be displayed
            sum = 0;               // reset the averaging variables
            count = 0;
        }
    }

    display(weight);  // unconditionally refresh the display
}

```

This way, your `loop()` always runs fast, and you can add code that will not be blocked by the stuff you wrote earlier.

**Edit**: As suggested by chrisl in a comment, a moving average may better serve your needs. I would try the exponentially-weighted version, as it is lightweight and simpler to implement. You may want to explore this path.

---
Tags: arduino-uno
---


# Question
Title: stream a "big" array of measures to a server through wifi
I'm measuring accelerations at "high frequency" (4kHz) from an accelerometer (ADXL355/ADXL357) to an esp32. It's crucial that no sample is lost while performing a measure which last say 2 seconds, thus I first record all the samples and then send the complete array of measures to a server over wifi knowing the IP and the port of the server.

The measures array is an int array of size 3bytes * 3axis * 4000Hz * 2seconds = 72000 bytes.

I tried to make an http server and send the measures array from the microcontroller to the server with a POST request and serializing the payload with json (ArduinoJSON library), but this is very costy in terms of memory, because I need to duplicate the array of measures and convert it to an array of strings.

Is there a better way to send this array over wifi to the server (some sort of stream?) optimizing the memory usage on the microcontroller? which arduino libraries may help in the task? could you link an example with code of a similar situation?

# Answer
JSON is a format trivial to write: you do not need a library for this. For example, an array of numbers could be serialized like this:

```
void serialize_array(Print &client, int *data, int count) {
    client.print('[');
    for (int i = 0; i < count; i++) {
        client.print(data[i]);
        client.print(i==count-1 ? ']' : ',');
    }
}

```

This would effectively stream the data without storing the JSON representation in memory.
> 2 votes

---
Tags: esp32, wifi, array, http, memory
---


title: ESP32 ADC <-> WiFi issue

text:
# Question
Title: ESP32 ADC <-> WiFi issue
I'm using the ESP32's ADC1 (not ADC2, which conflicts with WiFi functionality) to capture some analog data received at IO36 (an ADC1 port).

As soon as I uncomment the `WiFi.mode(WIFI_AP_STA)` line (even when the `WiFi.begin()` line is still commented out), analog readings go crazy!

Some side notes:

1. The hardware that processes the input signal to make it suitable for the ESP32 analog input uses the same power source as the ESP32 module.
2. A 100 μF SMD capacitor is connected to the source line of the ESP32 module just beside it to lessen the impact of its power consumption ripples on other devices.
3. I tried `adc1_get_raw`, which made no difference.
4. I tried this code on another ESP32 module; it also showed a huge difference in ADC1 readings before and after uncommenting `WiFi.mode(WIFI_AP_STA)`.
5. Using root APIs such as `esp_wifi_init` & `esp_wifi_set_mode` & `esp_wifi_start` instead of Arduino wrappers like `WiFi.mode` didn't help.

New clue: Apparently the issue is with the WiFi Access Point mode (i.e. WIFI\_AP), because setting Wi-Fi to Station mode (i.e. WIFI\_STA) doesn't cause this issue.

In general anything related to WiFi causes the ADC to get unstable. No matter which ESP32 board you use, you could simply serial plot any ADC1 channel before and after the WiFi initialization command, even with floating ADC1 pins you can see the difference.

```
#include <WiFi.h>
float R = 0;

void setup() {
  Serial.begin(500000);
  // WiFi.mode(WIFI_AP_STA);
  // uncommenting this line analogread goes crazy, even while the following line is still commented out
  // WiFi.begin();
  analogSetAttenuation(ADC_0db);
}

void loop() {
  R = analogRead(36);
  Serial.println(R/12.21);
}

```

# Answer
I've just had the same problem. I just put all of the WIFI connecting code into a function, read the ADC2 data then called the function to send, ending with WIFI.mode(WIFI\_OFF) to shut down the WIFI, read the data then started it all over again. I'm using ESPNOW so don't have to panic about hooking up to my network which would obviously take longer. With ESPNOW, the data is sent regardless and I have it sending every few seconds which is fine for me. I did try putting the connection code into loop, but it kept restarting the board. I've seen plenty of other stuff online about that. Putting it into a function seems to get around that.
> 1 votes

---
Tags: esp32, wifi, adc
---


# Question
Title: Using pushbutton to make Stepper motor rotate 90 degrees
Using a 28BYJ-48 Motor with a ULN2000 Driver. The motor works fine since I can rotate it using serial input. Pushbutton is connected properly, Can light up an led if I connect one. I want the motor to rotate 90 degrees everytime I push the button. When I run the code below the LEDs on the driver just blink rapidly, when I press and hold the button they stop blinking, keeping the state they were on already. e.g. if the LED A on the board was on at the moment I press the button, It stays on. If it was off, It stays off. you get the Idea.

code used:

```
#include <Stepper.h>;

 // pushbutton pin
 const int buttonPin = 2;

 int STEPS = 32;
 Stepper stepper(STEPS,8,9,10,11);

//create a variable to store a counter and set it to 0
int counter = 0;
void setup()
{
  pinMode(buttonPin, INPUT);
}

void loop()
{
 // local variable to hold the pushbutton states
  int buttonState;

  //read the digital state of buttonPin with digitalRead() function and store the           //value in buttonState variable
  buttonState = digitalRead(buttonPin);

  //if the button is pressed increment counter and wait a tiny bit to give us some          //time to release the button
  if (buttonState == LOW) // light the LED
  {
    counter++;
    delay(150);
  }

  if(counter == 1)
    stepper.step(512);  // zero degrees
  //else reset the counter to 0 which resets thr servo to 0 degrees
  else
   counter = 0;
}

```

EDIT 1: Modifying the code @Matej gave me, I was able to debug the problem that was causing the stepper to not rotate. the code:

```
#include <Stepper.h>

// pushbutton pin
const int buttonPin = 2;

const int STEPS = 32;
Stepper stepper(STEPS, 8, 9, 10, 11);
int val = 2048;

//create a variable to store a counter and set it to 0
int counter = 0;

unsigned long last_button_time = 0;   //for aving last millis

void setup(){
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  stepper.setSpeed(1000);
}

void loop(){
  bool buttonState;   // local variable to hold the pushbutton states

  //read the digital state of buttonPin with digitalRead() function and store the           //value in buttonState variable
  buttonState = digitalRead(buttonPin);
  //if the button is pressed incremen counter and wait a tiny bit to give us some          //time to release the button
  if(buttonState == HIGH && millis() - last_button_time > 200){ // light the LED
    last_button_time = millis();
    counter = 1;
    Serial.println(counter);
  }

  if (counter == 1) {
    Serial.println("Please Write the desired angle");
    val = Serial.parseInt();
    delay(5000);
    counter = 0;
    if(Serial.available() > 0) {
    Serial.println("Stepping: ");
    Serial.print(val);
    stepper.step(val);
    counter = 0;
    Serial.println(counter);
    }
    else {
      Serial.println("ERROR LOOPING THROUGH IF STATEMENT");
    }
  }

}

```

The Serial output looks like this:

```
1
Please Write the desired angle
Stepping:
00
1
Please Write the desired angle
Stepping:
20480
1
Please Write the desired angle
Stepping:
20480

```

please note that In the first attempt, I wrote "2048" in Serial input to define the value of the integer (val), and nothing happened. in the second and third attempt, I also wrote 2048 (0 at the end is the counter variable) and the motor started shaking, but it didn't rotate.

# Answer
> 0 votes
I edtied few things in your code. I am not sure if `LOW` value is correct, so I replaced it with `HIGH`. Second thing is timing. I removed all `delay()` functions instead of it you can see usage of `millis()`. That's for handling interval between button press and button release - second part of `if` will check if last time of button press is bigger than `200ms`, if yes, move stepper. Last things is stepping. You can see here `stepper.step(STEPS/4);`. `STEPS` is variable which you declared on the top of code. It's called steps per revolution, one revolution is `360°` so `90°` will be `STEPS/4`.

Here is the code, read it and test it:

```
#include <Stepper.h>;

// pushbutton pin
const int buttonPin = 2;

const int STEPS = 32;
Stepper stepper(STEPS, 8, 10, 9, 11);

//create a variable to store a counter and set it to 0
int counter = 0;

unsigned long last_button_time = 0;   //for aving last millis

void setup(){
  pinMode(buttonPin, INPUT);
  stepper.setSpeed(1000)
}

void loop(){
  bool buttonState;   // local variable to hold the pushbutton states

  //read the digital state of buttonPin with digitalRead() function and store the           //value in buttonState variable
  buttonState = digitalRead(buttonPin);

  //if the button is pressed increment counter and wait a tiny bit to give us some          //time to release the button
  if(buttonState == HIGH && millis() - last_button_time > 200){ // light the LED
    last_button_time = millis();
    counter++;
    stepper.step(STEPS/4);    //90° degrees
  }
}

```

# Answer
> -1 votes
**Just a quick Tweak:**

Please note while using Adruino, using "INPUT" mode without enabling the internal pull-up resistor, you need to ensure that the switch is connected properly and that you have external pull-up or pull-down resistors in your circuit. In the code you provided, you haven't included the necessary external pull-up resistor.

To tweak and fix the code, here a simple quick option:

Usage of **"INPUT\_PULLUP"** mode instead of **"INPUT"**:

This is the simpler and recommended approach. Just change the line:

```
pinMode(buttonPin, INPUT); to pinMode(buttonPin, INPUT_PULLUP);

```

It will enable the internal pull-up resistor of the Arduino, eliminating the need for external resistors in your circuit.

Here is quick fixed code:

```
#include <Stepper.h>;
// Using Stepper Motor to rotate 90 degree
// Reference: https://arduino.stackexchange.com/questions/61260/using-pushbutton-to-make-stepper-motor-rotate-90-degrees

// pushbutton pin
const int buttonPin = 2;

const int STEPS = 32;
Stepper stepper(STEPS, 8, 10, 9, 11);

//create a variable to store a counter and set it to 0
int counter = 0;

unsigned long last_button_time = 0;   //for having last millis

void setup(){
  pinMode(buttonPin, INPUT_PULLUP);
  stepper.setSpeed(1000)
}

void loop(){
  bool buttonState;   // local variable to hold the pushbutton states

  //read the digital state of buttonPin with digitalRead() function and store the           //value in buttonState variable
  buttonState = digitalRead(buttonPin);

  //if the button is pressed increment counter and wait a tiny bit to give us some          //time to release the button
  if(buttonState == HIGH && millis() - last_button_time > 200){ // light the LED
    last_button_time = millis();
    counter++;
    stepper.step(STEPS/4);    //90° degrees
  }
}

```

Connection Setup:

To connect an external switch to an Arduino using the internal pull-up resistor, ie. using "INPUT\_PULLUP" instead of just "INPUT" in your above code, you will need to make the following connections:

1. Connect one terminal of the switch to the digital input pin on the Arduino. Let's assume you're using pin 2 for this example.
2. Connect the other terminal of the switch to ground (GND) on the Arduino.

With this connection setup, you're essentially creating a circuit where the switch is connected between the digital input pin and ground. When the switch is not pressed, the internal pull-up resistor will pull the input pin's voltage to a high level (logic HIGH). When the switch is pressed, it will connect the input pin to ground, resulting in a low level (logic LOW).

Alternatively, In case, you use "INPUT" instead "INPUT\_PULLUP" which would not be a best approach here. You may follow the below example:

Here's an example of the circuit and code using an external pull-up resistor:

Circuit:

1. Connect one terminal of the switch to the digital input pin on the Arduino.
2. Connect the other terminal of the switch to the junction point between a pull-up resistor (e.g., 10K ohm) and Vcc (5V).

Code Example:

```
const int buttonPin = 2;  // Pin connected to the external switch

void setup() {
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);  // Enable internal pull-up resistor
}

void loop() {
  // Read the state of the button
  int buttonState = digitalRead(buttonPin);

  // Perform your desired actions based on the button state
  if (buttonState == LOW) {
    // The button is pressed
    // Do something...
  } else {
    // The button is not pressed
    // Do something else...
  }
}

```

Kindly note to add below line of code inside void setup() to enable internal pull-up resistor as shown in above code i.e. **digitalWrite(buttonPin, HIGH);** // Enable internal pull-up resistor

hope that helps. Great job Guyz, Happy coding.

---
Tags: arduino-uno-smd, stepper-motor
---


# Question
Title: avrdude: ser_open(): can't open device "\\.\COM5": Access is denied
I'm getting the error as follows

> Sketch uses 2952 bytes (9%) of program storage space. Maximum is 32256 bytes.
> Global variables use 196 bytes (9%) of dynamic memory, leaving 1852 bytes for local variables. Maximum is 2048 bytes.
> avrdude: ser\_open(): can't open device "\\.\COM5": Access is denied.
> Failed uploading: uploading error: exit status 1

The board I am using is Arduino Uno and checked the ports too. Also restarted and installed IDE again. But still not being able to deal with it. I will be happy with the help!

# Answer
In Windows (if you are using windows), There are two things may caused the problem:

* go to device manager \>\> ports \>\> and Uninstall all ports related to Arduino (including the COM5). Then connect the arduino again and it install it again automatically.
* Make sure that you close all "serial monitor", before uploading the sketch.
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: SIM800L - AT Commands not doing anything on Arduino Serial Monitor
I am trying to send AT commands to SIM800L through Arduino's Serial Monitor. However when I type any command in the serial monitor nothing happens. I'm using an Arduino MEGA 2560 and the TX/RX of the SIM800L is connected to 9 and 10 respectively. Here is the code:

```
#include <SoftwareSerial.h>

SoftwareSerial GPRS(9, 10);
boolean state, lastState;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  state = digitalRead(2);
  lastState = state;

  GPRS.begin(9600);
  Serial.begin(9600);

  GPRS.println("AT+CMGF=1");

  delay(1000);
}

void loop()
{
  while(GPRS.available()) {
    Serial.write(GPRS.read());
  }

  lastState = state;
  state = digitalRead(2);

  if ( state != lastState ) {
    sendSMS();
  }

  delay(500);
}

void sendSMS() {
  Serial.print("Switch was turned ");
  Serial.println(state ? "on" : "off");

  GPRS.println("AT+CMGS=\"+64XXXXXXXXX\"");

  delay(500);

  GPRS.print("Switch was turned ");
  GPRS.println(state ? "on" : "off");
  GPRS.write( 0x1a ); // ctrl+Z character

  delay(500);
}

```

Any help would be much appreciated!

EDIT2: I forgot to mention but I am able to send, receive, and call from the GSM Module (with a different code). However I am not able to read the the received messages, since I only get a +CMT "SM", message and I can't exactly use AT+CMGR or CMGL commands because the serial monitor does nothing with them. here's the code for that:

```
#include <SoftwareSerial.h>
SoftwareSerial sim(9,10);
int _timeout;
String _buffer;
String number = "+639XXXXXXXXX"; //-> change with your number
void setup() {
  delay(1000); //delay for 7 seconds to make sure the modules get the signal
  Serial.begin(9600);
  _buffer.reserve(50);
  Serial.println("Lets go!");
  sim.begin(9600);
  delay(1000);
  Serial.println("Type s to send an SMS, r to receive an SMS, and c to make a call");
}
void loop() {
  if (Serial.available() > 0)
    switch (Serial.read())
    {
      case 's':
        SendMessage();
        break;
      case 'r':
        RecieveMessage();
        break;
      case 'c':
        callNumber();
        break;
    }
  if (sim.available() > 0)
    Serial.write(sim.read());
}
void SendMessage()
{
  Serial.println ("Sending Message");
  sim.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);
  Serial.println ("Set SMS Number");
  sim.println("AT+CMGS=\"" + number + "\"\r"); //Mobile phone number to send message
  delay(1000);
  String SMS = "Wala kang jowa!";
  sim.println(SMS);
  delay(100);
  sim.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
  _buffer = _readSerial();
}
void RecieveMessage()
{
  Serial.println ("SIM800L Read an SMS");
  delay (1000);
  sim.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
  delay(1000);
  Serial.write ("Unread Message done");
}
String _readSerial() {
  _timeout = 0;
  while  (!sim.available() && _timeout < 12000  )
  {
    delay(13);
    _timeout++;
  }
  if (sim.available()) {
    return sim.readString();
  }
}
void callNumber() {
  sim.print (F("ATD"));
  sim.print (number);
  sim.print (F(";\r\n"));
  _buffer = _readSerial();
  Serial.println(_buffer);
}

```

# Answer
Do not use `SoftwareSerial` on a Mega2560 unless you *absolutely know what you are doing*.

SoftwareSerial does not work on many of the pins of the Mega2560, and since there are other *hardware* serial ports available there is seldom any reason to resort to using SoftwareSerial anyway.

Connect your SIM800L to the TX1/RX1 pins of the Mega2560 then communicate using the pre-defined `Serial1` object.
> 1 votes

# Answer
1. Make sure the RX of your arduino board is connected to TX of GSM and the TX should be connected in RX of GSM module.
2. Next try to do this

```
   GPRS.begin(9600);
   Serial.begin(115200);

```
3. Also double check your wirings, if you have a tester you might wanna check if both end are connected with each other. And in the loop try to print this `Serial.println(GPRS.available())` if it is not greater than 0 then you have a problem with your connection.

```
    #include <SoftwareSerial.h>
    SoftwareSerial sim(2,3);

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      sim.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      while(Serial.available() > 0){
        sim.write(Serial.read());
      }

      while(sim.available() > 0){
        Serial.write(sim.read());
      }
    }

```

> diagram reference.

Hope this help.
> 0 votes

---
Tags: arduino-mega, gsm
---


# Question
Title: Arduino AVR Program with default ATMEGA32U4 bootloader instead
I’m working an Arduino program that uses the FastLED library and is all coded in the Arduino IDE (not my choice, just a result of this OOS library).

However, I don’t want to run this on an “Arduino” board. Instead, I want to flash this to a factory fresh ATMEGA32U4 as an MCU for the project. However, the ATMEGA32U4 doesn’t come with the Arduino boot loader, but instead, DFU. I have flashing procedures designed for the DFU boot loader already and I don’t want to go swapping bootloaders.

Would the Arduino program work fine without swapping to the Arduino bootloader? My understanding is *yes* since the bootloader only controls the boot sequence, and has nothing to do with runtime.

# Answer
> 1 votes
> Would the Arduino program work fine without swapping to the Arduino bootloader?

Yes, the bootloader is only there for conveniently changing program memory via serial instructions.

Whatever method you use to put the "main" code there, it will be the same code and will operate the same.

---
Tags: bootloader, atmega32u4
---


# Question
Title: Problem when coding 4x4 keypad's key detection (without library)
Part of my current assignment involves reading the input from a 4x4 keypad connected to an Arduino UNO. While this may be done easily using \<Keypad.h\>, the project is being done with Tinkercad's online simulator, meaning I don't have access to that library. I have to do it the manual way.

This is the code I've got so far:

```
#include <Wire.h>
#define DIMENSIONS 4
const unsigned long period = 50;
unsigned long prevMillis = 0;
byte modo = 0;
const byte rowsPins[DIMENSIONS] = {11, 10, 9, 8};
const byte columnsPins[DIMENSIONS] = {7, 6, 5, 4};
char keys[DIMENSIONS][DIMENSIONS] = {
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

void setup()
{
    Serial.begin(9600);// debug
    for(byte i = 0; i < DIMENSIONS; i++){
        pinMode(columnsPins[i], INPUT);
        digitalWrite(columnsPins[i], HIGH);
        pinMode(rowsPins[i], INPUT_PULLUP);
    }
    Wire.begin();
}

void loop()
{
    switch(modo){
        case 0:
            Serial.print("Master (2) boot up\n");
            modo++;
            break;
        case 1:
            if(millis() >= 1000){
                modo++;
            }
            break;
        case 2:
            if (millis() - prevMillis > period){
                prevMillis = millis();
                for(byte c = 0; c < DIMENSIONS; c++){
                    pinMode(columnsPins[c], OUTPUT);
                    digitalWrite(columnsPins[c], LOW);
                    for(byte r = 0; r < DIMENSIONS; r++){
                        if(digitalRead(columnsPins[r]) == LOW){
                            Serial.println(keys[r][c]);
                        }
                    }
                    digitalWrite(columnsPins[c], HIGH);
                    pinMode(columnsPins[c], INPUT);
                }
            }
            break;
        default:
            break;
    }
}

```

(the "modes" and Wire.h are a different part of the assignment and not related to my issue)

This code should, in theory, read the input from the connected 4x4 keypad and then print on the serial monitor which key was pressed. I've done a fair bit of searching, and other solutions for detecting key presses without the Keypad library aren't super different from what I've done here. However, for some reason, what I wrote is not working properly for me.

On starting the simulation, the serial monitor prints 1, 5, 9, D continuously and repeatedly on a loop. Pressing the keys does sometimes print the appropriate character, but it does not stop the flood of 1s, 5s, 9s and Ds.

I know for a fact that it's not a matter of the pins being misconnected, I've checked for that at least a dozen times by now. It's most certainly a matter of code... but I can't figure out where the problem lies.

# Answer
In case 2:

```
digitalWrite(columnsPins[c], LOW);
for(byte r = 0; r < DIMENSIONS; r++){
   if(digitalRead(columnsPins[r]) == LOW){
   Serial.println(keys[r][c]);
   }
}

```

Since you just wrote one of the column pins low, you can guarantee that one is going to read low. Did you mean to read the row pins?
> 5 votes

---
Tags: arduino-uno, programming, keypad
---


# Question
Title: Instructables "Omnibot" -- using the "real" Uno R3 board
Step 4 of this instructable uses what seems to be a "knock-off" development version of the Uno R3 board, where an RF receiver is soldered to pads that don't exist on the R3 or R3 SMD boards:

https://www.instructables.com/OmniBot-Easy-Arduino-RC-Robots/

> ...
>
> 4. Locate available Gnd, Vcc, and Rx holes on your Arduino. (if using the recommended Arduino they can be found all near each other just below the ICSP pins.)
> 5. Insert the tinned wires through their respective holes and solder on the back side. White to RX, red to 5V, black to GND.
>
> ...

I am completely new to Arduino, so I'm a little puzzled by the lack of VCC. Sounds like this is just power. Is there any reason I can't hook the RF receiver to the D0 (RX) pin, 5v out, and GND headers?

# Answer
Yes, the holes they are showing it connected to are physically connected to the pins you mention. Connecting directly to those pins would be equivalent.
> 2 votes

---
Tags: arduino-uno
---


title: Changing SPI ports on an Arduino

text:
# Question
Title: Changing SPI ports on an Arduino
My end goal is to read information from an nRF24l01 module connected to my Arduino UNO R3, and generate an interrupt whenever a message is sent to the Arduino.

Now, I have read that for Hardware interrupts, only pins D2 and D3 can be used to generate interrupts. However, while connecting the MISO line, I saw that here it was mentioned that

> On some Arduino boards (see table above), pins MOSI, MISO and SCK are the same pins as digital pin 11, 12 and 13, respectively. That is why many tutorials instruct you to hook up the target to these pins.

On every website I have searched, MISO is always connected to 12. **Is there any way to change the MISO line from 12 to 3, or will I have to resort to using Pin change interrupts?** Another way I can think of to bypass this is to connect D12 to D3, but I'm afraid this may cause complications in the circuit.

# Answer
> I have read that for Hardware interrupts, only pins D2 and D3 can be used to generate interrupts

The pin-change interrupts, available on all pins of the Arduino Uno, are almost as good. I say "almost" because the only thing you have to do is work out which pin caused the interrupt, which can be trivial if you only set up one pin to generate interrupts.

> Is there any way to change the MISO line from 12 to 3,

Not if you used the hardware SPI on the chip. If you use bit-banged SPI you can use any pins.

I did a project for a temperature and humidity sensor, which logs to a SD card (using SPI), and also displays on a 8-digit display (using SPI). For the latter case I used bit-banged SPI, as described there.

I have a page about SPI and also a similar one on Stack Exchange.

My bit-banged SPI code is available here.

---

I'm not clear about why you don't just use the hardware SPI pins. Is that you want an interrupt when a SPI message arrives? There is a hardware interrupt for just that. See my posts about SPI for more details about that.
> 1 votes

# Answer
# My second answer ...

Your question, in bold, is a good example of an XY Problem. You asked:

> Is there any way to change the MISO line from 12 to 3, or will I have to resort to using Pin change interrupts?

This is the X question. However the Y question is your goal:

> My end goal is to read information from an nRF24l01 module connected to my Arduino UNO ...

I answered, in another answer, first about changing the MISO line from pin 12, and also pointed out that SPI transactions can generate interrupts.

However, as Juraj pointed out in a comment, the Arduino in this case is the **master** and the nRF24l01 is the **slave** (from the SPI point of view).

There is no way that a slave can burst into life and generate a message, and hence cause an interrupt. That is the master's job.

As I read on this page about the module it has an IRQ pin described thus:

> IRQ is an interrupt pin that can notify the master when there is new data to process.

So, your job is simplified, really. You don't need to detect when an SPI transaction starts (the Arduino will start the transaction), you need to connect the IRQ pin to an Arduino pin and detect that data is ready. Simple! Then you can easily use pin 2 or pin 3 if you want to use the "hardware" interrupts rather than the pin-change interrupts. (The pin-change interrupts are hardware interrupts too, though).
> 1 votes

---
Tags: arduino-uno, interrupt, spi, nrf24l01+
---


# Question
Title: ATMEGA2560 died inside a arcade game circuit
I am building arcade game with 10 player buttons (5 for each player) and one start button. All buttons have build in LED inside. Player buttons has LED for 12V and start button has led for 5V. I am using ATMEGA2560 pro boar. I have also 4 TM1637 displays (two for each player) showing time and score. I am using 12V adapter. This is my schematic:

This is test code which I had:

```
#include <Arduino.h>
#include <TM1637Display.h>

#define BTN_A1_PIN 16
#define BTN_A2_PIN 18
#define BTN_A3_PIN 28
#define BTN_A4_PIN 26
#define BTN_A5_PIN 47

#define BTN_B1_PIN 44
#define BTN_B2_PIN 36
#define BTN_B3_PIN 39
#define BTN_B4_PIN 46
#define BTN_B5_PIN 37

#define LED_A1_PIN 13
#define LED_A2_PIN 17
#define LED_A3_PIN 11
#define LED_A4_PIN 15
#define LED_A5_PIN 19

#define LED_B1_PIN 25
#define LED_B2_PIN 27
#define LED_B3_PIN 23
#define LED_B4_PIN 21
#define LED_B5_PIN 29

#define BTN_START_PIN 32
#define LED_START_PIN 35

#define DISPLAY_A_SCORE_CLK 20
#define DISPLAY_A_SCORE_DIO 10

#define DISPLAY_A_TIME_CLK 40
#define DISPLAY_A_TIME_DIO 43

#define DISPLAY_B_SCORE_CLK 42
#define DISPLAY_B_SCORE_DIO 33

#define DISPLAY_B_TIME_CLK 34
#define DISPLAY_B_TIME_DIO 38

typedef struct
{
  uint8_t btnIn;
  uint8_t ledOut;
} btn_t;

btn_t btn[] = {
    {
        .btnIn = BTN_A1_PIN,
        .ledOut = LED_A1_PIN,
    },
    {
        .btnIn = BTN_A2_PIN,
        .ledOut = LED_A2_PIN,
    },
    {
        .btnIn = BTN_A3_PIN,
        .ledOut = LED_A3_PIN,
    },
    {
        .btnIn = BTN_A4_PIN,
        .ledOut = LED_A4_PIN,
    },
    {
        .btnIn = BTN_A5_PIN,
        .ledOut = LED_A5_PIN,
    },
    {
        .btnIn = BTN_B1_PIN,
        .ledOut = LED_B1_PIN,
    },
    {
        .btnIn = BTN_B2_PIN,
        .ledOut = LED_B2_PIN,
    },
    {
        .btnIn = BTN_B3_PIN,
        .ledOut = LED_B3_PIN,
    },
    {
        .btnIn = BTN_B4_PIN,
        .ledOut = LED_B4_PIN,
    },
    {
        .btnIn = BTN_B5_PIN,
        .ledOut = LED_B5_PIN,
    },
    {
        .btnIn = BTN_START_PIN,
        .ledOut = LED_START_PIN,
    },
};

TM1637Display displayAScore(DISPLAY_A_SCORE_CLK, DISPLAY_A_SCORE_DIO);
TM1637Display displayATime(DISPLAY_A_TIME_CLK, DISPLAY_A_TIME_DIO);
TM1637Display displayBScore(DISPLAY_B_SCORE_CLK, DISPLAY_B_SCORE_DIO);
TM1637Display displayBTime(DISPLAY_B_TIME_CLK, DISPLAY_B_TIME_DIO);

void setup()
{
  for (int i = 0; i < 11; i++)
  {
    pinMode(btn[i].btnIn, INPUT_PULLUP);
    pinMode(btn[i].ledOut, OUTPUT);
  }
  displayAScore.setBrightness(0x0f);
  displayATime.setBrightness(0x0f);
  displayBScore.setBrightness(0x0f);
  displayBTime.setBrightness(0x0f);

  displayAScore.showNumberDec(1111, false);
  displayATime.showNumberDec(2222, false);
  displayBScore.showNumberDec(3333, false);
  displayBTime.showNumberDec(4444, false);
}

void loop()
{
  for (size_t i = 0; i < 11; i++)
  {
    if(0 == digitalRead(btn[i].btnIn))
    {
      digitalWrite(btn[i].ledOut, HIGH);
    }
    else
    {
      digitalWrite(btn[i].ledOut, LOW);
    }
  }
}

```

And this is what it looks like inside:

The problem is **ATMEGA2560** just burned. I was testing it firstly without TM1637 (they were connected to power but I did not use lib for them at that time) and it was working okay (buttons were lighting up upon pressing).

Then I added lib for TM1637 to code and for 2 seconds I saw "1111" "2222" ... so on as it is in code, so there is no bad connection. But after 2 seconds it started buzzing (probably linear regulator temp protection was kicking in) and ATMEGA just burned.

Now when I plug 12V in it MCU gets hot pretty fast. I can measure 5V on the linear regulator so it is not shorted. I had always connected only 12V and no power from USB. I know my wires are not the shortest but I would not expect that MCU dies. Could you help please? I don't want to plug the next 20€ chip just to see another expensive smoke.

# Answer
You fried it because you broke rule #1: "A Power Supply the Arduino is NOT!". Your displays can pull 320 Ma in themselves. That is over 2 watts of power before anything else. When you get a new one purchase a buck converter and power the LEDs with the 5V output of that, use the 12V to feed it. As I understand it The suggested maximum power dissipation for the Mega regulator is 1 Watt. So with 12V into the regulator the max current is about 140 mA (1W / (12V - 5V)), This does not count your LEDs.
> 1 votes

---
Tags: arduino-mega, hardware, atmega2560
---


# Question
Title: Connecting nRF24L01 to ATmega328PU with external 8 MHz crystal problem
I am trying to fix the problem of communicating between two nRF24L01+ together, one connected to an Arduino Uno and another connected to an ATmega328PU with an 8 MHz external crystal.

The bootloader on the ATmega328PU is “Arduino Pro or Pro Mini” 3.3 V, 8 MHz.

The problem is that the nRF24L01+ on the ATmega328PU is not responding (working). I am using the RF24 library as shown in the code below.

There are several things that I have already tried:

1. To make sure that both nRF24L01+ modules work, I connected one to an Arduino Uno and another to an Arduino Mega and they work perfectly. So, the problem is not with the nRF modules.
2. I changed the external crystal of the ATmega328PU to 16 MHz and changed the bootloader to Arduino Uno; didn’t work again.

The circuit diagram is shown below:

Transmitter code:

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN

const byte address[6] = "00001";
const int btn = 4;
int buttonState = 0;
int programState = 0;

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
  pinMode(btn, INPUT);
}

void loop() {
  buttonState = digitalRead(btn);
    // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
    if ((buttonState == LOW) && (programState == 0)) {
      programState = 1;
    }

    else if ((buttonState == HIGH)&& (programState == 1)) {
      const char text[] ="Hello World"; // you can customize this text to your wish
      radio.write(&text, sizeof(text));
      programState = 0;
      Serial.println("BUTTON");

      delay(1000);
  }
}

```

Receiver code:

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
const int output = 2;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  pinMode(output,OUTPUT);
  digitalWrite(output, LOW);
  delay(1000);
}

void loop() {
  if (radio.available()) {
    char text[32] = "";
    radio.read(&text, sizeof(text));
    Serial.println(text);
    if (strcmp(text,"Hello World")==0) {
      Serial.println("CORRECT");
      digitalWrite(output, HIGH);
      delay(2000);
      digitalWrite(output, LOW);
      delay(2000);
    }
  }
}

```

# Answer
> 0 votes
Assuming a basic test of the MCU works, say the blink sketch works at normal speed (0.5 Hz), try this format of the constructor:

`RF24 radio(7, 8, 4000000); // set SPI speed to 4MHz instead of default 10MHz`

The default of 10MHz maybe too high for your MCU configuration.

From https://github.com/nRF24/RF24/blob/master/COMMON\_ISSUES.md

Some more things to try:

EDIT

Most Nrf24L01 problems are related to an inadequate power supply. Some 3.3 volt power supplies, say those of a Nano where the 3.3 volts is derived from the USB/UART adaptor, don't work well here. You could try adding two capacitors across the power rails at the point on the breadboard where the power for the nrf24L01 is taken. Use a 100nF ceramic and a 10 to 100uF electrolytic. You barebones atmega328p should anyway have its own decoupling capacitor as close as possible to the chip's power pins. Use a 100nF ceramic.

The link above has other trouble shooting measures.

---
Tags: atmega328, nrf24l01+
---


# Question
Title: How can I get the Arduino IDE v0021 running on Windows XP to communicate with the latest Nano v3.0
After reading another post CH340 Nano avrdude: stk500\_getsync() not in sync resp=0xa4 I have discovered that the bootloader on current Nano v3.0 has been upgraded. However, the advice given to overcome this problem is based around a more modern version of the Arduino IDE communicating with an old bootloader. I have the reverse problem. I damaged my Arduino Nano that was working with a laptop running Windows XP and bought a replacement. It obviously has the latest bootloader installed so my version of the Arduino IDE v0021 (recommended to run on Windows XP) can no longer upload sketches to the board.

I have uploaded GRBL v1.1h to the Nano board from an Arduino IDE v1.8.19 installation on a Windows 7 computer but the older version of GRBL Control v0.8.1 running on Windows XP has compatibility issues with GRBL 1.1h. I need to upload an earlier version of GRBL that is compatible with GRBL Control v0.8.1 but the bootloader on the new Arduino Nano v3.0 runs at 115200 and the Arduino IDE v0021 expects a baud rate of 57600 so I get these errors

> stk500\_getsync():not in sync: resp=0x09
>
> stk500\_disable(): protocol error, expect=0x14, resp=0x51

Can I upload an older bootloader to a newer Arduino Nano so I can then flash an older version of GRBL that is compatible with GRBL Control v0.8.1 to run on Windows XP?

# Answer
> 1 votes
I agree with Juraj that any bootloader can be uploaded to the newer version of the Nano. However, the process of doing so is not simple. With Windows XP SP3 installed on my laptop I was running Arduino IDE v0021. The process involves connecting an Arduino UNO R3 to the Arduino Nano v3.0 but first you have to communicate with both boards through the Arduino IDE v0021. This requires two different USB drivers. For Device Manager to recognise the UNO R3 I had to copy the "Drivers" folder from my Arduino IDE v1.8.19 installation on my Windows 7 computer to my Arduino IDE v0021 installation folder on my laptop. Inside that drivers folder is a file called "Old\_Arduino\_Drivers.zip". You need to expand that into the "Drivers" folder. In Device Manager with the Arduino UNO R3 plugged in you can now update the driver for the "Unknown USB" device by searching in the "Drivers" folder. On my computer it installed it as Arduino UNO R3 on COM7. It may be a different COM port on your computer. ***NOTE: FTDI and CH340 drivers will NOT work on Windows XP with the Arduino UNO R3.***

Now disconnect the Arduino UNO R3 and connect the Arduino Nano v3.0. Once again Device Manager should not recognise it. Search the "Drivers" folder once again and it should find a driver. However, this time it will use an FTDI driver to install the Nano. It showed up in Device Manager as USB Serial Port on COM5.

After both these drivers were successfully installed my Arduino IDE v0021 could communicate with both Arduino boards and it could upload sketches to the Arduino UNO R3 but not the Nano...yet. I connected the Arduino UNO R3 and uploaded, "ArduinoISP" from the menu File \>\> Examples.

I then unplugged the USB cable from the Arduino UNO R3 and physically connected wires between the UNO and the Nano (see the connection diagram here).

With both boards wired correctly, plug the USB cable back into the Arduino UNO R3. You should see LEDs light up on both boards. Open the Arduino IDE v0021 and from the Tools menu select "Arduino Duemilanove or Nano w/ ATmega328" as the board. ***NOTE: Do NOT select "Arduino Uno" even though it is the board connected to your computer. You are about to burn a new bootloader to the Nano not the Uno.*** Next select whatever serial port has been allocated to the device. In my case COM7 was allocated to the UNO. Now from the "Tools" menu select "Burn Bootloader \>\> w/ Arduino as ISP". This worked for me and I was finally able to upload sketches to the Arduino Nano v3.0 using the old version 0021 of the Arduino IDE on Windows XP.

---
Tags: arduino-ide, arduino-nano
---


# Question
Title: Seting up registers in Samd based arduino board
I'm trying to setup the BOD33 for Samd51 MCU in th .ino file as a first thing, even before the #include lines in the .ino

```
// Define the base address for t_SUPC
#define T_SUPC_BASE 0x40001800UL

// Define the offsets for t_BOD33 and t_STATUS
#define T_BOD33_OFFSET 0x10
#define T_STATUS_OFFSET 0x0C

// Set the t_SUPC register
volatile uint32_t *t_SUPC = (volatile uint32_t *)T_SUPC_BASE;

// Set the t_BOD33 register
volatile uint32_t *t_BOD33 = (volatile uint32_t *)(T_SUPC_BASE + T_BOD33_OFFSET);

// Set the t_STATUS register
volatile uint32_t *t_STATUS = (volatile uint32_t *)(T_SUPC_BASE + T_STATUS_OFFSET);

// Clear bit 1 in t_BOD33 and then set it to 1
*t_BOD33 &= ~(1u << 1); // Clear bit 1

// Check bit 0 in t_STATUS and loop while it is 0
while ((*t_STATUS & 0x01) == 0)
{
}

*t_BOD33 &= (0x7D0300u << 1);

*t_BOD33 |= (1u << 1); // Set bit 1 to 1
while ((*t_STATUS & 0x01) == 0)
{
}

while ((*t_STATUS & 0x02) != 0)
{
}

// Clear bit 1 in t_BOD33 and then set it to 1
*t_BOD33 &= ~(1u << 1); // Clear bit 1
while ((*t_STATUS & 0x01) == 0)
{
}
*t_BOD33 |= (1u << 2);
*t_BOD33 &= ~(1u << 3);
*t_BOD33 |= (1u << 1); // Set bit 1 to 1

```

but I'm getting a compile problem and VScode is throwing those error, which I have no clue why since I never encountered it before the errors are :

""

```
0_2.ino:28:10: error: expected constructor, destructor, or type conversion before '&=' token
   28 | *t_BOD33 &= ~(1u << 1); // Clear bit 1
      |          ^~
0_2.ino:31:1: error: expected unqualified-id before 'while'
   31 | while ((*t_STATUS & 0x01) == 0)
      | ^~~~~
0_2.ino:35:10: error: expected constructor, destructor, or type conversion before '&=' token
   35 | *t_BOD33 &= (0x7D0300u << 1);
      |          ^~
0_2.ino:37:10: error: expected constructor, destructor, or type conversion before '|=' token
   37 | *t_BOD33 |= (1u << 1); // Set bit 1 to 1
      |          ^~
0_2.ino:38:1: error: expected unqualified-id before 'while'
   38 | while ((*t_STATUS & 0x01) == 0)
      | ^~~~~
0_2.ino:42:1: error: expected unqualified-id before 'while'
   42 | while ((*t_STATUS & 0x02) != 0)
      | ^~~~~
0_2.ino:47:10: error: expected constructor, destructor, or type conversion before '&=' token
   47 | *t_BOD33 &= ~(1u << 1); // Clear bit 1
      |          ^~
0_2.ino:48:1: error: expected unqualified-id before 'while'
   48 | while ((*t_STATUS & 0x01) == 0)
      | ^~~~~
0_2.ino:51:10: error: expected constructor, destructor, or type conversion before '|=' token
   51 | *t_BOD33 |= (1u << 2);
      |          ^~
0_2.ino:52:10: error: expected constructor, destructor, or type conversion before '&=' token
   52 | *t_BOD33 &= ~(1u << 3);
      |          ^~
0_2.ino:53:10: error: expected constructor, destructor, or type conversion before '|=' token
   53 | *t_BOD33 |= (1u << 1); // Set bit 1 to 1
      |          ^~

```

thank you in advance.

# Answer
> 3 votes
The line where the error starts should go to a function e.g. `setup()`. You can compile the code below.

```
// Define the base address for t_SUPC
#define T_SUPC_BASE 0x40001800UL
// Define the offsets for t_BOD33 and t_STATUS
#define T_BOD33_OFFSET 0x10
#define T_STATUS_OFFSET 0x0C

// Set the t_SUPC register
volatile uint32_t *t_SUPC = (volatile uint32_t *)T_SUPC_BASE;
// Set the t_BOD33 register
volatile uint32_t *t_BOD33 = (volatile uint32_t *)(T_SUPC_BASE + T_BOD33_OFFSET);
// Set the t_STATUS register
volatile uint32_t *t_STATUS = (volatile uint32_t *)(T_SUPC_BASE + T_STATUS_OFFSET);

void setup()
{
    // Clear bit 1 in t_BOD33 and then set it to 1
    *t_BOD33 &= ~(1u << 1); // Clear bit 1

    // Check bit 0 in t_STATUS and loop while it is 0
    while ((*t_STATUS & 0x01) == 0)
    {
    }

    *t_BOD33 &= (0x7D0300u << 1);

    *t_BOD33 |= (1u << 1); // Set bit 1 to 1
    while ((*t_STATUS & 0x01) == 0)
    {
    }

    while ((*t_STATUS & 0x02) != 0)
    {
    }

    // Clear bit 1 in t_BOD33 and then set it to 1
    *t_BOD33 &= ~(1u << 1); // Clear bit 1
    while ((*t_STATUS & 0x01) == 0)
    {
    }
    *t_BOD33 |= (1u << 2);
    *t_BOD33 &= ~(1u << 3);
    *t_BOD33 |= (1u << 1); // Set bit 1 to 1
}

```

---
Tags: c++
---