# Question
Title: Need Digistump library for QWERTY keyboard and Fixes for my issues!
Hello there I am trying to install `Digistump` library to support ATTiny85 by digispark. But I am encountering a problem when trying to install Digistump AVR boards after adding an additional board URL preference as the library doesn't shows up after searching.I dont know what's the problem even after I tried from the fixes from other solutions across the web.

So, I made an alternative method to work the board by installing `ATTinyCore` library. But it doesn't support `DIGIKEYBOARD` actions. So when I try to download from library manager there is only packages for AZERTY & Belgian AZERTY layout.

So for me I need a package that support QWERTY layout. How to install the library.?

# Answer
The description of DigiKeyboardFr says it is “based on DigisparkKeyboard library”, and gives the link to that library. DigisparkKeyboard doesn't seem to be available from the Arduino library manager: you will most likely have to install it manually. Manual installation of Arduino libraries is widely documented.
> 1 votes

---
Tags: avr, attiny85, digispark, arduino-ide-2
---


# Question
Title: I want the Arduino to be in sleep mode by default and have a button wake it up
I saw a library called LowPower\_LowPowerLab that can set the Arduino in sleep mode. In their example they put the Arduino to sleep using an external button, is there anyway to invert this behavior? I want the Arduino to save battery power by being in sleep mode and then when I need it, hold a button down to keep the Arduino awake and then release the button to put it back to sleep. In their example below I have tried changing the attachInterrupt to HIGH/RISING/FALLING with no change. Also coul

LowPowerLab's Example:

```
#include "LowPower.h"

// Use pin 2 as wake up pin
const int wakeUpPin = 2;

void wakeUp()
{
    // Just a handler for the pin interrupt.
}

void setup()
{
    // Configure wake up pin as input.
    // This will consumes few uA of current.
    pinMode(wakeUpPin, INPUT);
}

void loop()
{
    // Allow wake up pin to trigger interrupt on low.
    attachInterrupt(0, wakeUp, LOW);

    // Enter power down state with ADC and BOD module disabled.
    // Wake up when wake up pin is low.
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

    // Disable external pin interrupt on wake up pin.
    detachInterrupt(0);

    // Do something here
    // Example: Read sensor, data logging, data transmission.
}

```

# Answer
> In their example they put the Arduino to sleep using an external button, is there anyway to invert this behavior?

Of course. Put the Arduino to sleep in `setup` and make the button wake it up.

Some tips here.

Also, I wouldn't use LOW, I would use FALLING. LOW keeps interrupting the processor, so while you hold the button down it keeps entering the interrupt, which would make it unresponsive.
> 2 votes

---
Tags: battery, sleep
---


# Question
Title: XH-M131 Photoresistor Relay Module NC position
I have purchased XH-M131 Photoresistor Relay Module to automatically light my outdoor yard at sunset and turn it off at sunrise. I'ts working as it is supposed to, However, if I power off the relay, the light goes off.

I want this to be a closed circuit in such way if the relay malfunction or loose power, the outdoor light stays on which I can manually switch off if I want to.

BTW, I tried connecting the light wires to the otherside, but the whole thing reversed, light goes on when light detected which defies the purpose. Any suggestion or modifications.

# Answer
> 1 votes
If you put an additional relay (Relay B) between the XH-M131 and the light and connect the light to the mains via the Normally Closed pole of Relay B, the light will be ON unless Relay B is activated or you turn off the light switch. Then, connect the coil of Relay B (instead of the light) to the "other side" as you say, of the XH-M131, the logic will be such that when the sensor is exposed to light (daytime) the XH-M131 turns on. That will activate Relay B, switching it from Closed to Open and turn the light OFF. If the XH-M131 fails, the light will be ON.

---
Tags: relay
---


title: PubSubClient hanging on ESP32C3

text:
# Question
Title: PubSubClient hanging on ESP32C3
I may have done some things incorrectly here, but this I what I have for publishing image that I read from serial camera to the MQTT broker:

```
void capturePicture() {
  if (!cam.takePicture())
    client.publish("info", "Failed to snap!");
  else
    client.publish("info", "Picture taken!");

  char length[21];
  uint32_t jpglen = cam.frameLength();

  sprintf(length, "buffer length: %d", jpglen);
  client.publish("info", length);

  byte wCount = 0;  // For counting # of writes
  client.publish("info", "transfer about to begin");
  client.beginPublish("picture", jpglen, false);
  client.publish("info", "after beginPublish");

  while (jpglen > 0) {
    uint8_t* buffer;
    uint8_t bytesToRead = min((uint32_t)16, jpglen);  // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);

    client.write(buffer, bytesToRead);

    jpglen -= bytesToRead;
  }

  client.endPublish();
  client.publish("info", "transfer should have ended;");
}

```

I know the board is working, I am connected to the broker and I can receive messages. In the `loop` I am reading few sensors and pushing the string into the topic

```
void loop() {
  delay(1000);

  if (count == 5) capturePicture();

  if (!client.connected()) {
    reconnect();
  }

  int multi = analogRead(A2);
  int odor = analogRead(A1);
  int voc = analogRead(A0);

  char name[21];
  sprintf(name, "%d;%d;%d", multi, odor, voc);

  bool pubScss = client.publish("measurement", name);

  count++;
  client.loop();
}

```

and all that works fine.

what happens when `capturePicture()` gets executed is this:

```
Picture taken!
buffer length: 49048
transfer about to begin

```

--that's what I see on the topic's subscriber side, then it freezes for about 10secs and then it continues with sending messages from the `loop`.

So it seems like it never gets past `client.beginPublish("picture", jpglen, false);` call. I'm setting PubSubClient's buffer size to `client.setBufferSize(10235);`

What can be happening here? Something I can further test??

Thanks for advices!

# Answer
> 0 votes
The short form of the below is something like: **"After calling `.beginPublish()`, call `.endPublish()` before making a call to either `.publish()` or `.beginPublish()`.**

---

We don't have your actual code. And that makes things difficult. However, this is **a** source of problems in what you have shown:

```
  client.beginPublish("picture", jpglen, false);
  client.publish("info", "after beginPublish");
  ...
  client.endPublish();

```

It kind of looks like you may intended the second publish to help you debug the initial problem. But again, we don't have your code. I don't know if this (or something just like it) is in your original. In any case, it's not doing you any good as a debug aid.

---

The `.beginPublish()`/\[`.write()`-type stuff\]/`.endPublish()` constructs a message in the MQTT protocol as you make these calls. **By inserting `.publish()` call between them you are corrupting the communication.** In short, you're embedding an MQTT message part way inside of another MQTT message.

Something a bit like saying

```
HowHello. are you today?

```

instead of

```
Hello. How are you today?

```

This is confusing something, probably the server. Perhaps also the library itself and any client that receives whatever the server ends up passing along.

---

I tested with a few variations on this code:

```
//#define CAUSE_TROUBLE

void one_shot_message() {
  client.publish(MQTT_TOPIC, "[hi]");
}

void do_test() {
  static const char part1[] = "<Hello";
  static const char part2[] = " World>";
  static const char both_parts_length = // just being very explicit
      (sizeof part1 - 1) // part1 sans null terminator
    + (sizeof part2 - 1);// part2 sans null terminator
                       // the .publish accepting strings doesn't null terminate, so we aren't.

#ifndef CAUSE_TROUBLE
  one_shot_message(); // okay before beginPublish or after endPublish
#endif

  client.beginPublish(MQTT_TOPIC, both_parts_length, false);
#ifdef CAUSE_TROUBLE
  one_shot_message(); // not okay between beginPublish/endPublish
#endif
  client.print(part1);
  // tested with one_shot_message() called here (not-okay location) as well
  client.print(part2);
  client.endPublish();
}

```

What happens in the case of `#define CAUSE_TROUBLE` (at the least with server I'm using and the client I've written on a PC) is that a single corrupt-looking message comes through and then the ESP32 client reconnects to the server. Probably the server is closing the connection. It does this on a cycle of about 6 seconds. The corrupt message has the correct topic, which makes *some* sense because the topic is written as part of the `.beginPublish()` before there's an opportunity to corrupt the message. This may not be exactly what you're seeing, but I don't have good cause to think I should be seeing exactly what you're seeing; not the same exact code, client, server. It is similar anyway.

---

So, you can have `client.publish("info", "before beginPublish");` or a `client.publish("info", "after endPublish");` at those locations, but not between the begin and end calls. If you wanted to try doing something like that, you probably could probably do so by creating a second `PubSubClient` so that you could fire off these smaller messages in a separate protocol stream while in the middle of constructing/sending a larger message on the main stream. However the messages may not arrive in order, either because the of how the library works or because of timing in the network. So if you want to do that you may also want to send a counter value with each message so you can reconstruct the timeline in the sending code.

An aside regarding `sprintf` vs `snprintf`:

```
  char name[21];
  snprintf(name, sizeof name, "%d;%d;%d", multi, odor, voc);

```

`sprintf()` is something that exists to support very old code or very old compilers. There's otherwise no use case involving `sprintf()` that would not be better using `snprintf()`

---
Tags: esp32, mqtt
---


title: MPU6500 via SPI

text:
# Question
Title: MPU6500 via SPI
I'm trying to communicate with an MPU6500 sensor via SPI as I need the fastest possible update rate. I have trouble finding an easy to understand sample code, or perhaps a lightweight library how to configure and initialize the sensor and read gyro / accelerometer data via SPI.

So far I started adapting the code and info found at https://playground.arduino.cc/Main/MPU-6050 thought it would be fairly easy to use SPI instead of I2C "Wire", and adapt the configuration and registers based on the datasheet, but I realized there's too many possible pitfalls.

Any recommendations?

# Answer
For anyone who has not yet figured this out, its very simple.

Basically, for SPI communication with the sensor MPU 6500, its a bit different from what I2C has to offer.

In I2C, basically you will find the data packet is as follows:

(7 bit Slave Address + Read/Write Bit), but in SPI it is as follows:

(Read/Write Bit + 7 Bit Register Address), notice we dont even need the slave address in SPI as the Chip Select is connected from processor(Master) to Sensor(Slave).

So for SPI, lets say you want to write a value 64 to register 0x6B, then: Transmission\_data\[2\]; Transmission\_data\[0\] = 0x6B; Transmission\_data\[1\] = 64;

Lets say you want to read a value from register 0x43, which is GYRO\_X\_High Byte value, then, Transmission\_data\[1\]; Transmission\_data\[0\] = 0x43 | 0x80; // you need to or it with 0x80(decimal = 128)

Thanks...Hope this helps someone in need of help for SPI as I struggled too in finding this information.
> 1 votes

---
Tags: imu
---


title: DS3231 RTC not working with ESP32

text:
# Question
Title: DS3231 RTC not working with ESP32
I am using ESP-32-WROOM-32 with a RTC DS3231 module. I have connected SDA & SCL pins of RTC DS3231 with ESP32 D22 and D23 pins. Also, the VCC of RTC is connected to 3V3 of ESP32 and the GND of RTC is also connected to GND of ESP32 .RTC module is having attached battery also.

