body:
hello guys i'm new to this field i really need your help i want to wire a GSM module (SIM808) to a ESP32 board using the TX and RX pins so the pins are labeled RX and TX no pin number like the others how can i declare them in the code.
i already tested the code on an arduino uno on pins 0 and 1 (RX and TX) and it works fine here is the board i'm using :
i already tried using pins 16 and 17 but didn't work i need to try using pins number 40 and 41 according to image below
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/RY872.jpg

title: RX and TX pins on esp32

Answers: 1

body:
First off, thank you for all the guidance and support you've provided. As a beginner in the world of Arduino and embedded systems, it's been tremendously helpful.

The main issue I was facing had to do with not knowing how to declare the TX and RX pins in my C++ code, especially when these pins weren't labelled with their GPIO numbers like the others on my ESP32 board. After a bit of research and reading through your comments, I learned that these pins can simply be declared using their GPIO numbers, which are indicated on the schematic of the board.

For instance, to utilize RX0 and TX0, they need to be declared as 3 and 1 respectively. Here's an example:

     #define RXD 3  //RXD
        #define TXD 1  //TXD

        HardwareSerial SIM808(2);

    void setup()
    {
      //
      //
       SIM808.begin(9600, SERIAL_8N1, RXD, TXD);
    }

I was able to get the SIM808 module working with this method, but I'm noticing that the system isn't always consistent. Sometimes it takes a long time to execute commands, which is something I will have to look into.

I just wanted to express my gratitude for the warm welcome and helpful guidance I've received here. This being my first post, I was worried about asking a "dumb question," but the community has been nothing but supportive.

As I continue to learn and explore more about embedded systems, I'm sure I'll be back with more questions, and hopefully, in time, some answers of my own to contribute!


body:
I am working on a project that involves 3 [PN532_module][1]s to an ESP32, which sends the Tag_ID over BLE.
Plan A was to use One module on i2c_1, second on I2C_2 and third over SPI.

The SPI one works as expected.
Though I am having issues with using 2 I2c Buses using the same Adafruit Library. Exact issues are-
 - Unreliable reading while using 2 different i2c buses
 - Sometimes the SPI bus freezes after scanning a Tag on one of i2c connected readers.
My code is here

```c++

#include <Arduino.h>

#include <Wire.h>
//#include <Adafruit_PN532_2.h>
#include <Adafruit_PN532.h>

#define SDA_1 (21)
#define SCL_1 (22)
#define SDA_2   (33)
#define SCL_2   (32)

Adafruit_PN531 nfc1(SDA_1, SCL_1);
Adafruit_PN532 nfc2(SDA_2, SCL_2);

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10);
Serial.println("Serial ready");

  nfc1.begin();
  nfc2.begin();

  uint32_t versiondata_1 = nfc1.getFirmwareVersion();
  if (! versiondata_1) {
    while (1); // halt
  }
Serial.println(versiondata_1);

  uint32_t versiondata_2 = nfc2.getFirmwareVersion();
  if (! versiondata_2) {
    while (1); // halt
  }
Serial.println(versiondata_2);
}

void loop(void) {

  uint8_t success_1;
  uint8_t uid_1[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength_1;                        // Length of the UID (4 or 7 bytes

  uint8_t success_2;
  uint8_t uid_2[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength_2;                        // Length of the UID (4 or 7 bytes

  success_1 = nfc1.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid_1, &uidLength_1);
  delay(10);

  success_2 = nfc2.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid_2, &uidLength_2);
  delay(10);

  if (success_1)
  {
    Serial.println(success_1);
    Serial.print(" UID_1 Value: ");
    nfc1.PrintHex(uid_1, uidLength_1);
    Serial.println("");
  }
  delay(10);

  if (success_2)
  {
    Serial.print(" UID_2 Value: ");
    nfc2.PrintHex(uid_2, uidLength_2);
    Serial.println("");
  }
  delay(10);

}

```

  [1]: https://www.elechouse.com/product/pn532-nfc-rfid-module-purple-version/

title: How to use multiple PN532 over i2c bus(es) and SPI?

Answers: 0


body:
I found an old Google ADK 2012 in my closet and remembered it came with a Arduino board (?), an ARM 32-bit Cortex M3 micro-processor available at the time (possibly the DUE).

The ADK 2012 design files and source code were included as part of a software download at the event which is no longer available on the Android site, but I found a mirror here:

https://stuff.mit.edu/afs/sipb/project/android/docs/tools/adk/adk2.html

You can also see the kit in action from the Google I/O 2012 event where these kits were given out:

https://youtu.be/ZUaKSs3utrs

