body:
I have a problem with a project where one servo is resetting (browning out) two Arduino Pro Minis running 3.3v/8mHz. The two Arduinos are connected by SoftwareSerial on pins 9 and 10 and the slave sends yaw data to the master Arduino obtained from an MPU9250 breakout board. The power supply can supply 1 A of current. The servo is a small 2g servo that takes 3.3v at 50mA when moving (measured, not from the datasheet). Everything is hooked up on a breadboard. In case you're wondering, I am using an adaptation of the ServoTimer2 library to control the servos so as to not interfere with SoftwareSerial. I am baffled as to why one small servo is resetting two Arduinos. The Arduinos, along with the MPU9250, are only drawing 10mA. Could back EMF be causing the brownout?

In the past, I have done a similar circuit but with only one Arduino obtaining sensor data and not sending it over SoftwareSerial. This works completely fine with two servos, a Pro Mini, and an MPU9250 breakout board. This leads me to think it is some sort of software issue.

I have already received some guidance on the Arduino Discord stating to connect ceramic capacitors close to the servos, and this seems to sort of work, but I'm wondering if there might be a software way to do it with the least number of components possible.

Any help would be greatly appreciated!

title: How can I get servos to not brownout my Arduinos and power supply?

Answers: 2

body: You are seeing classic signs of power supply overload. Those motors can draw upto 10x there operating current when starting. Transients etc that are occuring are to fast for your meter to see but the electronics does. To view that you need a scope and a current probe. My recommendation is to get a larger power supply probably in the 3A range.

body:
_Note: Commonly you cannot use software to circumvent physics._

Your symptoms show that the initial current of the servo is too high for your power concept to maintain the voltage. Therefore your Nanos brown out.

An electric motor can easily take a multiple of its average current on acceleration. If blocked, and in the first moment it _is_ blocked by the inertia, you can observe factors in low tens. From 50 mA to 1 A it's just a factor of 20...

Please note that servos often control their motors with PWM, and you measure only the average. During the "active" state the current is higher, and depending on the motor's inductive properties can have "strange" wave forms.

Additionally, each wire adds an inductive and resistive component in series with your Nanos and the servo. The shorter and thicker the wires, the better.

So your case looks quite simple, and you have options:

- Decouple your power supply with appropriate capacitors. Ceramics with some tens of nF and an electrolyte or tantalum capacitor with some µF are common to provide the necessary current "reservoir" for the initial moment in different frequency ranges. Put them near the servo(s).
- Use a separate power supply for the servo(s). Do not forget to connect the grounds. But also here you might need capacitor(s) to avoid browning out the servo.


body:
I am currently researching OTA updates for ESP8266 firmware, and I have a question that I couldn't find an answer to:

Question: Is the number of OTA updates limited? According to the [documentation][1], it states: "The flash chip size should be large enough to hold the old sketch (currently running) and the new sketch (OTA) at the same time." Does this mean that the old sketch always remains, and with each new update, the previous versions continue to exist? If so, does this imply that after multiple updates, the flash memory will eventually be full, preventing any further updates?

Thank you for your assistance.

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#ota-basic-requirements

title: Understanding ESP8266 OTA Updates: A Question on Limitations

Answers: 2

body: No each update overrites the oldest one (if present) so there are only ever a maximum of 2 versions in flash

body:
This statement takes mainly two reasons into account:

1. The OTA update needs a complete sketch that executes the update. Overwriting a running sketch with an update crashes in almost all cases.
1. An OTA update can be disrupted or fail, as a wireless connection is notoriously unreliable. The device needs a working sketch after such events.

That's why the device stores the new sketch in a space separated from the old sketch.

But as soon as the "download" is complete and hopefully checked (by a hash or other means of checksum) to be error-free and valid, the old sketch is not needed any more. The system "switches" from the old sketch to the new sketch, in your case the bootloader overwrites the old sketch with the new sketch, see [the last part of the documentation][1] you link to.

The space after the now running new sketch is again free for the next OTA update.

However, there is a physical limit caused by [flash memory wear][2]. Commonly this is far away from the number of OTA updates a device will have in its lifetime.

  [1]: https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#update-process-memory-view
  [2]: https://en.wikipedia.org/wiki/Flash_memory#Memory_wear


body:
I am looking at refactoring my code by implementing callback functions in order to be able to reuse the abstract logic of other functions/classes.

However, I feel I need to learn more about the limits of callback functions on embedded systems like the teensy 4.0 I'm using. The reason I ask is because - if I'm correctly informed - std::function is adviced against on embedded systems due to memory overhead. Another reason for asking is that the functions I want to use for callback might run the risk of violating the principle of keeping callback functions short.

I've consulted the chapter devoted to embedded programming principles in Stroustrup's Programming: Principles and Practice Using C++. Unfortunately, he doesn't give advice on callback functions for embedded systems, specifically.

I understand I can simply rely on a trial and error methodology using function pointers, but figured I'd ask for your experience and advice before I rewrite a lot of code. In other words, I'm asking for good principles and guidelines.

title: How do I write efficient callback functions on a Teensy 4.0?

Answers: 1

body:
I have been using callbacks quite intensively on an Arduino Mega 2560,
for managing RS-485 messages. This board has roughly 8 times less flash
and 128 times less RAM than your Teensy. However, as the AVR core does
not support `std::function`, I used the good old C idiom for defining
callbacks:

```c++
void MyClass::register_callback(
        void (*callback)(some_type some_data, void *callback_data),
        void *callback_data);
```

It is up to the caller to nicely pack all the state needed by the
callback into a `struct`, and pass a pointer to this `struct` as the
last argument of `register_callback()`. The class will record both the
function pointer and the `void*` pointer. When the expected event
happens, the class calls the callback, giving it the saved `void*` as
its last argument. The callback then casts this pointer to a pointer to
the expected `struct`, and now it can access the state it needs.

Yes, this is a bit clumsy, but it is a tried and true way of handling
callback state in plain C. And the cost is marginal, especially for your
board that has orders of magnitude more resources than my Mega.

If you are afraid of the cost of `std::function`, I suggest you
implement a simple callback example using this method, then using
`std::function`, and you compare the memory usage. If the cost of
`std::function` turns out to be significant, you can always go the C
way. I suspect `std::function` will be just fine, and it really is more
convenient than handling the function pointer and the state as separate
arguments.


body:
I am  using an arduino Micro to generate 8 square waves on 8 pins. The idea is as follows: on pin 13 is the main square wave. It represents a certain BPM (beats per minute). The other 7 pins should give multiplications or divisions of that BPM.

It uses timer1 to trigger an interrupt at BPM/192 (this number is choosen to enable easy multiplications). It counts those interrupts and changes the states of the outputs when needed.

The codes seems to run fine for most divisions and most multiplications. However in certain cases like /2, there seem to be shorter pulses from time to time that throw the whole timing off.

Adding a short delay at the end of the loop seems to make the system more stable but still the short pulses appear from time to time.

Does anyone have an idea what the problem might be.

[![Oscilloscope reading][1]][1]

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

```
int counter[8] = {0,0,0,0,0,0,0,0}; //storing number of interrupts since last pulse
int trip[8] = {191,383,767,1535,3071,6143,12287,24575}; //number of interrupts needed for div/mult
int outputPin[8] = {13,12,11,10,9,8,7,6};

void setup() {

  for (int x = 0; x < 8; x++){

    pinMode(outputPin[x], OUTPUT);
    digitalWrite(outputPin[x], HIGH);

  }

  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A =2602; // 16000000 / (x * 8) -1
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10);//prescaler of 8
  TIMSK1 |= (1 << OCIE1A);
  sei();

}

void pulse(){

  for (int count = 0; count < 8; count++){

    counter[count]++;

  }

}

ISR(TIMER1_COMPA_vect){

  pulse();
}

void loop() {

  for (int y = 0; y < 8; y++){

    if(counter[y] > trip[y]){

      digitalWrite(outputPin[y],!digitalRead(outputPin[y]));
      counter[y] = 0;

    }

  }

  delayMicroseconds(100);

}
```

title: Square wave generator generates a shorter pulse from time to time

Answers: 1

body:
There are two issues here:

 1. There is a data race on `counter[]`: it can be modified in interrupt
    context while it is being read (or even modified) by the main
    program.

 2. Clearing `counter[y]` will make you loose ticks if for some reason
    (say some interrupt) you do it a little bit late. You should instead
    decrement it by `trip[channel]`.

Here is a safe way of managing the counters:

```c++
volatile int counter[8] = {...};  // don't forget `volatile`

// Return whether this channel has tripped, and update the count.
bool tripped(int channel) {
    noInterrupts();
    bool did_trip = counter[channel] >= trip[channel];
    if (did_trip) counter[channel] -= trip[channel];
    interrupts();
    return did_trip;
}

void loop() {
    for (int y = 0; y < 8; y++)
        if (tripped(y))
            digitalWrite(outputPin[y], !digitalRead(outputPin[y]));
}
```

Notice that the critical section (the section with interrupts disabled)
lives within the `for` loop, rather than around it. It is better to have
multiple small critical sections rather than one large one.

**Edit 1**: You don't need the delay. It makes the system “more stable”
because it reduces the likelihood that, on any given TIMER1\_COMPA
interrupt, the main program is accessing the counters (as it will spend
most of its time delaying). Adding this delay is in a way treating the
symptoms rather than the root cause of the data race.

**Edit 2**: Answering a comment. If you want the squares waves to stay
in sync, their frequency ratios should be integers. In your program,
this is almost, but not quite the case. For example, if you look at the
ratio between the first two channels:

channel 0: 191 interrupts per signal toggle
channel 1: 383 interrupts per signal toggle
ratio: 383 ÷ 191 ≈ 2.0052

The easy fix is to add 1 to every element of the `trip` array (384 ÷ 192
is _exactly_ 2).


body:
I just got an AVR ASP mkII external programmer and I am unsuccessfully trying to program my arduino with it.

All the settings in the IDE are correct. This is the error message that I am getting:
`avrdude: usbdev_open(): cannot open device: Permission denied`

Typing `lsusb` in a terminal, I am able to see the programmer.
`Bus 001 Device 007: ID 03eb:2104 Atmel Corp. AVR ISP mkII`

title: Unable to program with AVR ISP mkII under Linux

Answers: 0


body:
I am working on a project using a Rotary Encoder and I am trying to recieve the output from the encoder. As it stands I am able to get a count for degrees of change and direction of rotation, however depending on the speed the encoder spins I get a varying rotational output. For example if I rotate it slowly I can get 100's of counts for 180 degrees of rotation, but if I do so fast, then I could get 10 or so counts.

I believe my Arduino is running too slow to count each of the signals from the encoder, I measured the wavelength of a signal to be ~25 us when spun quickly but using the following code I found that my arduino is running at a loop rate of 200 loops per second.
```
void loop() {
  if(counter <= 1000){
    counter++;
    Serial.println(counter);
  }
}
```