Following is the code:

```
#include <Wire.h> // for I2C with RTC module
#include "RTClib.h" //to show time

RTC_DS3231 rtc;

void Scanner ()
{
  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;

  Wire.begin(22,23);
  for (byte i = 8; i < 120; i++)
  {
    Wire.beginTransmission (i);          // Begin I2C transmission Address (i)
    if (Wire.endTransmission () == 0)  // Receive 0 = success (ACK response)
    {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);     // PCF8574 7 bit address
      Serial.println (")");
      count++;
    }
  }
  Serial.print ("Found ");
  Serial.print (count, DEC);        // numbers of devices
  Serial.println (" device(s).");
}
void setup()
{
    // put your setup code here, to run once:
    Wire.begin(22,23);
    //Wire.begin();
    Serial.begin(115200);
         while(!Serial);

       ////////////////////////////////////

    ////////////////////////////////////////

    while (!rtc.begin())
    {
        Serial.println("Couldn't find RTC");
        Scanner();
        //Serial.println(DS3231_REG_STATUS);
        //        while (1)
        //        {
        //                  Serial.println("Couldn't find RTC");
        //
        //        }

        ;
    }
    Serial.println("Finally");
    // In setup function, we will call a function rtc.adjust(DateTime(__DATE__, __TIME__)) which will set the time according to our PC time.
    rtc.adjust(DateTime(__DATE__, __TIME__));
}
void loop()
{

    DateTime curr_time_obj = rtc.now();
    int day = curr_time_obj.day();
    int month = curr_time_obj.month();
    int year = curr_time_obj.year();
    int week_day = curr_time_obj.dayOfTheWeek();
    int sec = curr_time_obj.second();
    int hr = curr_time_obj.hour();
    int minute = curr_time_obj.minute();

    Serial.print("hour is ");
    Serial.println(hr);
    Serial.print("min is ");
    Serial.println(minute);
    Serial.print("secs is ");
    Serial.println(sec);
    Serial.println("############################");
    delay(5000);
}

```

Following is the output:

Some of the images of the circuit can be found here: https://drive.google.com/drive/folders/1fhM7o\_aZCGh88OBDcypVLqhKhizhXnNd?usp=sharing

I would appreciate any help to resolve this issue. Thanks

# Answer
> 0 votes
Warning

These modules normally come with a 200Ω resistor soldered next to the IN4148 Zener diode, as you can see in the image below.

ds3231 module problem fix The resistor and diode form a simple charging circuit designed for use with LIR2032 rechargeable batteries.

Be aware that some DS3231 modules come with a non-rechargeable CR2032 battery. If this is the case, you must remove the resistor because attempting to charge a non-rechargeable battery can cause serious damage.

> Blockquote

---
Tags: i2c, esp32, rtc
---


title: Wire.h not found!

text:
# Question
Title: Wire.h not found!
Here's the code that's making this error:

```
#include "Wire.h"

```

Here's the error:

```
fatal error: Wire.h: No such file or directory
 #include "Wire.h"
                  ^
compilation terminated.
Error compiling.

```

I also can't include any file from my `Arduino\libraries` folder. I tried to reinstall the IDE several times in different places and nothing happened. Why is this happening?

EDIT: after some time I discovered that this error occurs in header files only, not in sketches!

# Answer
> 4 votes
Use `#include <Wire.h>`