Here's my issue(s):
- When I try to set up and run the ADK 2012 IDE, I get an error stating "ADK2012.app" needs to be updated and disabled overlay on the icon.
![Screen Shot 2023-07-21 at 1.08.17 AM|295x291](upload://wC8Ql98SV4MuJJDc04LZIGSa9C.png)

- When I try to use the ADK Alternative Build System, I get an error stating `ld: symbol(s) not found for architecture i386`, which makes sense because Apple removed the ability to compile 32 bit programs on macOS starting with Xcode 10 (my Xcode: 13.4.1; macOS: 12.6.7)

- After connecting the board to my computer via USB to micro-USB, when I open the Arduino IDE, I'm able to select the port, but there is no option for this particular board, although from everything I've gathered, its essentially a custom version of the Arduino DUE made just for that event, and others have managed to [load the ADK 2012 onto a regular DUE](https://forum.arduino.cc/t/arduino-due-and-adk-2012/135978?page=3). So I've been trying it with both Arduino DUE boards (native and programmable)

- When I try to "Get Board Info" in Arduino IDE, the board name is "Unknown board", but all the other information is available (VID, PID, SN).
![Screen Shot 2023-07-21 at 1.22.47 AM|281x269](upload://j4Dxn4JMUir8cHUORYUrTH7Vsp9.png)

- After importing the ADK2 library into Arduino IDE and updating the demo code from the source download, I'm able to get the project sketch file to compile and verify without errors, however when I attempt to upload the changes to the board, I receive the following error: `No device found on cu.usbserial-AH015U12 Failed uploading: uploading error: exit status 1`. The device appears connected to my computer the whole time, including before and after the error.

I think I've exhausted all of my known options and just want to know whether & how it's possible to salvage a 10+ year old (modded but virtual identical) Arduino board.

TLDR; want to tinker with old Arduino board, custom IDE no longer works, Arduino IDE disconnects when attempting upload. Still salvageable or too old?

title: Salvaging Arduino board from Google ADK 2012

Answers: 0


body:
I'm trying to change my working rotary encoder code (stolen from [here][1]) to an interrupt-based code on my Mega2560. The trouble is that the result behaves very erratically, even though the physical setup is exactly the same as the working code. The determined encoder incrementation is jumping back and forth, when monotonically turning in one direction.

The interrupt-based code currently looks like this:
```
const long int baudrate = 115200;

const int debounceTime = 5;  // time in ms, in which the interrupt is not reacting. Starting at the first trigger of the switch.

const int clk1Pin = 19; // clkpin (signal A)
const int dt1Pin = 18; // dt pin (signal B)
const int sw1Pin = 4; // switchbutton pin

volatile int encoder1Val = 1500;  // what i want
volatile int firstSwitchTime = 0; // helper variable for debouncing
volatile int cnt = 0; // counters for debugging
volatile int cnt2 = 0;
volatile int cnt3 = 0;
volatile int cnt4 = 0;

volatile bool switchlock = false; // flags for debouncing and readout flow control
volatile bool readoutflag = false;

int cycletime;

void setup() {

  // Set up pins
  pinMode(clk1Pin, INPUT_PULLUP);
  pinMode(dt1Pin, INPUT_PULLUP);
  pinMode(sw1Pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(clk1Pin), encoder1Decoding, CHANGE);

  Serial.begin(baudrate);
}

void loop() {

  // only [print the data] and [release encoder1Val incrementing lock] after the debouncing period has passed
  cycletime = millis() - firstSwitchTime;
  if (cycletime > debounceTime) {
    readoutflag = true;
  }

  if (readoutflag == true && switchlock == true) {
    switchlock = false;
    readoutflag = false;
    Serial.print(encoder1Val);
    Serial.print(",");
    Serial.print(cnt4); // Total amount of interrupt calls between readouts
    Serial.print(",");
    Serial.print(cnt); // Amount of effective interrupts
    Serial.print(",");
    Serial.print(cnt2); // Amount of "increment branch" calls
    Serial.print(",");
    Serial.print(cnt3); // Amount of "decrement branch" calls
    Serial.println();
    detachInterrupt(digitalPinToInterrupt(clk1Pin)); //ensure atomic action
    cnt = 0;
    cnt2 = 0;
    cnt3 = 0;
    cnt4 = 0;
    attachInterrupt(digitalPinToInterrupt(clk1Pin), encoder1Decoding, CHANGE);
  }
}

void encoder1Decoding() {
  cnt4++;
  // if outside of debounceTime: change encoder1Val
  if (switchlock == false) {
    switchlock = true;
    firstSwitchTime = millis(); // remember the first time, the interrupt changed in a bouncing group
    cnt++;
    // .. decoding encoder ..
    if (digitalRead(clk1Pin) == digitalRead(dt1Pin)) {
      encoder1Val++;
      cnt2++;
    } else {
      encoder1Val--;
      cnt3++;
    }
  }
}
```
It is relatively complicated for debugging reasons, as will become clear in a moment. When turning the encoder counter-clockwise, the resulting output is this:

>    Value, Total Interrupts, Effective Interrupts, Increment Branch, Decrement Branch:
>
>    1501,2,1,1,0\
    1500,33,2,0,2\
    1499,0,0,0,0\
    1500,1,1,1,0\
    1499,19,2,0,2\
    1498,24,0,0,0\
    1499,5,2,2,0\
    1500,0,0,0,0\
    1501,15,1,1,0\
    1500,16,2,1,1\
    1501,43,0,0,0\
    1500,3,1,0,1\
    1501,1,1,1,0\
    1502,6,1,1,0\
    1503,3,1,1,0\
    1504,2,1,1,0\
    1505,1,1,1,0

The values should increase monotonically. They don't, so what's happening?

 1. The first readout makes sense: One successful interrupt call, one increment branch run, one value increase.
 2. The second readout is already strange: two decrements, but only one less value?
 3. The third is completely inexplicable: a decrement without the interrupt even being called.

I'm completely puzzled. Anybody got an idea where to start?

What I tried so far:
 - Searching the web. Seems to be a new problem.
 - Using the encoder without interrupts ("polling"). Works flawlessly, but is speed limited.
 - Explicitly analyzed the bouncing period of this rotary encoder using interrupts. Worked flawlessly. Result is: BouncingTime is mostly less than 5ms (very few outliers).
 - Plotted the data coming from clk and dt (x-ticks are 1ms, they're overlapping):

[![enter image description here][2]][2]

There is one bounce visible in the beginning, but the rest seems quite alright.

As I'm completely at a loss, any help is much appreciated!

Edit 2023-07-25:
----------------
The most important question is, why the ISR keeps on decrementing encoder1Val, even though i only turn in positive direction. This happens in all variants of the code. An absolutely stripped down version with the same behaviour can be found below:

    void loop() {
      Serial.println(encoder1Val);
      delay(500);
    }

    void encoder1Decoding() {

      if (millis() - firstSwitchTime > debounceTime) {
        firstSwitchTime = millis();

        if (digitalRead(clk1Pin) == digitalRead(dt1Pin)) {
          encoder1Val++;

        } else {
          encoder1Val--;

        }
      }
    }

Result:
> 1500\
1494\
1497\
1502\
1513\
1515\
1518\
1515\
1516

  [1]: https://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/
  [2]: https://i.stack.imgur.com/RyNUF.png

title: Rotary Encoder with interrupts - erratic behaviour

Answers: 0


body:
Here there, recently I am testing **Lora Ra-02 module** I saw many videos and it is easy to set up, according to this schematic:

> LoRa SX1278 Module-----Arduino Nano Board
>
> 3.3V-------
>
> Gnd---------Gnd
>
> En/Nss------D10
>
> G0/DIO0------D2
>
> SCK---------D13
>
> MISO----------D12
>
> MOSI----------D11
>
> RST-------------D9

I am using a very common library called [sandeepmistry][1]. and I tried this code:

```c
#include <SPI.h>
#include <LoRa.h>

int counter = 1;

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

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);
  // send packet
  LoRa.beginPacket();
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();
  counter++;
  delay(500);
}
```
When I run it, it just sticks in this line {Serial.println("**Starting LoRa failed!**");}

Then I updated the code and tried to reduce the SPI Frequency because I am using **Arduino Nano**  now the code is this:

```c
#include <SPI.h>
#include <LoRa.h>

int counter = 1;
int frequency = 8E6; // Set the desired frequency here

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("LoRa Sender");
  LoRa.setSPIFrequency(frequency); // Add the missing semicolon here
  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);
  // send packet
  LoRa.beginPacket();
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();
  counter++;
  delay(500);
}
```
This code passes the line **Starting LoRa failed!** but it again stuck in here

>    LoRa Sender
>    Sending packet: 1

So why won't it do `LoRa.beginPacket();` and loop the code? Why does it stop here?

  [1]: https://github.com/sandeepmistry/arduino-LoRa

title: LoRa Ra-02 Module begin and beginPacket not working in Arduino Nano

Answers: 1

body:
Have you set the pins properly? Try doing:

```c
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin
```

There is a problem with the way your SX1276 is connected to the board, which is why `.begin()` returns false.


body:
I want to communicate over serial to another device (dfplayer) and also set the microcontroller into sleep mode.

The ATtiny85 does not have a hardware serial pin so I need to use a virtual serial (like `SoftwareSerial.h`)

I've googled a lot and tried a lot of things but it basically seems to come always to the same problem. `SoftwareSerial` (or `NeoSWSerial`) do not work with `avr/sleep`. Something to do with interrupts,

> NeoSWSerial.cpp.o (symbol from plugin): In function `NeoSWSerial::read()':
(.text+0x0): multiple definition of `__vector_2'
.pio\build\attiny85\src\main.cpp.o (symbol from plugin):(.text+0x0): first defined here

AltSoftSerial won't work because it requires a 16bit timer which the ATtiny does not have__

Is there anything I can do about this?

---------

What I actually want to do

Connect 6 buttons with 6 different resistors to a single ADC pin of the controller. When a button is pressed wake up the device /if necessary), read the ADC value, pick a track based on that value and then play the track on the dfplayer.

After a while, if no button is pressed, put the dfplayer and the mcu to sleep. And that's why I need the mcu at all. You can't set the dfplayer to sleep or wake it up without serial

--------

Update:

I confused SPI and Serial indeed. I need to use serial communication

I want to send and receive packages. Send: `InitCommand`, Receive: `PlayerInitialized` / `InitializationFailed`. And so on.Well it's some hex codes of course but you get the point I think

My flow should basiclly look like this:

boot/wakeup  // <-- this is where I need the interrupt, don't I?
read adc value
pick track number based on adc value
send PlayTrack command to DFPlayer
delay x ms
send Sleep command to DFPlayer
go back to sleep

But the issue is in the combination of the Sleep and SoftwareSerial library. It's not the interrupt that is an issue. At least not yet

title: ATtiny85 with sleep and serial

Answers: 2

body:
Thanks to [@Delta_G](https://arduino.stackexchange.com/users/33871) I was able to figure out a solution.

I took the source files of the SoftwareSerial library [from github](https://github.com/arduino/ArduinoCore-avr/tree/master/libraries/SoftwareSerial/src) and copied it to my project. I renamed it so it wont give any conflicts. I then continued to comment out the interrupts in the cpp file and took care of calling `handle_interrupt` from my program. I also had to remove the inline keyword from the `handle_interrupt` function

I've posted my [modified files on github][1].

  [1]: https://gist.github.com/boop5/0cad063d281f181d31f84593eaffd12a

body:
> boot/wakeup // <-- this is where I need the interrupt, don't I?

Is the interrupt to detect that you have pressed one of the buttons? If you have that then you shouldn't need to use a timer to wake up.

If you connect your buttons with resistors in such a way that any button at all will send at least 0.6Vcc (ie. 3V upwards for a 5V system) then that could be configured to generate an interrupt (a rising interrupt). So you might set up the resistors so the buttons send 3.2V, 3.5V, 3.8V, 4.1V, 4.4V and 4.7V. That gives you six different voltages and they are all high enough to be considered "high" on a digital pin. Then make that pin generate the interrupt and also do the ADC reading on it once you wake up.

Then you can put the processor into a deep sleep until a button is pressed. While the track is playing you might also set up a watchdog timer interrupt so that you can wake up and check if it is time to put the player to sleep as well.


body:
I want to search for bt devices in each loop(), store them and query them one by one. This works fine so far. However, when I try to reset the corresponding variables, **I get the following error: "Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled."**

This is to ensure that new devices are found rather than iterating over old (no longer existing) devices.

```
// BT
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
#define BT_DISCOVER_TIME 10000

//BT_DEVICES
BTScanResults* pScanResults;
String** deviceNames;
int numDevices;

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

  //BT
  SerialBT.begin(DEVICE_NAME, true); // device is master
}

void loop() {
  btDiscover();
  requestData();
}

void btDiscover() {
  pScanResults = SerialBT.discover(BT_DISCOVER_TIME);

  if (pScanResults != nullptr && pScanResults->getCount() > 0) {
    for (int i = 0; i < pScanResults->getCount(); i++) {
      BTAdvertisedDevice* pDevice = pScanResults->getDevice(i);
      if (pDevice != nullptr) {
        String deviceName = pDevice->getName().c_str();
        if (deviceName.startsWith(SLAVE_NAME_PATTERN)) {
          addDeviceName(deviceName.c_str());
        }
      }
    }
  }
  SerialBT.discoverClear();

}

bool deviceNameExists(const String& name) {
  for (int i = 0; i < numDevices; i++) {
    if (deviceNames[i]->equals(name)) {
      return true;
    }
  }
  return false;
}

void addDeviceName(const String& name) {
  if (!deviceNameExists(name)) {
    deviceNames = (String**)realloc(deviceNames, (numDevices + 1) * sizeof(String*));
    deviceNames[numDevices] = new String(name);
    numDevices++;
  }
}
void requestData() {
  for (int i = 0; i < numDevices; i++) {
    SerialBT.connect(*deviceNames[i]);
    SerialBT.println("REQUEST");
    delay(100);
    String message = SerialBT.readStringUntil('\n');

    StaticJsonDocument<200> jsonDocument;
    DeserializationError error = deserializeJson(jsonDocument, message);
    if (error == DeserializationError::Ok) {
      serializeJson(jsonDocument, Serial);
      Serial.println();
    } else {
      // Fehler beim Parsen der JSON-Nachricht
      Serial.println("ERROR");
    }
    SerialBT.disconnect();
  }
}

```

i tried something similar to this:
```
delete pScanResults;
    pScanResults = nullptr;
  }

  delete[] deviceNames;
  deviceNames = nullptr;
  numDevices = 0;
```

how can i realize this? i tried vectors instead of String**, but that triggered the problem instantaneously (without the ressetting "function")

I have also tried the library "ListLib.h". When I use the Clear() function of this library, I get no messages after the first 2 lines. (hangs up?)

mh ok... if i use btDiscover() only (without arrays and so), it works as expected. but if i add my requestData() inside of btDiscover(), i get only once message from each client... idk

ok maybe discover and connect/disconnect dont work together?

mh when i use addDeviceName(deviceName.c_str()) with a variable, i get only one time the messages of clients. if replace the variable with a String, then it works as expected.

title: ESP32 - resetting BT(classic)-Discovery variables ends in memory chaos

Answers: 0


body:
I come from web world, so i usually code in a more procedurally manner, so the loop is a bit difficult to handle.

i mean if i do something like `if(condition) doSomething()` it will exec `doSomething()` a lot, or a click of a button....

```cpp
bool condition = false;
void loop(){
  if(condition){
    doSomething();
  }

}

void doSomething(){
  condition = false;
  // ........
}
```
iam doing things like this, but i feel its wrong somehow

so iam struggling why could be the "best" architecture to execute `doSomething()` only once, in a way it not become a hell of state management, some kind of event driven, event sourcing or something more battle tested for arduino

iam totally newbie in this hardware/arduino world

title: "Best" architecture for handle events

Answers: 3

body:
You don't have to use their "setup" and "loop" paradigm, you know. This will work:

<!-- language: c++ -->

    #include <Arduino.h>

    int main ()
      {
      init ();  // initialize timers
      Serial.begin (115200);
      Serial.println ("Hello, world");
      Serial.flush (); // let serial printing finish
      }  // end of main

So, inside your code, if you want to do something once, do it once. If you want to make a loop, make one. Just like in C++. Which is what the Arduino code is.

---

> so iam struggling why could be the "best" architecture to execute doSomething() only once

Put it in `setup` if you want to run with their "setup" and "loop" paradigm. It was just designed for beginners, to clarify that some things you do once, and some things you do in a loop.

body:
The usual way to do things only once (at startup) is to put them in `setup()`.

You put only statements in `loop()` that need endless repetitions.

You can think of the underlying main function as:

```c++
int main() {
    setup();
    for (;;) {
        loop();
    }
}
```

Therefore, your example can be:

```c++
void setup() {
    doSomething();
}

void loop() {
}

void doSomething() {
    // ........
}
```

---

**Addition after clarification**

You commented:
> as far as i know i cant detect a button press outside of the loop right? when i said to execute once i mean, when press a button, it should do somenthing only once, this control of what should/was executed is a bit tricking, can go out of control and became a mess

With that requirement, you are right, you need to put the check and reaction inside `loop()`. However, you can "hide" the "mechanic" inside the called function:

```c++
void setup() {
}

void loop() {
    doSomething();
}

void doSomething() {
    static bool isDone = false;
    if (!isDone && condition) {
        isDone = true;
        // ........
    }
}
```

A dedicated variable is simple and clear. You might choose some other type and value, depending on the actual things to do.

body:
Coming from the Web world, you are most likely used to work in a
single-threaded environment (save for Web workers). You have been
trained to program in a non-blocking fashion, as blocking the browser's
UI thread would freeze the user interface. This is actually **a valuable
asset** when moving to Arduino programming. Most Arduino programs run on
a single-threaded, bare-metal platform. Non-blocking code is a must for
all but the most trivial programs, and is not easy to master for
newcomers.

The most striking difference between an Arduino and your typical
JavaScript environment (be it a browser or Node.js) is that in
JavaScript the event loop is _implicit_. You do not see it, but it runs
under the hood of your interpreter. It looks conceptually like this:

```c++
void JavaScript_event_loop() {
    if (there_is_a_pending_event()) {
        dispatch_the_event_to_the_registered_callback();
    }
}
```

On the Arduino, however, you have to write the event loop yourself. Most
often you do not need full-blown event queue management, as you know
beforehand the set of events your program will have to handle. Your
typical Arduino loop should normally look like this:

```c++
void loop() {
    if (event_foo_happened())
        handle_event_foo();
    if (event_bar_happened())
        handle_event_bar();
    if (event_baz_happened())
        handle_event_baz();
    // etc...
}
```

There are a few recurring idioms for testing common events. Here are
some examples:

```c++
// Handle a periodic event (like setInterval()).
uint32_t now  = millis();
static uint32_t last_event_time;
if (now - last_event_time >= event_period) {
    // Use `last_event_time = now;` instead of this if you want to
    // guarantee a minimal interval between events:
    last_event_time += event_period;  // this avoids systematic drift
    handle_periodic_event();
}

// Handle a rising edge on an input_pin.
uint8_t pin_state = digitalRead(pin);
static uint8_t previous_pin_state;
if (previous_pin_state == LOW && pin_state == HIGH)
    handle_input_rising_edge();
previous_pin_state = pin_state;

// Handle Serial data.
if (Serial.available())
    handle_input_byte(Serial.read());

// Handle a push button with a debouncing library.
button.update();
if (button.fell())
    handle_button_press();
```

A few recommended readings:

* The [Blink Without Delay][blink] Arduino tutorial shows how to handle
  periodic events
* [Reading Serial on the Arduino][serial] is a tutorial showing how to
  buffer serial input in order to handle one full message at a time
* [Bounce2][debounce] is an example of a button-debouncing library
* [The Finite State Machine][fsm] is a nice tutorial on writing finite
  state machines, which sooner or later you will need for handling some
  situations in a non-blocking way

[blink]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
[serial]: https://www.majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27
[debounce]: https://github.com/thomasfredericks/Bounce2
[fsm]: https://www.majenko.co.uk/blog/our-blog-1/the-finite-state-machine-26

------------------------------------------------------------------------

**Edit**: Regarding the example code you posted, I would like to rewrite
your `loop()` like this:

```c++
void loop() {
    if (condition) {
        doSomething();
        condition = false;  // <- move this out of doSomething()
    }
}
```

It doesn't look like a big change, but there is an idea here that can
help make your code more readable and maintainable. The idea is to think
of your program in terms of “events” you have to respond to. This should
feel natural to someone raised on JavaScript, and it is also a good
approach for programming microcontrollers. You then want to handle the
event detection/dispatching and the event response as separate problems.
The function `doSomething()` should not have to care about the
`condition` variable, as it is only used to handle the event detection
and dispatching, which is the responsibility of the event loop.

> When i said to execute once I mean, when press a button, it should do
> something only once, this control of what should/was executed is a bit
> tricking, can go out of control and became a mess.

To detect a button press you _do_ have to manage some state, there is no
way around it. Your program should not respond to the _state_ of the
button (pressed or released) but instead to specific _transitions_ of
this state (press or release events).

In its most basic form, the problem is about detecting a falling edge
(or rising edge, depending on how the button is wired) on the input
signal. This is handled by remembering the state you had on the previous
loop iteration, and comparing this previous state with the state you are
reading right now, as show in the “Handle a rising edge on an input pin”
example above.

Real buttons have an additional issue, namely mechanic bounce: when the
button is actuated, the signal can go through many fast transitions
before settling into a stable state. In order to deal with this, you
have to look at the timing of the transitions and sort out the legit
ones from the spurious ones. This is called [debouncing][]. There are a
few libraries out there than can handle this for you. Most will also do
edge detection, which makes handling button presses as simple as testing
for `button.fell()` (again, see example above). Some will even report
distinct event types for short press, long press and double press.

[debouncing]: https://learn.adafruit.com/make-it-switch/debouncing


body:
I could not understand one point related with Arduino code.

Let's say i have following code

```cpp
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
}

void loop()
{

}
```

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

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

I examine the generated file with `avr-size`.

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

As you can see .data + .text = consuming program storage space. Then i checked this document. https://courses.cs.washington.edu/courses/csep567/04sp/pdfs/avr-libc-user-manual.pdf. It says about `avr-size`

    Note:
    The avr-size program (part of binutils), coming from a Unix background,
    doesn’t account for the .data initialization space added to the .text section, so in
    order to know how much flash the final program will consume, one needs to add
    the values for both, .text and .data (but not .bss), while the amount of pre-allocated
    SRAM is the sum of .data and .bss.

Then, i check contents of .data section with

    avr-objdump.exe -s -j .data <my.elf>

Then I got

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

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

title: How .data + .text section can be = How much flash the final program will consume

Answers: 2

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

body:
Just to expand on what JRobert said, variables which are initialized, and other literals (eg. the word "foo" in your example) have to come from somewhere, and thus are stored in program (flash) memory and copied into RAM as part of the C++ initialisation.

However, uninitialised variables do not take up flash memory. Compare:

<!-- language: lang-c++ -->

    char foo [1000];
    void setup()
    {
      Serial.begin(9600);
      Serial.println("foo");
      Serial.print (foo);
    }

    void loop()
    {
    }

This reports for the Uno:

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

However if you initialise that global variable foo, like this:

<!-- language: lang-c++ -->

    char foo [1000] = { 1, 2, 3, 4, 5 };
    void setup()
    {
      Serial.begin(9600);
      Serial.println("foo");
      Serial.print (foo);
    }

    void loop()
    {
    }

Now the flash takes 1000 more bytes:

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

This clearly shows that, since uninitialised variables at global scope are set to zero, the compiler has generated code to do just that. However initialised variables have to be copied from flash into RAM.

A very useful technique when using these chips with not much RAM is to use the "F" macro, which effectively tells the compiler to copy strings directly from flash, rather than into RAM, thus saving RAM space. For example:

<!-- language: lang-c++ -->

    Serial.println (F("Hello, world"));

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

---

# Putting initialised arrays into flash

I've got a lengthy discussion about using PROGMEM for storing data, other than just literal strings for printing [on my forum](https://www.gammon.com.au/forum/?id=12615).

This example code here shows how you can store messages in PROGMEM (flash memory) and retrieve them at runtime. It uses `pgm_read_word` to read the pointers, and then `strcpy_P` to copy the string from PROGMEM into RAM, so it can then be printed.

<!-- language: lang-c++ -->

    const int NUMBER_OF_ELEMENTS = 10;

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

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

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

      unsigned int count = 0;

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

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

      }  // end of setup

    void loop () { }

This particular example doesn't use much RAM:

    Sketch uses 2220 bytes (6%) of program storage space. Maximum is 32256 bytes.
    Global variables use 188 bytes (9%) of dynamic memory, leaving 1860 bytes for local variables. Maximum is 2048 bytes.


body:
I have an esp32 WROOM-32 connected to a MQ9 gas sensor to GPIO35. Both are powered separately. measuring the output from the sensor directly using a multi-meter shows a constant reading of 0.145 V but the readings on esp32 shows 3.3V and if fluctuates too much.

The circuit:
MQ-9 AO -> voltage divider (using 1k and 2.2k ohm) -> ESP32 (GPIO35)

Sample Code:
```
void setup() {
  Serial.begin(9600);
  analogReadResolution(11);
  analogSetWidth(11);               // 11Bit resolution
  analogSetAttenuation(ADC_0db);
}
void loop() {
 int ADC = analogRead(35);
 float volt = (ADC * 3.3) / 2045;
 Serial.print("Volt : ");
 Serial.println(volt);
 Serial.print("Analog : ");
 Serial.println(ADC);
 Serial.println("");
 delay(1000);
}
```
Image of the error:
[![Readings and Fluctuation][1]][1]

  [1]: https://i.stack.imgur.com/ExXcR.jpg

title: ESP32 Shows Incorrect Input Voltage From Analog Pin

Answers: 0


body: I need to add support for the UNO R4 (both models) for a library I'm maintaining. The library uses the LED on pin 13 as status indicator. I can't find any information whether that LED is still there on the R4 Minima and Wifi boards. The R4 Wifi has this nice LED matrix, so the other LED might be gone for it.

title: Does the UNO R4 still have the standard on-board led on pin 13?

Answers: 1

body: The schematics for the R4 Minima and Wifi boards can be found at:  https://docs.arduino.cc/resources/schematics/ABX00080-schematics.pdf and https://docs.arduino.cc/resources/schematics/ABX00087-schematics.pdf .  Pin 13 is also labeled SCK. A LED is attached to this pin.


body:
This is my current code (Arduino Mega 2560):

    #define p1 2
    #define p2 3

    void setup() {
     pinMode(p1, OUTPUT);
     pinMode(p2, OUTPUT);
     Serial.println("ARDUINO : CONNECTED");
    }

    void loop() {
     if (Serial.available()) {
      String state = Serial.readString();

      if (state.startsWith("LED1ON")) {
        digitalWrite(p1, HIGH);
      }
      if (state.startsWith("LED1OFF")) {
        digitalWrite(p1, LOW);
      }
      if (state.startsWith("LED2ON")) {
        digitalWrite(p2, HIGH);
      }
      if (state.startsWith("LED2OFF")) {
        digitalWrite(p2, HIGH);
      }
      // ... and next condition LED
     }
    }

how can i do for multiple input serial use seperator(";") ? like : LED1ON;LED2OFF

expacted:
one time command (LED1ON;LED2OFF) many condition (led turn on and led 2 turn off)

please, tks

title: Separate from Serial for digitalWrite()

Answers: 3

body: Consider refactoring your code such that you read in strings then search through the string character by character copying each character to a new string until you find a semicolon.  When this happens do not copy the semicolon.  Instead execute the existing "if" statements to turn on / off the LEDs based on the content of the new string.  When done, erase the new string, loop back and continue to copy characters to the new string until the next semicolon.  If there is no more data to be copied, read in more data until data is unavailable.

body:
You might want to get used to visit [the Arduino library reference][1] to learn what is possible and how to use it.

For your case, you are interested in the method [`readStringUntil()`][2].

The reading, understanding, experimenting, debugging, and finishing is left as an exercise to the user.

  [1]: https://www.arduino.cc/reference/en/
  [2]: https://www.arduino.cc/reference/en/language/functions/communication/serial/readstringuntil/

body:
[readString](https://www.arduino.cc/reference/en/language/functions/communication/serial/readstring/) reads from Serial until it times out. This means it might undershoot or overshoot both the end of the line (if there is one) or the semicolon.

I suggest reading into a `char` buffer (say, of 30 bytes length) until either a newline or semicolon is reached. Then terminate the buffer with 0x00 (to make it a proper "C" string) and then do a simple string compare (`strcmp`).


body:
I'm beginner in Arduino and recently programmed an Arduino uno board with various PS/2 to USB converters. They work when typing in Serial Monitor of Arduino IDE, but not in the other programs such as Notepad.

[![enter image description here][1]][1]

How can I connect the board as HID keyboard for usual works with my PS/2 keyboard?

**Update:**

As @KIIV mentioned in the comments, Uno hasn't native USB and his suggestion is to start with boards such as Leonardo.

I want to ask, what is the straightforward way of using Uno for this purpose?

  [1]: https://i.stack.imgur.com/hhZVB.png

title: How to use Arduino Uno as PS/2 to USB converter for typical keyboard usages?

Answers: 1

body:
As the Uno has no generic USB module, it generally works only as a virtual serial device. Without additional hardware you cannot make a Uno work as a USB keyboard. In principle.

A possible solution is the usage of [V-USB][1]. This nice library uses [bit-banging][2] to realize low-speed USB communication. A USB keyboard commonly is such a low-speed USB device.

Another possible solution is an accompanying software "driver" on the PC. It will receive the key events via the USB serial port and translate them to key events for the operating system. But I'm sure you will not want this.

  [1]: https://www.obdev.at/products/vusb/index.html
  [2]: https://en.wikipedia.org/wiki/Bit_banging


body:
In my code I have a number of boolean flags that tell me if data has been written to specific places in the EEPROM. I need to save these flags to the EEPROM and recover them on a restart.

Is the following syntax valid to update a single bit in an EEPROM cell?
```
EEPROM.update (0, EEPROM.read(0)| 0x20);
```

ie I'm reading cell '0' , putting a '1' into bit 5 and then updating cell; '0' of the EEPROM. There will be several other bits to be updated throughout the running of the programme.

title: changing a single bit in an arduino EEPROM byte

Answers: 1

body:
Yes, your syntax is indeed correct. The `|` operator is the bitwise OR operator in C and C++, and it's used to set a specific bit in a byte. Here's a breakdown of what your line of code does:

- `EEPROM.read(0)` reads the current value of the first byte in the EEPROM.
- `0x20` is the hexadecimal representation of 32, which is `00100000` in binary. This means that the fifth bit (counting from zero) is set to 1, and all other bits are set to 0.
- `EEPROM.read(0) | 0x20` performs a bitwise OR operation on the current value of the first byte in the EEPROM and `0x20`. This will set the fifth bit of the byte to 1, and leave the other bits unchanged.
- `EEPROM.update(0, EEPROM.read(0) | 0x20)` updates the first byte in the EEPROM with the new value.

So, your approach to set a specific bit in an EEPROM byte is correct.

Here's a more detailed example:

```cpp
byte bitToSet = 5; // Bit number to set (0-7)
byte eepromAddress = 0; // EEPROM address (0-1023 for ATmega328)

// Read current value
byte currentValue = EEPROM.read(eepromAddress);

// Create mask for bit to set
byte mask = 1 << bitToSet;

// Update value
byte newValue = currentValue | mask;

// Write updated value back to EEPROM
EEPROM.update(eepromAddress, newValue);
```

It's worth noting that the `EEPROM.update()` function is smart enough to only perform a write if the new value is different from the old one. This is important because the EEPROM has a limited number of write cycles. So using `EEPROM.update()` instead of `EEPROM.write()` can help extend the life of the EEPROM.


body:
I'm reading about [powering alternatives for the arduino board][1], and I have run across two confusing sentences in Section 5, powering via 3V3/5V pin. First, it says:

> 3V3 and 5V pins **can also be used as power inputs if no regulated power supply is connected** through the other power inputs (USB port, barrel jack connector or VIN pin).

But then right afterwards, it says:

> Although 3V3 and 5V pins can be used as power inputs, it is **not recommended if no power supply is connected** through the USB port, the barrel jack connector, or the VIN pin.

(emphasis mine)

Which is correct? When powering via the 3V3 or 5V pin, should I have a different power supply connected elsewhere, or not?

  [1]: https://docs.arduino.cc/learn/electronics/power-pins

title: Confusing language on arduino docs about powering via 3V3/5V pins

Answers: 0


body:
Let's suppose I have a class named `Foo`, and `sizeof(Foo)` is 10 bytes.

As I understand it, creating a Foo with 'automatic' scope (on the stack) has zero overhead. If the Object occupies 10 bytes, it consumes 10 bytes on the stack. Period.

I'm kind of fuzzy about how creating objects with 'new' works on an 8-bit AVR. I know that 'new' ultimately calls malloc(), and that on Windows/Linux, malloc() ultimately asks the operating system for memory whose management is up to the OS itself. But... with 8-bit AVR, there *is no* operating system. So, presumably, something else has ultimate responsibility for managing its heap. And presumably, there's some kind of overhead involved so it can keep track of which bytes have been returned to it by a destructor, and which ones are still in use.

So... using the hypothetical 10-byte `Foo` as an example... if I make 7 sequential calls in a row to `new Foo()`, how many bytes will it *actually* burn through (including overhead)?

For objects that have to be instantiated via `new`, but will persist "forever" (until the next reset), is there any special syntax that tells the compiler/malloc()/whatever, "This object will **never** be destroyed, so there's no need to preserve any information that would otherwise be necessary to release its memory eventually"?

---

Giving this a bit of context, assume `View` is a class with multiple templated subclasses (let's say, `TemperatureView<int, int, int, int>` and `LabelView<int, int, int, const char*>`), and I'm doing something like this:

~~~
const PROGMEM char* pLABEL = "Foo:";
View* views[] = {
    (new TemperatureView<0,3,0,2>{}),
    (new LabelView<1,4,0,pLABEL>{})
};
~~~

I'm trying to figure out just how big of a penalty hit (in terms of wasted ram from overhead) I'm taking by rolling it all into one nice, neat combined declaration instead of doing something like:

~~~
const PROGMEM char* pLABEL = "Foo:";
TemperatureView<0,3,0,2> firstTemp {};
LabelView<1,4,0,pLABEL> firstLabel {};
View* views[] = {
    &firstTemp,
    &firstLabel
};
~~~

(I originally wanted to put the objects whose addresses were being added to views[] in automatic/stack, but apparently, that's taboo because the compiler thinks the array will outlive the objects whose addresses would otherwise be stored there)

title: Overhead of using 'new' to create object in dynamic ram vs automatic to create on stack

Answers: 2

body:
If you make an automatic variable, its lifetime is the lifetime of the function it is inside, so it won't persist forever, unless it is at global scope, or it is declared `static`.

The overhead of using `new` is the size of the object you allocate plus a couple of bytes to keep track of what that bit of memory is used for.

> if I make 7 sequential calls in a row to new Foo(), how many bytes will it actually burn through (including overhead, which appears to be two bytes, see test below)

Seven times the size of the object plus the overhead I mentioned.

Normally you would release that memory with `delete` unless you want it kept forever.

> For objects that have to be instantiated via new, but will persist "forever" (until the next reset), is there any special syntax that tells the compiler/malloc()/whatever, "This object will never be destroyed ...

No. It persists until you call `delete` which there is no compunction to do.

I wrote a test program for my Uno to see what the overhead was, to use `new`.

<!-- language: lang-c++ -->

    #include "memdebug.h"

    void showFreeMemory ()
      {
      Serial.print (F("Free memory = "));
      Serial.println (getFreeMemory ());
      } // end of showFreeMemory

    typedef struct {char s [20]; } foo;

    void setup ()
      {
      Serial.begin (115200);
      Serial.println ();
      showFreeMemory ();   // 1664
      foo * bar = new foo;
      showFreeMemory ();   // 1642
      strcpy (bar->s, "Hello, world");
      Serial.println (bar->s);
      delete bar;
      showFreeMemory ();   // 1664
      }  // end of setup

    void loop () { }

> I'm trying to figure out just how big of a penalty hit (in terms of wasted ram from overhead)

Two bytes, by the looks, for each allocation.

> (I originally wanted to put the objects whose addresses were being added to views[] in automatic/stack, but apparently, that's taboo because the compiler thinks the array will outlive the objects whose addresses would otherwise be stored there)

I'm not sure what you mean by that, can you give a concrete example?

---

I think you will save more memory by using PROGMEM, which you seem to be doing, a bit.

See my post [here](https://www.gammon.com.au/forum/?id=12615) for ideas about doing that.

---

## Reference

I got memdebug.h (and memdebug.c) from [Andy's workshop - Debugging AVR dynamic memory allocation](https://andybrown.me.uk/wk/2011/01/01/debugging-avr-dynamic-memory-allocation/)

body:
Just as a small complement to the previous answer... The documentation
of the avr-libc has a whole page discussing the workings of `malloc()`.
The section titled [Implementation details][doc] states:

> Dynamic memory allocation requests will be returned with a two-byte
> header prepended that records the size of the allocation. This is
> later used by `free()`. The returned address points just beyond that
> header.

This is consistent Nick Gammon's experimental finding.

[doc]: https://www.nongnu.org/avr-libc/user-manual/malloc.html#malloc_impl


body:
I wish to create a rudimentary ethernet in/out - switch/hub where I can (sort of) daisy chain my boards. (I don't wish to use a ethernet switch/router/hub)

- One port would be acting as server
- The other would be acting as a client
(and forward any messages received on the first port after some processing/modification)

I am using an **STM32 Bluepill** with 2 Mini w5500 Modules (adafruit) connected via SPI. Nothing else is connected to SPI. All the other GPIOs are connected to relay drivers.

I use the Ethernet library. I have made sure they are connected to different CS pins and I have tried to assign `Ethernet.init();` before doing anything with specific Ethernet modules but that keeps disconnecting and is working very unreliably.

I understand that some modification in the library might be needed (I, by no means could figure out how and what).

References:

<https://forum.arduino.cc/t/2-network-shields/111509>
<https://forum.arduino.cc/t/connect-multiple-ethernet-shields-to-arduino-uno-using-spi/284008/16>

But no one seems to have gotten it to work. Please help.

title: Ability to connect 2 or more w5500 Modules and deal with them as objects

Answers: 0


body:
I didn't find much documentation about ESP promiscuous mode (just from the espressif sdk although I'm using ArduinoIDE https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/api-reference/wifi/esp_wifi.html )

So from seeing some sample codes ( https://github.com/spacehuhn/ArduinoPcap/blob/master/examples/esp8266_pcap_serial/esp8266_pcap_serial.ino and https://www.youtube.com/watch?v=3Ac6X6ZBQ0g ) the esp8266 doesn't work properly for some people but for others (https://www.esp8266.com/viewtopic.php?t=12127) it seems to work properly, so I don't know if it's a hardware limitation.

I tried making a simple sketch to try it for my NodeMCU 0.9 and compared the packets from wireshark and I saw the majority of the packets come incomplete or with anomalies
```
#include <ESP8266WiFi.h>
#include <Arduino.h>

extern "C" {
#include <user_interface.h>
}

static void ICACHE_FLASH_ATTR handlePacket(unsigned char* buf, uint16_t len) {
  for (int c=0; c < len; c++){
    Serial.printf("%d:%d  ", c, (int)buf[c]);
  }
  Serial.println();
}

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

  wifi_set_opmode(STATION_MODE);
  wifi_promiscuous_enable(0);
  WiFi.disconnect();
  wifi_set_promiscuous_rx_cb(handlePacket);
  wifi_set_channel(6);
  wifi_promiscuous_enable(1);
}

void loop(){}
```
From the example code that works, the guy seems to use esp8266 sdk, is the ArduinoIDE a limitation for this monitor mode thing?

https://bbs.espressif.com/viewtopic.php?t=3072
https://github.com/kieransimkin/esp8266-freedom

title: Is there a way to use ESP8266 in promiscuous(monitor) mode and see the the wifi packets?

Answers: 0


body:
I am a newbie in electronics. Please correct me if I am wrong.
I am replacing a pot with a digital pot (DS3502) in a circuit.
The Vcc of the circuit is 12V. But the digital pot can have a maximum of 5.5V as Vcc.
I am controlling the digital pot with an Arduino UNO. Can I use 5V from the Arduino as the Vcc of the digital pot and 12V as the Vcc of the circuit?
I kept the ground common for both.

The connection is as below:

DS3502 Arduino Uno

VCC --- 5V

GND --- GND

SDA --- A4

SCL --- A5

DS3502 Circuit

RL --- GND

RW --- Circuit

[![enter image description here][1]][1]

This is a constant current circuit of 21mA, to drive a laser. But I want to slightly tune the intensity of laser using the digital pot. So I am replacing it with digital pot. But I am getting an open connection in the place of resistor. I have only use RL and RW to circuit. RH is kept opened. Do I need to connect RH and V bias to 12V(Vcc of my constant current circuit)? I don't have much knowledge in circuits. Please spare me if I am wrong

  [1]: https://i.stack.imgur.com/O4pYS.jpg

title: Digital Pot with Arduino

Answers: 1

body:
If you look at [the datasheet](https://www.analog.com/media/en/technical-documentation/data-sheets/DS3502.pdf) it mentions that Vcc can be from 2.5V to 5.5V, and clearly the I2C connection is referenced to Gnd. Therefore you would connect the Uno to the DS3502 in the usual way (Gnd, Vcc, SDA and SCL).

The "digital pot" side has a separate input (V+) which can be from 4.5V to 15.5V.

>  Can I use 5V from the Arduino as the Vcc of the digital pot and 12V as the Vcc of the circuit?

Your terminology is a bit loose here. You can use 5V from the Arduino to the Vcc pin of the pot (pin 3) and 12V to V+ and RH (pins 6 and 9). The output will be on RW (the wiper, pin 7).

It also looks like you would connect Gnd and RL (pins 2 and 8) to Gnd on the Arduino.

Although, conceivably I think, you could connect Gnd (pin 2) to Gnd on the Arduino, and RL (pin 8) to the Gnd of the "other circuit" - the one you are controlling. It looks like they are separate.

I think you might keep RL and Gnd not connected, to reduce digital noise.

The A0 and A1 pins are for modifying the I2C address.

[![DS3502 typical wiring][1]][1]

  [1]: https://i.stack.imgur.com/bYAmf.png


body:
I have to handle a String coming in over UART containing a bunch of information, part of it is a MAC-address that I get by using String.substring(a, b) returning a 12-char String representing a mac-address `"B8C9A45BA770"` <- (just an example).

**I need the format of the mac-address to be a uint8_t array like so
`{ 0xB8, 0xC9, 0xA4, 0x5B, 0xA7, 0x70 }`.**

So I need a function to convert a String to a uint8_t*. Sadly I have no clue how to convert this. There has so be an easy way right? its "C8" to 0xC8 and so forth...

Any ideas on this?

title: Parse char* mac-string to uint8_t array

Answers: 1

body:
Personally I'd go with a basic implementation such as this one.

    const uint8_t MAC_length = 6;
    uint8_t* MAC_buffer[6];

    uint8_t fromHexChar(char c)
    {
        uint8_t result = 0
        if ((c >= '0') && (c <= '9'))
            result = c - '0';
        else if ((c >= 'A') && (c <= 'F'))
            result = 10 + c - 'A';
        else if ((c >= 'a') && (c <= 'f'))
            result = 10 + c - 'a';
        return result
    }

    uint8_t* toMAC(String s)
    {
        for (uint8_t i = 0; i < MAC_length; i++)
        {
            MAC_buffer[i] = (fromHexChar(s.charAt(2*i)) << 4) | fromHexChar(s.charAt(2*i + 1));
        }
        return MAC_buffer;
    }

Probably it can be optimized, but this is such a simple job and to be used so rarely that I think this is enough.

Important: I did not test this code, so there may be bugs inside.

If you need to start from an arbitrary point in the String instead of at the beginning, you simply have to modify it this way:

    uint8_t* toMAC(String s, uint8_t startIdx)
    ...
            MAC_buffer[i] = fromHexChar(s.charAt(2*i + startIdx)) << 4 | fromHexChar(s.charAt(2*i + startIdx + 1));

Note for future me: I checked both on a simulator and in the code, and `charAt` is safe to use even when the index is outside the string boundaries (it simply returns 0).


body:
I have a few cheap Nano clones that I bought online that have worked for the past couple of months. They were working fine today until suddenly the Arduino IDE had trouble uploading sketches to them.

Here is the full error message:
```
Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

Sketch uses 2080 bytes (6%) of program storage space. Maximum is 30720 bytes.

Global variables use 212 bytes (10%) of dynamic memory, leaving 1836 bytes for local variables. Maximum is 2048 bytes.

An error occurred while uploading the sketch

avrdude: ser_open(): can't set com-state for "\\.\COM5"
```

I have tried troubleshooting multiple ways, but none of the following worked:
- unplugged/replugged in nano
- restarted computer
- swapped to another nano clone
- changed USB cables
- changed USB ports
- tried uploading other code
- downloaded the CH340 drivers

I tried uploading to an Arduino Mega and that DID work, however, I would like to be able to use the Nano.

I am using version 1.8.19

Thanks for the help.

title: Having trouble uploading sketch to Nano

Answers: 2

body:
See https://arduino.stackexchange.com/questions/13292/have-i-bricked-my-arduino-uno-problems-with-uploading-to-board/13293#13293.

I know you mentioned Nano, but it is the same concept.

If a sketch you previously uploaded sets up the watchdog timer to fire too quickly the new sketch may not upload.

Try holding down reset while you start the upload process and then release reset when the upload starts. See the part of the linked answer headed "Watchdog timer problems".

body: The cheap Nano requires you to use the old bootloader. I use them without problems most of the time. When it fails to upload I first check tools and validate the bootloader it is running. If it is correct I then close the IDE, power down the Nano and then reopen and repower it, between the two it usually solves the problem.


body:
I have in my code in c, this function:
```c
    fseek(file, 0, SEEK_SET);
```
I need to use the same function with Arduino ide. Is this correct?
```c
    file.seek(file.size());
```
Or what is the alternative function in Arduino ide?

title: Using file.seek() with arduino ide

Answers: 1

body:
According to <https://www.arduino.cc/reference/en/libraries/sd/seek/> :

### SD - seek()

Seek to a new position in the file, which must be between 0 and the size of the file (inclusive).

### Syntax

    file.seek(pos)

### Parameters

* file: an instance of the File class (returned by SD.open()).
* pos: the position to which to seek (unsigned long).

---

If you want to seek to the start of the file, therefore you should seek to zero, not `file.size()`. Using `file.size()` would seek to the end of the file.


body: I just got a MMC5603 magnetometer from Adafruit however the measurements are unreliable. For example when I convert it to a heading it goes from 200° to 180° and then back to 200° if I move it radially.

title: How to calibrate MMC5603 magnetometer

Answers: 1

body:
To calibrate a magnetometer you should perform hard-iron and soft-iron calibration. There's some guides online about how to do this but I found [this digikey guide][1] to be the most informative. Adafruit also has a guide [here][2]

I had some issues getting this to work however so here's some tricks

## Using an M1 macbook

Both guides recommend to use MotionCal but it hasn't been updated in several years. If you downloaded the macOS version it might not show any available ports. To fix this you need to compile it from source – you can find details in this [Github Issue][3] but the TL;DR is:

1. `git clone git@github.com:PaulStoffregen/MotionCal.git`
2. `brew install wxwidgets`
3. Open the `Makefile`
4. Comment the line `OS = LINUX`
5. Uncomment the line`OS = MACOSX_CLANG`
6. Under `else ifeq ($(OS), MACOSX)` add `-arch arm64` to the `CFLAGS`
7. Run `make` and it should build

I had some issues with it not building after this which was resolved by deleting the directory and then redoing these steps

## Using an Arduino UNO

Both guides say to use **Adafruit Sensor Lab** which is too large to fit onto an Arduino UNO's flash. Instead you can you use this code:

```c++
#include <Arduino.h>

#include <Adafruit_MMC56x3.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_MMC5603 mmc = Adafruit_MMC5603(12345);

int loopcount = 0;

// Hard-iron calibration settings
const float hard_iron[3] = {
    0, 0, 0
};

// Soft-iron calibration settings
const float soft_iron[3][3] = {
    { 1, 0, 0 },
    { 0, 1, 0 },
    { 0, 0, 1 }
};

void setup(void)
{
    Serial.begin(115200);
    while (!Serial)
        delay(10); // will pause Zero, Leonardo, etc until serial console opens

    Serial.println("Adafruit_MMC5603 Magnetometer Test");
    Serial.println("");

    /* Initialise the sensor */
    if (!mmc.begin(MMC56X3_DEFAULT_ADDRESS, &Wire)) { // I2C mode
        /* There was a problem detecting the MMC5603 ... check your connections */
        Serial.println("Ooops, no MMC5603 detected ... Check your wiring!");
        while (1)
            delay(10);
    }

    /* Display some basic information on this sensor */
    mmc.printSensorDetails();
}

void loop(void)
{
    static float hi_cal[3];
    // Get a new sensor event
    sensors_event_t event;
    mmc.getEvent(&event);

    // Put raw magnetometer readings into an array
    float mag_data[] = { event.magnetic.x,
        event.magnetic.y,
        event.magnetic.z };

    // Apply hard-iron offsets
    for (uint8_t i = 0; i < 3; i++) {
        hi_cal[i] = mag_data[i] - hard_iron[i];
    }

    // Apply soft-iron scaling
    for (uint8_t i = 0; i < 3; i++) {
        mag_data[i] = (soft_iron[i][0] * hi_cal[0]) + (soft_iron[i][1] * hi_cal[1]) + (soft_iron[i][2] * hi_cal[2]);
    }

    // 'Raw' values to match expectation of MOtionCal
    Serial.print("Raw:");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(int(mag_data[0] * 10));
    Serial.print(",");
    Serial.print(int(mag_data[1] * 10));
    Serial.print(",");
    Serial.print(int(mag_data[2] * 10));
    Serial.println("");

    // unified data
    Serial.print("Uni:");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(0);
    Serial.print(",");
    Serial.print(mag_data[0]);
    Serial.print(",");
    Serial.print(mag_data[1]);
    Serial.print(",");
    Serial.print(mag_data[2]);
    Serial.println("");

    delay(10);
}
```

which will output the magnetometer data correctly formatted at the correct baud rate. Then you just open up MotionCal, select the right port

  [1]: https://www.digikey.com/en/maker/projects/how-to-calibrate-a-magnetometer/50f6bc8f36454a03b664dca30cf33a8b
  [2]: https://learn.adafruit.com/adafruit-sensorlab-magnetometer-calibration/magnetic-calibration-with-motioncal
  [3]: https://github.com/PaulStoffregen/MotionCal/issues/11


body:
Good day to you all, I am asking here to confirm that my project is feasible. I have low knowledge of Arduino and other components. Please help me in achieving this project.

I already have the peristaltic pump and pH sensor working with Arduino uno. Now I want the output of the pH sensor to be displayed in a webpage or web app, In the webpage I will also make a formula on how much volume is released from the peristaltic pump.

So there are two things on my webpage output: the acidity of the liquid and the volume released. I want a wireless setup, so I guess I would use ESP32 (notsure)? Now I kind of getting hard on how to put it on a webpage and the important part is, how to pass the data from the arduino to the ESP32?. Any ideas? or things that I would do?

OR

I  would use the ESP32 alone since I have not so many components and I think the ESP32 can cater for the pHsensor (analog signal) and pwm (motor Peristaltic pump). Correct me if I'm wrong. By this, I won't be having problems about the communication to the arduino and esp32 (UART).

Additional Info:\
Current Set up-\
Arduino - controls the pump and pHsensor\
ESP32 - Webpage or webserver

Is there any way that I could do this with ESP32 alone? so that I won't be having problems with UART.

I want to thank you in advance for giving me insights.

Update:

by this I decided to use ESP32 alone for the whole project. I just need to rewire all. I'm hoping the ESP32 has PWM pins to control the pwm peristaltic pump and pHsensor(analog signal) pins. Please confirm if you know that ESP32 has these pins(for pwm and analog). By the way I'm using the ESP32S where the TXD0 is in pin 35 which is the GPIO1 and the RXD0 is in pin 34 which is the GPIO3. –
Johannes Remotigue
 2 days ago   Delete

title: A peristaltic pump with pH sensor and web based output project

Answers: 1

body:
Yes. You will need to add a solid state switch or similar to power the motor. The ESP32 has the radio needed to connect to your wifi so that part is already there. The ESP can be configured as a client or server so take your pick. There is a lot published on the web about doing this with code even posted. The device also has a lot of computing power so it could become a stand alone device which reports the results to the web server or works in conjunction with it.

All you will need to add is mainly code.  This should get you started. Just be cautious as the Arduino is generally 5V and the ESP is 3.3 volt so some voltage translation may be needed and if using 5V modules and/or MOSFETS. If MOSFETs are involved be very careful of the Vgs ratings to be sure it is on with 3V.


body:
My NodeMCU V3 got overheated and died. Please help me figure out what i did wrong.

Brief Desrip: Project is an RC Car on ESPNOW Protocol. Transmitter setup have an Arduino Nano to take values from Two analogue joysticks and sends to a NodeMCU through Tx & Rx Pins, which then Transmits the values to the NodeMCU V3 in my Receiver (An RC CAR) over ESPNOW Protocol. Transmitter side is working perfect.

But, the NodeMCU V3 in my Receiver setup has got overheated and Died during a full throttled action. Here I am attaching the wiring diagram of the receiver setup. Please help me figure out whether there is any issues with the wiring.

[![WIRING DIAGRAM ][1]][1]

  [1]: https://i.stack.imgur.com/92aTY.png

title: NodeMCU V3 GOT OVERHEATED AND DIED

Answers: 1

body:
Based on https://lastminuteengineers.com/l298n-dc-stepper-driver-arduino-tutorial/, you have wired your servo incorrectly. The third pin on the bottom blue connector (VSS) is the second input, not the output.

[![Power wiring diagram of the L298N][1]][1]

I can only speculate what happened, but I suspect that the servo tried to draw power from the D4 pin which overloaded and fried some internal circuitry of the ESP8266.

  [1]: https://i.stack.imgur.com/DQbwW.png


body:
I am learning to work with TinyML, and I have Arduino Nano 33 BLE Sense board connected to my desktop.

I would like to continue working from my laptop(s) even when I don't have a board with me.

Do you know if there is an emulator for this board that I could use to dome basic programming and exercises?

title: Emulator for Arduino Nano 33 BLE Sense and TinyML

Answers: 0


body:
I have followed [these instructions][1] to start using my new Uno R4 WiFi with the Arduino IoT Cloud. Everything works fine (even though sometimes the example screens do not exactly correspond with the actual screens). My Uno R4 WiFi is online and the online dashboard can switch the LED on and off even with the board powered from a battery and not physically connected via USB. **The only problem is that I still cannot upload a sketch via WiFi.** The instructions say:

> Once in the sketch tab, let’s open the board's drop down menu. There,
> a new option to connect our board should be available. The name of the
> board configured for the cloud will appear, followed by the
> Over-the-Air option.

But that drop down menu is not available and if I disconnect the USB I get `No associated device found` even though in Things-Setup the board is shown as being online.

Can someone explain what I am missing here? Or perhaps the Uno R4 WiFi is not compatible with the IoT cloud or the online IDE but that seems unlikely for a heavily advertised new WiFi product from Arduino.

  [1]: https://docs.arduino.cc/arduino-cloud/features/ota-getting-started?_gl=1*1rlls4d*_ga*Mjg3NTgyOTM5LjE2ODA4NjMxNDQ.*_ga_NEXN8H46L5*MTY5MDU3NDE2NS43MC4xLjE2OTA1NzQ4NzYuMC4wLjA.

title: Uno R4 WiFi board is online but no OTA option for upload

Answers: 0


body:
**What I want to do**: attach six buttons to a single input. Each button triggers a different action.

**How I want to do it**: Use an AD conversion and add a resistor with different values to each button so that you can distinguish between the different input signals
I use these values: 1k, 4.7k, 18k, 22k, 55k, 300k

Vcc is stable 3.3v but I also tried it on 5v. I use Vcc as reference value for the ADC.

**The problem I have**: no matter what I do I always read the same value on the ADC. Connected to  GND it reads 0 and on Vcc it reads a value that’s always the same regardless what resistor I actually use.

I tried a lot of things I’ve found on the internet but nothing really worked for me. I’m clearly doing something wrong

This is the method I call in `setup()` to initialize the converter on ADC2(pb4)

    void initADC()
    {
      // 8-bit resolution
      // set ADLAR to 1 to enable the Left-shift result (only bits ADC9..ADC2 are available)
      // then, only reading ADCH is sufficient for 8-bit results (256 values)

      ADMUX =
                (1 << ADLAR) |     // left shift result
                (0 << REFS1) |     // Sets ref. voltage to VCC, bit 1
                (0 << REFS0) |     // Sets ref. voltage to VCC, bit 0
                (0 << MUX3)  |     // use ADC2 for input (PB4), MUX bit 3
                (0 << MUX2)  |     // use ADC2 for input (PB4), MUX bit 2
                (1 << MUX1)  |     // use ADC2 for input (PB4), MUX bit 1
                (0 << MUX0);       // use ADC2 for input (PB4), MUX bit 0

      ADCSRA =
                (1 << ADEN)  |     // Enable ADC
                (1 << ADPS2) |     // set prescaler to 64, bit 2
                (1 << ADPS1) |     // set prescaler to 64, bit 1
                (0 << ADPS0);      // set prescaler to 64, bit 0
    }

The code is taken from here https://www.marcelpost.com/wiki/index.php/ATtiny85_ADC

The page seems to be down at the moment so here is an archived version of it
https://web.archive.org/web/20230128091128/https://www.marcelpost.com/wiki/index.php/ATtiny85_ADC

In the `loop()` method I do basically this: Read ADC and then blink an LED *n* times, based on the read value.

    ADCSRA |= (1 << ADSC);         // start ADC measurement
    while (ADCSRA & (1 << ADSC) ); // wait till conversion complete

    uint8_t adcValue = ADCH;

    if (adcValue >= 0 && adcValue < 32) {
      blink(1);
    } else if (adcValue >= 32 && adcValue < 126) {
      blink(2);
    } else if (adcValue >= 126 && adcValue < 193) {
      blink(3);
    } else if (adcValue >= 193 && adcValue < 227) {
      blink(4);
    } else if (adcValue >= 227 && adcValue < 245) {
      blink(5);
    } else if (adcValue >= 245 && adcValue <= 255) {
      blink(6);
    }
    delay(60000);

My breadboard has the resistors going from Vcc to an empty row and I connect a jumperwire from PB4 to one of these resistors and do an external reset of the microcontroller to test my setup. They share GND/Vcc

What am I doing wrong? What can I do to *debug* this?

Thanks

title: How to properly read ADC on an ATtiny85?

Answers: 1

body:
Unfortunately [@jsotola][1] only posted their solution as a comment. But it was the correct answer. So I'll just post my solution here

I now use a voltage divider setup with these values:

Voltage divider formula `Vs * R2 / (R1 + R2)`

Vs: 3.3v
R2: 100k Ohm
R1: 10k (3.0v), 27k (2.8v), 38k (2.6v), 50k (2.2v), 65k (2.0v)

Using an 8-bit ADC, I came up with these *if* statements to distinguish between the inputs. I gave it some room for deviation

    if (adcValue >= 227 && adcValue <= 237)
    {
      // 10k ohm (3.0V -> adc 232)
    }
    else if (adcValue >= 212 && adcValue <= 223)
    {
      // 18k ohm (2.8V -> adc 217)
    }
    else if (adcValue >= 196 && adcValue <= 206)
    {
      // 27k ohm (2.6V -> adc 201)
    }
    else if (adcValue >= 181 && adcValue <= 191)
    {
      // 38k ohm (2.4V -> adc 186)
    }
    else if (adcValue >= 165 && adcValue <= 175)
    {
      // 50k ohm (2.2V -> adc 170)
    }
    else if (adcValue >= 150 && adcValue <= 160)
    {
      // 65k ohm (2.0V -> adc 155)
    }

Here is a picture of my breadboard. I know it's not a real schematic but I couldn't figure that out right now. But I hope it's good enough

[![enter image description here][2]][2]

  [1]: https://arduino.stackexchange.com/users/40318
  [2]: https://i.stack.imgur.com/xl81z.jpg


body:
To collect temperature and BPM, I connected a max30101 in my Heltec WiFi kit V3 with ESP32. The data collected are stored in arrays to extract statistical features from signals which an algorithm will process to predict anxiety or baseline (with two other additional libraries).
The problem is that I see a very slow communication on the serial which increase if I add u8x8 library to print values on my builtin OLED. Thus, BPM are always very slow reaching a maximum of 20 BPM.

This is my code:

```
#include <PlaquetteLib.h> // --> Smoothing and scaling operations [https://sofapirate.github.io/Plaquette/]
using namespace pq; // --> use plaquette library as "pq"
Smoother smoother3(3.0f); // --> third moving mean of 3 seconds for ST values
Smoother smoother2(3.0f); // --> second moving mean of 3 seconds for HR values
#include <Wire.h> // --> I2C connection
#include "MAX30105.h" // --> Sparkfun library for MAX30101 sensor [https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library]
MAX30105 particleSensor; // --> used for BPM and ST
#include "Scaler.h" // --> Feature extraction library [https://github.com/eloquentarduino/everywhereml]
#include "Classifier.h" // --> Classification library containing Logistic Regression algorithm [https://github.com/eloquentarduino/micromlgen]
Eloquent::ML::Port::LogisticRegression clf; // --> declare classifier library
#include "heartRate.h" // --> Optical Heart Rate Detection (PBA Algorithm) [https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/blob/master/src/heartRate.h]
#include <Arduino.h>
#include <U8x8lib.h>
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(18, 17, 21);

//____________________________________________________________________________________________________________________________________________________________________________
//DEFINING GLOBAL VARIABLES
//hr
const byte RATE_SIZE = 3; //Averaging
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
//st
float degree; // --> raw peripheral skin temperature in °C
float st; // averaged peripheral skin temperature in °C
unsigned long time_printing = 0; // --> variables for millis delay (1Hz)
const byte WINDOW_SIZE = 60;
byte signal1[WINDOW_SIZE];
byte signal2[WINDOW_SIZE];
byte signal1Index = 0;
byte signal2Index = 0;

//_________________________________________________________________________________________________________________________________________________________________________
void setup() {

  //instrumental initialization
  //Serial.begin(9600);
  Plaquette.begin();
  Wire.begin(41, 42);
  u8x8.begin();

  //hr sensor
  particleSensor.begin(Wire, I2C_SPEED_FAST);
  byte ledBrightness = 0x1F;
  byte sampleAverage = 1;
  byte ledMode = 3;
  byte sampleRate = 100;
  int pulseWidth = 411;
  int adcRange = 4096;
  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
  particleSensor.setPulseAmplitudeRed(0); //0 mA
  particleSensor.setPulseAmplitudeIR(0);  // 0 mA
  particleSensor.setPulseAmplitudeGreen(0x19); // 1 mA

  //st sensor
  particleSensor.enableDIETEMPRDY();

  //u8x8.setFont(u8x8_font_8x13B_1x2_r);
  //u8x8.drawString(0, 4, "Initializing...");
  //delay(2000);
  //u8x8.clearDisplay();
  //u8x8.setFont(u8x8_font_open_iconic_check_4x4);
  //u8x8.drawGlyph(6, 2, 0x40);
  //delay(2000);
  //u8x8.clearDisplay();

  }

//_________________________________________________________________________________________________________________________________________________________________________
// BPM values with MAX30101 sensor 1Hz
void hrCollection() {
/**
* The particle sensor capture the green led emission from the inner wrist. When a blood pulse happen, the photodiode capture a pulse of light which corresponds to a heart beat.
* In order to be able to capture peaks throw the wrist, the green led has been accurately set up in the setup() section, following the instructions published by the authors
* on page 22 of the paper. [https://pdfserv.maximintegrated.com/en/an/AN6409.pdf]
* The peaks, corresponding to the BPM, are computed throw a PBA algorithm, then, they are averaged with a moving window of size 3.
*/
  long irValue = particleSensor.getGreen();

  if (checkForBeat(irValue) == true)
  {
    //We sensed a beat!
    long delta = millis() - lastBeat;
    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);

    if (beatsPerMinute < 255 && beatsPerMinute > 20)
    {
      rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
      rateSpot %= RATE_SIZE; //Wrap variable

      //Take average of readings
      beatAvg = 0;
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
      beatAvg /= RATE_SIZE;

    }
  }

  // Add beatAvg to signal1
  signal1[signal1Index] = beatAvg;
  signal1Index = (signal1Index + 1) % WINDOW_SIZE;

}

//_________________________________________________________________________________________________________________________________________________________________-
// ST values with the particle sensor 1Hz.
void stCollection() {
/**
* Peripheral skin Temperature has been measured in degree Celsius thanks to an InfraRed thermophile that capture the emissivity of the human skin.
*/

  degree = particleSensor.readTemperature();

  st = degree >> smoother3;

  // Add st to signal2
  signal2[signal2Index] = st;
  signal2Index = (signal2Index + 1) % WINDOW_SIZE;

}
//____________________________________________________________________________________________________________________________________________________________________________
// Feature Extraction
void extraction(float* features) {
  // Calculate minimum, maximum, mean, median, standard deviation, variance, skewness, and kurtosis for signal1 (beatAvg)
  int beatMin = INT_MAX;
  int beatMax = INT_MIN;
  float beatSum = 0.0;
  float beatSumSquares = 0.0;
  float beatSkewness = 0.0;
  float beatKurtosis = 0.0;
  byte sortedSignal1[WINDOW_SIZE];

  for (byte i = 0; i < WINDOW_SIZE; i++) {
    if (signal1[i] < beatMin) {
      beatMin = signal1[i];
    }
    if (signal1[i] > beatMax) {
      beatMax = signal1[i];
    }
    beatSum += signal1[i];
    beatSumSquares += pow(signal1[i], 2);
    sortedSignal1[i] = signal1[i];
  }

  float beatMean = beatSum / WINDOW_SIZE;

  std::sort(sortedSignal1, sortedSignal1 + WINDOW_SIZE);

  byte middle = WINDOW_SIZE / 2;
  byte beatMedian;
  if (WINDOW_SIZE % 2 == 0) {
    beatMedian = (sortedSignal1[middle - 1] + sortedSignal1[middle]) / 2;
  } else {
    beatMedian = sortedSignal1[middle];
  }

  float beatStdDeviation = sqrt((beatSumSquares / WINDOW_SIZE) - pow(beatMean, 2));
  float beatVariance = pow(beatStdDeviation, 2);

  for (byte i = 0; i < WINDOW_SIZE; i++) {
    float deviation = signal1[i] - beatMean;
    beatSkewness += pow(deviation, 3);
    beatKurtosis += pow(deviation, 4);
  }
  beatSkewness /= (WINDOW_SIZE * pow(beatStdDeviation, 3));
  beatKurtosis /= (WINDOW_SIZE * pow(beatStdDeviation, 4));

  // Calculate minimum, maximum, mean, median, standard deviation, variance, skewness, and kurtosis for signal2 (st)
  float stMin = FLT_MAX;
  float stMax = FLT_MIN;
  float stSum = 0.0;
  float stSumSquares = 0.0;
  float stSkewness = 0.0;
  float stKurtosis = 0.0;
  float sortedSignal2[WINDOW_SIZE];

  for (byte i = 0; i < WINDOW_SIZE; i++) {
    if (signal2[i] < stMin) {
      stMin = signal2[i];
    }
    if (signal2[i] > stMax) {
      stMax = signal2[i];
    }
    stSum += signal2[i];
    stSumSquares += pow(signal2[i], 2);
    sortedSignal2[i] = signal2[i];
  }

  float stMean = stSum / WINDOW_SIZE;

  std::sort(sortedSignal2, sortedSignal2 + WINDOW_SIZE);

  middle = WINDOW_SIZE / 2;
  byte stMedian;
  if (WINDOW_SIZE % 2 == 0) {
    stMedian = (sortedSignal2[middle - 1] + sortedSignal2[middle]) / 2;
  } else {
    stMedian = sortedSignal2[middle];
  }

  float stStdDeviation = sqrt((stSumSquares / WINDOW_SIZE) - pow(stMean, 2));
  float stVariance = pow(stStdDeviation, 2);

  for (byte i = 0; i < WINDOW_SIZE; i++) {
    float deviation = signal2[i] - stMean;
    stSkewness += pow(deviation, 3);
    stKurtosis += pow(deviation, 4);
  }
  stSkewness /= (WINDOW_SIZE * pow(stStdDeviation, 3));
  stKurtosis /= (WINDOW_SIZE * pow(stStdDeviation, 4));

  // Store the calculated features in the features array
  features[0] = beatMin;
  features[1] = beatMax;
  features[2] = beatMean;
  features[3] = beatMedian;
  features[4] = beatStdDeviation;
  features[5] = beatVariance;
  features[6] = beatSkewness;
  features[7] = beatKurtosis;
  features[8] = stMin;
  features[9] = stMax;
  features[10] = stMean;
  features[11] = stMedian;
  features[12] = stStdDeviation;
  features[13] = stVariance;
  features[14] = stSkewness;
  features[15] = stKurtosis;
}
//_____________________________________________________________________________________________________________________________________________________________________________

//_____________________________________________________________________________________________________________________________________________________________________________
void loop() {

  Plaquette.step();

  hrCollection();
  stCollection();

  float features[16]; // Create the features array
  extraction(features);

  if (!processor.transform(features))
  return;

  //Serial.print(beatsPerMinute); Serial.print(","); Serial.print(st); Serial.print(","); Serial.println(clf.predictLabel(processor.X));

  char heart[3];
  char temperature[2];
  u8x8.setFont(u8x8_font_open_iconic_embedded_2x2);
  u8x8.drawGlyph(4, 1, 0x46);
  u8x8.setFont(u8x8_font_lucasarts_scumm_subtitle_r_2x2_f);
  itoa(beatsPerMinute, heart, 10);
  u8x8.drawString(7, 1, heart);
  itoa(st, temperature, 10);
  u8x8.drawString(7, 3, temperature);
  u8x8.drawString(0, 5, clf.predictLabel(processor.X));
}

```

When I print on 9600 without u8x8 the printing is normal even if the problem with BPM persists, when I add u8x8 I see on the serial a very slow printing. 115200 baud rate doesn't show anything but empty squares. I am wondering if the problem could be the bad quality wires or I am making some mistake inside the code.

title: Slow I2C communication

Answers: 0


body:
I am using an Arduino Uno R3 to send instructions to a serial monitor in a Python program with Serial.println.  But when I send a specific line, I get a a `UnicodeDecodeError`.

The line in the Arduino code that causes this error is:

```
Serial.println("Press '1,2,3,4,5' to run motor at 10%, 20%, 30%, 40%, 50% for 2 seconds");
```

My Python code to read the serial data is:
```
def get_serial_data(self):
        while 1:
            try:
                serial_data = self.serial_connection.readline().decode('Ascii')
                filtered_serial_data = serial_data.strip('\r\n')
                self.serial_monitor.insert(END, filtered_serial_data)
            except TypeError:
                pass
```
and is called from a thread:
```
thread1 = threading.Thread(target=self.get_serial_data)
        thread1.daemon = True
        thread1.start()
```

But I get the following error:
```
UnicodeDecodeError: 'ascii' codec can't decode byte 0x85 in position 36: ordinal not in range(128)
```

Can anyone help why this is happening or how to fix, I saw a stackoverflow post to use a try, except block to get it to ignore this line, but I want to print it out, and I want to understand why I get this error.

title: How to fix UnicodeDecodeError when using Serial.println

Answers: 1

body:
I solved the issue.  It was a memory issue not a decoding issue.  Because the dynamic memory was mostly used up, it affected the encoding of the data.  Reducing the amount of memory my code was using resolved the issue.

I also discovered, that `Serial.println("some text")` uses a lot of dynamic memory.  So by reducing the amount of text I was encoding helped, but also by wrapping the the text in `F()`, like this:

```
Serial.println(F("some text"))
```
Which stores the string in flash memory not sram.  Heres a helpful link on the F function:

https://arduinogetstarted.com/faq/what-is-serial.println-f


body:
like discribed in the title my temperature sensor goes to -127 after a few minutes of run time, it works again after a restart, I have already replaced the sensor and I'm using the same code for the temperature which I had used before which has been running flawlessly for almost 6 months now, I really have no clue what I did wrong hopefully someone got an idea.

Thank you!

title: DS18B20 doesn't work reliably

Answers: 1

body:
There's a problem with using OneWire and Wire/I2C in one Sketch at once.

I believe this is because OneWire takes too long not sure, but this is probably why the temperature reading went to -127 after a while to fix thi.

I used an NTC 10K at 20°C. Below you can see code to make the NTC work and how to wire it!

Hope this helps!

Code:
```
#include <math.h>
const int thermistor_output = A1;

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

void loop() {
  int thermistor_adc_val;
  float output_voltage, thermistor_resistance, therm_res_ln, temperature;
  thermistor_adc_val = analogRead(thermistor_output);
  output_voltage = ( (thermistor_adc_val * 5.0) / 1023.0 );
  thermistor_resistance = ((5 * (10.0 / output_voltage)) - 10);
  thermistor_resistance = thermistor_resistance * 1000 ;
  therm_res_ln = log(thermistor_resistance);
  temperature = (1 / (0.001129148 + (0.000234125 * therm_res_ln) + (0.0000000876741 * therm_res_ln * therm_res_ln * therm_res_ln)));
  temperature = temperature - 273.15;
  Serial.print("Temperature in degree Celsius = ");
  Serial.print(temperature);
  Serial.print("\n");
  delay(1000);
}
```

Wiring:
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/aPGbo.png


body:
I have built a speedometer, based on this
youtube video: https://www.youtube.com/watch?v=gKuJxjxNP-k&t=34s

The speedometer is for a car, so it needs to be in real-time and accurate, with the actual speed that the car reads. The speedometer is built with a NEO-6m GPS module with an antenna. It is hooked up to an Arduino Nano and an OLED 0.96".

This is the code and wiring diagram. The code is the same as the video and uses TinyGps library. But simplified to just show me the current speed(kmh). I have removed every other line of code, to reduce latency.
[![Wiring diagram of speedometer. Uisng NEO-6M GPS, Nano, and OLED 0.96"][1]][1]

```

#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3 //unused
SoftwareSerial neogps(rxPin,txPin);

#include <TinyGPS++.h> //1.0.3
TinyGPSPlus gps;
//---------------------------------------------------------------------------
int x_max    = 128;       //OLED display width, in pixels
int y_max    = 62;        //OLED display width, in pixels
int x_center = x_max/2;
int y_center = y_max/2+10;
int speed;
int adjspeed;// Adjusted speed for oversetimation by car
int num_sat;

//satellite logo
#define sat_logo_width 20
#define sat_logo_height 20

const unsigned char sat_logo[] = {
  0x00, 0x01, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x60, 0x30, 0x00,
  0x60, 0x78, 0x00, 0xc0, 0xfc, 0x00, 0x00, 0xfe, 0x01, 0x00, 0xff, 0x01,
  0x80, 0xff, 0x00, 0xc0, 0x7f, 0x06, 0xc0, 0x3f, 0x06, 0x80, 0x1f, 0x0c,
  0x80, 0x4f, 0x06, 0x19, 0xc6, 0x03, 0x1b, 0x80, 0x01, 0x73, 0x00, 0x00,
  0x66, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x70, 0x00, 0x00
};
//---------------------------------------------------------------------------

//Program variables
double lat;
double lng;

void gauge() {

  //TOP LEFT: draw satellite logo and number of satellites
  u8g.drawXBM(0, 0, sat_logo_width, sat_logo_height, sat_logo);
  u8g.setPrintPos(18, 5);
  u8g.print(num_sat, 5);

  //---------------------------------------------------------------------------
  // Show Speed and align its position
  u8g.setFont(u8g_font_profont22);
  u8g.setPrintPos(54,60);

  if (adjspeed>99) {
    u8g.setPrintPos(47,60);
  }

  u8g.print(adjspeed);
  //---------------------------------------------------------------------------
}

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

  neogps.begin(9600);

  u8g.setFont(u8g_font_chikita);
  u8g.setColorIndex(1);
}

void loop(void){

  Read_GPS();

  //Display Data on Oled
  {
    u8g.firstPage();
    do {
      gauge();
    }
    while( u8g.nextPage() );
  }

}

void Read_GPS(){

  boolean newData = false;

for (unsigned long start = millis(); millis() - start < 100;)
  {
    while (neogps.available())
    {
      if (gps.encode(neogps.read()))
      {
        newData = true;
        break;
      }
    }
  }

  //If newData is true
  if(newData == true){
    newData = false;
    Get_GPS();
  }
  else {
    //no data
  }
}

void Get_GPS(){
  num_sat = gps.satellites.value();

  if (gps.location.isValid() == 1) {
    speed = gps.speed.kmph();
    adjspeed = 1.03*speed; // the speed is adjusted(increaed) to match the speed that the actuall car outputs. (Because there is a law stating that cars need to overestimate the actual speed by a little bit
    Serial.print("Speed: ");
    Serial.println(adjspeed);

  }
}
```

The speedometer is accurate and shows the right speed, but there is a latency of around 1-2 seconds. For example, if the car starts accelerating from 0, the OLED shows the speed 1-2 seconds later, the same with when the car brakes. I need the latency to be, at least, less than a second.

I'm a bit of a beginner and not sure how to reduce this latency. I was hoping for someone here to explain to me how I can reduce this latency

  [1]: https://i.stack.imgur.com/ymHbX.jpg

title: GPS speedometer with NEO 6M - latency issue

Answers: 0


body:
I'm currently working on a project using an ESP32 (the [Waveshare ESP32 Driver Board][1]), and I am trying to read data from an SD card, but consistently getting a "SD Card Mount Failed" error. I am using the [Adafruit SD card reader breakout board][2] and the Arduino IDE.

Here's how I've wired the SD card reader to the ESP32

```
SD card     ESP32
-------     -----
3.3V        3.3V
GND         GND
CLK         pin 18 (SCK)
DO          pin 19 (MISO)
DI          pin 23 (MOSI)
CS          pin 5 (SS)
```

And here's the relevant code I'm using to setup and test the SD card:

    #define SCK  18
    #define MISO  19
    #define MOSI  23
    #define CS  5

    int setup_sd_card() {

      SPIClass spi = SPIClass(VSPI);
      spi.begin(SCK, MISO, MOSI, CS);

      if (!SD.begin(CS,spi,80000000)) {
        Serial.println("ERROR: SD Card Mount Failed");
        return -1;
      }
      uint8_t cardType = SD.cardType();

      if(cardType == CARD_NONE){
        Serial.println("ERROR: No SD card attached");
        return -1;
      }

      // Code to print out SD card details...

      return 1;
    }

I've triple-checked my wiring but the code always fails at `if (!SD.begin(CS,spi,80000000))`. I've tried 3 different SD cards of different sizes, all formatted to FAT32 (64GB, 256GB, 1024GB)

Could the issue be related to the ESP32 not being a stock one because it has some hardware for driving an e-paper screen? Here is the schematic: https://www.waveshare.com/w/upload/8/80/E-Paper_ESP32_Driver_Board_Schematic.pdf

[![Waveshare ESP32 Schematic][3]][3]

Can anyone suggest what might be the issue or what else I could try to debug this problem? Any help would be greatly appreciated.

  [1]: https://www.waveshare.com/e-paper-esp32-driver-board.htm
  [2]: https://www.adafruit.com/product/254
  [3]: https://i.stack.imgur.com/cQCu6.jpg

title: SD Card Mount Failed with Waveshare ESP32 using Arduino IDE

Answers: 2

body:
The issue turned out to be a faulty SD card.

I had tried other SD cards but must have used incorrect wiring for them.

EDIT: Here is the updated code:

    #define CS        5
    #define SCK       18
    #define MOSI      23
    #define MISO      19

    SPIClass spi(VSPI);

    int setup_sd_card() {
      spi.begin(SCK, MISO, MOSI, CS);

      if (!SD.begin(CS,spi,4000000)) {
        Serial.println("ERROR: SD Card Mount Failed");
        delay(1000);
        return -1;
      }
      Serial.println("Finished initializing SD card. Getting card type...");

      uint8_t cardType = SD.cardType();

      if(cardType == CARD_NONE){
        Serial.println("ERROR: No SD card attached");
        delay(1000);
        return -1;
      }

      Serial.print("SD Card Type: ");
      if (cardType == CARD_MMC){
        Serial.println("MMC");
      } else if(cardType == CARD_SD){
        Serial.println("SDSC");
      } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
      } else {
        Serial.println("UNKNOWN");
      }
      Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
      Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));

      Serial.println("SUCCESS! (SD CARD)");

      return 1;
    }

body:
There are at least two problems with your code.

First I think you have a typo in the frequency. Default frequency is 4 MHz, but your parameter in `begin` is 80 MHz, which I doubt will work.

You initialize the `spi` object on the stack in the function and then supply it to the SD instance. The `spi` object on stack will be removed when the function ends and the SD object will crash. It has to be an allocation on heap as `SPIClass* spi = new SPIClass(VSPI);` or a global variable `SPIClass spi(VSPI);`.

And since you use the default pins of VSPI you can use just `spi.begin()` without the pin numbers.


body:
I'm using an ESP32 and it's fine, I have no issues at all.
I was just curious that after flashing a new firmware via OTA, like this:

```
#include <ESPAsyncWebSrv.h>
#include <Update.h>

void http_page_flash(AsyncWebServerRequest* request) {
    if (!check_auth(request)) {
        return request->requestAuthentication();
    }

    request->send_P(200, "text/html", flash_html, http_page_flash_processor);
}

void http_api_flash(AsyncWebServerRequest* request) {
    if (!check_auth(request)) {
        return request->requestAuthentication();
    }

    ESP.restart();
}

void http_api_flash_part(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final) {
    if (!check_auth(request)) {
        return request->requestAuthentication();
    }

    if (index == 0) {
        if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
            Update.printError(Serial);
            request->redirect("/flash?status=error&message=" + String(Update.errorString()));
        }
    }

    if (len) {
        if (Update.write(data, len) != len) {
            Update.printError(Serial);
            request->redirect("/flash?status=error&message=" + String(Update.errorString()));
        }
    }

    if (final) {
        if (Update.end(true)) { //true to set the size to the current progress
            request->redirect("/flash?status=success");
        }
        else {
            Update.printError(Serial);
            request->redirect("/flash?status=error&message=" + String(Update.errorString()));
        }
    }
}
```

`time()` result doesn't seem to re-set to 0.
When accessing newly submitted entries which are time-based, they are timestamped as if the board never reset to 0, but all my entries are reset to 0 (so the memory is being reset):

```
void device_data::push(int co2_ppm, float rh, float temp_c, int sensor_status, unsigned long sequence_number) {
    unsigned long now = (unsigned long)time(NULL);

    current_ventilation_state_co2 = determine_current_ventilation_state(current_ventilation_state_co2, co2_ppm, global_config_data.co2_ppm_low, global_config_data.co2_ppm_medium, global_config_data.co2_ppm_high);
    current_ventilation_state_rh = determine_current_ventilation_state(current_ventilation_state_rh, rh, global_config_data.rh_low, global_config_data.rh_medium, global_config_data.rh_high);

    latest_measurement.relative_time = now;
    latest_measurement.set_co2(co2_ppm);
    latest_measurement.set_rh(rh);
    latest_measurement.set_temp(temp_c);
    latest_measurement.sensor_status = sensor_status;
    latest_measurement.sequence_number = sequence_number;
    latest_measurement.state_at_this_time = get_highest_ventilation_state(current_ventilation_state_co2, current_ventilation_state_rh);

    very_short_data.pushOverwrite(latest_measurement);
    // ...
}
```
The data is completely reset as the ring buffer is back to being size=0, but `now` is not close to 0, it's just increased as if it completely survived the `ESP.restart()` call.

I'm just curious, is this by design? Is this a bug?
Is `time()` somehow saved to flash? Or to some special restart-persistent memory?
I use the flash to store my configuration, but I never store or restore the time in any of my configuration.

If it's some special static ram which is not flash storage, can I also access this for my own purposes?

title: `time()` doesn't reset to 0 when calling `ESP.restart();` on ESP32?

Answers: 0