The code for the Rotary Encoder:
Dt and Clk pin representing the 2 signal wires, both being pulled up
```
void loop(){

  //take clk pin state
  clkState = digitalRead(clkPin);

  //if clk state changed then wheel is rotating, react to rising edge to avoid double count
  if(clkState != preClkState && clkState == HIGH){
    Serial.write(digitalRead(dtPin));
    //check direction of spin based on dtpin
    if(digitalRead(dtPin)== HIGH){
      counter++;

      clockwiseDirection = true;
    }else{
      counter--;

      clockwiseDirection = false;
    }

    //output values
    Serial.write("Direction: ");
    if(clockwiseDirection){
      Serial.write("Clockwise | Counter: ");
    }else{
      Serial.write("Counter Clockwise | Counter: ");
    }

    Serial.print((int)counter);
    Serial.print("\n");

  }

  //update pre pos
  preClkState = clkState;

}
```

Thanks in advance.

title: Not registering complete rotary encoder input

Answers: 1

body:
Serial transmission takes time. Let's assume that you have set up the `Serial` with 9600 baud. This means 9600 bits per second. A single byte transmission commonly consists of a start bit, the data bits, and a single stop bit. This gives a total of 10 bits per byte. Therefore, your transfer rate is 9600 bits/s / 10 bits/byte = 960 bytes/s.

Estimating with a quick look at your source, each loop of your sketch sends about 40 characters, commonly encoded as a byte per character. And you claim that it achieves 200 loops per second, so the transfer rate is 40 bytes/loop * 200 loops/s = 8000 bytes/s.

Calculating back to bits/s results in a baudrate of roughly 80000 bits/s. So presumably you set up your `Serial` with 57600 or 115200 baud.

---

How to solve the issue?

Separate the acquisition of the encoder data from the transmission of the counter value. You can use interrupts, for example on the clock signal. However, this is not for the faint heart.

The `Serial` uses a transmission buffer of unspecified size. See the last paragraph of [its documentation][1]:

> As of Arduino IDE 1.0, serial transmission is asynchronous. If there is enough empty space in the transmit buffer, `Serial.write()` will return before any characters are transmitted over serial. If the transmit buffer is full then `Serial.write()` will block until there is enough space in the buffer. To avoid blocking calls to `Serial.write()`, you can first check the amount of free space in the transmit buffer using `availableForWrite()`.

You can check that the transmit buffer has room for your message. Send only, if there is enough room.

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


body:
I was learning/building with a new Arduino Nano ESP32 yesterday and left the Arduino IDE running overnight on Ubuntu 23.04 and it used all the space on my hard drive to write log files which broke my system till I booted in with a pen drive and removed some files to make space to then boot normally and find out what the problem was.

How can I limit the size of these log files, or even disable them?

title: Arduino IDE v 2.2.1 log file not limited in size (on Ubuntu 23.04)

Answers: 0


body:
I have rigged two different DHT22 sensors to an Arduino Nano board. Both temperature readings are more or less comparable but they produce very different humidity readings.

The sensors are:

 - Sensor No. 1 is an [IDUINO-Version of the DHT22][1] on PIN 2
 - Sensor No. 2 is a [DHT22 in Grove version from Seeeds Studio][2] on PIN 3

The simple code is build on one of the basic examples as followed:

    #include "DHT.h"
    #define DHTPIN_2 2     // Digital pin connected to the DHT sensor_1
    #define DHTPIN_3 3     // Digital pin connected to the DHT sensor_2
    #define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
    #define DHTTYPE_11 DHT11   // DHT 11  (AM2302), AM2321

    DHT dht_1(DHTPIN_2, DHTTYPE);
    DHT dht_2(DHTPIN_3, DHTTYPE);

    void setup() {
      Serial.begin(9600);   //consider baud in serial monitor!
      Serial.println(F("DHT22 test!"));
      dht_1.begin();
      dht_2.begin();
    }

    void loop() {
      delay(5000);
      float h_1 = dht_1.readHumidity();
      float t_1 = dht_1.readTemperature();
      float h_2 = dht_2.readHumidity();
      float t_2 = dht_2.readTemperature();

      //Check if any reads failed and exit early (to try again).
      if (isnan(h_1) || isnan(t_1)) {
        Serial.println(F("Failed to read from DHT sensor_1!"));
        return;
      }

      // Check if any reads failed and exit early (to try again).
      if (isnan(h_2) || isnan(t_2)) {
        Serial.println(F("Failed to read from DHT sensor_2!"));
        return;
      }
      Serial.print(F("Humidities: "));
      Serial.print('\n');
      Serial.print(F("s_1: "));
      Serial.print(h_1);
      Serial.print(F(" s_2: "));
      Serial.print(h_2);
      Serial.print('\n');
      Serial.print(F("Temperatures: "));
      Serial.print('\n');
      Serial.print(F("s_1: "));
      Serial.print(t_1);
      Serial.print(F(" s_2: "));
      Serial.print(t_2);
      Serial.print('\n');
    }

The resulting output on the Serial Monitor is:

    Temperatures:
    s_1: 25.30 s_2: 23.40
    Humidities:
    s_1: 6.20 s_2: 66.40
    Temperatures:
    s_1: 25.20 s_2: 23.40
    Humidities:
    s_1: 6.00 s_2: 66.10
    Temperatures:
    s_1: 25.10 s_2: 23.40
    .
    .
    .
The humidity reading from sensor_1 seems defective, just having the 10th of the value of sensor_2. Is there a fix for that? Is it possible to re calibrate sensor_1 or is it broken?

Thank you!

## Edit: swapping the sensors (suggested by jsotola) ##
The output results in:

    Temperatures:
    s_1: 22.60 s_2: 24.70
    Humidities:
    s_1: 67.80 s_2: 7.30

Its the sensor it seems.

  [1]: https://alexnld.com/product/am2302-dht22-temperature-and-humidity-sensor-module-for-arduino-scm/
  [2]: https://wiki.seeedstudio.com/Grove-Temperature_and_Humidity_Sensor_Pro/

title: Incorrect reading from DHT22 (on a Nano board)

Answers: 1

body:
The difference in humidity readings may be traced to any number of reasons including faulty parts, incorrect programming or low voltages (*please post at what voltage you are running the sensors at*) to name a few.

Let us speculate that one of the sensors is reporting relative humidity and the other absolute.  Absolute humidity does not consider temperature where as relative does.  From [this web site][1] we get the following conversion equation:

[![relative to absolute humidity equation][2]][2]

This equation converts relative humidity to absolute. Finding the saturation vapor pressure measured in pascal is not trivial.  So we will use [this web site][3] to calculate this value.

Let us use the sample:

 - Temperature 1: 22.60 C
 - Temperature 2: 24.70 C
 - (assumed) Relative Humidity: 67.80 %
 - (assumed) Absolute Humidity: 7.30

So, average temperature is 23.65 C.
Using this temperature and the above web page, the vapor pressure is 2923 PA.

AH = (67.80 x 2923) / (462.5 x (273.15 + 23.65) x 100)
AH = 0.014437 Kg/(meter cubed)

As absolute humidity is normally written as grams per cubic meter:

AH g/(meter cubed) = 0.014437 * 1000 = 14.43 g/(meter cubed)

14.43 is not 7.30.  Consider your options.  Check your circuit, voltages and software (*does varying the amount of time between samples result in different values*). Also consider running more tests in better conditions (*placing both sensors inside the same sealed container over a long period of time to mitigate exposure to different conditions*).

---
Added later...

Evidently problems with the DHT11 humidity sensor is a known problem:

 * [Arduino.cc forum][4]
 * [Partical.io forum][5]
 * [Raspberry Pi forum][6]
 * [Another from Arduino.cc form][7]

  [1]: https://www.omnicalculator.com/physics/absolute-humidity#relative-humidity
  [2]: https://i.stack.imgur.com/MouhZ.jpg
  [3]: https://www.weather.gov/epz/wxcalc_vaporpressure
  [4]: https://forum.arduino.cc/t/dht11-temp-ok-but-rh-values-wildly-off/94396
  [5]: https://community.particle.io/t/inaccurate-humidity-with-dht22-bad-sensor/24637
  [6]: https://forums.raspberrypi.com//viewtopic.php?f=37&t=101860
  [7]: https://forum.arduino.cc/t/humidity-sensors-very-inaccurate/174810


body:
We have Arduino IDE code that oscillates a plate on a lead screw powered by stepper motor to move back and forth.

We have the lead screw move 8 mm in one direction, then 8 mm in the opposite direction, for a total displacement of 16 mm. After this movement we have a counter that will then count as 1 "revolution" essentially. After reaching a specified count that program will stop.

Currently the program continues to run indefinitely. Any help/suggestions would be appreciated.

```c++
// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type.
// Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(40000);
  stepper.setAcceleration(20000);
}

void loop() {
  static int counter = 0; // Initialize a counter variable and start at 0

  // Set the target position:
  stepper.moveTo(400); // is in steps. setting to default

  // Run to target position with set speed and acceleration/deceleration:
  stepper.runToPosition();

  delay(0);

  // Move back to zero:
  stepper.moveTo(0);
  stepper.runToPosition();

  delay(0); //microseconds
  counter++; //adds 1 to the counter

  if (counter >= 2) {
    return; //exit the loop
  }
}
```

title: We have Arduino IDE code that needs to stop after a set number of "revolutions"

Answers: 1

body:
    if (counter >= 2) {
        return; //exit the loop
      }

The return statement will end the loop, but the loop function is called over and over repeatedly.  So it will just start over again.

There are a few possibilities here.  You can replace the `return` statement with `while(1);` which will lock up execution there until the board is reset.

If you don't need the loop function to repeat ever then you can simply move all of your code into the setup function as it will only run once.  Then the loop function can just be empty.

And lastly, you could add a boolean variable and put the code you want to run only sometimes under an if statement that checks that variable.  At the end of the process you set the variable to false to stop the other code from running.  This would allow you to add code later to set it back at the press of a button or something in case you wanted the option to start the process again.

    bool running = true;
    void loop(){
      if(running){
          // do things
      }
      if (counter >= 2){
        running = false;
      }
    }


body:
I cannot install the esp_camera library. When I try to add the .zip, I get "does not contain a valid library.

Everything about this ESP-32 Cam seems to rely on that library, and I can't find a way to install from https://github.com/espressif/esp32-camera or any other way.

Thanks.

title: Impossible to install the esp_camera library

Answers: 1

body:
It's not a "library" in the way that the Arduino system uses the term. That is, it's not designed to be placed under `<sketchbook>/libraries` directory way typical Arduino libraries are.

The good news is that you don't need to install it, because you already have it. It comes as part of the SDK files packaged into the ESP32 Arduino core as it is installed through the boards manager.

You'll find the header various places under the `<arduino15>/packages/esp32/hardware/esp32/<version-number>/tools/sdk/esp32<architecture>/include/esp32-camera/driver/include/esp_camera.h` where arduino15 refers to [this](https://support.arduino.cc/hc/en-us/articles/360018448279-Open-the-Arduino15-folder), `version` refers to whatever version of the board package you have installed, and `architecture` is nothing, or `c2`, `s3`, or various other related esp32 suffixes.

The bulk of the code being in `<arduino15>/packages/esp32/hardware/esp32/<version>/tools/sdk/esp32<architecture>/lib/libesp32-camera.a`