Including files in double quotes (") will point to headers in current working directory first.

Edit: ... and there is nothing wrong with copying headers to CWD if you are modifying them, but that's probably not what you want.

# Answer
> 0 votes
First go to your library folder and check whether u included that Wire.h header file or not.If not then first include that file then problem will get solved automatically.

# Answer
> 0 votes
I had a similar issue and found this question. However, the solution for me is different.

I already had `#include <Wire.h>`, nevertheless the compiler told me it's missing. It turned out, I had selected a wrong board from a previous project. Needed to change to "Arduino Uno".

# Answer
> 0 votes
I copy here the answer from https://forum.arduino.cc/t/wire-h-no-such-file-or-directory-solved/297761, cause it worked for me:

> It's not enough to put "#include \<Wire.h\>" in the source file you are using the library in. It seems you must also put "#include \<Wire.h\>" in the main \*.ino file for the sketch as well, before it can be used in any other source code files.

---
Tags: arduino-ide, library, wire-library, core-libraries
---


# Question
Title: Connect to wifi works only without password (Problem around WPA security)
I have an ESP32 Joy-it - SBC NodeMCU-ESP32 that should be use with board "ESP32 Dev Module". IDE says : Chip is ESP32-D0WDQ6 (revision v1.0).

Website product: https://joy-it.net/en/products/SBC-NodeMCU-ESP32

When I make a wifi scan, I find my AP, but if I connect with SSID + Password (both WPA (Internet box router - Freebox Crystal France) and WPA2 Personal (Xiaomi A2 Lite)), it doesn't work.

So I tried to make an AP without password on my phone, and ESP32 can connect without problem.

To do that, I used the default sketch "Wifi -\> Wifi Client". My SSID and my password contain only letters/numbers (Only ASCII chars).

I tried to burn the bootloader, but nothing change.

I am using :

* IDE Arduino 2.2.1
* esp32 by espressif 2.0.14

Does somebody have an idea ?

# Answer
> 1 votes
Solution, I'm using an old Freebox, which has only Open or WPA security,

Just add : `WiFi.setMinSecurity(WIFI_AUTH_WPA_PSK);` to allow connection to my router.

For people with *WEP* security, just use `WIFI_AUTH_WEP`

---
Tags: esp32, wifi
---


# Question
Title: Arduino read thermocouple Type K with ADS1115
I ordered a ADS1115 so I could measure temperature of a type K thermocouple, but I am not managing to get accurate readings. I had it working while having a normal A0 pin, but since the type K table shows pretty low voltages, the 0-1023 scale is not accurate.

When the thermocouple is at room temperature (around 22°c), it shows 00.0 millivolts on the multimeter (which I dont understand since it does not match with the table), and my program outputs a value of around -40 and a voltage of -0.005. When I heat it up until I measure 10.0 millivolts (around 250°c according table), the Arduino prints a value of 53 and a millivolts of 300.

What am I doing wrong? I suspect something with the calculation, but I am not able to find out how I should do it, I know very little about millivolts.

Can someone help me out what I am doing wrong here and what I should do?

I have the thermocouple and ADS1115 connected as shown in the image below.

The code I am using is as following

```
#include <Adafruit_ADS1X15.h>

const int analogFruitPin = 0;

Adafruit_ADS1115 ads;

void setup()
{
  Serial.begin(9600);
  ads.begin();
  ads.setGain(GAIN_FOUR);
  ads.setDataRate(RATE_ADS1115_860SPS);
}

void loop()
{
  int sensorValue = ads.readADC_SingleEnded(analogFruitPin);
  float voltage = sensorValue * (5.0 / 32768.0);
  Serial.println(voltage,3);
  Serial.println(sensorValue);
  delay(500);
}

```

# Answer
Welcome! Interesting but expected. Thermocouples need what is called a cold junction compensation. That is a circuit or another thermonuclear that compensates for the thermocouple effect where the lead wires are connected to your measuring device. These thermocouple lead wires should be the same metallic material as the wires in the thermocouple. The metals are different where you connect to the measuring device and will generate a voltage as the temperature changes regardless of the sensing probe, that is how the thermocouple works. This link will help: https://www.tegam.com/what-exactly-is-cold-junction-compensation/

For more information check this link: https://randomnerdtutorials.com/arduino-k-type-thermocouple-max6675/
> 0 votes

# Answer
To simplify your thermocouple temperature sensor project, consider using an ADC which also contains a cold junction temperature sensor. This product from Adafuit.com integrates both into one package by using a Microchip.com MCP9601 integrated circuit.

In short, thermocouples generate small amounts of voltage where dissimilar metals touch. This is true where the thermocouple wires are touching each other. And is also true where the thermocuple wires are touching the metal connecting them to the ADC circuit (commonly called the "cold junction"). To find the temperature where the thermocouple wires are touching we need to subtract the effects of the "cold junction". To do that, we need to first know the temperature of the "cold junction". We commonly do this with a second temperature sensor as it is a more practical (and portable) solution than a traditional zero centigrade ice bath (likely where the term "cold junction" came from).
> 0 votes

---
Tags: arduino-nano, temperature-sensor, voltage
---


# Question
Title: Unable to find/connect I2C devices (SHT31 & SGP30)
I have recently purchased an Arduino Nano 33 IOT together with two sensors:

However, so far I have not succeeded in reaching any of these two sensors. For example I connect the SHT31 sensor like this:

* +3.3V to Vin
* GND to GND
* A4 to SDA
* A5 to SCL

I have tried the default Adafruit SHT31-D example without success, the program appears to hang. I have tried a standard I2C scanner but it does not find any devices with the sensor connected. When the sensor is disconnected, it does find two devices (the IMU and something else I guess).

I believe there is something funky going on with the I2C connection of the internal sensors and the external ones but I have no idea how to troubleshoot this issue. I read some stuff about TwoWire (extern TwoWire Wire1; after the #include) but I am having a hard time figuring out if this is what I need and how to implement it.

I found these topics myself:

https://forum.arduino.cc/index.php?topic=639188.0

https://forum.arduino.cc/index.php?topic=658967.0

edit: I haven't had success dealing with these issues so far and I am still looking for some help with my problems!

# Answer
I had a similar problem, but the fix turned out to be simple. All the tutorials for SHT3x sensors say to connect the VIN to the 3.3V GPIO. I checked using a test meter, the SHT3x was getting voltage but numerous SH3x libraries didn't seem to work, and a couple of I2C sketches also found nothing. So I tried moving the VIN lead to the 5V GPIO pin - it works perfectly. Perhaps my USB connection lacks enough power, or perhaps my SHT3x needs 5V. Either way it works - happy now !
> 2 votes

# Answer
one can code an I2C sensor (I'm using a SHT31) using custom GPIO ports like so:

```
//I2C Bus Pins
#define SDA 8
#define SCL 9

#include "Adafruit_SHT31.h"
TwoWire I2Cbus = TwoWire(0);
Adafruit_SHT31 sht31 = Adafruit_SHT31(&I2Cbus);

void setup(){
  Serial.begin(115200);            // USB communication with Serial Monitor
  Serial.print("Starting serial...");

  Serial.print("Starting SHT31...");
  startSHT();
}

 // ********************************************************
 void startSHT(){
  I2Cbus.begin(SDA, SCL, 100000ul);
  if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
     Serial.println("Couldn't find SHT31");
while (1)
delay(1);
  }
}

```
> 1 votes

# Answer
Without a schematic I will take a SWAG" For I2C to work it needs a pull up resistor for SCL another for SDA. Both are open drain/collector outputs neither of which can drive a + (logic 1) on the bus.
> 0 votes

---
Tags: sensors, arduino-nano, i2c, wire-library, iot
---


# Question
Title: 6v High Torque Servo Won't Function On Motor Shield?
I have only ever been able to get this servo to “somewhat” work when connected to 5v pin on the shield, the ground on the shield, and the signal line attached to whatever pin. But 5v is not enough and 9v is too much. I'm trying a million different ways to power this thing, but I don't understand why I give it an appropriate voltage from X source (while still having the signal line connected of course), and it doesn't want to move at all.

So currently my Arduino is powered via USB. The shield/motor is powered from a 12v 2a power supply, which with a simple voltage divider circuit gets me 6.29V. Multimeter seems to show this works. Also the “Vin Connect” jumper on back was cut to make the screw terminals a dedicated power line for the motor, per Arduino website. I tried this set up without cutting the jumper too, same - no result.

Can anyone help me out? All I want to do is power my arduino with shield, and motor, however that has to happen, and be able to run the "Servo Sweep" example code.

https://docs.arduino.cc/hardware/motor-shield-rev3

https://www.amazon.com/ANNIMOS-Digital-Voltage-Stainless-Waterproof/dp/B07KTSCN4J

# Answer
> 0 votes
It may pay to think about current required as well as voltage. Looking at a data sheet I found online (data sheet link) it refers to a stall current of 3.5A when running at 6V.

What do you mean by “somewhat”? Can you give more detail on the behavior you see? It may be useful to hook your multimeter up as an ammeter to get an idea of whether current draw is approaching the limit of the wall plug (2A) used.

---
Tags: arduino-uno, power, servo, arduino-motor-shield, voltage
---


# Question
Title: Feather M0 doesn't show up as a COM or Serial port
I am trying to upload a simple blink program on my Adafruit Feather M0 Radio with LoRa Radio Module to ensure that it connects to my PC. So far, I have:

* Gone through 4 data cables
* Tested for connection on 3 different devices (laptop on Windows 11, desktop on Windows 10, and computer running CentOS respectively)
* Followed the direction for using the board with the IDE here and here

But the Port submenu is greyed out and when it isn't, it just doesn't have the port that recognizes my Feather. When going into Device Manager, I can't see it in the list of devices even when I refresh.

# Answer
Turns out the bootloader/USB firmware wasn't loaded in, which is why the double-tap reset wasn't working. I looked into the option of using another board as a programmer to get the bootloader in my Feather, but it proved to be more of a hassle than I thought so I'm just going to get a replacement. Hope this helps someone out in the future.
> 1 votes

---
Tags: arduino-ide, feather
---


# Question
Title: RFM69HCW connected to Arduino Nano 33 BLE
I tried to connect my RFM69HCW to Arduino Nano 33 BLE, so that I won't be needing a logic level shifter to downgrade the voltage, since Arduino Nano is already 3.3V. Upon checking its data sheet and pinout, I noticed there's no dedicated pin for CS (Chip Select).

Which pin should I use as CS in the Arduino Nano?

Which pin should I connect the DI0 pin of RFM69HCW in the Arduino Nano?

# Answer
> 0 votes
On any Arduino you can use any free digital pin as SPI CS.

# Answer
> 0 votes
There is no dedicated CS pin, and you can use any available Dx pin – which enables you, among other things, to have several devices on the same bus. The CS pin allows you to select (hence the S) the right device.

---
Tags: arduino-nano-ble, lora
---


# Question
Title: Alternative to polling interrupt flag from main loop?
I am using an ISR, which is written to be as minimal as possible:

```
volatile bool interrupt1{};

void ISR1() {
    interrupt1 = true;
}

```

The interrupt is handled by polling the interrupt1 variable in `loop()`:

```
if (interrupt1 == true) {

// Do stuff

interrupt1 = false;
}

```

Even though the interrupt signal coming in on the gpio isn't polled, the method described above is instead polling the interrupt variable from `loop()`.

As an alternative to the above, is it possible to use some kind of push logic on the software side whenever an interrupt occurs, instead of continuously polling the interrupt variable? I hesitate to handle the full task from the ISR, as it's performing a lot of things.

What are my options here?

# Answer
If the task is pretty short and time sensitive, your best option is to put it in the interrupt handler.

If the task is big and not too urgent (like: it could well wait for a millisecond or so), your approach of polling the flag within `loop()` is the best one, provided the main program is non-blocking.

If the task is both big and urgent... you may have a difficult problem. You could try both approaches and see which one works best. Or you may try to split the task into a top half (short and urgent) and a bottom half (long but not so urgent). The interrupt handler would then perform the top half and set a flag, whereas the main loop would poll the flag and perform the bottom half.

**Edit**: for a short discussion on the top half / bottom half approach, see the first paragraphs of this article on Linux kernel development.
> 10 votes

# Answer
Since you tagged it Teensy: You could also reduce the priority of the interrupt, so that it can be interrupted by higher priority interrupts. Thus you can implement interrupts with longer durations without blocking important system functions.

Here is an example using the GPT1 and GPT2 timers running at different priorities:

```
#include "Arduino.h"
#include "TeensyTimerTool.h"

using namespace TeensyTimerTool;

PeriodicTimer loPrioTimer(GPT1);
PeriodicTimer hiPrioTimer(GPT2);

void onLowPrioTimer() // some long task running from interrupt with low prio
{
    Serial.printf("  Start low prio isr @t=%d ms\n", millis());

    for (int i = 0; i < 10; i++)
    {
        Serial.printf("    lowPriority task %d\n",i);
        delay(10);
    }

    Serial.println("  Stop low prio isr");
}

void onHiPrioTimer() // high prio, will interrupt the low prio isr
{
    Serial.printf("high priority @t=%d ms\n", millis());
}

void setup()
{
    while (!Serial) {}

    loPrioTimer.begin(onLowPrioTimer, 500ms); // GPT1
    hiPrioTimer.begin(onHiPrioTimer, 50ms);   // GPT2

    NVIC_SET_PRIORITY(IRQ_GPT1, 128); // lowest prio
    NVIC_SET_PRIORITY(IRQ_GPT2, 16);  // high prio
}

void loop()
{
}

```

which prints:

```
high priority @t=1057 ms
high priority @t=1107 ms
high priority @t=1157 ms
high priority @t=1207 ms
high priority @t=1257 ms
high priority @t=1307 ms
high priority @t=1357 ms
high priority @t=1407 ms
high priority @t=1457 ms
high priority @t=1507 ms
  Start low prio isr @t=1507 ms
    lowPriority task 0
    lowPriority task 1
    lowPriority task 2
    lowPriority task 3
    lowPriority task 4
high priority @t=1557 ms
    lowPriority task 5
    lowPriority task 6
    lowPriority task 7
    lowPriority task 8
    lowPriority task 9
high priority @t=1607 ms
  Stop low prio isr
high priority @t=1657 ms
high priority @t=1707 ms
high priority @t=1757 ms
high priority @t=1807 ms
high priority @t=1857 ms
high priority @t=1907 ms
high priority @t=1957 ms
high priority @t=2007 ms
  Start low prio isr @t=2007 ms
    lowPriority task 0
    lowPriority task 1
    lowPriority task 2
    lowPriority task 3
    lowPriority task 4
high priority @t=2057 ms
    lowPriority task 5
    lowPriority task 6
    lowPriority task 7
    lowPriority task 8
    lowPriority task 9
high priority @t=2107 ms
  Stop low prio isr
high priority @t=2157 ms
high priority @t=2207 ms
high priority @t=2257 ms
high priority @t=2307 ms

```

This shows that the high priority timer (running at 50 ms interval) intercepts the low priority ISR which runs every 500 ms for about 100 ms.
> 3 votes

---
Tags: c++, interrupt, teensy
---


# Question
Title: Why is my variable giving the wrong value?
I'm making a program to show numbers in a WS2812 LED and TM1637. I'm also using a common 4x4 keypad.

The WS2812 LED is just DIY with 25 x 10. Only two values can be displayed in a LED matrix just now. Without the LED part of the program, just the TM1637 and keypad connected to the Arduino, everything is fine. But adding the LED part of the program, I found out that entering 2 on keypad puts an erroneous value in my variable (-256 to exact). I tried debugging my code and found out that replacing the last iteration

`for (int i = 225; i <= 231; i++) {`

with this line

`for (int i = 225; i <= 230; i++) {`

mysteriously solved my problem. Any thoughts why this is happening?

```
#include <Keypad.h>
#include <Arduino.h>
#include <TM1637Display.h>
#include <Wire.h>
#include <FastLED.h>
// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3
#define NUM_LEDS  225
#define LED_PIN   12
CRGB leds[NUM_LEDS];
TM1637Display display(CLK, DIO);
int DisplayNos=0;
int KeyNum;
char key;
boolean NewKey = false;
boolean DeleteAll=false;
int SavedNum;
// for 3 digits
int ExtractDigit[3] = {0, 0, 0};
byte DigitPoint= 1;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {11, 10, 9, 8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad
//Create an object of keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
  Serial.begin(9600);
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(250);
}
void loop(){
int k;
//  uint8_t data[] = { 0x0, 0x0, 0x0, 0x0 };
//  uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 };
  display.setBrightness(0x0f);
  key = keypad.getKey();// Read the key
  // Print if key pressed
  if (key){
    Serial.print("Key Pressed : ");
    Serial.println(key);
    if (isDigit(key)){
      KeyNum = key-48;
      Serial.println(key);
      Serial.println(DisplayNos);
      if (DigitPoint==1){
        DisplayNos = 0;
        DisplayNos = KeyNum;
      }
      if (DigitPoint==2){
        DisplayNos = KeyNum + (DisplayNos*10);
      }
      if (DigitPoint==3){
        DisplayNos = KeyNum + (DisplayNos*10);
      }
      DigitPoint= DigitPoint+1;
      if (DigitPoint==4){
        DigitPoint=1;
      }
    }
      if (key=='*'){   // asterist key cancels all char
      DisplayNos = 0;
      DigitPoint = 1;
    }
    if (key=='#'){   // asterisk key cancels all chars

    }
    NewKey = true;
  }
  display.showNumberDec(DisplayNos,false,3,0);
  if (NewKey == true){
    DisplayLED();
    FastLED.show();
  }
}
void DisplayLED(){
int LedNum;
byte digitnos;
NewKey = false;
  ExtractDigit[3] = (DisplayNos/100)%10;
  ExtractDigit[2] = (DisplayNos/10)%10;
  ExtractDigit[1] = (DisplayNos)%10;
  for (int digitnos= 1; digitnos <= 3; digitnos++) {
    LedNum = (digitnos-1)*9;
    if (ExtractDigit[digitnos] == 1){
      leds[21-LedNum]= CRGB::Blue;
      leds[28+LedNum]= CRGB::Blue;
      leds[29+LedNum]= CRGB::Blue;
      leds[71-LedNum]= CRGB::Blue;
      leds[78+LedNum]= CRGB::Blue;
      leds[121-LedNum]= CRGB::Blue;
      leds[128+LedNum]= CRGB::Blue;
      leds[171-LedNum]= CRGB::Blue;
      leds[178+LedNum]= CRGB::Blue;
      leds[221-LedNum]= CRGB::Blue;
      leds[229+LedNum]= CRGB::Blue;
      leds[228+LedNum]= CRGB::Blue;
      leds[227+LedNum]= CRGB::Blue;
    }
    if (ExtractDigit[digitnos] == 2){
      for (int i = 20; i <= 22; i++) {
        leds[i-LedNum] = CRGB::Blue;
      }
      leds[26+LedNum]= CRGB::Blue;
      leds[30+LedNum]= CRGB::Blue;
      leds[68-LedNum]= CRGB::Blue;
      leds[74-LedNum]= CRGB::Blue;
      leds[76+LedNum]= CRGB::Blue;
      leds[122-LedNum]= CRGB::Blue;
      leds[128+LedNum]= CRGB::Blue;
      leds[170-LedNum]= CRGB::Blue;
      leds[180+LedNum]= CRGB::Blue;
      leds[218-LedNum]= CRGB::Blue;
      leds[225+LedNum]= CRGB::Blue;
      leds[226+LedNum]= CRGB::Blue;
      leds[227+LedNum]= CRGB::Blue;
      leds[228+LedNum]= CRGB::Blue;
      leds[229+LedNum]= CRGB::Blue;
      for (int i = 225; i <= 231; i++) {
        leds[i-LedNum] = CRGB::Blue;
      }
    }
  }
  }

```

# Answer
> 2 votes
```
#define NUM_LEDS  225
...
CRGB leds[NUM_LEDS];
...
  leds[225 + LedNum] = CRGB::Blue;
  leds[226 + LedNum] = CRGB::Blue;
  leds[227 + LedNum] = CRGB::Blue;
  leds[228 + LedNum] = CRGB::Blue;
  leds[229 + LedNum] = CRGB::Blue;

```

Your RGB matrix has 225 LEDs, but you're writing to RAM out of range and destroying their stored data and/or variables.

---
Tags: ws2812, keypad
---


title: Change USB VID and PID (Leonardo)

text:
# Question
Title: Change USB VID and PID (Leonardo)
I'm new to using electronic boards, and have followed a guide online for printing a 6 DoF (degree of freedom) mouse. I'm stuck on an optional step that requires me to change the PID and VID of a "Arduino Leonardo" board.

I've located the appropriate "boards.txt" file, but I'm not sure which line to change. I've edited a few, but I'm worried I'll mess things up (a tutorial for it mentions they had destroyed 3 trying to rename it, and is back from 2009), and the ones I've changed do not result in a change.

I have checked out previous questions people have made regarding this topic, but quite frankly I can't understand the technical terms used in those.

This is the code in question I'm trying to compile, and lists example PID and VIDs as well.

I would love a clear explanation on which PID/VID I need to edit in the "boards.txt", so I can safely modify the board to be read as the space mouse in the code.

# Answer
> C:\Users\\%USERNAME%\AppData\Local\Arduino15\packages\arduino\hardware\avr

```
leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341     <--- here
leonardo.build.pid=0x8036
leonardo.build.usb_product="Arduino Leonardo"

```

---

```
leonardo.build.vid=0x256f
leonardo.build.pid=0xc631
leonardo.build.usb_product="SpaceMouse Pro Wireless (cabled)"

```
> 2 votes

---
Tags: usb, arduino-leonardo
---


# Question
Title: Arduino Nano Every USB Connection not working
I have two original (designed and assembled in Italy) Arduino Nano Every Boards from a German Web Shop. They came sealed in original packaging. When I try to connect them to my PC, they don't power up.

What I've tried so far:

* 6 different USB cables
* 1 Desktop PC with Arch Linux as well as Windows 10, all USB Ports available (front headers, back side motherboard)
* 1 Laptop PC with Arch Linux
* 1 Google Pixel 4 XL using a USB-B to -C adapter

No combination of the USB cables with any of the aforementioned USB Ports / Machines / Operating Systems allow the Arduino Nano Every Boards to boot up (no LEDs flashing).

I tried powering the boards using a 9V battery block on the V\_in and GND pins, which works. I also tried powering the boards using a 9V battery block and then connecting the USB, but the aforementioned machines / operating systems do not recognize a new device connected via USB, despite the boards being powered (LEDs flashing).

I also triple-checked the physical connection of the USB cables on both ends to be sure they are inserted properly. I can use the aforementioned USB cables, USB ports, machines, and operating systems to charge other devices or transfer data with other devices (like, e.g., smartphones, e-book readers, USB flash memory sticks, external hard drives, ...).

What should I try next to get the Arduino Nano Every working?

Please let me know which extra information I should provide. Thanks!

Note: As far as I can see, using `lsusb` on Linux should always list connected USB devices, regardless of the groups my user's in. Nevertheless, I also loaded the `cdc_acm` module and added `SUBSYSTEMS=="usb-serial", TAG+="uaccess"` to a udev rule located at `/etc/udev/rules.d/01-ttyusb.rules`, and reloaded the udev rules, to no avail.

# Answer
I've ordered an Arduino Nano (not "Every") from a different web shop now, and it powers up as soon as I connect to USB. Since the Arduino Nano uses mini-USB (the Arduino Nano Every uses micro-USB), I'm using a different cable from the ones I tried on the two Arduino Nano Every boards I have. But given that I tried multiple cables that also work with other devices, I'm confident now that the two boards I have are just broken. I've had bad luck.
> -1 votes

# Answer
These types of questions often requires considerable trouble shooting until the cause is found. In order to make this useful to as many people as possible, let us compile a list of actions. *(Add a comment if any have additional actions to try and I'll add them to the list.)*

* "...powering the boards using a 9V battery block on the V\_in and GND pins..."

Confirm the 9V supply is connected to VIN. An internal voltage regulator will then provide the necessary 5V and 3V3 to the rest of the Nano-Every. Consider if 9V was accidentally connected to either the 5V or 3V3 pins, parts of the Nano-Every my be damaged.

* "using lsusb on Linux should always list connected USB devices"

Yes, it should. If "lsusb" is typed before and after plugging in the Nano Every there should be an additional USB device listed. If there is no change, there may be something physically wrong (bad cable or incorrect cable (i.e. charging only), bad Nano or burnt out part).

Also, "lsusb" normally does not require root privileges. But consider trying "sudo lsubs" to confirm all USB devices are seen.

Here is an example output of "lsusb" run when an Nano-Every was connected to a Ubuntu computer:

```
$ lsusb
...
Bus 001 Device 004: ID 2341:0058 Arduino SA Arduino Nano Every

```
* "I also loaded the cdc\_acm module ..."

Inspecting a Ubuntu system that can successfully program a Nano-Every, I see no package with the words cdc\_acm in it installed.

*(I'm going to have to look into the above. While Ubuntu's package manager does manage cdc-acm.ko, cdc-acm.ko exists.)*

* "...and added SUBSYSTEMS=="usb-serial", TAG+="uaccess" to a udev rule located at /etc/udev/rules.d/01-ttyusb.rules"

Be aware that adding a udev rule with a low value such as "01\*" is likely to be obscured by any udev rule with a higher number should a match be found. Most developers add udev rules which start with a high number such as "99\*" to mitigate this problem.

This said, it is unlikely a modification to udev rules is necessary. Most if not all Linux distributions will handle a USB/CDC type of peripheral adequately with out modifications. Plugging in a Nano-Every into the above mentioned Ubuntu computer generates a new device at /dev/ttyACM0.

* "I tried powering the boards using a 9V battery"

Avoid using PP3 type 9 Volt batteries. They can be problematic when their lower current capacity has been reached. At which point their output voltage may drop. Leading to unexpected results. If such a battery is necessary, pay close attention to current needs adding up all the expected maximum currents. In brief, lower powered processor on Arduino boards built using an LDO (Low DropOut regulator) have the best chance of working as expected. Other Arduino boards may not work as well and high current components such as a motor, solenoid or relay will likely not work.
> 0 votes

# Answer
It's some regression in linux core and 1200baud touch doesn't work properly (it seems it's used switching between updi mode and serial link).

I started using script mentioned in https://github.com/arduino/ArduinoCore-megaavr/issues/124 and i was able to upload it in most cases (but better than mostly failing) when I execute it few seconds before the upload.

For example curiosity nano board with Atmega4809 works perfectly as it's emulating debugger+serial+mass storage (but needs correct VID/PID in udev rules or connecting storage)

Mentioned script:

```
#!/usr/bin/python3
#   Run this script to reset the Arduino Nano Every
#   eg. sudo python3 mcu_reset.py
#
# Note: You must install pyserial first; i.e. sudo pip3 pyserial

import serial
import os, sys
# total arguments
n = len(sys.argv)
if n >= 2:
    port = sys.argv[1]
else:
    port = '/dev/ttyACM0'

print("Port: {}".format(port))

#re-enable hupcl temporarily (necessary for arduino reset using serial port)
os.system('sudo /bin/stty -F {} hupcl'.format(port))

try:
    #perform Arduino Nano Every reset "handshake"
    ser = serial.Serial()
    ser.baudrate = 1200
    ser.port = port
    ser.open()
    ser.close()

except serial.SerialException:
    print("Error: serial.SerialException")
    exit()

```
> 0 votes

---
Tags: arduino-nano, usb, arduino-nano-every
---


# Question
Title: Servo starts spinning 360 degrees after a few minutes
I'm using my ESP8266 as a web server to tilt a camera with the servo Tower Pro Micro Servo 9G.

```
#include <Servo.h>
#include <ESP8266WiFi.h>

const char* ssid     = "SSID";
const char* password = "password";

Servo tilt;

WiFiServer server(8082);

void setup() {
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  server.begin();
  Serial.println("Server started");
  tilt.attach(2);
  tilt.write(100);
}

void loop() {
  WiFiClient client = server.available();
  if (!client)
  {
    return;
  }
  Serial.println("Waiting for new client");
  while(!client.available())
  {
    delay(1);
  }
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

  int value = LOW;

  if(request.indexOf("/SERVO=UP") != -1){
        int t = tilt.read();
        if(t <= 125) {
          delay(10);
          tilt.write(t+8);
        }
  }
  if(request.indexOf("/SERVO=DOWN") != -1){
        int t1 = tilt.read();
        if(t1 >= 75) {
          delay(10);
          tilt.write(t1-8);
        }
    }

  client.println("HTTP/1.1 200 OK"); //
  client.println("Content-Type: text/html");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.print(" CONTROL Servo: ");

  if(value == HIGH)
  {
    client.print("ON");
  }
  else
  {
    client.print("OFF");
  }
  client.println("<br><br>");
  client.println("<a href=\"/SERVO=UP\"\"><button>ON</button></a>");
  client.println("<a href=\"/SERVO=DOWN\"\"><button>OFF</button></a><br />");
  client.println("</html>");
  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
}

```

The first minutes it works fine but after a few minutes it starts turning 360° nonstop. Although, you can't turn this servo over 180°?! Does anyone of you know what is going on here? Thanks!

# Answer
> 0 votes
If it works and then doesn't, it makes this seem like a mechanical issue.

To check, write a simple program that just moves the servo around. Leave out all the extra web code. Wait to see if starts behaving erratically and you can save yourself the headache of hunting issues in your code that don't exist.

---
Tags: esp8266, servo
---


title: Sweeping servo 90 degrees

text:
# Question
Title: Sweeping servo 90 degrees
```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

```

I have found this code that makes servo go 180 and back, but when I switch 180 degrees with 90, which is what I need, my servo doesn't do that (I tried the code in Arduino simulator).

Do I have to change something elese in the code (like delay time) so it whould go 90 degrees up and then 90 down?

Here is the link of circuit:

https://circuits.io/circuits/3597808-servo-90-degrees

# Answer
> 2 votes
No you **don't have to change any time delay** in order to get it rotating by 90 degrees, **delay would just change the speed** of rotation of the servo. The simulator you are using is at fault here as the sketch with **180 changed to 90** works flawlessly.

```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop()
{
  for(pos = 0; pos < 90; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 90; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

```

MAKE SURE THAT YOU CHANGE **BOTH OF THE 180'S TO 90**.

# Answer
> 2 votes
I just created a simulation on Wokwi Arduino simulator based on your code and it works perfectly fine. Here is the **permanent** link

# Answer
> 0 votes
This line of code will properly set up the PWM timers to output the correct signal to move the servo to the value set in 'pos'

```
myservo.write(pos);

```

It has nothing do with speed. The servo will try to reach 'pos' as fast as possible.

The delay(15) in your code is the delay time between each "myservo.write(pos);"

The for loop works like this:

```
myservo.write(0); // Go to 0 degrees
delay(15); // Wait 15ms
myservo.write(1); // Go to 1 degrees
delay(15); // Wait 15ms
myservo.write(2); // Go to 2 degrees
delay(15); // Wait 15ms
myservo.write(3); // Go to 3 degrees
delay(15); // Wait 15ms

```

etc...

The time in seconds it takes to make a rotation is (range\_in\_degrees x 15)/1000

e.g. 180deg x 15ms/1000 = 2.7 seconds 90deg x 15ms/1000 = 1.35 seconds

Increasing the 15ms delay will make the servo rotate slower.

Also, make sure that you change the 180 degrees to 90 in BOTH for loops. If you change the value in one, the servo will slowly sweep from 0 to 90, then jump to 180 and slowly swing back to 0 and repeat. (or vice versa, depending on which one you forgot to change)

---
Tags: servo
---


# Question
Title: Some of my <include> statements do not work
I'm trying to include the thing...

```
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLEServer* pServer = NULL;

void setup() {
  // put your setup code here, to run once:

}

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

}

```

But it simply doesn't see what's inside the .h files:

```
C:\Users\void\AppData\Local\Temp\.arduinoIDE-unsaved20231028-7016-1na7gr9.y1do\sketch_nov28b\sketch_nov28b.ino:6:1: error: 'BLEServer' does not name a type; did you mean 'Server'?
 BLEServer* pServer = NULL;                        // Pointer to the server
 ^~~~~~~~~
 Server

```

May it be, I bought the wrong board? I've set it as lolin s2 mini.

# Answer
> 1 votes
Many of the ESP32 variants have Bluetooth/BLE support. The ESP32-S2 board/module you're trying to use does not. The module has WiFi, but not Bluetooth.

So you need another board, Lolin seems to have an -S3 version of your board. But many other boards would work.

The majority of the `<BLEServer.h>` header's contents are conditionally compiled based on whether or not `CONFIG_BLUEDROID_ENABLED` is `#define`d.

And this only done for modules that have support for Bluetooth. The Lolin S3 version of the Mini would have Bluetooth support and in the configuration file it would use you can see it defined. In the one for the S2 board you are trying to use it is missing.

In effect, although you're including the header, it is as though it were blank. So no definition of the `BLEServer` type. It would have been nice if they'd handled this a different way, but this is not uncommon.

---
Tags: esp32, compilation-errors, board
---


# Question
Title: L298n driver with Arduino with 2 motors won't work
I connected the 12v power supply with 9v battery. The problem is that when i run 1 motor at time from any side (out 1, 2 out 3, 4) it works perfectly, but when I try to run both of them, only one will run and the other won't. They work if I run one motor at a time.

Is this a problem with not enough power? The motors are DC gear motors. This is the code:

```
int in1 = 12;
int in2 = 13;
int in3 = 8;
int in4 = 9;
int en1 = 11;
int en2 = 10;
void setup() {
   pinMode(in3, OUTPUT);
   pinMode(in4, OUTPUT);
   pinMode(en1, OUTPUT);
   pinMode(in1, OUTPUT);
   pinMode(in2, OUTPUT);
   pinMode(en2, OUTPUT);
}

void loop() {
   analogWrite(en1, 255);
   digitalWrite(in1, LOW);
   digitalWrite(in2, HIGH);
   analogWrite(en2, 255);
   digitalWrite(in3, LOW);
   digitalWrite(in4, HIGH);
}

```

# Answer
> 0 votes
Yes, most likely. Motors can draw a lot of power and your 9v battery is probably struggling to output enough voltage. 50-100 mA is about the max current you want to draw from a 9v. 9v batteries have a high internal resistance and the voltage will drop *potentially* well below 9v when you draw a lot of current from them. Used to make Altoids tin USB chargers back in the day with a 9v but cellphones now need multiple Amps of power and so do motors.

Here's a couple things you can do to check:

Set up your code to run both motors. Connect a motor to one side and see if it works. Then connect it to the other side (without changing the program or other wiring.) If that motor runs on both sides, check the other motor. This will make sure both motors are good and that both channels on the driver are good. Check the voltage on the battery and the motor and write down the values each time. If the current you measure with a single motor is much higher than 25-50 mA, 2 motors will exceed the limit. Note the motor (label them) and the channel it is connected to.

If that seems to check out, connect both motors. We know they don't both spin, but take this time and measure battery voltage and motor voltage. Measure the current if possible too. If you are getting greater than 50-100mA from the battery, you are likely going to have issues.

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


# Question
Title: How to properly declare a random URL in ESPAsyncWebServer?
I'm trying to make a onetime URL with a random string to for example give a user onetime access to a house with a smart lock. I have a function to make a fixed 8-character string and the following code with the address that is randomly made.

```
  controlserver.on(userurl, HTTP_GET, [](AsyncWebServerRequest *request){
   if(urlactive==true){
   if(request->authenticate("admin","admin")){
      running=true;
      request->send(200);

      Serial.println("entered");
      urlactive=false;
      }else {
       return request->requestAuthentication();
      }
   }else{
       generateRandomString();
       request->send(200, "text/html", HTML_CSS_STYLING+ "<body>"
    "<br><h1 style=\"color:white; direction: rtl;\">LInk is not valid!</h1></body>" );

   }
  });

```

the following function generates the `userurl` which is a `const char*` because the requirement of ESPAsyncWebServer library.

```
void generateRandomString() {
  const char specialChars[] = "0123456789";
  const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  String randomStringurl = "";
  String keppmyuserpass = "";
  randomStringurl += letters[random(26, 51)];
  for (int i = 0; i < 6; i++) {
    randomStringurl += letters[random(0, 51)];
  }
  randomStringurl += specialChars[random(0, 9)];
  Serial.println(randomStringurl);
  userurl = randomStringurl.c_str();

}

```

everything works fine when I enter the generated string that I convert into `const char*` using `c_str()` but I noticed an error when I copied the string partially by accident and too much to my surprise, I saw that the popup for the username and password showed up and I didn't expecte it, because I have a `notFound` function that will show an error when the entered URL doesn't exist. entered different strings but the problem is persistent. I think there is a problem with my string conversion to `const char*` using `c_str()`. but is it?

Here is compliable code, the wifi mode is STA `WiFi.mode(WIFI_STA);` :

```
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>

const char* userurl;
String  randomStringurl = "";
String  keppmyuserpass = "";

AsyncWebServer server(80);

const char* ssid = "your_ssid";
const char* password = "your_password";

const char* PARAM_MESSAGE = "message";

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}
void generateRandomString() {
  const char specialChars[] = "0123456789";
  const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  randomStringurl = "";
  keppmyuserpass = "";
  randomStringurl += letters[random(26, 51)];
  for (int i = 0; i < 6; i++) {
    randomStringurl += letters[random(0, 51)];
  }
  randomStringurl += specialChars[random(0, 9)];
  Serial.println(randomStringurl);
  userurl = randomStringurl.c_str();
  keppmyuserpass = randomStringurl;
  keppmyuserpass += letters[random(26, 51)];
  keppmyuserpass += specialChars[random(0, 9)];
  Serial.println(keppmyuserpass);

}
void setup() {

    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.printf("WiFi Failed!\n");
        return;
    }

    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(200, "text/plain", "Hello, world");
    });

    // Send a GET request to <IP>/get?message=<message>
    server.on(userurl, HTTP_GET, [] (AsyncWebServerRequest *request) {
        String message;
        if (request->hasParam(PARAM_MESSAGE)) {
            message = request->getParam(PARAM_MESSAGE)->value();
        } else {
            message = "No message sent";
        }
        request->send(200, "text/plain", "Hello, GET: " + message);
    });

    // Send a POST request to <IP>/post with a form field message set to <message>
    server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
        String message;
        if (request->hasParam(PARAM_MESSAGE, true)) {
            message = request->getParam(PARAM_MESSAGE, true)->value();
        } else {
            message = "No message sent";
        }
        request->send(200, "text/plain", "Hello, POST: " + message);
    });

    server.onNotFound(notFound);

    server.begin();
    generateRandomString();
}

void loop() {
}

```

And here is the code from ESPAsyncWebServer.h library, that required the `url` to be a `const char* uri` what am I doing wrong?

```
AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody);

```

New Update: So, I forgot to add a `"/"` before the URL, by doing so it solved the problem and here is the new function:

```
void generateRandomString() {
  const char specialChars[] = "0123456789";
  const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  randomStringurl = "";
  keppmyuserpass = "";
  randomStringurl +="/";
  randomStringurl += letters[random(26, 51)];
  for (int i = 0; i < 6; i++) {
    randomStringurl += letters[random(0, 51)];
  }
  randomStringurl += specialChars[random(0, 9)];
  Serial.println(randomStringurl);
  userurl = randomStringurl.c_str();
  keppmyuserpass = randomStringurl;
  keppmyuserpass += letters[random(26, 51)];
  keppmyuserpass += specialChars[random(0, 9)];
  OTUPC = keppmyuserpass.c_str();
  Serial.println(keppmyuserpass);

}

```

But when I renew the link, the new link is not recognized and the first generated link was working. I think that @6v6gt might be right about this: "Could it also be that the value of `userurl` must be known when `setup()` runs and the callback is registered?"

# Answer
> 1 votes
6v6gt is right, that the URI for the handler must be known, when you use the `on()` function to set the handler. Inside the library, the `on()` function calls `setUri(const String& uri)`, which which saves the `uri` in the classes interal `String` member variable. Thus the handle will not notice, if the originally used variable changes.

I think the most elegant solution here would to be to use a regular expression for your handler URI (A regular expression is a string expression, that describes a template that can match other strings). That will let the handler match any URI, that fits that regex. Inside the handler you can then get the relevant part of the URI and check, if it is currently valid. If yes, you serve your content, otherwise you serve an error (for example a 404 Not Found).

The third answer to this question has a code snippet for this:

```
#include <uri/UriRegex.h>

web_server.on(UriRegex("/home/([0-9]+)/first"), HTTP_GET, [&]() {
    web_server.send(200, "text/plain", "Hello from first! URL arg: " + web_server.pathArg(0));
});

```

The part of the URI, that's between the brackets, is the regex group, that is then made available via `web_server.pathArg(0)`. Your current code creates a string with one capital letter, 6 lower case letters and one digit, thus a regex group `([A-Z][a-z]{6}[0-9])`. You can read about how regex work online.

When you look at this repo of ESPAsyncWebServer (I'm not sure, which version you have), in the Readme right at the end under "path variable" you find this snippet:

```
server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) {
  String sensorId = request->pathArg(0);
});

```

And a note, that regex support must be enabled.

As I didn't test this, I suggest you try both methods and see, what works for you.

---
Tags: esp8266
---


title: Unable to get keypad key in while loop

text:
# Question
Title: Unable to get keypad key in while loop
I'm a beginner into Arduino so I have a little problem where I'm trying to do a countdown on LCD using while loop but I'm also trying to get a key input inside that same while loop. Problem is that its hard to get a input in that while because there are delay because of timer. Tried to look around the internet for solution but didn't find one. If anybody got a good solution I would be great full if you post it :) Thanks again!

Here is my code:

```
while (gameInProgress) {

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Until boom! ");
    lcd.print(timer);
    lcd.setCursor(0, 1);
    lcd.print(passwordInputed);

    char key = keypad.getKey();
    if (key && gameInProgress) {
      passwordInputed += key;
    }

    analogWrite(buzzerPin, 145);
    delay(200);
    analogWrite(buzzerPin, 0);
    delay(800);
    timer--;
    if (timer == 0){
      gameInProgress = false;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Boom happend!");
      lcd.setCursor(0, 1);
      lcd.print("You lost :(");
    }
  }

```

# Answer
In general, when a program needs to perform two or more functions (for example, counting off seconds and reacting to a button press that could happen at any moment) a state machine programming pattern will provide an optimal solution.

Essentially, remove all calls to delay(). Instead, record the value returned from millis() outside the loop. If tracking a, say, 1 second (1000ms) interval, add 1000 to the recorded value. Each time through the loop, check if mills() is greater then the recorded value. When it is, change the state, add 1000 to the recorded value again and do what ever is needed when the state indicating 1 second has elapsed has changed. Now clear the state and wait for the cycle to repeat.

As this loop with out calls to delay() is being executed as fast as possible, a scan for a button press can be added and the necessary reaction to that button press can be very responsive.

Add states as needed for more complex behavior. Remember, in most state machines, outputs normally happen upon state changes. And there are no delays within the loop. Tests to trigger state changes are run as fast as possible each time through the loop.
> 0 votes

---
Tags: arduino-uno, timers, time, keypad
---


title: ESP32 SPI Mutual Communication

text:
# Question
Title: ESP32 SPI Mutual Communication
I have two ESP32 cards. I want to set one of these cards as Master and the other as Slave and communicate via SPI. I have done this before on Arduino Uno, but I cannot do this on ESP32. Below are my Master and Slave codes that I have prepared simply. I can't get what I want in any way. Can anyone help?

**Master Code:**

```
#include <SPI.h>

#define CS_PIN 5  // Choose the appropriate pin for Chip Select (CS)

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

void loop() {
  char dataToSend = 'A';

  digitalWrite(CS_PIN, LOW); // Start communication with the slave
  SPI.transfer(dataToSend); // Send data to the slave
  digitalWrite(CS_PIN, HIGH); // End communication with the slave

  delay(2000); // Delay for demonstration purposes
}

```

**Slave Code:**

```
#include <SPI.h>

#define CS_PIN 5  // Choose the appropriate pin for Chip Select (CS)

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

void loop() {
  if (digitalRead(CS_PIN) == LOW) {  // Check if CS (Chip Select) is LOW, meaning the device is selected
    char receivedData = SPI.transfer(0); // Read received data from the master

    // Display received data on the serial monitor
    Serial.println("Received Data: " + String(receivedData));

    delay(1000);  // Optional delay for demonstration purposes
  }
}

```

***New Code - New Problem:***

I tried to adapt the codes at https://microcontrollerslab.com/esp32-spi-communication-tutorial-arduino/. From what I understand it uses the following pins for SPI: MISO-12; MOSI-13; SCLK-14; SS-15. I set my connections the same way, but I cannot get the output I expected from the Slave. It remains waiting at the slave.wait line.

**Master Code:**

```
#include <SPI.h>

// Define ALTERNATE_PINS to use non-standard GPIO pins for SPI bus

  #define HSPI_MISO   MISO
  #define HSPI_MOSI   MOSI
  #define HSPI_SCLK   SCK
  #define HSPI_SS     SS

static const int spiClk = 1000000; // 1 MHz

//uninitalised pointers to SPI objects
SPIClass * hspi = NULL;

void setup() {
  //initialise instance of the SPIClass attached to HSPI
  hspi = new SPIClass(HSPI);

  //initialise hspi with default pins
  //SCLK = 14, MISO = 12, MOSI = 13, SS = 15
  hspi->begin();

  pinMode(HSPI_SS, OUTPUT); //HSPI SS
}

// the loop function runs over and over again until power down or reset
void loop() {
  hspi_send_command();
  delay(100);
}

void hspi_send_command() {
  byte data_on = 0b00000001; // data 1 to turn on LED of slave
  byte data_off = 0b0000000; // data 0 to turn off LED of slave

  hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  digitalWrite(HSPI_SS, LOW);
  hspi->transfer(data_on);
  digitalWrite(HSPI_SS, HIGH);
  hspi->endTransaction();

  delay(1000);

  hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
  digitalWrite(HSPI_SS, LOW);
  hspi->transfer(data_off);
  digitalWrite(HSPI_SS, HIGH);
  hspi->endTransaction();
  delay(1000);

}
*/

```

**Slave Code:**

```
#include <ESP32SPISlave.h>

ESP32SPISlave slave;

static constexpr uint32_t BUFFER_SIZE {32};
uint8_t spi_slave_tx_buf[BUFFER_SIZE];
uint8_t spi_slave_rx_buf[BUFFER_SIZE];

#define LED 2

void setup() {
    Serial.begin(115200);
    delay(2000);
    pinMode(LED, OUTPUT);
    // begin() after setting
    // HSPI = CS: 15, CLK: 14, MOSI: 13, MISO: 12 -> default
    // VSPI = CS:  5, CLK: 18, MOSI: 23, MISO: 190
    slave.setDataMode(SPI_MODE0);
    slave.begin();
    // slave.begin(VSPI);   // you can use VSPI like this

    // clear buffers
    memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
    memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
}

void loop() {
    // block until the transaction comes from master
    Serial.println("Initialize...");

    slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);

    Serial.println("*********************");

    // if transaction has completed from master,
    // available() returns size of results of transaction,
    // and buffer is automatically updated
    char data;
    while (slave.available()) {
        // show received data
         Serial.print("Command Received: ");
         Serial.println(spi_slave_rx_buf[0]);
         data = spi_slave_rx_buf[0];
         slave.pop();
    }
    if(data == 1 )
    {
        Serial.println("Setting LED active HIGH ");
        digitalWrite(LED, HIGH);
    }
    else if(data == 0 )
    {
        Serial.println("Setting LED active LOW ");
        digitalWrite(LED, LOW);
    }
}

```

# Answer
For ESP32, unless the exact board variant is specified, by default the macros for `MISO`, `MOSI`, `SCK` and `SS` are defined as follows and are used for VSPI(i.e. SPI0):

```
static const uint8_t SS    = 5;
static const uint8_t MOSI  = 23;
static const uint8_t MISO  = 19;
static const uint8_t SCK   = 18;

```

This can be seen in the source code and HSPI is automatically configured to use SCLK 14, MISO 12, MOSI 13 and SS 15 when `SPI.begin()` is called, see this part of the source code.

Since you defined `HSPI_SS` as `#define HSPI_SS SS`, when you do `pinMode(HSPI_SS, OUTPUT);`, you are actually setting pin 5 as output, not the pin 15 that you thought it was.

There are two ways to properly set up the HSPI port.

1. What you can do is to define the macros as follows and call `hspi->begin();` by passing your configuration:

```
#define HSPI_MISO   12
#define HSPI_MOSI   13
#define HSPI_SCLK   14
#define HSPI_SS     15

void setup() {
  hspi = new SPIClass(HSPI);
  hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, HSPI_SS);
  // rest of your setup code
}

```
2. As you can see from the source code shown in the above link, if you don't explicitly pass the pins as parameters when calling `SPI.begin()`, the library will automatically assign the pins based on whether VSPI is used (SCLK 18, MISO 19, MOSI 23, SS 5), or HSPI is used (SCLK 14, MISO 12, MOSI 13 and SS 15). So all you need to define is your `HSPI_SS` pin:

```
#define HSPI_SS     15

void setup() {
  hspi = new SPIClass(HSPI);
  hspi->begin();
  // rest of your setup code
}

```
> 2 votes

# Answer
You can see the Slave-Master codes that send messages from Master to Slave using the "Hello From Master" string.

**Master Code:**

```
#include <SPI.h>

#ifdef ALTERNATE_PINS
  #define VSPI_MISO   19
  #define VSPI_MOSI   23
  #define VSPI_SCLK   18
  #define VSPI_SS     5
#else
  #define VSPI_MISO   MISO
  #define VSPI_MOSI   MOSI
  #define VSPI_SCLK   SCK
  #define VSPI_SS     SS
#endif

static const int spiClk = 1000000; // 1 MHz

char input;

const int size_arr = 25;
char buf[size_arr];
String sendData = "Hello from Master";

//uninitalised pointers to SPI objects
SPIClass* vspi = NULL;

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

    vspi = new SPIClass(VSPI);

#ifndef ALTERNATE_PINS
    vspi->begin();
#else
    vspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS);
#endif

    pinMode(VSPI_SS, OUTPUT); //HSPI SS

    vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
}

void loop() {
    input = Serial.read();

    if(input == 's'){
      sendData.toCharArray(buf, size_arr);
      spi_transmis(VSPI_SS, buf);
    }
    delay(50);
}

void send_spi(int selectPin, byte pram) {
    digitalWrite(selectPin, LOW);
    vspi->transfer(pram);
    digitalWrite(selectPin, HIGH);
    vspi->endTransaction();
    delayMicroseconds(75);
}

void spi_transmis(int selectPin, char buf[]) {
  for (int i = 0; i < size_arr; i++) {
    send_spi(selectPin, buf[i]);
  }
  send_spi(selectPin, '\n');
}

```

**Slave Code:**

```
#include <ESP32SPISlave.h>

ESP32SPISlave slave;

static constexpr uint32_t BUFFER_SIZE { 1 };
uint8_t spi_slave_tx_buf[BUFFER_SIZE];
uint8_t spi_slave_rx_buf[BUFFER_SIZE];

const int size_arr = 151;
char buf[size_arr];

volatile int pos = 0;
volatile bool active;
volatile bool process;

String received;

void setup() {
    Serial.begin(115200);
    slave.setDataMode(SPI_MODE0);
    slave.begin(VSPI);

    memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
    memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
}

void loop() {
    recvHandle();
    spiHandler();
}

void spiHandler() {
  slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);

  while (slave.available()) {
      char c = spi_slave_rx_buf[0];
      if (c == '\n') {
        buf[pos] = '\0';
        process = true;
      } else {
        buf[pos++] = c;
      }
      slave.pop();
  }
}

void recvHandle() {
  if (process) {
    received = String(buf);
    process = false;
    pos = 0;
    Serial.println(received);
    delayMicroseconds(20);
  }
}

```
> 1 votes

---
Tags: arduino-ide, esp32, spi, communication
---


# Question
Title: `.readFileCounts()` not working on DFPlayer mini module
I just played around using a `MP3-TF-16P` module, aka `DFPlayer mini`. The library and the examples I used as a basis can be found here.

My current setup contains a button (NC, normally closed), which is connected to Pin `D2` and has an interrupted attached to it. The button input is debounced by using a time difference inside the ISR. The code (based on getStarted example) can be found below.

Using the button to play the next song works as expected. However, when trying to get the total number of tracks located on the SD card by calling `Serial.println(player.readFileCounts())` as shown in the FullFunction example the board does neither print anything nor respond to any further commands. Even using the FullFunction example does not print anything.

Could someone please double-check this behaviour? Is this a module-related ore a library-related problem, since I am using a `MP3-FT-16P` module which might be a cheap clone of the original `DFPlayer mini` module? Does this work with other `MP3-FT-16P` modules out there meaning that mine is faulty?

```
#include "stdint.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

#define interruptPin 2
#define softSerialRx 10
#define softSerialTx 11
#define debounceDelayMillis 1000

volatile uint32_t lastInterruptTime = 0;
volatile bool interruptOccured = false;

SoftwareSerial softSerial(softSerialRx, softSerialTx);
DFRobotDFPlayerMini player;

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

  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), interruptHandler, FALLING);

  Serial.println(F("Initing player ..."));
  // `player.begin(stream)` returns true when module is initialized
  if (!player.begin(softSerial)) {
    Serial.println(F("... failed"));
    while(true) {
      // never leave this loop since initialization went wrong
    }
  }
  Serial.println(F("... ready."));

  // volume: 0 ... 30
  player.volume(30);

  // when using `player.readFileCounts()` player module does not respond to further commands
  // Serial.println(player.readFileCounts());
}

void loop() {
  // read status messages from DFPlayerMini on its software serial port when available
  if (player.available()) {
    printPlayerStatus(player.readType(), player.read());
  }

  if (interruptOccured) {
    Serial.println("Button pressed");
    player.next();
    interruptOccured = false;
  }
}

void interruptHandler() {
 uint32_t interruptTime = millis();
 if (interruptTime - lastInterruptTime > debounceDelayMillis) {
   interruptOccured = true;
 }
 lastInterruptTime = interruptTime;
}

void printPlayerStatus(uint8_t type, uint16_t value){
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number: "));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError: "));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

```

# Answer
These DFPlayer modules are more difficult to drive than the examples suggest. Whenever you send a command to the DFPlayer (such as player.setVolume(30)) the module will return some sort of acknowledgement or a status command. You need to be calling the player.available() method and then player.readType() and player.read() continually in loop() to keep the SoftwareSerial buffer free before you try sending commands. So calling player.setVolume(30) and then player.readFileCounts() in setup() may be overfilling the buffer before you start clearing it and the buffer will contain unread messages that are not the expected file count reply thus confusing the library. The other thing to consider is that it takes the module a second or two to initialise the SD card after .begin() and you really need to wait for the DFPlayerCardOnline status message to come in before you can ask for file counts.

I've written a more comprehensive library to drive these but it's not mature enough to share yet.
> 2 votes

# Answer
These worked for me:

```
int fileCounts = 0;

myDFPlayer.readFileCounts();
fileCounts = myDFPlayer.readFileCountsInFolder(0);

Serial.println(fileCounts);
```
> 1 votes

# Answer
OK... For those who are looking for the answer, I found it in a complicated way, reading the library file. When the begin() task is executed, within the parameters, the COM port is required, but two more parameters are also allowed: ACK and doReset. Then begin(com\_player, false, true); the ACK parameter blocks the responses of the serial parse.
> 0 votes

---
Tags: arduino-nano, sd-card, audio
---


# Question
Title: Using ESP32CAM board but no face is enrolled
I was working on a project to use the ESP32CAM board to detect faces and open some sort of lock. The program can detect the face using the yellow box that shows up as you can see from the following image:

But after clicking "Enroll Face", nothing changes. I'm currently using the default CameraWebServer application located in the ESP32CAM board examples. Any advice to solve these issues would be greatly appreciated

# Answer
The short version is you need an ESP32-S3 (which the ESP32CAM isn't) if you want practical face recognition from this example. But you *may* be able to make face recognition work on the ESP32CAM with this example *very slowly* if you really want to try it.

---

A comment the example code explains:

> You must select partition scheme from the board menu that has at least 3MB APP space. Face **Recognition is DISABLED for ESP32** and ESP32-S2, because it takes up from 15 seconds to process single frame. Face *Detection* is ENABLED if PSRAM is enabled as well

My understanding is "detection" refers to just what you're seeing in the image you've included, that it can find faces (**any** face) and draw a box around it. This makes sense because the board has PSRAM.

"Recognition" is detection of the **specific** face you "enroll", which "is DISABLED for ESP32". And the ESP32CAM uses an ESP32 (importantly not more powerful ESP32-**S3**)

You can see this again in the form of code rather than a comment in the web server code.

The web page served is not configured to show anything different when those features are disabled. It it just passes events back to the web server code. However, if you're looking at the serial output you should see messages saying "Unknown command: face\_enroll" and "Unknown command: face\_recognize" if you have the Core Debug Level setting at Info level or higher.

---

They say it takes 15 seconds on an plain ESP32, which apparently means it is possible if a bit useless. So, if you really want to try it you may be able to modify this line in app\_httpd.cpp to read:

```
#define CONFIG_ESP_FACE_RECOGNITION_ENABLED 1

```

~~I may try it later if I find my ESP32CAM. But the expectation is that it will "work" but have horrible performance.~~ Well, I found my ESP32CAM and edited that line and yes, it barely functions, but you can see that does technically work, at least for a little while. I may be crashing it during the enroll process or it might just be picking up what it thinks are extra faces and it's so bogged down that it stops responding, which may have motivated why they just disabled it outright. Either way, yeah, it behaves more or less as explained by the comment.
> 1 votes

---
Tags: web-server, esp32-cam
---


# Question
Title: Do I connect multiple I2C units to the microcontroler in series or parallel?
I have a project (still planning) with three I2C sensors: GPS, 3-axis gyro+accelerometer, and OLED. Do I connect SDA/SCL in series, or do I connect them in parallel?

# Answer
Use the Wikipedia page on the protocol as an introduction to your learning curve on I2C. I may cite:

> At the physical layer, both SCL and SDA lines are \[a ...\] bus design, \[...\]

This means that all devices connect in parallel (image from the same page, public domain):

> Rp are pull-up resistors, Rs are **optional** series resistors. (Emphasis by me)
> 3 votes

# Answer
Connect the three I2C devices in parallel.
> 1 votes

---
Tags: sensors, i2c, gps, accelerometer, gyroscope
---


# Question
Title: What does avrdude: Device signature = 0x000000 mean? Faulty wiring? Software issue? Incorrect tutorial?
I followed this tutorial a couple of times and when I clicked on bootloader I get this error:

```
avrdude: Device signature = 0x000000

```

To see the configuration file click here.

1. Why do I get this error (Arduino can't communicate with chip, problem with software)?
2. How can I fix it?
3. Is something in the tutorial incorrect?

> Keep in mind I use an `Arduino Uno Rev. 3` and `ATmega328P`

# Answer
There is one part of the tutorial that is incorrect - or rather *missing*.

When you open the serial port the Arduino resets. That includes when the serial port is opened by `avrdude`.

You need to prevent that from happening, so that the ArduinoISP sketch receives the serial data, not the Arduino's bootloader.

There's a number of ways of doing that:

* Add a 10uF or greater capacitor between RESET and GND on the Arduino
* Add a small (say 100R) resistor between RESET and 5V on the Arduino
* Cut the RESET-EN trace on the underside of the Arduino

Of those my preferred method is the first: add a 10uF or greater capacitor between RESET and GND on the Arduino.

---

**Update:**

Now that you have provided photographs of your actual setup I can see that the ground wire between your Arduino and the breadboard is actually plugged into the VIN pin of the Arduino, not GND.
> 4 votes

# Answer
Unfortunately the three prominent threads on the Arduino forum on this topic are closed, so their good but incomplete information is baked in time:

So let me add a bit more useful information in the hope it permeates.

> Device signature = 0x000000

Means the MCU **did not respond with a signature**. There is a very thin chance that's because it reported all zeros when asked for a signature, but a much higher chance that **it did not respond at all**. Correct signature bytes are found here (eg. ATmega328P = 0x1E950F) and crucially, all Atmel microcontrollers have one.

Further, the error:

> avrdude: Device signature = 0x000000
>
> avrdude: Yikes! Invalid device signature.

will occur if you're using ArduinoISP to flash a target Arduino and the **target is not physically connected**. So it really is an "all bets are off" message that doesn't pinpoint any particular cause. To troubleshoot, checking wiring if a good first step.

Do not, on the other hand, concern yourself with the external clock signal. In contrast to some guides, the ATmega328P at least comes factory configured to use an internal RC oscillator, so even a correctly connected crystal or resonator on the `XTAL` pins will not show any activity until the first successful flash.
> 2 votes

# Answer
Can confirm previous answer about changing SPI clock. I edited ArduinoISP.ino example and changed `#define SPI_CLOCK (1000000 / 6)` to `#define SPI_CLOCK (128000/6)` and after that I successfully burned bootloader to my UNO
> 0 votes

# Answer
One of the reason for getting weird device signature like 0x000000/0x0000ff/0xff0000 is not having the crystal clock right.

When I tried uploading the sketch I was getting this different device signatures. I had no idea it could be clock setting because we don't generally get this option to set the clock on regular Arduino boards upload options.

I was using this Atmega328PU clone Chinese board and wasn't able to upload a sketch. Than I tried uploading the sketch using miniCore board (where by default it was External 16MHz Clock selected). Same signature issues still.

For some reason I tried uploading with 8MHz Clock and this time the device signature was right

i.e. `device signature = 0x1e950f (probably m328p)`

and was able to successfully upload the sketch.

I highly recommend trying this.
> -1 votes

---
Tags: arduino-uno, atmega328, bootloader, avrdude, error
---


# Question
Title: First Uses of Digispark can't get past upload error
Windows 7 (64Bit) Parallels VM on Macbook Pro running BigSur. Arduino version 1.18.19, Digispark ATtiny85 Micro USB.

Loaded Boards Manager http://digistump.com/package\_digistump\_index.json and updated all. Installed Windows Driver DPinst64 from digistump. Device Manager shows:

> libusb-win32 USB Devices
> Digispark Bootloader

This a first-time use of Digispark.

I have written a couple of successful programs for the ESP32 devkit v1.

```
Test Program

    void setup() {
      // initialize the digital pin as an output.
      pinMode(0, OUTPUT); //LED on Model B
      pinMode(1, OUTPUT); //LED on Model A
    }

    // the loop routine runs over and over again forever:
    void loop() {
      digitalWrite(0, HIGH); // turn the LED on (HIGH is the voltage level)
      digitalWrite(1, HIGH);
      delay(5000); // wait for a second
      digitalWrite(0, LOW); // turn the LED off by making the voltage LOW
      digitalWrite(1, LOW);
      delay(5000); // wait for a second
    }

```

Compiles OK. Upload immediately goes to the following error: (with the Digispark not plugged in).

> Running Digispark Uploader...
> Plug in device now... (will timeout in 60 seconds)
> Assertion failed: res \>= 4, file library/micronucleus\_lib.c, line 100

I can find no relevant information on the error, I need help.

# Answer
> 0 votes
The device is only in bootload mode for a brief moment after power-up, therefore you have to unplug the device before hitting upload, and *only* connect it once it tells you to. This way the programmer can hit the bootloader in time to halt normal bootup, before execution is handed off to your code.

Literally stumbled over the same issue today, dunno why it won't just tell you this in the console right away.

---
Tags: digispark
---


title: GPS module Serial.begin value

text:
# Question
Title: GPS module Serial.begin value
I've disassembled a drone and found a GPS module. I want to use it. I haven't found any information about the architecture and the `Serial.begin` value I have to use. Could I break it if I tried different values of `Serial.begin` as 4800, 9600 and different types of architecture like NMEA with TinyGPS?

The module: https://www.aliexpress.us/item/3256805691773977.html

I've tried this sketch and `ss.available()` is constantly false, why aren't any chars available?

```
#include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(4, 3);

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

  Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
}

void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  }

  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.print(chars);
  Serial.print(" SENTENCES=");
  Serial.print(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
  if (chars == 0)
    Serial.println("** No characters received from GPS: check wiring **");
}

```

# Answer
> 0 votes
The GPS module you link to is UART-I2C dual mode. You switch between these 2 modes by (de)soldering resistors. Check first which mode the module is in.

Most GPS these days are in 9600 baud, when in UART mode. Try that too.

---
Tags: arduino-uno, gps, tinygps
---


title: What type of pin header is this?

text:
# Question
Title: What type of pin header is this?
Most of the Arduino uno boards have black female pin header. when i bought a ardiuno uno the digital pins 0 to 7 are made of silver pins. What type of pin header is that? How to use these kind of pin headers?

# Answer
> 3 votes
These are corrupted female headers so remove them and solder new ones.

---
Tags: arduino-uno, pins, breadboard
---


title: PWM and attachInterrupts issues

text:
# Question
Title: PWM and attachInterrupts issues
I'm trying to control the speed of a DC current motor with PWM.

I use an arduino UNO to send PWM signal to a mosfet Velleman vma411 to change the average tension of a my motor which is wired to stabilized power supply (about 10V). In order to get the rotational frequency of my motor, I have a hall effect sensor next to the rotational axis. Each half turn the sensor changes value (either 0 or 5V). To detect the changes I use `attachInterrupt()` to detect the changes.

When the arduino is not sending any PWM signal, the frequency measured is perfectly fine (I verified it using an oscilloscope). BUT when I send PWM signal to my motor, the frequency makes no more sense (about 1 value out of 3 is 10 times higher than the expected one).

To solve this issue I tried three different things :

* putting a capacitor (between 100 microF and 2200 microF) between the arduino and the mosfet sig port,
* using a average value of the last 10 measured frequencies,
* adding a numerical filter,
* using one `ground` pin for the mosfet and a different one for the sensor port,

Nevertheless any of those ideas really worked for me.

I suppose this may be due to some electrical reflection issues? Maybe should I change my mosfet or use a L298N?

Thanks in advance

My code which goal is to measure accurately the rotational frequency while sending a PWM signal to the mosfet:

```
/*
alimentation du capteur : 4V
mesure précise jusqu'à au moins 10V
*/

//ports
int rotation_port = 3;
int mosfet_sig_port = 11;
int debug_port = 10;

//mesures :
volatile long t_new;
volatile long t_old;
volatile long res;
volatile float frequence;
volatile float old_frequence;

// asser
float rapport_cyclique = 127; //entre 0 et 255

void setup() {
  pinMode(rotation_port, INPUT_PULLUP); // pour interrupt
  attachInterrupt(digitalPinToInterrupt(rotation_port), capteur_hall_changement, FALLING);
  pinMode(debug_port, OUTPUT);
  pinMode(mosfet_sig_port, OUTPUT);
  Serial.begin(115200);
  old_frequence = 100;
}

void capteur_hall_changement() {
  t_new = micros();
  res = 1.0 / (t_new - t_old) * 1000000;
  if (res/old_frequence <= 1.5) {
    frequence = res;
    old_frequence=frequence;
  }
  t_old = t_new;
  Serial.println(frequence);
}

void loop() {
  // Envoi du signal PWM sur la sortie numérique mosfet_sig_port
  analogWrite(mosfet_sig_port, int(rapport_cyclique));
}

```

# Answer
When you use interrupts your PWM can work bad so don't use them both at the time.
> 0 votes

---
Tags: arduino-uno, motor, interrupt, pwm, mosfet
---


# Question
Title: Connecting Arduino Uno's TX pin directly to Esp8266 esp-01
I am new to esp8266 esp-01 and trying to figure out how to use it, in many tutorials on internet, I have seen people have connected Arduino uno's TX pin directly to esp8266 esp-01 without any voltage divider, we know that Arduino TX pin uses 5v, so isn't that will kill the esp-01 which is not 5v tolerant ?

# Answer
Esp01 is not 5v tolerant so it could corrupt it at any time so don't do this and use voltage divider.
> -1 votes

---
Tags: arduino-uno, esp8266
---


title: DS3231 RTC module and battery problem

text:
# Question
Title: DS3231 RTC module and battery problem
I have a CR2032 battery connected to a DS3231 module as backup battery. When the module is connected to 5V the battery voltage is at 4.3V and without power 3.7V.

That means the module is trying to charge the nonchargeable battery. I couldn't find a rechargeable (LIR23032) battery to buy and after some research someone in forums suggested to remove the diode from the module...

1. If I keep using the CR2032 battery for long run 24/7, how long will it last? Is there a risk of explosion?
2. Is there any other way than modifying the module itself?

# Answer
> 3 votes
> If i keep using the CR2032 battery for long run 24/7, how long will battery last? is there a chance of explosion?

Yes. Recharging a non-rechargeable battery is dangerous. It should be avoided at all costs.

> is there any other way than modifying the module it self?

You have to prevent the power getting to the battery. That power is fed through a diode (hence 4.3V, which is 5V minus 0.7v for a silicon diode forward voltage). Without knowing what the module is, I can't tell you if there is any other way that modifying it - however I would guess that no there isn't. You need to stop that power getting to the battery, and that can only be done at some point between where the power comes in to the module and the battery itself - and the simplest method is to remove the diode.

The purpose of that diode is to prevent power from the battery from trying to power the rest of your circuit when you remove the main power. Removing the diode will have no adverse affect. You just won't be able to charge a rechargeable battery in future.

# Answer
> 0 votes
You can remove either or both the resistor and diode. The battery in the Amazon DS3231 clock modules is already connected to the DS3231 IC. I just removed the resistor- by the way, it isn't 200 ohms, it is 200 mega ohms, but that still allows way too much current into a non rechargable CR2032 battery. I tried using it with the charging circuit, and the non rechargeable battery swelled up over the course of 2 days!

---
Tags: ds3231-alarms
---


# Question
Title: Arduino button voltage versus HIGH/LOW state
I'm measuring voltage between button's ground and input pole on the following sketch. When button is on `off` state, there's `5V` there, when it's switched on and led turs on, there's `0`. Is this a correct way, and also how do I make it easier to write code and have `LOW` represent led being off. In this sketch, `digitalWrite(led1, LOW);` means the LED is actually turned on, so how do I tweak this to be representative of actual state, `high=led on`.

```
#include <ezButton.h>

// -----
// Declaration
// -----

const int button1  = 9;
const int led1     = 4;
int ledState = LOW;

ezButton button(button1);

// -----
// Setup
// -----

void setup()
{

  pinMode(led1, OUTPUT);
  pinMode(button1, INPUT_PULLUP);
  button.setDebounceTime(50);

}

// *****
// Main Loop
// *****

void loop()
{

  if( digitalRead(button1) == LOW ) {
    digitalWrite(led1, HIGH);
  }
  else  {
    digitalWrite(led1, LOW);
  }

}

// *****

```

# Answer
> 2 votes
To answer the posted question literally: **Yes**, it is the correct way *for your circuit*, which has the button between the pin and GND, and the LED between VCC and the pin:

simulate this circuit – Schematic created using CircuitLab

I can understand the confusion. However, the meaning is right, because the **level** on the button's pin **is `LOW`** if pressed. And the **level** on the LED's pin **needs to be `LOW`** for current to flow.

You can define your own constants:

```
// other stuff left out

const int LED_ON = LOW;
const int LED_OFF = HIGH;

const int BUTTON_PRESSED = LOW;
const int BUTTON_RELEASED = HIGH;

void loop()
{
  if (digitalRead(button1) == BUTTON_PRESSED) {
    digitalWrite(led1, LED_OFF);
  }
  else {
    digitalWrite(led1, LED_ON);
  }
}

```

---

If you want to keep using `HIGH` and `LOW`, but interpret them as:

* `HIGH` = button pressed / LED on
* `LOW` = button released / LED off

Then you need to modify the circuit:

simulate this circuit

Unfortunately, there is no pin mode `INPUT_PULLDOWN` for the button pin, so you need to provide the pull down resistor externally. Make sure to set the pin to `INPUT`, not `INPUT_PULLUP`.

A common value for the pull down resistor is 10 kΩ.

---
Tags: arduino-uno, button
---