body:
Hello fellow arduino users! I have a question regarding using the Sparkfun Canbus shield in conjunction with the LSM6DS33 sensor on a dual SPI configuration. I have managed to get theese two to initialize but after reviewing the data it seems that the accelerometer is sending wrong readings... I am guessing the SPI devices mess with each other. Any idea on how to fix this? I am using an UNO R3 and here is the code:
```
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <Canbus.h>
#include <TinyGPS++.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>
#include <Keypad.h>
#include <Adafruit_LSM6DS33.h>
#define LSM_CS 9
#define LSM_SCK 13
#define LSM_MISO 12
#define LSM_MOSI 11
Adafruit_LSM6DS33 lsm6ds33;
TinyGPSPlus gps;
SoftwareSerial ss(3,2);
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad membrane = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
String s;
int IATMP;
float MAF;
int VSPD;
int RPM;
float MAF2=0.0;
float DeltaMAF=0.0;
char iatbuffer[64];
char mafbuffer[64];
char vspdbuffer[64];
char rpmbuffer[64];
unsigned long currtime;
unsigned long deltatime;
const unsigned char UBLOX_INIT[] PROGMEM={
0xB5,0x62,0x06,0x08,0x06,0x00,0xC8,0x00,0x01,0x00,0x01,0x00,0xDE,0x6A
};

//********************************Setup Loop*********************************//
void setup() {
  ss.begin(9600);
  //Initialize Serial communication for debugging
  Serial.begin(115200);
  while (!Serial){
    delay(10); }
  for(unsigned int i=0;i<sizeof(UBLOX_INIT);i++){
    ss.write(pgm_read_byte(UBLOX_INIT+i));
    }

  if(Canbus.init(CANSPEED_500))  /* Initialize MCP2515 CAN controller at the specified speed */
  {

    Serial.println(F("CAN Init Ok"));
    delay(1500);
  }
  else
  {

    Serial.println(F("Can't init CAN"));
    return;
  }

if (!lsm6ds33.begin_SPI(LSM_CS, LSM_SCK, LSM_MISO, LSM_MOSI)) {
    Serial.println(F("Failed to find LSM6DS33 chip"));
    while (1) {
      delay(10);
    }
  }

Serial.println(F("LSM6DS33 Found!"));
lsm6ds33.setAccelRange(LSM6DS_ACCEL_RANGE_2_G);
lsm6ds33.setGyroRange(LSM6DS_GYRO_RANGE_125_DPS);
lsm6ds33.setAccelDataRate(LSM6DS_RATE_12_5_HZ);
lsm6ds33.setGyroDataRate(LSM6DS_RATE_12_5_HZ);
lsm6ds33.configInt1(false, false, false);

/*int i=0;
char input = membrane.getKey();
char usrid[4]={0};
while(!input){}
if (input){
  usrid[i]=input;
  i++;
  }
input = membrane.getKey();
while(!input){}
if (input){
  usrid[i]=input;
  i++;
  }
input = membrane.getKey();
while(!input){}
if (input){
  usrid[i]=input;
  i++;
  }
input = membrane.getKey();
while(!input){}
if (input){
  usrid[i]=input;
  i++;
  }
s= String(usrid);
*/

}

//********************************Main Loop*********************************//
void loop(){

while(ss.available()>0){

gps.encode(ss.read());
if(gps.location.isUpdated()){
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
lsm6ds33.getEvent(&accel, &gyro, &temp);
currtime=millis();
Serial.print(s);
Serial.print(",");
Canbus.ecu_req(MAF_SENSOR,mafbuffer);
   MAF2=MAF;
   MAF = atof(mafbuffer);
    DeltaMAF=MAF-MAF2;
  // Serial.print("Engine RPM: "); //Uncomment for Serial debugging
      Serial.print(mafbuffer);
      Serial.print(F(","));
      Serial.print(DeltaMAF);
      Serial.print(F(","));
      delay(10);
Canbus.ecu_req(VEHICLE_SPEED,vspdbuffer);
    VSPD = atoi(vspdbuffer);
    //Serial.print("Engine RPM: "); //Uncomment for Serial debugging
      Serial.print(vspdbuffer);
      Serial.print(F(","));
      delay(10);
Canbus.ecu_req(IAT,iatbuffer);
    IATMP = atoi(iatbuffer);
    //Serial.print("Engine RPM: "); //Uncomment for Serial debugging
      Serial.print(iatbuffer);
      Serial.print(F(","));
      delay(10);

Canbus.ecu_req(ENGINE_RPM,rpmbuffer);
    RPM = atoi(rpmbuffer);
    //Serial.print("Engine RPM: "); //Uncomment for Serial debugging
      Serial.print(rpmbuffer);
      Serial.print(F(","));
      delay(10);
     if (RPM>800){
      Serial.print(F("idling"));
      Serial.print(F(","));
      }else{
        Serial.print(F("running"));
        Serial.print(F(","));
        }

Serial.print(accel.acceleration.x);
Serial.print(F(","));
Serial.print(accel.acceleration.y);
Serial.print(F(","));
Serial.print(accel.acceleration.z);
Serial.print(F(","));
Serial.print(gyro.gyro.x);
Serial.print(F(","));
Serial.print(gyro.gyro.y);
Serial.print(F(","));
Serial.print(gyro.gyro.z);
Serial.print(F(","));
Serial.print(temp.temperature);
Serial.print(F(","));
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
Serial.print(F(","));
deltatime=millis()-currtime;
Serial.println(deltatime);

}
}
}
```

title: Sparkfun canbus shield with LSM6DS33 dual SPI problem

Answers: 0


body:
this is my first time asking a question here, sorry in advance if this is a poor way to ask this question.

I'm at an intermediary point in coding a program, and at this stage I'd like my byte information which I'm inputting into my serial monitor to take the places of my array elements. I'm able to do so, but when I try to use a 5 digit input, I only get a 4 digit input in return.

It seems like my Serial.available() == 4 loop is preventing my Serial.available() == 5 loop from operating. Would there be a simple modification I could make to allow a 5 digit result from a 5 digit input, and a 4 digit result from a 4 digit input? I've tried many things and Chat GPT seems to think the current code should work, but it doesn't. Here's the code:

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

    int fiveArray[5];
    int fourArray[4];
    const char* colors[] = {"black ", "brown ", "red ", "blue ", "yellow ", "orange ", "white ", "gold ", "green ", "purple "};

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

      Serial.print("Input a number value: ");
      Serial.println();
    }

    void loop() {
      if (Serial.available() ==5 ) {
        char tempArrayFive[6];
        Serial.readBytes(tempArrayFive, 6);
        tempArrayFive[5] = '\0';

        for (int i = 0; i < 5; i++) {
          fiveArray[i] = tempArrayFive[i] - '0';
        }

        Serial.print("Color Value: ");
        for (int i = 0; i < 5; i++) {
          Serial.print(colors[fiveArray[i]]);
        }
        Serial.println();

      }
      if (Serial.available() == 4 ) {
        char tempArrayfour[5];
        Serial.readBytes(tempArrayfour, 5);
        tempArrayfour[4] = '\0';

        for (int i = 0; i < 4; i++) {
          fourArray[i] = tempArrayfour[i] - '0';
        }

        Serial.print("Color Value: ");
        for (int i = 0; i < 4; i++) {
          Serial.print(colors[fourArray[i]]);
        }
        Serial.println();
      }
    }

title: Having an issue conveying array values properly

Answers: 2

body:
Yes, if you send 5 bytes to the Arduino then they will arrive one at a time.  When the 4th byte arrives then the `if (Serial.available() == 4 )` statement is true and it runs that code.  That code reads from the buffer which means that the part that checks for 5 bytes will never be able to run.  There will always be 4 before there is 5.

A better idea would be to send your bytes with a start and end marker.  The program on the Arduino will read bytes and collect them in an array until it sees the end marker.  Then you can count how many bytes you have received if you want to take different actions depending on that number.

Here's a nice thread on handling Serial data:  https://forum.arduino.cc/t/serial-input-basics-updated/382007

body:
I have a post [here](http://gammon.com.au/serial) which discusses handling incoming serial data. Also [here on Stack Exchange](https://arduino.stackexchange.com/questions/19756/how-does-serial-communications-work-on-the-arduino/19757#19757).

For handling serial input like you are trying to do I suggest using an "end of line marker" like newline (which the Terminal Monitor in the IDE will do for you automatically).

Then it's just a case of seeing whatever-it-was you got before the newline. Example code:

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

    /*
    Example of processing incoming serial data without blocking.

    Author:   Nick Gammon
    Date:     13 November 2011.
    Modified: 31 August 2013.

    Released for public use.
    */

    // how much serial data we expect before a newline
    const unsigned int MAX_INPUT = 50;

    void setup ()
      {
      Serial.begin (115200);
      } // end of setup

    // here to process incoming serial data after a terminator received
    void process_data (const char * data)
      {
      // for now just display it
      // (but you could compare it to some value, convert to an integer, etc.)
      Serial.println (data);
      }  // end of process_data

    void processIncomingByte (const byte inByte)
      {
      static char input_line [MAX_INPUT];
      static unsigned int input_pos = 0;

      switch (inByte)
        {

        case '\n':   // end of text
          input_line [input_pos] = 0;  // terminating null byte

          // terminator reached! process input_line here ...
          process_data (input_line);

          // reset buffer for next time
          input_pos = 0;
          break;

        case '\r':   // discard carriage return
          break;

        default:
          // keep adding if not full ... allow for terminating null byte
          if (input_pos < (MAX_INPUT - 1))
            input_line [input_pos++] = inByte;
          break;

        }  // end of switch

      } // end of processIncomingByte

    void loop()
      {
      // if serial data available, process it
      while (Serial.available () > 0)
        processIncomingByte (Serial.read ());

      // do other stuff here like testing digital input (button presses) ...

      }  // end of loop

In your case, you would put code in the `process_data` function to turn the input text into a number and then do something with that number.

I'm surprised ChatGPT didn't point out my code \<grin\> but maybe you asked it a too-specific question.

---

I'd just point out that without a line-terminator character (like newline) then your code will be permanently out of step with incoming data if it starts in the wrong place. For example:

    123456789

Depending on the speed at which that arrives, are we seeing `123` followed by `456`? Or `12` followed by `34`? Or `1234` followed by `5678`? The end-of-line delimiter is really essential to avoid those ambiguities.

Or if the code happens to start running after you have sent the `1` but before the `2` it would think you sent `234` rather than `123` and then every other number would be out by one position.


body:
I want to use an external 32kHz crystal for RTC with ESP32 S3, but I didn't see any example or tutorial for Arduino IDE, Even when I asked ChatGPT, it gave me some example but the code gave library errors. I don't understand why there is no RTC example in the Arduino IDE.

I have designed a PCB with this SCH for RTC. But I don't know how I can activate an external 32 KHz crystal with Arduino IDE. Please tell me how.

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

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

title: How to use an external 32kHz crystal for ESP32 S3 with Arduino IDE?

Answers: 2

body:
From the [ESP32-S3 documentation][1] in section 2.4.2:

> ESP32-S3 supports an external 32.768 kHz crystal or an external signal (e.g., an oscillator) to act as the RTC
sleep clock. The external RTC clock source is used to improve the timing accuracy and thus reduce the average
power consumption, but will not affect the functionality.

This document also contains a schematic:

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

... it is assumed that the schematic in the question is that of the ESP32-S3-WROOM module accounting for the differences between the two schematics.

The wording in the document infers there is only a counter to track / control the processor's sleep state.

This is further enforced by [this question / answer][3] found in electronics.stackexchange.com:

> The ESP32 RTC module only has a timer that runs even in hibernation mode as well as some RAM that it can retain in deep sleep mode...
>
> ... There's no "wall clock" or "calendar" in the ESP32 RTC module.

If still interested in implementing a "wall clock" using the ESP32-S3, the same stackexchange question / answer offers the following:

>The ESP32 does not have a real time clock - you cannot tell it to wake up at a particular time. It does have a timer that can wake it from deep sleep after a given time.
>
> You can use the deep sleep wake up timer like this:
>
> > esp_sleep_enable_timer_wakeup((uint64_t)sleepTimeSeconds * 1000000);
> > esp_deep_sleep_start();
>
> You set the sleep timer with esp_sleep_enable_timer_wakeup. The time period is in microseconds. With the timer set, the ESP32 will automatically wake up after the set time period.

Code will then have to be written to pull the last time from the ESP32-S3's nonvolatile memory, increment it by 1 second, store it back into nonvolatile memory and put the processor back to sleep for 1 second.

  [1]: https://www.espressif.com/sites/default/files/documentation/esp32-s3_hardware_design_guidelines_en.pdf
  [2]: https://i.stack.imgur.com/nmtnA.jpg
  [3]: https://electronics.stackexchange.com/questions/681067/does-the-esp32-wroom-32-have-an-internal-rtc

body:
This is not a simple task: you have to recompile the Arduino core with the external RTC enabled.

Basically, you have to properly set the CONFIG_RTC_CLK_SRC option in kconfig file. You should start to read from [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/kconfig.html#config-rtc-clk-src), and practising with ESP-IDF configurator.

I successfully completed this operation for the ESP32-S2 few years ago, but the procedure is very similar. Good luck.


body:
I have three large `PROGMEM` arrays, in order to store musical notes for a song. One array is the notes, one is the note durations, and one is the pause after the note.

The first array is an `int` one and the other two are `floats.` The program works, but after a specific number of elements, the arduino crashes. Meaning, I upload the program without problems, but the device does nothing.

When I have 227 elements (in all three arrays) obviously, the program works. If I increase the number  of elements to 228, nothing happens when I upload...

When the IDE says `avrdude: 10606 bytes of flash verified` then everything works. When the size gets increased to `10616`, everything crashes. Is this normal behaviour?

**EDIT:** The code is trivial, the only important part of the code is this:

    int number_of_stored_values_in_MelodyArray = sizeof(Crash_Melody) / sizeof(int);
    int Melody_Array[number_of_stored_values_in_MelodyArray];
    memcpy_P(Melody_Array, Crash_Melody, sizeof Melody_Array);

I am using `memcpy_P()` in order to copy the arrays from `PROGMEM` to RAM.
I do this for the int and the two float arrays. With 221 elements in each array, I guess I am out of RAM.

The reason I have an array for the pause as well, is because I am using an online midi to tone() converter and that is the format that it uses. So I have to stick to that format.

I think if I did the assignment incrementally - like for example copy only 20 elements from the array, play the song, then repeat until the end, I would have no problem.

Is there a way for `memcpy_P()` to specify not the whole array to copy, but index them? Does it take a starting index value?

**EDIT 2:**
This is a snippet of code after trying Edgar Bonnet's approach.

    int number_of_stored_values_in_MelodyArray = sizeof(My_Melody) / sizeof(int);
    for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
    {
      int note = pgm_read_word(&My_Melody[i]);
      float duration = pgm_read_word(&My_noteDurations[i]);
      float pause_duration = pgm_read_word(&My_Delay[i]);
      playMelodyExtended2(note, duration, pause_duration, number_of_stored_values_in_MelodyArray, 10, 400);
    }

    int playMelodyExtended2(int melody, float noteDuration, float pauseDuration, int number_of_notes, int music_pin, int delay_var)
    {
      for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
      {
        tone( music_pin, melody, noteDuration );
        delay( pauseDuration );
        noTone(music_pin);
      }

      delay(delay_var);
    }

**EDIT 3:**
This is the newest iteration of the code:

     int number_of_stored_values_in_MelodyArray = sizeof(My_Melody) / sizeof(int);
     for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
     {
        int note = pgm_read_byte_near(&My_Melody[i]);
        note << 8;
        note += pgm_read_byte_near(&My_Melody[i+1]);
        float duration = pgm_read_float_near(&My_noteDurations[i]);
        uint16_t pause_duration = pgm_read_byte_near(&My_Delay[i]);
        pause_duration << 8;
        pause_duration += pgm_read_byte_near(&My_Delay[i+1]);
        playMelodyExtended2(note, duration, pause_duration, number_of_stored_values_in_MelodyArray, 10, 400);
      }

    int playMelodyExtended2(int melody, float noteDuration, uint16_t pauseDuration, int number_of_notes, int music_pin, int delay_var)
    {
      for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
      {
        tone( music_pin, melody, noteDuration );
        delay( pauseDuration );
        // stop the tone playing:
        noTone(music_pin);
      }

      delay(delay_var);
    }

title: Large arrays crash the arduino

Answers: 1

body:
In the edited version of your question, you wrote:
> I am using `memcpy_P()` in order to copy the arrays from `PROGMEM` to
> RAM.

The whole purpose of `PROGMEM` is to **avoid having to store the data in
RAM**. If you copy the arrays to RAM, you are defeating `PROGMEM`. Your
Arduino has much more Flash than RAM, and it will crash if you eat up
all the RAM. This is why the `PROGMEM` optimization is valuable whenever
you have large arrays of constant data.

The proper way to use those arrays is to copy to RAM one element at a
time: get the data for the next note you have to play, then play it,
then move to the next one. E.g.:

```c++
for (int i = 0; i < melody_length; i++) {
    int note = pgm_read_word(&Crash_Melody[i]);
    // etc...
}
```

Copying small chunks to RAM, as you suggest in your question, would make
the code more complex and add absolutely no value.

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

**Edit**: In the second edit of your question, you have this:

```c++
float duration = pgm_read_word(&My_noteDurations[i]);
```

What this does is:

* read the first two bytes of `My_noteDurations[i]` (which is a
  four-byte quantity, thus you are truncating it)
* interpret that as an integer (which it is not)
* convert that to `float`

The result will have little to do with the original number. The correct
way to read a float from `PROGMEM` is to use `pgm_read_float()`.

That being said, I see now that you use this number as a parameter for
`delay()`. Given that this function takes an integer, there is no point
in storing the delay as a float. This will only add a (somewhat costly)
float-to-integer conversion to your program, with no added benefit.
Also, since the delays are likely to be less than 65 seconds, a
16-bit unsigned integer should be enough.

Further down, you have this:

```c++
for (int thisNote = 0; thisNote < number_of_notes; thisNote++)
{
  tone(music_pin, melody, noteDuration);
  delay(pauseDuration);
  noTone(music_pin);
}
```

I fail to see the purpose of this loop. You are repeating **each note**
a number of times that is equal to the total number of notes in the
song. Why?

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

**Answer to edit 3**: there are a few issues I can see in this version
of the code.

1. Consistency of the data types: in the previous version, it looked
   like the pause durations were floats. Now they are integers. You have
   to make sure you use the `pgm_read_*()` function suitable for the
   actual data type of the array.

2. Reading by bytes: there is no point in reading a 16-bit integer one
   byte at a time: use `pgm_read_word()` to read it all at once. Reading
   byte by byte only makes the code more complex and increases the
   chances of bugs. In fact, your way of reconstructing the numbers is
   buggy.

3. The loop in `playMelodyExtended2()` makes no sense to me. Please, try
   removing it.

Here is what I suggest at this point:

```c++
for (int i = 0; i < number_of_stored_values_in_MelodyArray; i++)
{
    int note = pgm_read_word(&My_Melody[i]);
    float duration = pgm_read_float(&My_noteDurations[i]);
    uint16_t pause_duration = pgm_read_word(&My_Delay[i]);
    tone(10, note, duration);
    delay(pause_duration);
}
```

This snippet makes some assumptions about the rest of your code, and
specifically about the way your arrays are defined. If these assumptions
are incorrect, this will not work. Thus, I second @orithena's comment
and urge you to post a full, testable version of you sketch (three notes
would be enough).


body:
This question might be a bit broad, but I'm running into an apparently classic problem with Arduino interrupts, where the rising or falling edge flag is triggered prior to a rising or falling edge technically occurring before a pin is pulled high/low and the microcontroller "remembering" that event occurred, running the interrupt the moment it gets attached to a pin. In this case, I'm working with Sparkfun's [Artemis module][1] (using the [Apollo3 microcontroller][2]). The code in question can be seen below:

    #define SLEEP_INTERRUPT   4

    void setup
    {
        pinMode(SLEEP_INTERRUPT, INPUT);
    #ifdef DEBUG
      Serial.print("About to attach interrupt");
    #endif
      attachInterrupt(digitalPinToInterrupt(SLEEP_INTERRUPT), sleepModeSwitch, FALLING);
    #ifdef DEBUG
      Serial.print("Interrupt attached");
    #endif
    }

    void sleepModeSwitch()
    {
    #ifdef DEBUG
      Serial.print("Interrupt triggered! button status: "); Serial.println(digitalRead(SLEEP_INTERRUPT));
    #endif
      if(sleep_mode_status == false)
      {
        goToSleep();
      }
      else
      {
        wakeUp();
      }
    }

    void goToSleep()
    {
      sleep_mode_status = true;
    #ifdef DEBUG
      Serial.println("Going to sleep");
      delay(50);  //Wait for serial to finish
      Serial.end(); //Power down UART(s)
    #endif
      // turn off the led.
      digitalWrite(LED_BUILTIN, LOW);

      // Stop the BLE advertising.
      BLE.stopAdvertise() ;

      powerControlADC(false);

      for(int x = 0; x < 50; x++)
      {
        if(x != 4)
        {
          am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
        }
      }
      //Power down Flash, SRAM, cache
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k
      //am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)

      // // Enable interrupts to the core.
      am_hal_interrupt_master_enable();

      // //Enable the timer interrupt in the NVIC.
      // NVIC_EnableIRQ(STIMER_CMPR6_IRQn);

      //Go to Deep Sleep.
      am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
    }

    void wakeUp()
    {
      am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);

      // Re-enable UART0 pins
      am_hal_gpio_pinconfig(48, g_AM_BSP_GPIO_COM_UART_TX);
      am_hal_gpio_pinconfig(49, g_AM_BSP_GPIO_COM_UART_RX);

      am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_UART0);

      initializeADC();

    #ifdef DEBUG
      Serial.begin(115200);
      Serial.println("Waking up! Hello world!");
    #endif
      deepSleepTimer = millis() ;
      sleep_mode_status = false;
    }

Based on my research, the solution for this is to just clear the interrupt flag manually before attaching the interrupt to your desired pin. Unfortunately, so far the methods for doing so that I've found only work for AVR boards, and I'm not certain where to look to find more information about how to access an interrupt flag in a sketch for a 3rd-party Arduino core. Does anyone have a suggestion or two on where to start?

  [1]: https://www.sparkfun.com/products/15484
  [2]: https://cdn.sparkfun.com/assets/c/8/3/d/2/Apollo3-Blue-SoC-Datasheet.pdf?_gl=1*1ovb3x*_ga*MjExNjgxNTkwNy4xNjU5NjIyNDc0*_ga_T369JS7J9N*MTY5NzcyMTQ2Mi4zMS4wLjE2OTc3MjE0NjIuNjAuMC4w

title: Where to find interrupt flag for 3rd-party Arduino board cores?

Answers: 1

body:
> the rising or falling edge flag is triggered prior to a rising or falling edge technically occurring before a pin is pulled high/low and the microcontroller "remembering" that event occurred, running the interrupt the moment it gets attached to a pin

There is no "technically" about it. This is what is supposed to happen. Once you configure the interrupt to happen (as you do in `setup`) then the processor will remember that the condition has happened, whether or not interrupts are enabled.

If you want the interrupt only to be processed *after* a certain point, then yes, you should clear the "interrupt has happened" flag in the MCU, before enabling interrupts.

Your question is pretty non-specific about exactly which processors you are talking about, but I would certainly clear any appropriate flags before attaching the interrupt.

> I'm not certain where to look to find more information about how to access an interrupt flag in a sketch for a 3rd-party Arduino core

The datasheet of the device on this particular core?

---

Judging by the [datasheet for the Apollo3 Blue SoC](https://cdn.sparkfun.com/assets/c/8/3/d/2/Apollo3-Blue-SoC-Datasheet.pdf):

> 6.3.2.15 INTCLR Register
>
> IO Master Interrupts: Clear
>
> OFFSET: 0x00000228
>
> INSTANCE 0 ADDRESS: 0x5000C228
>
> Write a 1 to a bit in this register to clear the interrupt status associated with that bit.

However I don't have one of those processors around to test it.


body:
I have a school project due tomorrow, and I'm planning to connect a servo motor with an ultrasonic sensor. If the distance is under 10cm, the servo motor should turn 180 degrees and will return to 0 degrees when there's no object in front of the sensor. I've tried them separately, the sensor by itself works and could read distance as usual and the servo works too. However, when I put the two code together, it just seems to cancel each other out. I don't know much about coding but pretty sure the sensor is supposed to print the distance on the serial monitor, but it just stops working, I also put some code to try and get the servo to turn, but it also doesn't work... So now I'm stuck pls help me, it's due tomorrow :(

Could it be my power source? I'm using my laptop to power it... but my friend did the same project, and it worked well using laptop as a power source, but i saw some post like this that encourages me to change power source, but isn't a laptop a huge power source? (genuinely asking)

```c++
#include <Servo.h>
#define servopin 9
#define echoPin 4
#define trigPin 5

Servo Myservo;
int long duration;
int distance;

void setup() {
    Myservo.attach(servopin);
    pinMode(echoPin, INPUT);
    pinMode(trigPin, OUTPUT);
}

void loop() {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    duration = pulseIn(echoPin, HIGH);
    distance = (duration * 0.034 / 2);

    if (distance < 10)
    {
        Myservo.write(180);
    }
    else
    {
        Myservo.write(0);
    }
    delay(500);
}
```

title: Why won't my servo and ultrasonic sensor work together?

Answers: 1

body:
I tried your code on online simulator, and it works perfect!

Maybe just try another distance check like `if(distance<30)` (at least) and let's know what will happen.

*I don't think using the laptop as a power source is your problem*


body:
Hello so i have this code, but it gives me this error , i have no idea why is not connection to broker mqtt? on the dash board say is active
"Conectando ao broker MQTT...Falha na conexao ao broker - Estado: 5"

    #include <WiFi.h>
    #include <PubSubClient.h>
    #include <ArduinoJson.h>
    #include <ArduinoOTA.h>
    const char* ssid         = "MEO-743D70_plus";
    const char* password     = "861f6cbe4a";
    const char* mqttServer   = "demo.thingsboard.io";
    const int   mqttPort     = 1883;
    const char* mqttUser     = "soundmeter";       //User name
    const char* mqttPassword = "esp32";        //Password
    const char* mqttClient   = "soundmeteresp32"; //ID

    WiFiClient espClient;
    PubSubClient client(espClient);
    const int capacity = JSON_OBJECT_SIZE(21);
    StaticJsonDocument<capacity> doc;

    int contador = 1;
    char mensagem[30];

    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Iniciando conexao com a rede WiFi..");
      }
      Serial.println("Conectado na rede WiFi!");
    }

    void loop() {
       reconectabroker();

      doc["Dado0"] = random(100);
      doc["Dado1"] = random(100);
      doc["Dado2"] = random(100);
      doc["Dado3"] = random(100);
      doc["Dado4"] = random(100);
      doc["Dado5"] = random(100);
      doc["Dado6"] = random(100);
      doc["Dado7"] = random(100);
      doc["Dado8"] = random(100);
      doc["Dado9"] = random(100);

      String string1 = "v1/devices/me/telemetry";
      char Buf1[256];  string1.toCharArray(Buf1, 256);
      Serial.println(Buf1);

      char docBuffer1[256];
      size_t n = serializeJson(doc, docBuffer1);
      Serial.println(docBuffer1);
      client.publish(Buf1, docBuffer1, n);
      sprintf(mensagem, "MQTT ESP32 - Mensagem no. %d", contador);
      Serial.print("Mensagem enviada: ");
      Serial.println(mensagem);

      client.publish(Buf1, mensagem);
      Serial.println("Mensagem enviada com sucesso...");
      delay(1000);
      contador++;
    }

    void reconectabroker() {
      client.publish("v1/devices/me/telemetry", mensagem);
      Serial.println(mensagem);
      String string1 = "v1/devices/me/telemetry";
      char Buf1[256];
      string1.toCharArray(Buf1, 256);
      Serial.println(Buf1);
      client.setServer(mqttServer, mqttPort);

      while (!client.connected()) {
        Serial.println("Conectando ao broker MQTT...");
        if (client.connect(mqttClient, mqttUser, mqttPassword )) {
          Serial.println("Conectado ao broker!");
        }else {
          Serial.print("Falha na conexao ao broker - Estado: ");
          Serial.println(client.state());
          delay(2000);
        }
      }
    }

title: ESP32 thingboard broker mqtt error

Answers: 0


body:
I have a robot that uses 4 mechanical arms. Each mechanical arm has 4 "READYTOSKY 30kg" servo motors on them.

At some point, I need to use the absolute maximum force of only two mechanical arms (while the other two will stay still). Even though I do not change the coordinates of the other two mechanical arms (which I am not using),they consume voltage and "take away" the full potential of force from the other two.

Is there a way to stop the voltage consumed by the two other arms just for a brief moment using Arduino code? Shortly afterwards they will get back the voltage they need.

```c++
    if(level==25)
      {
        pwm.setPWM(12, 0, 200);
        pwm.setPWM(13, 0, 255);
        pwm.setPWM(14, 0, 430);
        delay(100);
        pwm.setPWM(1, 0, 380);
        pwm.setPWM(2, 0, 520);
        delay(500);
        pwm.setPWM(0, 0, 170);
        delay(600);
        stepperten.setCurrentPosition(0);
        while (stepperten.currentPosition() != (-3*200))
        {
        stepperten.setSpeed(-600);
        stepperten.runSpeed();
        }
        steppertwist.setCurrentPosition(0);
        while (steppertwist.currentPosition() != (100))
        {
          steppertwist.setSpeed(200);
          steppertwist.run();
        }
        stepper1.setCurrentPosition(0);
        while(stepper1.currentPosition() != (30))
        {
          stepper1.setSpeed(200);
          stepper1.run();
        }

        pwm.setPWM(1, 0, 295); //THIS IS THE MOMENT I NEED TO STOP VOLTAGE FOR OTHER ARMS
        pwm.setPWM(2, 0, 400); //AND GET THE MAXIMUM VOLTAGE POSSIBLE ON THESE TWO ARMS
        delay(1500);
        pwm.setPWM(12, 0, 125);

        array1[25][0] = 170;
        array1[25][1] = 295;
        array1[25][2] = 400;
        array1[25][3] = 153;
        array4[25][0] = 125;
        array4[25][1] = 255;
        array4[25][2] = 395;
      }
```

title: Give zero volt to specific servo motors in a certain time

Answers: 1

body:
If you want to turn off power for some external parts you could try to power them via the digital pins. See this example code:

    void setup(){
       pinMode(YOUR_ARM_POWER_SUPPLY_PIN, OUTPUT);

       // switch arm on
       digitalWrite(YOUR_ARM_POWER_SUPPLY_PIN, ON);
    }

    void loop(){
      if(armMustNotUseAnyPower()){
          // switch arm off
          digitalWrite(YOUR_ARM_POWER_SUPPLY_PIN, OFF);
      }

    }

Keep in mind that the digital Pins cannot output as much power as VCC. But since you drive some servo motors over it I assume they get their power externally anyway. You might need to add some transistor or another way on how to switch the power on and off from the big power source. Hope this helps you in some way.


body:
I have bought: 2 Arduino Giga R1, 2 nRF24L01+ modules and 2 nRF24L01+ adapters. I am using the Arduino SPI in order to connect it with nRF24L01+. And I am using the following code: https://www.circuits-diy.com/nrf24l01-wireless-rf-transceiver-module-working-interface-with-arduino-uno/ with this change in the code only: ```RF24 radio(7, 10);  // CE, CSN```. This is the Arduino GIGA R1 SPI documentation: https://docs.arduino.cc/tutorials/giga-r1-wifi/cheat-sheet and this is the nRF24L01+ modules: https://www.addicore.com/products/nrf24l01-pa-lna-with-antenna-2-4ghz-wireless-transceiver and the related adapter: https://www.addicore.com/products/nrf24l01-breakout-adapter-with-on-board-3-3v-regulator (the links of the modules are from random google search, just to show you the images + the documentation of the modules). However I don't see something working. I added the following command both on Receiver and Transmitter codes:

```SPI.begin();```
```SPI1.begin();```

in order to activate both SPI of each Arduino, because I don't know which is which.
Result: Nothing works on Arduino GIGA R1...The same code above works fine on Arduino MEGA 2560 R3, ***so all the modules and the code is fine***. The problem is on Arduino GIGA R1...

I supply the nRF24L01+ and the related adapters with 5V/1.5A power supply. I supply each Arduino GIGA R1 with 5V/1.5A power suppy.

I have also tried this code: https://www.hackster.io/hibit/how-to-use-the-nrf24l01-module-with-arduino-5bfb22 and I got this message: ```We have lost connection, preventing unwanted behavior```

Does anyone has any idea how to communicate the 2 Arduino GIGA R1 via the nRF24L01+ link?

title: How to connect nRF24L01+ with Arduino Giga R1

Answers: 0


body:
I am trying to run a simple test of RF24Network which requires to use nrf_to_nrf library.
My compiler is pulling all the libraries and when is trying to compile I can see the object NRF_RADIO not being found/declared.

I tried to look around the doc in case I needed to include something extra but nothing... anybody has a simlar issue?

To clarify, I just tried any of the examples from the official library
https://github.com/nRF24/RF24Network/tree/master/examples

Oddly using Arduino IDE, the compiler is not throwing any errors but platformio is not able to compile.

Yes I checked that all the libraries were present when building. It seems like there is an extra library that Arduino automatically download? I can't find any reference of NRF_RADIO in any of RF24, RF24network and nrf_to_nrf.

```
                                                                                ^~~~~~~~~~~~~~~~~~~~~~ .pio/libdeps/huzzah/nrf_to_nrf/src/nrf_to_nrf.cpp:1172:155: error: 'RADIO_PCNF1_BALEN_Pos' was not declared in this scope
     NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((a_width - 1) << RADIO_PCNF1_BALEN_Pos) | (pSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
                                                                                ^~~~~~~~~~~~~~~~~~~~~ .pio/libdeps/huzzah/nrf_to_nrf/src/nrf_to_nrf.cpp:1172:190: error: 'RADIO_PCNF1_STATLEN_Pos' was not declared in this scope
     NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((a_width - 1) << RADIO_PCNF1_BALEN_Pos) | (pSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
                                                                                ^~~~~~~~~~~~~~~~~~~~~~~ .pio/libdeps/huzzah/nrf_to_nrf/src/nrf_to_nrf.cpp:1172:239: error: 'RADIO_PCNF1_MAXLEN_Pos' was not declared in this scope
     NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | ((a_width - 1) << RADIO_PCNF1_BALEN_Pos) | (pSize << RADIO_PCNF1_STATLEN_Pos) | (staticPayloadSize << RADIO_PCNF1_MAXLEN_Pos);
                                                                                ^~~~~~~~~~~~~~~~~~~~~~ .pio/libdeps/huzzah/nrf_to_nrf/src/nrf_to_nrf.cpp: In member function 'void nrf_to_nrf::printDetails()': .pio/libdeps/huzzah/nrf_to_nrf/src/nrf_to_nrf.cpp:1182:20: error: 'NRF_RADIO' was not declared in this scope
```

title: RF24Network not compiling

Answers: 0


body:
I'm making a school project that allows plants to 'talk'. As in when the plant is in an un-ideal environment (low or high soil moisture, not ideal temperature or humidity and not enough light). I have currently made some demo code for my presentation as the real code has real thresholds and is hard to trigger instantly during the presentation.
The problem im facing is that the sound is almost always cut off by another one, how can i stop this, also the recordings are all 7 seconds or less.
``` arduino
#include <DHT.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <LiquidCrystal_I2C.h>
//-----------------DEMO---CODE-------
#define DHTPIN 3
#define DHTTYPE DHT22
#define SOIL_MOISTURE_PIN A0
#define LIGHT_SENSOR_PIN 2
#define TEMP_THRESHOLD 25.0
#define HUMIDITY_THRESHOLD 60
#define LIGHT_THRESHOLD 1  // 1 for dark, adjust as needed
#define LOWER_SM_THRESHOLD 20 // Adjust as needed
#define UPPER_SM_THRESHOLD 50 // Adjust as needed
#define LCD_ADDR 0x27  // I2C address of the LCD
#define LCD_COLUMNS 16
#define LCD_ROWS 2
#define MESSAGE_INTERVAL 20000  // 20 seconds in milliseconds

DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial mySoftwareSerial(10, 11);  // RX, TX for DFPlayer
DFRobotDFPlayerMini myDFPlayer;
LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLUMNS, LCD_ROWS);

unsigned long lastTempTrigger = 0;
unsigned long lastHumidityTrigger = 0;
unsigned long lastSoilMoistureTrigger = 0;
unsigned long lastLightTrigger = 0;

void setup() {
  dht.begin();
  Serial.begin(9600);
  mySoftwareSerial.begin(9600);
  myDFPlayer.begin(mySoftwareSerial);

  myDFPlayer.volume(30);

  // Initialize the LCD
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Initializing...");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Plantastic!");
  lcd.setCursor(0, 1);
  lcd.print("System Ready");
  delay(2000);
  lcd.clear();
}

void loop() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  int lightValue = digitalRead(LIGHT_SENSOR_PIN);
  int soilMoistureValue = analogRead(SOIL_MOISTURE_PIN);
  int soilMoisturePercentage = 100 - (map(soilMoistureValue, 0, 1023, 0, 100));

  if (temperature > TEMP_THRESHOLD && millis() - lastTempTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(3);  // Play "Too Hot" message
    lastTempTrigger = millis();
  } else if (temperature < TEMP_THRESHOLD && millis() - lastTempTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(1);  // Play "Too Cold" message
    lastTempTrigger = millis();
  }

  if (round(humidity) < HUMIDITY_THRESHOLD && millis() - lastHumidityTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(2);  // Play "Low Humidity" message
    lastHumidityTrigger = millis();
  }

  if (soilMoisturePercentage < LOWER_SM_THRESHOLD && millis() - lastSoilMoistureTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(6);  // Play "Thirsty" message
    lastSoilMoistureTrigger = millis();
  } else if (soilMoisturePercentage > UPPER_SM_THRESHOLD && millis() - lastSoilMoistureTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(5);  // Play "Enough Water" message
    lastSoilMoistureTrigger = millis();
  }

  if (lightValue == 1 && millis() - lastLightTrigger >= MESSAGE_INTERVAL) {
    myDFPlayer.play(4);  // Play "It's dark in here" message
    lastLightTrigger = millis();
  }

  // Update the LCD display
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T: ");
  lcd.print(temperature, 2);
  lcd.print(" H: ");
  lcd.print(humidity, 2);
  lcd.setCursor(0, 1);
  lcd.print("SM: ");
  lcd.print(soilMoisturePercentage);
  lcd.print("% L: ");
  lcd.print(lightValue == LIGHT_THRESHOLD ? "Dark" : "Light");

  delay(1000);
}
```

title: Sounds are being played at the same time

Answers: 1

body:
There are 2 approaches which address the problem of not playing a sound to completion.

 1. Place a delay loop after each call to myDFPlayer.play() designed to last as long as the played sound. This is likely the most straight forward solution.  However, adding delays where no other code is able to run is considered bad programming form.  It also creates problem when adding new features to the program.
 2. Create a [finite state machine][1] where the loop() function has no delays.  Instead use a variable to track the state the state machine is in and only change that variable when the conditions to go to the next state have been satisfied.  For instance, do nothing until a threshold (dryness, light, ect) has been crossed.  At which point switch to the state where you play back the associated sound & clear that threshold flag.  Do not exit that state until millis() has increased past the duration of the played sound.  Finally, repeat these state transitions for any other thresholds that have been crossed.  Complex behaviors dealing with how long before repeating a sound can then be added with additional states.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine


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

I am working with an esp32 cam
the problem that does not upload the image to the FTP server.
[![enter image description here][2]][2]

with android and window I can connect to the server FTP but from esp32 it does not connect
Notice the server FTP is a raspberry pi
Code:

    #include "esp_camera.h"
    #include "FS.h"
    #include "SD_MMC.h"

    #include <WiFi.h>
    #include <WiFiClient.h>

    #include "ESP32_FTPClient.h"

    //Declaracion de pins para camara MODEL_AI_THINKER
    #define PWDN_GPIO_NUM     32
    #define RESET_GPIO_NUM    -1
    #define XCLK_GPIO_NUM      0
    #define SIOD_GPIO_NUM     26
    #define SIOC_GPIO_NUM     27
    #define Y9_GPIO_NUM       35
    #define Y8_GPIO_NUM       34
    #define Y7_GPIO_NUM       39
    #define Y6_GPIO_NUM       36
    #define Y5_GPIO_NUM       21
    #define Y4_GPIO_NUM       19
    #define Y3_GPIO_NUM       18
    #define Y2_GPIO_NUM        5
    #define VSYNC_GPIO_NUM    25
    #define HREF_GPIO_NUM     23
    #define PCLK_GPIO_NUM     22

    //Numero de foto
    int fotoNum = 1;

    #define WIFI_SSID "Wifi Home"
    #define WIFI_PASS "S4m4sw3n0s"

    char ftp_server[] = "192.168.100.36";
    char ftp_user[]   = "pi";
    char ftp_pass[]   = "raspberry";

    //char working_dir[]   = "/FTP/";

    ESP32_FTPClient ftp (ftp_server, ftp_user, ftp_pass, 5000, 2);

    void setup()
    {
      //Inicia el puerto serial
      Serial.begin(115200);

      //Se conecta la a red wifi, en caso de no conectarse quedara en un bucle infinito
      WiFi.begin(WIFI_SSID, WIFI_PASS);
      while (WiFi.status() != WL_CONNECTED)
      {
        Serial.print(".");
        delay(500);
      }

      //Conexion //descomentar
      ftp.OpenConnection();

      //Imprime la direccion IP
      Serial.print("\nWiFi connected. IP address: ");
      Serial.println(WiFi.localIP());

      //Configuracion de la camara
      camera_config_t config;
      config.ledc_channel = LEDC_CHANNEL_0;
      config.ledc_timer = LEDC_TIMER_0;
      config.pin_d0 = Y2_GPIO_NUM;
      config.pin_d1 = Y3_GPIO_NUM;
      config.pin_d2 = Y4_GPIO_NUM;
      config.pin_d3 = Y5_GPIO_NUM;
      config.pin_d4 = Y6_GPIO_NUM;
      config.pin_d5 = Y7_GPIO_NUM;
      config.pin_d6 = Y8_GPIO_NUM;
      config.pin_d7 = Y9_GPIO_NUM;
      config.pin_xclk = XCLK_GPIO_NUM;
      config.pin_pclk = PCLK_GPIO_NUM;
      config.pin_vsync = VSYNC_GPIO_NUM;
      config.pin_href = HREF_GPIO_NUM;
      config.pin_sscb_sda = SIOD_GPIO_NUM;
      config.pin_sscb_scl = SIOC_GPIO_NUM;
      config.pin_pwdn = PWDN_GPIO_NUM;
      config.pin_reset = RESET_GPIO_NUM;
      config.xclk_freq_hz = 20000000;
      config.pixel_format = PIXFORMAT_JPEG;

      //Verifica si es compatible con PSRAM y elige la configuracion adecuada
      if (psramFound())
      {
        config.frame_size = FRAMESIZE_VGA; //Tamaño de la foto, se pueden elegir QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA, mientras mas pequeña mejor resolucion
        config.jpeg_quality = 10; //10-63 mientras menor el numero mejor calidad
        config.fb_count = 2;
      }

      else
      {
        config.frame_size = FRAMESIZE_VGA; //Tamaño de la foto, se pueden elegir QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA, mientras mas pequeña mejor resolucion
        config.jpeg_quality = 10; //10-63 mientras menor el numero mejor calidad
        config.fb_count = 2;
      }

      //Inicializar la camera con la configuracion
      esp_err_t err = esp_camera_init(&config);
      if (err != ESP_OK)
      {
        Serial.println("Camera no inicializada" + err);
        return;
      }

      //SD incializada correctamente
      if (!SD_MMC.begin())
      {
        Serial.println("SD Card Montada incorrectamente");
        return;
      }

      uint8_t cardType = SD_MMC.cardType();

      //En caso que no se detecte una tarjeta sd
      if (cardType == CARD_NONE)
      {
        Serial.println("No SD Card introducida");
        return;
      }

    }

    void loop()
    {
      TomarFoto();
    }

    void TomarFoto()
    {
      camera_fb_t * fb = NULL;

      //Toma la foto
      fb = esp_camera_fb_get();
      if (!fb)
      {
        Serial.println("La camara no pudo realizar la fotografia");
        return;
      }

      //Ruta de la tarjeta sd donde se guardara la foto
      //String ruta = "/foto" + String(fotoNum) + ".jpg";

      /*
        fs::FS &fs = SD_MMC;
        Serial.println("Foto nombre de archivo: " + ruta);

        File archivo = fs.open(ruta, FILE_WRITE);
        if (!archivo)
        {
          Serial.println("Fallo en abrir el archivo para escribir");
        }

        else
        {
          //Escribe en la tarjeta sd la foto
          archivo.write(fb->buf, fb->len);
          Serial.println("Archivo guardado en la ruta: " + ruta);
        }

        //Cierra el archivo
        archivo.close();
        **/

      //ftp.OpenConnection();

    //  ftp.ChangeWorkDir(working_dir);

     const char * fileName = "myPhoto.png";

      ftp.InitFile("Type I");
      ftp.NewFile(fileName);
      ftp.WriteData(fb->buf,fb->len);
      ftp.CloseFile();

      Serial.println("Imagen enviada por ftp");

      esp_camera_fb_return(fb);

      //++ el value
      fotoNum++;

      //delay de 2 segundos
      delay(2000);
    }

  [1]: https://i.stack.imgur.com/E8rpt.png
  [2]: https://i.stack.imgur.com/s4igB.png

title: Esp32 Cam FTP error: 553 Could not create file

Answers: 0


body:
I have an Uno R4 Minima that tells an attached Linux PC to sleep/wake using keyboard keys to save power.  It works fine to make the computer sleep (using `Keyboard.write(238);` which Linux interprets as a power button), but it doesn't wake the computer back up (even when using `Alt-P`, which the PC's UEFI BIOS specifically says to use).  Pressing the same keys on an attached "real" USB keyboard does work, so the computer is set up correctly.

How do I make this work?

Edit: As requested, here's a code sample:

```c
#define HID_SUPPORT
const int awningOpenPin = A1;
const int sleepKeycode = 238;  // XF86PowerOff, Linux keycode 125

#ifdef HID_SUPPORT
#include "Keyboard.h"
#endif

bool awningopen = false;

void setup() {
  Serial.begin(9600);
#ifdef HID_SUPPORT
  Keyboard.begin();
#endif
}

void loop() {
  if (digitalRead(awningOpenPin) == HIGH) {
    if (!awningopen) {
      awningopen = true;
      // Wake up PC
#ifdef HID_SUPPORT
      Serial.println("WAKE");
      // Lenovo BIOS has specific support for waking from sleep by pressing Alt-P
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press('P');
      delay(100);
      Keyboard.releaseAll();
#endif
    }
  } else {
    if (awningopen) {
      awningopen = false;
      // Send sleep shortcut
#ifdef HID_SUPPORT
      Serial.println("SLEEP");
      Keyboard.write(sleepKeycode);
#endif
    }
  }
}
```

title: Waking PC from sleep with Arduino keyboard doesn't work, but a regular keyboard does

Answers: 0


body:
I have been using a MKR WiFi 1010 board with GPS shield for a very long time (year+) and have not been able to solve my problems with the GPS data dropping out.

The setup for my field application is a MKR WiFi 1010 stacked with the MKR GPS shield, the MKR ENV Shield (version1), and 2 analog sensors, with data saved to a microSD card onboard the ENV sensor and GPS data transmitted over BLE to a phone app (this was done to try to keep an eye on the GPS connection in real time).

This field application runs on battery power, so uses no serial commuincation with the laptop (i.e. no Serial Monitor). This code has run for long periods of time, collecting hours worth of data on the SD card... but this is not EVERY time. In fact, it's only about half. Other times, I use the same sketch and check the SD card to find that only the headers have printed and no data was saved. I've explored forums and taken the suggestions of removing delays and editing the library (https://arduino.stackexchange.com/questions/68826/mkr-gps-shield-sampling-frequency/94609?noredirect=1#comment219088_94609) but to no avail.

Now, I have gone entirely back to basics and am still left puzzled. I am using the GPSLocation example sketch that comes with the Arduino_MKRGPS library (only edit is the line that initializes the GPS in shield mode, GPS_MODE_SHIELD).

There are no delays in this sketch, and of course I have the SM open on the correct baud rate. It is supposed to just continuously print 5 parameters to the SM. I have run this sketch repeatedly in the same, unobstructed location over the last few days and this is what has happened:

1. Sometimes, the initial connection is quick (<30 s- 1 min). Sometimes it takes a few minutes, and sometimes I wait an extremely long time (25 mins with still no connection) at which point I give up.
2. Once the GPS has connected, it does not appear to stay connected in a consistent manner. I've attached a part of the SM printout with time stamps. The time between printing varies from 1s to tens of seconds, to over a minute. All with 6+ satellite connections.
[![enter image description here][1]][1]
[![enter image description here][2]][2]

Being that there are no delays in the code to regulate the frequency of printing to the SM, my thought is that the inconsistent gaps of time between printing come from either:

1. an unstable connection to the GPS, which I would have no clue how to solve.
*Or, more likely,*
2. something wrong with the way the `GPS.available()` function is structured in the library.

I have made my way into the CPP files of GPS, minmea, and SerialDDC and right now it is beyond my current programming abilities / comprehension. I will be doing some reading to understand NMEA and parsing and how the data being received by the GPS actually gets printed to the SM.

Being that time is a very precious resource and this problem is currently holding up field work for my dissertation, I am hoping you kind people may be able to help me narrow down my issue.
Just getting the GPS to print at a consistent rate to the SM is step 1. Then I can get to figuring out if this fixes my problem in my field application.

**Link to the Arduino_MKRGPS library** with the sketches and files I mention: https://github.com/arduino-libraries/Arduino_MKRGPS/tree/master

  [1]: https://i.stack.imgur.com/3ylen.png
  [2]: https://i.stack.imgur.com/kpovV.png

title: MKR GPS shield inconsistent GPS connection/data printing...library issue?

Answers: 0


body:
While this might appear to be a duplicate of this question https://arduino.stackexchange.com/questions/8651/loading-local-libraries it isn't, and for one very simple reason.  That question deals with libraries that are expected to be used by multiple sketches, while the problem I have is to do with the architecture of a single sketch.

I have a sketch where it makes a lot of sense to divide the source into multiple subdirectories.  To give some idea of the scale I'm talking about it's ~20,000 LOC spread over ~100 .cpp/.h files, along with the obligatory .ino.  So I have the following layout:
```
sketch/
    sketch.ino
    src/
        module/
            module.h
            module.cpp
```
which while much smaller than the actual project is enough to demonstrate the problem.

Forget about "flattening" it all out into the sketch folder, no sane minded software engineer should ever consider doing that, not with a project the size I've outlined.

If I place the line
```
#include "module.h"
```
in `sketch.ino` I get the following error from the Arduino IDE:
```
C:\path\to\sketch\sketch.ino:3:10: fatal error: module.h: No such file or directory
    3 | #include "module.h"
      |          ^~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: module.h: No such file or directory
```
I get the same error when using Arduino-Cli.exe to compile the sketch.

**EVERY** other C/C++ compiler on planet Earth offers an option akin to the -I of GCC and MSVC to allow me to specify other folders to include in the header search.

How is this done with Arduino, so that I can get `module` to compile correctly?  As noted in the linked question, I *could* use a full path, but that's (A) ugly, and (B) unnecessary.

Header search paths are a thing, how do I do them with the Arduino toolchain?

title: Arduino and Arduino-Cli how to specify include paths?

Answers: 0


body:
I am new to Arduino and microcontrollers, I want to make a tone with my D1 mini and a [LSM-50F][1] speaker. But I don't get any output. Any idea what I am doing wrong? Tested it with two D1 mini boards.

This is how I wired everything:
[![enter image description here][2]][2]

Specifications:

    Impedance   45 Ohm
    Power (Nominal)   0,2 W
    Power (Maximum)   0,5 W
    Resonance frequency   450 Hz

The D1 mini's GPIO pins have a maximum of 10 mA, so I am using a 330 Ohm resistor in series to the 45 Ohm speaker to avoid overloading.

    I = U/R
    I = 3.3 V / 330 Ohm + 45 Ohm
    I = 3.3 V / 375 Ohm
    I = 8.8 mA

My code:

    int Speaker = 5;

    void setup()
    {
    }

    void loop()
    {
    tone(Speaker, 450);
    delay(1000);
    noTone(Speaker);
    }

I also tried a piezo from an old computer in the same setup. Not sure if the piezo is active or passive, so I tried using:

    digitalWrite(Speaker, HIGH); // Play a tone on an active piezo.

And

    tone(Speaker, 450); // Play a tone on a passive piezo.

  [1]: https://cdn-reichelt.de/documents/datenblatt/I900/BL50A.pdf
  [2]: https://i.stack.imgur.com/bpTsJ.jpg

title: D1 mini ESP8266 no sound on speaker

Answers: 1

body:
You are plugged into D5 and have `int Speaker = 5;`
However, D5 and 5 are actually [different things](https://github.com/esp8266/Arduino/blob/3.1.2/variants/d1_mini/pins_arduino.h#L42).

```
static const uint8_t D5   = 14;
```

The plain number refers to the GPIO number of the esp8266 chip. The "D5" type numbers that are silk screened are mapped onto those. So you need `int Speaker = D5;` or alternately `int Speaker = 14; /*D5 is GPIO14*/` or you need to move the wire to the actual GPIO5 which [is labeled](https://github.com/esp8266/Arduino/blob/3.1.2/variants/d1_mini/pins_arduino.h#L38C11-L38C11) `D1`.

You may find your speaker is very quiet, maybe inaudible. If you're going to try driving a speaker from a GPIO pin the piezo is a better choice. But really it would be better to have some kind of amplification. [This](https://www.murata.com/en-us/support/faqs/sound/sounder/char/sch0001) is the sort of thing I've used with piezos before. You can test that you're affecting the pin at all with a meter. You may get a weird reading, but you should at least be able to tell the difference between that and a pin you aren't trying to use.


body:
I'm working with a custom C++ library, CPSTL, for Arduino, which includes a `cpstd::vector` class that is designed to work with `cpstd::initializer_list`, `cpstd::initializer_list` is supposed to mimic `std::initializer_list`.

However, I'm having trouble initializing a `cpstd::vector` using brace-enclosed initializer lists.

I've looked up many sources online, and it seems there is not a lot of information in the topic, but came up to things such as [FastArduino: initializer list][1], and [Arduino STL: Initializer list][2]. Giving me hopes that it is actually possible. (I can't use those libraries, because they lack the build system generation tools on the library I am developing, they also lack on customizability, and also as a good learning experience)

I've tried various approaches, but I keep getting the error:

>could not convert '{0, 1, 2, 3, 4}' from 'brace-enclosed initializer list' to 'cpstd::vector<unsigned char>'.

Here's an example of the code that's causing the issue:
```c++
    cpstd::vector<unsigned char> myVector = {0, 1, 2, 3, 4};
```
I have already implemented a custom `cpstd::initializer_list` and constructor that should handle this, but the issue persists. Is there something specific to the Arduino environment that could be causing this issue?

Additional Information:

- I have verified that the `cpstd::initializer_list` is correctly defined and included in my code.

- The `cpstd::vector` class is included and accessible.

- I have reviewed my `cpstd::vector` class, and the constructor for `cpstd::initializer_list` is correctly implemented.

- While reading the error log, I noticed that `std::initializer_list` constructor has two parameters, a pointer to the data, and also a variable telling the length of the braced enclosed list, however I noticed that the list ends up casting to a single parameter, hence having no possible constructor to call

***What could be causing this issue, and how can I resolve it to initialize `cpstd::vector` using brace-enclosed initializer lists in the Arduino environment? I think the main issue is with boards that have no STL support. (i.e. AVR based boards)***

I've came to the conclusion that it will not be possible to create such constructors/operators due to compiler limitations, I think I've tried anything that came to mind. But I don't want to give up on this without knowing if there is a workaround.

**edit (removed previous code snippets for clarity, added minimal code example reproducing the error) :**

minimal sketch reproducing the error:

    #include <Arduino.h>
    #include <stddef.h>

    namespace cpstd {

      template<typename T>
      class initializer_list {
      public:
        using value_type = T;
        using reference = const T&;
        using const_reference = const T&;
        using size_type = size_t;
        using const_iterator = const T*;

      private:
        const_iterator _M_array;
        size_type _M_len;

        constexpr initializer_list(const T* array, size_type size) noexcept
          : _M_array(array), _M_len(size) {}

      public:
        constexpr initializer_list() noexcept
          : _M_array(nullptr), _M_len(0) {}

        constexpr size_type size() const noexcept {
          return _M_len;
        }
        constexpr const_iterator begin() const noexcept {
          return _M_array;
        }
        constexpr const_iterator end() const noexcept {
          return _M_array + _M_len;
        }
      };
    }

    template<typename T>
    class exampleClass{
      protected:
        T buffer[10];
        size_t len;

      public:
        exampleClass(): len(0) {}
        exampleClass(cpstd::initializer_list<T> il){
          len = il.size();
          for(size_t i = 0; i < len; i++){
            buffer[i] = *(il.begin()+i);
          }
        }

        exampleClass& operator=(cpstd::initializer_list<T> il){
          len = il.size();
          for(auto i = il.begin(); i < il.end(); i++){
            buffer[i] = *i;
          }
        }

        size_t size() const {return len;}
        T data(size_t x) const {return buffer[x];}
    };

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

      exampleClass<uint8_t> myObject = {0,1,2,3};

      Serial.println(myObject.size());
      Serial.println(myObject.data(0));
      Serial.println(myObject.data(1));
      Serial.println(myObject.data(2));
      Serial.println(myObject.data(3));

    }

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

    }

  [1]: https://jfpoilpret.github.io/fast-arduino-lib/initializer__list_8h_source.html
  [2]: https://github.com/mike-matera/ArduinoSTL/blob/master/src/initializer_list

title: How to handle class initialization when using brace-enclosed initializer lists

Answers: 1

body:
So I have been messing around with the minimal example code and found a working solution, I'll post the solution just in case someone finds themselves having the same issue on the future, the only downside is that it feels a bit hacky to my taste, I still wonder if there is a better solution. And would gratly appreciate any feedback.

I found out that the compiler does not ackowledges the initializer_list class for braced enclosed initializers if the class is not under the namespace std.

The way I came arround this problem lies on using the preprocessor directive below:

    #if __has_include(<initializer_list>)

With this line conditional compilation takes place, and we can specify what to do whenever std::initializer_list is present or not.

- If std::initializer_list is not present an implementation is provided.
- cpstd::intitlizer_list is only a template alias of std::intitializer_list

minimal sketch with the solution:

    #include <Arduino.h>
    #include <stddef.h>

    namespace std {

      template<typename T>
      class initializer_list {
      public:
        using value_type = T;
        using reference = const T&;
        using const_reference = const T&;
        using size_type = size_t;
        using const_iterator = const T*;

      private:
        const_iterator _M_array;
        size_type _M_len;

        constexpr initializer_list(const T* array, size_type size) noexcept
          : _M_array(array), _M_len(size) {}

      public:
        constexpr initializer_list() noexcept
          : _M_array(nullptr), _M_len(0) {}

        constexpr size_type size() const noexcept {
          return _M_len;
        }
        constexpr const_iterator begin() const noexcept {
          return _M_array;
        }
        constexpr const_iterator end() const noexcept {
          return _M_array + _M_len;
        }
      };
    }

    namespace cpstd {
      template<class T>
      using initializer_list = std::initializer_list<T>;
    }

    template<typename T>
    class exampleClass{
      protected:
        T buffer[10];
        size_t len;

      public:
        exampleClass(): len(0) {}
        exampleClass(cpstd::initializer_list<T> il){
          len = il.size();
          for(size_t i = 0; i < len; i++){
            buffer[i] = *(il.begin()+i);
          }
        }

        exampleClass& operator=(cpstd::initializer_list<T> il){
          len = il.size();
          for(auto i = il.begin(); i < il.end(); i++){
            buffer[i] = *i;
          }
        }

        size_t size() const {return len;}
        T data(size_t x) const {return buffer[x];}
    };

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

      exampleClass<uint8_t> myObject = {0,1,2,3};

      Serial.println(myObject.size());
      Serial.println(myObject.data(0));
      Serial.println(myObject.data(1));
      Serial.println(myObject.data(2));
      Serial.println(myObject.data(3));

    }

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

    }


body:
I'm trying to trigger a picture using the GPIO13 of an esp32-cam, AI Thinker model.
I'm using that example as a base:
https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/
but instead of the PIR/Transistor combination, I'm using a press button with a pull-up resistor that pulls the GPIO13 pin down when pressed, simulating the PIR signal.
I'm feeding the esp-32 cam with a 5V power supply and the button circuit with the 3.3v
pin of the esp32, all grounded.
All hardware, SD card and so on is tested ok, I got the right voltages and I can see the GPIO13 Pin going to ground on my scope, but I just doesn't work.
Any ideas?
Edit 1: I'm using the ESP32-CAM-MB USB Board

title: Triggering a picture with esp32-cam and GPIO13

Answers: 1

body:
Checking the [specs of the cam board](https://docs.ai-thinker.com/en/esp32-cam), I see that `GPIO13` has the function `HS2_DATA3`, suggesting that the SD card is using that pin (which is also corroborated by [this article](https://dr-mntn.net/2021/02/using-the-sd-card-in-1-bit-mode-on-the-esp32-cam-from-ai-thinker).)

This may or may not be a problem, as the state of `GPIO13` is only relevant for sleep/wakeup when the chip is sleeping, and only relevant for SD card access when the chip is running; but there is an external addon: your pullup resistor on the button is still there when the chip is running. The PIR module from the tutorial that you're trying to replace probably has an open collector output (floating when inactive, pulled LOW when active).

My best hunch is to get rid of the pullup resistor on your button, so that the pin is floating during SD card access.

There still is the possibility that you then interfere with the SD card data when you keep the button pressed. If that is the case, you may need to put a resistor in _series_ with the button, so that the wake-up signal is weaker than the SD card data signal (start at 100KOhm and reduce until wake-up works).

If that isn't it, the question is lacking details. As you did not even post a description of what exactly "just does not work", first thing would be to produce a minimal sketch just to test sleep/wakeup via GPIO13 and post that here.


body:
I'm new to Arduino and my question is rather theoretical. I have an Arduino Nano board (Atmega168 processor), a button, a display. I have written a button handler that does not stop code execution. My idea is: poll the button in "loop" cycle, and if it is pressed, perform `k++`. When `k` exceeds a specified value, perform `cnt++` and print it on the display.

Code example №1 works correctly. I get 1 -> 2 -> 3 -> ...:

```
void loop() {
 if (digitalRead(button_pd) == LOW) {
    k = k + 1;
    if (k >= 20) {
      k = 0;
      cnt = cnt + 1;
    }
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(cnt);
  }
}
```

Code example №2 is incorrect. I get 16 -> 27 -> 40 -> ... Seems like not `cnt` is printed, but `k`.

```
void loop() {
  if (digitalRead(button_pd) == LOW) {
    k = k + 1;
    if (k >= 20) {
      k = 0;
      cnt = cnt + 1;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(cnt);
    }
  }
}
```

Here's my program:

```
#include <LiquidCrystal_I2C.h>

#define button_pd 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int k = 0;
int cnt = 0;

void setup() {

  pinMode(button_pd, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(cnt);

}

void loop() {

  // button handler

}

```

My question is. Why examples №1 and №2 work differently?

title: "if" condition problem / question

Answers: 2

body:
The timings are different.

Every operation on the LCD takes time. This:

```c++
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(cnt);
```

involves some I2C communication, and thus takes orders of magnitude more
time than `k++;`.

On the first version of your `loop()`, these operations are performed on
each iteration, while the button is being pressed. On the second
version, they are performed only when `k` reaches 20, thus twenty times
less often. The second version thus runs twenty times faster... too fast
for the LCD to correctly refresh and show all the values it is being
asked to display.

I recommend you do not rely on loop counting for controlling timings.
Instead, use the Arduino function specifically designed for time
management. For example, if you want to increment the counter every
200 ms, you should record the time when the button is pressed (the
falling edge of the signal), and increment `cnt` 200 ms later:

```c++
uint8_t previous_state;  // previous state of the button
uint32_t press_timestamp;  // time when the button was pressed

void loop() {
    uint32_t now = millis();
    uint8_t state = digitalRead(button_pd);
    if (previous_state == HIGH && state == LOW)  // falling edge
        press_timestamp = now;
    previous_state = state;
    if (state == LOW && now - press_timestamp >= 200) {
        cnt = cnt + 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(cnt);
    }
}
```

body:
Thanks. Somehow code example №3 works correctly. I have used a library for timer and simplified code from the answer above.

```
#include <LiquidCrystal_I2C.h>
#include <millisDelay.h>       // Timer

#define button_pd 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int k = 0;
int cnt = 0;

//uint8_t previous_state;  // previous state of the button

millisDelay d;

void setup() {
  pinMode(button_pd, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(cnt);
}

void loop() {

    uint8_t state = digitalRead(button_pd);
    if (state == LOW)
        d.start(300);
    //previous_state = state;
    if (d.justFinished()) {
        cnt = cnt + 1;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(cnt);
    }

}

```