# Question
Title: Bad readings from 12V pwm fan tachometer signal
I have the following circuit:

(The Arduino is powered via the USB)

The problem is that I the reading from the fan's tachometer signal are incorrect,

I tried to add the two resistors as voltage dividers but still the readings are wrong. When I check the voltage of the tachometer signal with a multimeter, in the time the multimeter is connected the readings are somewhat correct (not 100%).

Here is a snippet from the fan's documentation:

(BTW: When I used a different 12v pwm fan and didn't use a voltage divider the readings were incorrect only in the time I switched the 12v power off until the fan stopped spinning (after it stopped spinning the tachometer stopped sending signals so the rpm was 0 which was correct).)

Working code (correct tacho signal value):

```
const byte tachpin = 2;

unsigned int tacho = 0;
long int startTime = 0;
long int elapsed = 0;

void setup() {
  Serial.begin(9600);
   // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = _BV(COM1A1)
           | _BV(COM1B1)
           | _BV(WGM11);
    TCCR1B = _BV(WGM13)
           | _BV(CS10);
    ICR1   = 320;

    pinMode(tachpin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(tachpin), tachisr, RISING);
    startTime = millis();
}

void tachisr(){
  tacho++;
}

void loop() {
      elapsed = millis() - startTime;
      if(elapsed > 1000) {
        int tachcopy = 0;
        noInterrupts();
        tachcopy = tacho;
        tacho = 0;
        interrupts();
        rpm = (tachcopy / 2.0) * (60000 / elapsed);
        Serial.println(rpm,DEC);
      }
      startTime = millis();
}

```

Correct reading from working code

> rpm = 0, tachcopy = 0
> rpm = 1150, tachcopy = 39
> rpm = 2360, tachcopy = 80
> rpm = 2655, tachcopy = 90
> rpm = 2773, tachcopy = 94
> rpm = 2655, tachcopy = 90
> rpm = 1268, tachcopy = 43

Not working code (incorrect tachometer signal):

```
const byte tachpin = 2;

unsigned int tacho = 0;
long int startTime = 0;
long int elapsed = 0;
long int rpm = 0;
unsigned int pwmValue = 0;
unsigned int outValue = 0;
unsigned int seconds_counter = 0;

void setup() {
  Serial.begin(9600);
   // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = _BV(COM1A1)
           | _BV(COM1B1)
           | _BV(WGM11);
    TCCR1B = _BV(WGM13)
           | _BV(CS10);
    ICR1   = 320;

    // Set the PWM pins as output.
    pinMode( 9, OUTPUT); //!!!ADDED LINE!!!

    pinMode(tachpin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(tachpin), tachisr, RISING);
    startTime = millis();
}

void tachisr(){
  tacho++;
}

//!! ADDED FUNCTION !!!
void analogWrite25k(int value)
{

    OCR1A = value;

}

void loop() {

      elapsed = millis() - startTime;
      if(elapsed > 1000) {
        int tachcopy = 0;
        noInterrupts();
        tachcopy = tacho;
        tacho = 0;
        interrupts();
        startTime = millis();
        rpm = (tachcopy / 2.0) * (60000 / elapsed);
        Serial.print("rpm = ");
        Serial.print(rpm,DEC);
        Serial.print(", tachcopy = ");
        Serial.println(tachcopy,DEC);

        seconds_counter++;
      }

      analogWrite25k(100); //!!!ADDED LINE!!!

}

```

Not working code output:

> rpm = 737854, tachcopy = 25012
> rpm = 738591, tachcopy = 25037
> rpm = 737824, tachcopy = 25011
> rpm = 738591, tachcopy = 25037
> rpm = 738562, tachcopy = 25036
> rpm = 737854, tachcopy = 25012
> rpm = 738562, tachcopy = 25036
> rpm = 737854, tachcopy = 25012
> rpm = 738562, tachcopy = 25036
> rpm = 737824, tachcopy = 25011
> rpm = 738591, tachcopy = 25037
> rpm = 737854, tachcopy = 25012
> rpm = 738562, tachcopy = 25036
> rpm = 737854, tachcopy = 25012
> rpm = 738562, tachcopy = 25036
> rpm = 737854, tachcopy = 25012

Readings when using 10K ohm resistor as pull up (instead of the voltage divider (10K+4.7K)) and maxing out analogWrite25k - `analogWrite25k(320);`:

> rpm = 6165
> rpm = 6401
> rpm = 6136
> rpm = 6136
> rpm = 6165
> rpm = 6018
> rpm = 6283
> rpm = 5870
> rpm = 6047
> rpm = 6578
> rpm = 6460
> rpm = 6224
> rpm = 5782
> rpm = 6047
> rpm = 6136
> rpm = 6136
> rpm = 6313
> rpm = 5988
> rpm = 6224
> rpm = 6195
> rpm = 6136
> rpm = 5900

Which is interesting because the max speed of the fan is ~3000rpm (so rpm readings are about x2 max fan rpm when maxing out analogWrite25k)

**Update:**

Added debounce + 10K Ohm to Arduino 5V:

```
#define DEBOUNCE 10
//Interrupt handler. Stores the timestamps of the last 2 interrupts and handles debouncing
unsigned long volatile ts1=0,ts2=0;
//Calculates the RPM based on the timestamps of the last 2 interrupts. Can be called at any time.
unsigned int calcRPM(){
    unsigned long ts1_copy, ts2_copy;
    noInterrupts();
    ts1_copy = ts1;
    ts2_copy = ts2;
    interrupts();

    Serial.print(ts1_copy);
    Serial.print(" / ");
    Serial.print(ts2_copy);
    Serial.print(" / ");
    Serial.println(ts2_copy - ts1_copy);
    return (60000000.0 / (ts2_copy - ts1_copy ) / 2.0);
}

void tachisr2() {
    unsigned long m=micros();
    if((m-ts2)>DEBOUNCE){
        ts1=ts2;
        ts2=m;
    }
}

```

Output after adding debounce:

> rpm = 2953.92
> 90923308 / 90923320 / 12
> rpm = 2500000.00
> 91948328 / 91958496 / 10168
> rpm = 2950.43
> 92994188 / 92994200 / 12
> rpm = 2500000.00
> 94031032 / 94031040 / 8
> rpm = 3750000.00
> 95047108 / 95057256 / 10148
> rpm = 2956.25
> 96093308 / 96093320 / 12
> rpm = 2500000.00
> 97119144 / 97129296 / 10152
> rpm = 2955.08

When the value is ~2900 it is the correct value.

**Update 2**

Hope you can help me with another problem, The rpm value is scattering on a range of up to 120rpm+ even on low fan cycle of 800 rpm, of course when the elapsed time wait is bigger the scattering range is lower, the rpm reading might be not precise by about ~10%, I saw videos of live speed reading from BIOS of PC fan connected to PC motherboard and some of the fans are more precise (maybe because of BIOS code? (maybe there is a standard that specifies minimum time before reading the tacho counter?)), The question is are the tachometer sensors on 12V PC fans not supposed to be super precise by design or do I still have some problems with my circuit?, If I want a more precise rpm reading should I use an external tachometer sensor? which one is the best? optical/magnet based? (btw my current circuit doesn't include the 4.7KOhm resistor from the schematic, only 10KOhm pull up to 5V)

# Answer
**1. Open Collector Output of a module.**

The power for the open collector output should come from the MCU, not (indirectly) from the sensor's power supply. It is very similar to wiring a push button switch on the low side. Usually, the internal pullup resistor of the Arduino pin which is connected to the module passes enough power to detect the status of this output (as you have done). This internal pullup resistor has a value of around 30k. It is also possible to add a lower value external pull up resistor, if required say because of electrical noise, between the Arduino's 5v power rail and the pin. Ensure, however, that the current is within the tolerance of the connected device.

Measuring PWM voltages with a multimeter will not be successful, as you have discovered. These tend to integrate and show an average voltage. Say 12 volts at a 50% duty cycle will be read as 6 volts. Use an oscilloscope to see the voltage across the wave form.

**2. Electrical Interference.**

Your figure here `tachcopy = 25012` indicate that your 25KHz signal is leaking through and being detected as pulses from the sensor. Powering the open collector via the Nano's 5v power rail (as above) may eliminate this. Maybe also better decoupling on the 12 volt power supply (say adding a big capacitor).

**3. Code Issues**

Your code has an number of issues which should be cleaned up. Some may show up after only about 25 days. Some may show up after the next recompilation and some affect the accuracy of the results.

* `unsigned int tacho = 0;` should be volatile.
* `int tachcopy = 0;` should be unsigned int to match the data tape it is copying.
* Variables which are derived from millis() should be unsigned long (uint32\_t) as here: `elapsed = millis() - startTime;`.
* This `(60000 / elapsed)` should be forced to a floating point division say `(60000.0 / elapsed)`
* This could be in setup() instead of loop(): `analogWrite25k(100); //!!!ADDED LINE!!!`

**4. "rpm readings is about x2 max fan rpm"**

I can't explain that. It may be that the sensor output needs to be debounced.

**5. Sample debounce routine (lockout principle)**

```
// Simple debounce routine. Based on original code.
// After accepting a pulse locks out further pulses for 3 ms
// Should be OK for 100Hz (period 10ms)

void tachisr(){
  // ISR (external interrupt)
  static uint32_t lastAcceptedPulseAtMs = 0 ; // static initialised once only
  uint32_t ms = millis() ;
  if ( ms - lastAcceptedPulseAtMs >= 3 ) {  // 3 ms - tune if required
    lastAcceptedPulseAtMs = ms ;
    tacho++;
  }
}

```

Note: An ISR should be quick to execute and should not contain Serial.print() etc.
> 1 votes

---
Tags: arduino-nano, pwm
---


# Question
Title: Flow meter using Wemos Mini - ISR not in IRAM!
I'm trying to use a flow meter with Wemos Mini. Most tutorials are using Arduino boards ( which code and HW work OK ), but since I want this device to send alerts over the internet when abnormal usage/leakage is detected, I want to use Wemos Mini using How to Use Water Flow Sensor - Arduino Tutorial. On top of if will add my code for notifications using Telegram.

BUT - after uploading the original code (before adding Telegram changes ), an error occurs during code run : `ISR not in IRAM!`

I tried to change Pin - but still getting this error,

# Answer
> 1 votes
This happens because of conflicts between Serial and external interrupts Put ICACHE\_RAM\_ATTR before your interrupt function, like this  `ICACHE_RAM_ATTR void ISR()`

# Answer
> -1 votes
For WEMOS or NODEMCU you must predefine interupt routine for example

**void ICACHE\_RAM\_ATTR ServiceLimitSwitchUpperShield\_12\_D6();**

//it is solve problem for ATTACHINTERRUPT - you must predefine this method **before use setup (very important )** Then this message error ISR not IRAM will be not displayed .

In a setup you can for example define attachInterrupt(digitalPinToInterrupt(12), **ServiceLimitSwitchUpperShield\_12\_D6** , FALLING );

Look for page https://community.blynk.cc/t/error-isr-not-in-iram/37426/23

---
Tags: isr
---


title: Pro Micro ATMEGA32U4 unable to upload

text:
# Question
Title: Pro Micro ATMEGA32U4 unable to upload
I have a simple flashing led program that I want to upload on my pro micro (see image) but it doesnt work (see image: no port available, Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload.)

I have successfully uploaded this program on my arduino uno.

Ive followed this guide for the drivers and more. https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/installing-windows

Thanks for help

# Answer
Your board will only present a serial port if the sketch that is running on it is programmed to present a serial port. The board does not have an actual serial port for communication with the PC - only what the sketch provides.

If the sketch doesn't provide one, or if the sketch isn't running (for example if it was compiled for the wrong board by accident) then you will never see a serial port.

Since the "normal" way of resetting the board to enter the bootloader (which *does* present its own serial port) is to open the serial port at 1200 baud, since you don't have one to open it's kind of hard to get to the bootloader. However, depending on *what* bootloader you have installed there are a number of options that can help you:

1. Briefly connecting RST to GND just before uploading may activate the bootloader for a few seconds.
2. Doing the above *twice* in rapid succession may activate the bootloader for longer (depending on the bootloader version)

Erasing the chip and reinstalling the bootloader is the only real way that is guaranteed to work, though. But that said, I have seen boards come out of China *without any bootloader at all* \- so reinstalling the bootloader is always a good first option with cheap boards. You can use your Arduino UNO as an ISP programmer (using the ArduinoISP sketch and treating it like you're making a breadboard Arduino).
> 2 votes

# Answer
I have also problem with China boards, after 3 days of googling and trying get boards to work, I found out, that chip it self have difference.one chip is for bootloader from arduino micro, and one from lilypad arduino USB, it is about chip ID when arduino IDE is calling for upload sketch, thers are two 4bit id when it cals. And one is chip with cristal 16MHz lilypad arduino USB, and another version 8MHz Arduino micro, but board is it self looks like Arduino pro micro, Chip type have only few letters difference, if I will never find out that solution, if I will not have two chip comparisions .

Last row of numbers makes chip type difference and vendor id depends to what chip type we have. And what clock speed is using. And I see on the veb that many peoples have this problem to not be able to upload simple sketch because of that chip model.
> 0 votes

---
Tags: programming, led
---


# Question
Title: unable to program esp32cam via cloned esp32-cam-mb
I bought a couple of ESP32CAMs from aliexpress... althought the listing shows them with two buttons, I got the ESP32-CAM-MB boards with just the reset button...

I have my computer set up to dual boot Windows and Linux so when I got an error in windows, I rebooted and installed the ESP32 boards for Arduino 2.1 and went ahead. I had to also install esptool and pyserial for it to work, but it ended up recognizing the port and every time I try to program it the flash flashes, but the programmer responds with

> ```
> A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0xb)! The chip needs to be in download mode.
>
> ```

When I enable the serial console and press the reset button I get the following:

```
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:6968
load:0x40078000,len:13072
ho 0 tail 12 room 4
load:0x40080400,len:3896
entry 0x40080688
[0;32mI (31) boot: ESP-IDF v4.1-dirty 2nd stage bootloader[0m
[0;32mI (31) boot: compile time 16:15:01[0m
[0;32mI (31) boot: chip revision: 3[0m
[0;32mI (34) boot_comm: chip revision: 3, min. bootloader chip revision: 0[0m
[0;32mI (41) boot.esp32: SPI Speed      : 40MHz[0m
[0;32mI (46) boot.esp32: SPI Mode       : DIO[0m
[0;32mI (51) boot.esp32: SPI Flash Size : 4MB[0m
[0;32mI (55) boot: Enabling RNG early entropy source...[0m
[0;32mI (60) boot: Partition Table:[0m
[0;32mI (64) boot: ## Label            Usage          Type ST Offset   Length[0m
[0;32mI (71) boot:  0 nvs              WiFi data        01 02 00009000 00005000[0m
[0;32mI (79) boot:  1 otadata          OTA data         01 00 0000e000 00002000[0m
[0;32mI (86) boot:  2 app0             OTA app          00 10 00010000 00300000[0m
[0;32mI (94) boot:  3 spiffs           Unknown data     01 82 00310000 000f0000[0m
[0;32mI (101) boot: End of partition table[0m
[0;32mI (106) boot_comm: chip revision: 3, min. application chip revision: 0[0m
[0;32mI (113) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x1d2048 (1908808) map[0m
[0;32mI (849) esp_image: segment 1: paddr=0x001e2070 vaddr=0x3ffbdb60 size=0x04d3c ( 19772) load[0m
[0;32mI (857) esp_image: segment 2: paddr=0x001e6db4 vaddr=0x40080000 size=0x00400 (  1024) load[0m
[0;32mI (858) esp_image: segment 3: paddr=0x001e71bc vaddr=0x40080400 size=0x08e54 ( 36436) load[0m
[0;32mI (880) esp_image: segment 4: paddr=0x001f0018 vaddr=0x400d0018 size=0x9df74 (647028) map[0m
[0;32mI (1127) esp_image: segment 5: paddr=0x0028df94 vaddr=0x40089254 size=0x0b6a0 ( 46752) load[0m
[0;32mI (1159) boot: Loaded app from partition at offset 0x10000[0m
[0;32mI (1159) boot: Disabling RNG early entropy source...[0m
�
SD Size: 29557MB  OK

```

I can see that the board is in `SPI_FAST_FLASH_BOOT` mode which according to the linked documentation is wrong... but how to I get it to reboot in the correct mode?

Others have had similar issues, but they use another tool stack, so I am not sure what their solution would translate to in the Arduino 2.1 IDE...

# Answer
> 1 votes
While making sure I included all the correct links and pictures in the question, I found the answer - if an SD card is inserted, the flashing cannot be performed.

Removing the SD card and resetting the ESP32 works. I now have a very bright flashing LED

---
Tags: esp32, programmer, esp32-cam
---


# Question
Title: My Arduino IDE won't compile even simple sketches suddenly... How can I fix that??? this is the error message I get... I did work well at first!
```
private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/hardware -hardware /Users/daniellecomte/Library/Arduino15/packages -tools /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/tools-builder -tools /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/daniellecomte/Library/Arduino15/packages -built-in-libraries /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/libraries -libraries /Users/daniellecomte/Documents/Arduino/libraries -fqbn=arduino:avr:mega:cpu=atmega2560 -vid-pid=0X2341_0X0042 -ide-version=10805 -build-path /var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/arduino_build_880660 -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.1.1 -prefs=runtime.tools.avrdude.path=/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9 -prefs=runtime.tools.avr-gcc.path=/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2 -verbose /var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/untitled1415726107.tmp/sketch_may19a/sketch_may19a.ino
/private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/hardware -hardware /Users/daniellecomte/Library/Arduino15/packages -tools /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/tools-builder -tools /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/daniellecomte/Library/Arduino15/packages -built-in-libraries /private/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/AppTranslocation/8AC1112E-019A-430D-A268-5BEDD561B4FC/d/Arduino.app/Contents/Java/libraries -libraries /Users/daniellecomte/Documents/Arduino/libraries -fqbn=arduino:avr:mega:cpu=atmega2560 -vid-pid=0X2341_0X0042 -ide-version=10805 -build-path /var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/arduino_build_880660 -warnings=all -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.1.1 -prefs=runtime.tools.avrdude.path=/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino9 -prefs=runtime.tools.avr-gcc.path=/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2 -verbose /var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/untitled1415726107.tmp/sketch_may19a/sketch_may19a.ino
Using board 'mega' from platform in folder: /Users/daniellecomte/Library/Arduino15/packages/arduino/hardware/avr/1.6.21
Using core 'arduino' from platform in folder: /Users/daniellecomte/Library/Arduino15/packages/arduino/hardware/avr/1.6.21
Detecting libraries used...
"/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR   "-I/Users/daniellecomte/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino" "-I/Users/daniellecomte/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/variants/mega" "/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/arduino_build_880660/sketch/sketch_may19a.ino.cpp" -o "/dev/null"
Generating function prototypes...
"/Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR   "-I/Users/daniellecomte/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/cores/arduino" "-I/Users/daniellecomte/Library/Arduino15/packages/arduino/hardware/avr/1.6.21/variants/mega" "/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/arduino_build_880660/sketch/sketch_may19a.ino.cpp" -o "/var/folders/sv/y8kh1rhd4sz23xbxsnppbp700000gn/T/arduino_build_880660/preproc/ctags_target_for_gcc_minus_e.cpp"
fork/exec /Users/daniellecomte/Library/Arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/bin/avr-g++: no such file or directory
Error compiling for board Arduino/Genuino Mega or Mega 2560.

```

# Answer
> 1 votes
> avr-g++: no such file or directory

Try downloading the IDE again. It looks like it has lost sight of where the compiler is. Preferably not a nightly build but one of the stable versions.

# Answer
> 1 votes
This indicates something has gone wrong with your Arduino AVR Boards installation. To make sure it has been fully uninstalled you need to take some drastic action. Be aware this is somewhat advanced and will remove all boards you have installed via Boards Manager:

1. Click the link on the line following **File \> Preferences \> More preferences can be edited directly in the file**. This will open the `/Users/daniellecomte/Library/Arduino15` folder.
2. Delete all files and folders under the Arduino15 folder except for preferences.txt. Please be very careful when deleting things from your computer. When in doubt, back up!
3. Restart the Arduino IDE

Verify that you can now compile for your board before reinstalling any packages via Boards Manager.

# Answer
> 1 votes
recommended is to install Arduino AVR Boards newest version through this simple steps, go to Tools -\> Boards -\> Board Manager -\> Install "Arduino AVR Boards (X.Y.Z).

---
Tags: arduino-uno
---


# Question
Title: How to change the I2C address of the AS5048B?
I saw this video from James Bruton. See the links to the GitHub repos in the video description.

I bought a few AS5048B boards from AMS, so I can measure the position of my stepper motors.

In the `sosandroid` repo, I ran `program_address` and was able to get one of them working, but they all have the same I2C address, and because I want to have 6 of them running simultaneously, it of course won't work. I know I could get an I2C multiplexer...

I also tried setting the A1 and A2 pins on the AS5048B to high and low, which change the I2C address (for a total of 4)... But I want to change the I2C address permanently for each board.

It looks to me like `program_address` is supposed to permanently program the I2C address, which the user can specify in the .ino file:

```
// Construct our AS5048B object with an I2C address of 0x40
AMS_AS5048B mysensor(0x40);

```

But no matter what I set it to (e.g. `0x40, 0x41, 0x42, 0x43, 0x44`), the Arduino I2C scanner always finds `0x44`, which is the default address, so the `program_address` must not be working.

EDIT: the default address is actually `0x40`. I must have programmed it to `0x44` without knowing (I was playing around with this board trying to figure this all out).

I know that normally the I2C addresses cannot be changed, but it looks like this one can:

Here's a snippet from the link above. It says the OTP bits can be programmed/burned (only once!). My understanding is that the I2C address is saved in the OTP bits.

> Program the OTP bits permanently:
>
> 1. Write dec.253 into the OTP control register (dec.3) to enable the special programming mode
> 2. Set the Burn bit (dec.8) in the OTP control register (dec.3) to enable automatic programming procedure
> 3. Write dec.0 into the OTP control register (dec.3) to disable the special programming mode

I am using the Teensy 4.1 using PlatformIO in VS Code, and I also tried using an Arduino Uno in the Arduino IDE.

My wiring is as follows:

**So how do I program the I2C address on the AS5048B boards?**

## EDIT:

* I changed an image to text, and cleaned things up.

As @6v6gt requested, I used the I2C scanner and it is still showing 0x40 (on this particular board), so it must not have been programmed (unless it's possible to program it to 0x40 even though 0x40 is its default value). The only thing I changed from the `program_address` repo is this line in the .ino file:

```
// Construct our AS5048B object with an I2C address of 0x40
AMS_AS5048B mysensor(0x48);

```

I changed the 0x40 to 0x48. But now I am getting this in the serial monitor:

```
Angle degree : I2C error: 2
359.9780273437

```

Since I must have programmed the other board to 0x44 successfully, I am trying to think of what I did differently, but I don't remember.

There are hundreds of lines of code in `program_address` (and the .h and .cpp file), so I probably shouldn't post all of it here. But here's the GitHub repo.

# Answer
The device slave I2C address consists of the hardware setting on pins A1, A2 **and upper MSBs programmable by the user.** It is the setting of the MSBs, in addition to A1/A2 that I believe the OP is after.

The information provided by @Nick Gammon concerning A1 and A2 is correct, but does not consider the other 5 bits (the MSBs). It appears that you can, indeed, permanently set a new I2C slave address on the device.

You need to read the programming application note very carefully, but they explain how to burn those bits into the register....it seems straightforward and is really just four steps, but I suppose it can be a little daunting, e.g., "***slave address consist of 5 programable bits (MSBs) and the hardware setting of Pins A1 and A2 I²C address \<4\> is by default not programmed and due to the inversion defined as '1'***"

The application note gives an example of the 4 steps....

It may be the case that you already changed the I2C address default to 0x44 by following the instructions. \[edited to add\] Can you post the complete program \[Arduino IDE code\] that you used to *try* to change the I2C address?
> 4 votes

# Answer
> but they all have the same I2C address

No, they have 4 possible addresses, based on how you configure A1 and A2. So you can have 4 different addresses immediately.

> But I want to change the I2C address permanently for each board.

For each board, set up A1 and A2 differently.

This only gives you 4 different addresses, not 6. You could conceivably connect 8 devices to two different Atmega328 chips, and have them do the readings and forward the results using a protocol you devise, to your "main" board. The Atmega328 chips only cost around $US 5 each so this isn't a big deal.

Another approach would be to run SDA and SCL through a multiplexer chip, so that you enable one batch of 4 chips and then the other batch. Without trying it out, it is hard to say if this would work satisfactorily.
> 2 votes

---
Tags: i2c
---


# Question
Title: How to write single binary code to output pin
I am relatively new to arduino and coding in general and im just looking for a code to write a single string of binary code e.g.; "01000111101" To a specified output pin instead of copying and pasting

"Digital write (high) Digital write (low) Etc."

preferably with the option to change speed between bits. Would be very appreciative for someone to help me out

# Answer
> 2 votes
If timing is not critical, consider dividing the number of interest by 2. If there was a remainder set the Arduino pin to 1. If not set it to 0. Then delay for as long as needed. Keep doing this until there is nothing left to divide 2 into.

However, sending out data in serial fashion is as old as computers. Likely older. Consequently there are a lot of built in features which do this. Specifically, it is not necessary to explicitly code up a function to convert a value to serial data. Even on an Arduino.

---
Tags: programming, atmega
---


# Question
Title: Why doesn't OTA work with the Ai-Thinker ESP32-CAM board?
I have working code on an Ai-Thinker ESP32-CAM board, programming over serial.

I would like to reprogram using OTA, but adding in the functionality from the BasicOTA sketch (which I have done on various other boards successfully) fails when OTA programming is attempted, the board reboots following an abort() and a stack trace is generated.

The invaluable ESP32 exception decoder shows the fault occurs from checking if memory location is safe to write.

Normally, I would choose a partition option which includes OTA, but the Ai-Thinker board doesn't have this option in the IDE

# Answer
The `boards.txt` file configures what can be configured in the Arduino IDE for each board.

On my installation, this is found at `C:\Users\MyUser\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\boards.txt`

I found the section `esp32cam.name=AI Thinker ESP32-CAM` and changed the lines:

```
esp32cam.upload.maximum_size=3145728
esp32cam.build.partitions=huge_app

```

to

```
esp32cam.upload.maximum_size=1966080
esp32cam.build.partitions=min_spiffs

```

The various options are detailed in the same file with keys named `esp32.menu.PartitionScheme.`, and for some boards these options are configurable be the user. To add this, remove (or comment out with a `#` character) the two lines found above so they look like:

```
# esp32cam.upload.maximum_size=3145728
# esp32cam.build.partitions=huge_app

```

and add the required menu selections for your application- e.g.

```
esp32cam.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
esp32cam.menu.PartitionScheme.huge_app.build.partitions=huge_app
esp32cam.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
esp32cam.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32cam.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32cam.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080

```

After making any changes to `boards.txt`, restart the Arduino IDE for the change to take effect. Note that these changes (and any changes to the installation) may be overwritten by any future upgrades or library updates, so note your changes so they can be easily reapplied.

Alternatively, add the menu lines to `boards.local.txt`, introduced in Arduino 1.6.6 so they should persist during updates. In this case, no change needs to be made to `boards.txt`, as the `boards.local.txt` entries override those in `boards.txt`. I haven't tested this, hopefully it works across library updates and IDE upgrades.
> 2 votes

# Answer
You do not have to go through the hassle with editing the boards.txt if you want to have OTA only if you do not need it or you want a custom partition scheme.
That said the **OTA partition** is always what is left so e.g. `Med Spiffs App 1.9MB, Spiffs 190KB` means 1.9 MB OTA partiton.
The caveat is if you want to OTA a 1.8 MB App with 1 MB Spiffs that will NOT work. The OTA file has to be around 100kb (from experience) smaller than the availabe OTA partition. If you want to update APP and SPIFFS thats a topic on its own. So before editing your boards.txt check the following:

* App (uncompressed) is OTA space + ~100KB
* your OTA routine runs stable with/in small apps
* no connection problems during upload and
* proper OTA error handling in your code
* for initial testing attach no hardware to the board.
* If using the unmodified camera example or a custom on with face recognition you will fail with OTA because this is to big (~3MB APP!)
* OTA routines (incl wifi libs) take ~800 kB for basic OTA

As I use AIThinker32cam modules in various scenarios I know what you are through ;-)
Enclosed two custom board definitions (with no OTA) as there is no predefined (ESP32 core 1.04) in `C:\Users\YOUR_USERNAME\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\boards.txt` just copy and paste into the section (search for `esp32AiThinkerCam.menu.PartitionScheme` :

```
esp32AiThinkerCam.menu.PartitionScheme.noota_3g=1MB APP/3MB SPIFFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
esp32AiThinkerCam.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
esp32AiThinkerCam.menu.PartitionScheme.no_ota=2MB APP/2MB SPIFFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32AiThinkerCam.menu.PartitionScheme.no_ota.upload.maximum_size=2097152

```

and the "magic unlocker" is the `noota_3g.csv` found in `C:\Users\YOUR_USERNAME\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\partitions`,there the partition scheme isdefined. If you want to change that for custom partitions please ask a new question.
**EDIT**
Enclosed acomplete boards.txt part for AI-Thinker just replace the complete existing part with this amd you have a bunch of new options - all tested in production with ESP32 core 1.04. (without custom partition schemes):

```
##############################################################

esp32AiThinkerCam.name=ESP32 AI Thinker Cam

esp32AiThinkerCam.upload.tool=esptool_py
esp32AiThinkerCam.upload.maximum_size=1310720
esp32AiThinkerCam.upload.maximum_data_size=327680
esp32AiThinkerCam.upload.wait_for_upload_port=true

esp32AiThinkerCam.serial.disableDTR=true
esp32AiThinkerCam.serial.disableRTS=true

esp32AiThinkerCam.build.mcu=esp32
esp32AiThinkerCam.build.core=esp32
esp32AiThinkerCam.build.variant=esp32
esp32AiThinkerCam.build.board=ESP32_DEV

esp32AiThinkerCam.build.f_cpu=240000000L
esp32AiThinkerCam.build.flash_size=4MB
esp32AiThinkerCam.build.flash_freq=40m
esp32AiThinkerCam.build.flash_mode=dio
esp32AiThinkerCam.build.boot=dio

esp32AiThinkerCam.menu.CPUFreq.240=240MHz (WiFi/BT)
esp32AiThinkerCam.menu.CPUFreq.240.build.f_cpu=240000000L
esp32AiThinkerCam.menu.CPUFreq.160=160MHz (WiFi/BT)
esp32AiThinkerCam.menu.CPUFreq.160.build.f_cpu=160000000L
esp32AiThinkerCam.menu.CPUFreq.80=80MHz (WiFi/BT)
esp32AiThinkerCam.menu.CPUFreq.80.build.f_cpu=80000000L

esp32AiThinkerCam.build.partitions=default
esp32AiThinkerCam.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
esp32AiThinkerCam.menu.PartitionScheme.default=Default 1.2MB APP/1.5MB SPIFFS (OTA)
esp32AiThinkerCam.menu.PartitionScheme.default.build.partitions=default
esp32AiThinkerCam.menu.PartitionScheme.defaultffat=Default FATFS 1.2MB APP/1.5MB FATFS (OTA)
esp32AiThinkerCam.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
esp32AiThinkerCam.menu.PartitionScheme.noota_3g=1MB APP/3MB SPIFFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
esp32AiThinkerCam.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
esp32AiThinkerCam.menu.PartitionScheme.no_ota=2MB APP/2MB SPIFFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32AiThinkerCam.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32AiThinkerCam.menu.PartitionScheme.huge_app=3MB APP/1MB SPIFFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.huge_app.build.partitions=huge_app
esp32AiThinkerCam.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
esp32AiThinkerCam.menu.PartitionScheme.noota_ffat=2MB APP/2MB FATFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
esp32AiThinkerCam.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
esp32AiThinkerCam.menu.PartitionScheme.noota_3gffat=1MB APP/3MB FATFS (No OTA)
esp32AiThinkerCam.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
esp32AiThinkerCam.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
esp32AiThinkerCam.menu.PartitionScheme.minimal=Min SPIFFS 1.3MB APP/700KB SPIFFS (OTA)
esp32AiThinkerCam.menu.PartitionScheme.minimal.build.partitions=minimal
esp32AiThinkerCam.menu.PartitionScheme.min_spiffs=Med SPIFFS 1.9MB APP/190KB SPIFFS (OTA)
esp32AiThinkerCam.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32AiThinkerCam.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080

esp32AiThinkerCam.menu.FlashMode.qio=QIO
esp32AiThinkerCam.menu.FlashMode.qio.build.flash_mode=dio
esp32AiThinkerCam.menu.FlashMode.qio.build.boot=qio
esp32AiThinkerCam.menu.FlashMode.dio=DIO
esp32AiThinkerCam.menu.FlashMode.dio.build.flash_mode=dio
esp32AiThinkerCam.menu.FlashMode.dio.build.boot=dio
esp32AiThinkerCam.menu.FlashMode.qout=QOUT
esp32AiThinkerCam.menu.FlashMode.qout.build.flash_mode=dout
esp32AiThinkerCam.menu.FlashMode.qout.build.boot=qout
esp32AiThinkerCam.menu.FlashMode.dout=DOUT
esp32AiThinkerCam.menu.FlashMode.dout.build.flash_mode=dout
esp32AiThinkerCam.menu.FlashMode.dout.build.boot=dout

esp32AiThinkerCam.menu.FlashFreq.80=80MHz
esp32AiThinkerCam.menu.FlashFreq.80.build.flash_freq=80m
esp32AiThinkerCam.menu.FlashFreq.40=40MHz
esp32AiThinkerCam.menu.FlashFreq.40.build.flash_freq=40m

esp32AiThinkerCam.menu.UploadSpeed.921600=921600
esp32AiThinkerCam.menu.UploadSpeed.921600.upload.speed=921600
esp32AiThinkerCam.menu.UploadSpeed.115200=115200
esp32AiThinkerCam.menu.UploadSpeed.115200.upload.speed=115200
esp32AiThinkerCam.menu.UploadSpeed.256000.windows=256000
esp32AiThinkerCam.menu.UploadSpeed.256000.upload.speed=256000
esp32AiThinkerCam.menu.UploadSpeed.230400.windows.upload.speed=256000
esp32AiThinkerCam.menu.UploadSpeed.230400=230400
esp32AiThinkerCam.menu.UploadSpeed.230400.upload.speed=230400
esp32AiThinkerCam.menu.UploadSpeed.460800.linux=460800
esp32AiThinkerCam.menu.UploadSpeed.460800.macosx=460800
esp32AiThinkerCam.menu.UploadSpeed.460800.upload.speed=460800
esp32AiThinkerCam.menu.UploadSpeed.512000.windows=512000
esp32AiThinkerCam.menu.UploadSpeed.512000.upload.speed=512000

esp32AiThinkerCam.menu.DebugLevel.none=None
esp32AiThinkerCam.menu.DebugLevel.none.build.code_debug=0
esp32AiThinkerCam.menu.DebugLevel.error=Error
esp32AiThinkerCam.menu.DebugLevel.error.build.code_debug=1
esp32AiThinkerCam.menu.DebugLevel.warn=Warn
esp32AiThinkerCam.menu.DebugLevel.warn.build.code_debug=2
esp32AiThinkerCam.menu.DebugLevel.info=Info
esp32AiThinkerCam.menu.DebugLevel.info.build.code_debug=3
esp32AiThinkerCam.menu.DebugLevel.debug=Debug
esp32AiThinkerCam.menu.DebugLevel.debug.build.code_debug=4
esp32AiThinkerCam.menu.DebugLevel.verbose=Verbose
esp32AiThinkerCam.menu.DebugLevel.verbose.build.code_debug=5

```
> 2 votes

# Answer
As stated in the comments by @Codebreaker007 using the ESP32 Wrover Module works and if you put the pin definitions inline in the app there isn't a problem

```
#define CAMERA_MODEL_AI_THINKER

#if defined(CAMERA_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
#else
  #error "Camera model not selected"
#endif

```
> 1 votes

# Answer
Here.

Download this working ESP32-CAM sketch zip file with working OTA uploading: "Working\_ESP32\_CameraWebServer\_V2\_with\_OTA"

at

https://github.com/wjsanek/wjsanek.git

Make sure you read the simple "READ ME FIRST" file in the zip after unzipping.

This sketch overcomes any "file to big" or other OTA sketch uploading problems with this crumby, tempremental ESP32-CAM board (the $5 ESP8266 NodeMCU is better but the Arducam camera for it costs $23).

The ESP32-CAM board does not like to transmit very far.
> 0 votes

# Answer
OTA Requires you to partition your ESP32 with two sets of space for your program (ota\_0 and ota\_1 partitions) - during the OTA process, the unused one gets updated, and will be the next one that boots up.

This means that there's no room left for the camera (most camera driver libraries store the image in SPIFFS) to store the image data (OV2640 is 1622x1200 pixels, which is 1946400 bytes) because the only available partition schemes with OTA in Arduino IDE is 1.9mb program with 0.19mb (190kb) SPIFFs, which is 10-times-not-enough space to store camera images in.

the wjsanek project in here looks interesting - they're using one of the OTA partitions as the SPIFF for the camera. Very clever.
> 0 votes

---
Tags: wifi, esp32, ota, partition
---


# Question
Title: Good practice to assign shift-register pins at the same time?
I'm new to bit register manipulation and am trying to set input and output values of some pins. The code sample I have on hand does it this way::

```
DDRD |= (1 << 2);
DDRD |= (1 << 4);
DDRD &= ~(1 << 5);
PORTD |= (1 << 2);
PORTD &= ~(1 << 4);
PORTD &= ~(1 << 5);

```

I have two questions:

1. This is part of a code where I'm attempting to determine the time for a capacitor's discharge between pins 2 and 4. The arduino helpfiles mention that there may be a benefit to triggering both pins at once. Therefore: Is it is it possible to do `DDRD |= B00010100;` and `PORTD |= B00000100;` or combine the first three `DDRD` lines so it happens simultaneously, or does it have to be separately called?
2. Why is it `PORTD &= ~(1 << 4)` and not `PORTD |= ~(1 << 4);`Can this conflict with the previous state of PORTD.

# Answer
> ```
> DDRD |= (1 << 2);
> DDRD |= (1 << 4);
>
> ```

The equivalent to that is:

```
DDRD |= (1 << 2) | (1 << 4);

```

However I prefer `bit` because it does the shift for you:

```
DDRD |= bit(2) | bit(4);

```

---

> Why is it `PORTD &= ~(1 << 4)` and not `PORTD |= ~(1 << 4);`

`PORTD &= ~(1 << 4)` is turning a bit **off**. First you invert the sense of the bit with the **ones complement operator** (~) and then by **anding** it, it means that all bits are retained except that one. So this is basically turning bit 4 off. If you used `|=` it would turn all of the other bits **on**.

Equivalent code:

```
PORTD &= ~bit(4);

```

Based on your example you meant bit 5 not bit 4.

---

> ```
> PORTD |= (1 << 2);
> PORTD &= ~(1 << 4);
> PORTD &= ~(1 << 5);
>
> ```

That is turning on bit 2, and turning off bits 4 and 5, and leaving the rest unchanged.

---

> Thanks. In that case would DDRD &= B00000000; DDRD |= B00010100; have a similar result ...

If you do `DDRD &= B00000000;` then you are setting all bits to zero. So the simple equivalent to the above would be:

```
DDRD = B00010100;

```

This is a straight assignment, so you don't need to clear any bits.

Or, you could write:

```
DDRD = bit(2) | bit(4);

```

---

> Do you know if bit() faster or is it cleaner compared to 1 \<\< x; or is it better for me to hook up a scope to test this myself?

It is **exactly the same**. `bit` is just a `#define` in the Arduino.h file, as follows:

```
#define bit(b) (1UL << (b))

```

So all it does is save you writing the brackets and the shift left operator. It expands out to the same as what you were writing and thus will execute at the same speed, and take the same amount of memory.
> 2 votes

---
Tags: c++, shift-register
---


title: RMS Voltage Value

text:
# Question
Title: RMS Voltage Value
it has been a week that I'm struggling with the arduino to measure the RMS Voltage value. By OSC I can see that the RMS voltage value changes around 3V. But I can't see it by serial port. I think my sampling or conversion has problem and I can't find it. I really appreciate it if anyone can take a look at my codes and suggest anything.

```
float readRMS_new(int pin, int vref) {
  int numReadings[100];
  const unsigned long samplingInterval = 2;  // Interval between RMS calculations in milliseconds
  unsigned int readingsSum = 0;   // Sum of squared readings
  unsigned int readingsCount = 0; // Number of readings taken
  unsigned long lastSamplingTime = 0;  // Time of the last RMS calculation
  float rmsVoltage = 0;
  float finalVoltage = 0;
  float circuitGain = 4.31;  // Gain of the circuit

  unsigned long currentTime = millis();  // Current time

  // Check if it's time to perform an RMS calculation
  if (currentTime - lastSamplingTime >= samplingInterval) {
    lastSamplingTime = currentTime;  // Update the last sampling time

    // Perform RMS calculation
    for (int i = 0; i < 100; i++) {
      numReadings[i] = analogRead(pin);
      readingsSum += pow(numReadings[i] - vref, 2);
      readingsCount++;
    }

    // Calculate RMS voltage
    float rms = sqrt(readingsSum / readingsCount);
    rmsVoltage = rms * 0.0048;
    finalVoltage = rmsVoltage * circuitGain;

    if (finalVoltage > 0.0f) {
      // Print RMS voltage
      Serial.print("RMS Voltage: ");
      Serial.println(finalVoltage, 3);  // Print with 3 decimal places
    }

    // Reset variables for the next RMS calculation
    readingsSum = 0;
    readingsCount = 0;

    return finalVoltage;
  }

  return 0.0f;  // Return 0 if it's not time to perform an RMS calculation
}

```

Regards

Farzaneh

# Answer
> 2 votes
There are multiple issues with this piece of code:

1. Local variables, i.e. variables defined inside functions or braced blocks, are created each time the execution enters the function or block, and destroyed when it leaves it. Thus, `lastSamplingTime` will always be zero when it is checked. If you want the variable to preserve its value across invocations of the function, you have to either make it global or qualify it as `static`.
2. There is no point in storing the readings in an array, as you never read back any element of the array other than the one you just stored. The array is then eating memory for no good reason.
3. The Arduino will not be able to take more than one reading every 112 µs, or 100 readings in 11.2 ms. There is no point in trying to ensure a 2 ms interval between RMS calculations.
4. There is no point in counting the readings: you know you are taking 100 of them.
5. You should avoid using `pow()` for squaring an integer: this is a floating-point function which is prone to rounding errors.
6. Maybe the most serious issue: on the Mega, an `unsigned int` is 16-bits, and cannot store numbers larger than 65,535. `readingsSum` is very likely going to overflow and give you a meaningless result.
7. Returning zero to mean “no data available” is probably not a very good choice, as zero is also a perfectly valid result. You should consider returning an impossible value, like `-1` (an RMS reading cannot be negative).

Here is how I would write the computation of the RMS value:

```
long readingsSum = 0;
for (int i =0; i < 100; i++) {
    long reading = analogRead(pin) - vref;
    readingsSum += reading * reading;
}
float rms = sqrt(readingsSum / 100);

```

Note that `reading` is of type `long` in order to avoid the squaring to overflow.

# Answer
> 0 votes
Thank you all for your time dedication. Finally increasing the sampling and optimize the same codes I could achieve my goals. I will post the functioning code for those who might need it.

```
float readRMS(int pin, int vref) {

  int lecturas[200]; // declaring the matrix

  float suma = 0; // sum of the squares

  float rms = 0;  // squares mean

  float volt = 0;  //

  float Volt_Final = 0;

  for (int cont = 0; cont < 200; cont++) {

    lecturas[cont] = analogRead(pin);

    delayMicroseconds(200);
  }
  for (int j = 0; j < 200; j++) {

    //Serial.println(lecturas[j]);

    suma = suma + pow((lecturas[j] - vref), 2);

    //Serial.println(suma);
  }
  rms = sqrt((suma / 200));

  volt = (rms / 1024) * 5;

  //Serial.println(volt);

  //suma=0;

  // Reset variables for the next RMS calculation

  rms = 0;

  lecturas[200] = 0;

  //Volt_Final = (volt * 4.31); //real voltage with circuit gain

  return volt;
}

```

---
Tags: arduino-mega, analog-sampling, digital-analog-conversion
---


title: Determine if a XIAO ESP32C3 is charging

text:
# Question
Title: Determine if a XIAO ESP32C3 is charging
When the XIAO ESP32C3 is charging a LiPo battery, there is a small LED on the board that lights up. Is there any way to access this information in an Arduino program?

# Answer
> 0 votes
No, according to the schematic it's not wired to any pin on MCU.

---
Tags: battery, charging
---


# Question
Title: How to drive two Stepper motors and use an Ultrasonic sensor together?
I am working on an autonomous robot using two 4-pin stepper motors, HC-SR04 ultrasonic sensor, 2 L298N motor drivers (one for each motor), and an Arduino Uno. My problem is that when I use the stepper motors with the Stepper library, only one motor works at a time. My solution was to control the one step at a time in a short period of time, which worked, however, this introduces a new problem. The ultrasonic sensor requires a delay to work, but this makes the movement of the robot quite slow and jittery as it works only by one step at a time. When I remove the delay from the ultrasonic sensor, it starts returning the correct value, but then also returning 0 right after each correct value. My solution was to ignore the returned 0, but this is not ideal.

How can I use two stepper motors at the same time and use an Ultrasonic sensor?

Here is my code:

```
#include <Stepper.h>
#include <Ultrasonic.h>

/*
 * Pass as a parameter the trigger and echo pin, respectively,
 * or only the signal pin (for sensors 3 pins), like:
 * Ultrasonic ultrasonic(13);
 */
 Ultrasonic ultrasonic(13, 12);
 int distance;

 int driveSpeed = 100;
 int stepsPerRevolution = 200;
 int leftMotorStep = 0;
 int rightMotorStep = 0;

 // Time interval between steps for both motors
 const int stepInterval = 10;  // Adjust as needed

 // Last step time for each motor
 unsigned long leftMotorLastStepTime = 0;
 unsigned long rightMotorLastStepTime = 0;

 Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
 Stepper leftMotor(stepsPerRevolution, 4, 5, 6, 7);

 void setup() {
   Serial.begin(9600);
   rightMotor.setSpeed(driveSpeed);
   leftMotor.setSpeed(driveSpeed);
 }
 void loop() {
   distance = ultrasonic.read();

   Serial.print("Distance in CM: ");
   Serial.println(distance);
   delay(250); //This delay makes the motors behave strangely

   if (distance < 15) {
     Serial.println("AVOIDING OBSTACLE!");
     // Perform obstacle avoidance behavior
     avoidObstacle();
   } else if (distance < 30) {
     Serial.println("APPROACHING OBSTACLE!");
     // Perform slow approach behavior
     slowApproach();
   } else {
     Serial.println("DRIVING!");
     // Perform normal driving behavior
     drive();
   }
 }

 void avoidObstacle() {
   // Stop the robot
   halt();

   // Rotate the robot to avoid the obstacle
   leftM();

   // Delay to allow the rotation to complete
   delay(1000);
 }

 void slowApproach() {
   // Slow down the motors
   int slowSpeed = 50;
   rightMotor.setSpeed(slowSpeed);
   leftMotor.setSpeed(slowSpeed);

   // Move the robot forward slowly
   forwardM();

   // Delay to allow the slow approach
   delay(1000);
 }

 void drive() {
   // Set the motors back to the normal speed
   rightMotor.setSpeed(driveSpeed);
   leftMotor.setSpeed(driveSpeed);

   // Move the robot forward
   forwardM();
 }

 void forwardM() {
   rightMotor.step(1);
   leftMotor.step(1);
 }
 void leftM() {
   rightMotor.step(1);
   leftMotor.step(-1);
 }
 void rightM() {
   rightMotor.step(-1);
   leftMotor.step(1);
 }
 void reverseM() {
   rightMotor.step(-1);
   leftMotor.step(-1);
 }
 void halt() {
   rightMotor.step(0);
   leftMotor.step(0);
 }

```

# Answer
Try this code.

Here is a simulation. https://wokwi.com/projects/366108641014000641

Click on the sensor to set the distance in the simulation

NOTE: centimeters is `cm`, not `CM`.

Not tested on hardware.

```

// https://arduino.stackexchange.com/questions/93302/how-to-drive-two-stepper-motors-and-use-an-ultrasonic-sensor-together

#include <Stepper.h>
#include <Ultrasonic.h>

/*
 * Pass as a parameter the trigger and echo pin, respectively,
 * or only the signal pin (for sensors 3 pins), like:
 * Ultrasonic ultrasonic(13);
 */

 Ultrasonic ultrasonic(13, 12);

 int distance;

 int slowSpeed          =  100;
 int driveSpeed         = 1000;
 int stepsPerRevolution =  100;
 int leftMotorStep      =    0;                         // current step speed and direction
 int rightMotorStep     =    0;

 int stepSpeed          =   10;                         // this is the motor speed

 const int stepInterval =    1;                         // Time interval between steps for both motors

 unsigned long leftMotorLastStepTime  = 0;              // Last step time for each motor
 unsigned long rightMotorLastStepTime = 0;

 Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
 Stepper leftMotor (stepsPerRevolution, 4, 5,  6,  7);

 void setup() {
   Serial.begin(9600);
   rightMotor.setSpeed(1);
   leftMotor. setSpeed(1);
 }

 void loop() {

  distance = ultrasonic.read();

  Serial.print("Distance in cm: ");
  Serial.print(distance);  Serial.print("\t");

  switch (distance) {                              // used switch/case for cleaner looking code
    case 0 ... 14:
      Serial.println("avoid");
      avoidObstacle();                             // Perform obstacle avoidance behavior
      break;

    case 15 ... 29:
      Serial.println("approach");
      slowApproach();                              // Perform slow approach behavior
      break;

    default:
      Serial.println("drive");
      drive();                                     // Perform normal driving behavior
      break;
  }

  rightMotor.step(rightMotorStep);                 // this actually moves the motors
  leftMotor .step(leftMotorStep);
}

 void avoidObstacle() {
   halt();                                          // Stop the robot
   leftM();                                         // Rotate the robot to avoid the obstacle
 }

 void slowApproach() {
   rightMotor.setSpeed(slowSpeed);                  // Slow down the motors
   leftMotor. setSpeed(slowSpeed);
   forwardM();                                      // Move the robot forward slowly
 }

 void drive() {
   rightMotor.setSpeed(driveSpeed);                 // Set the motors back to the normal speed
   leftMotor. setSpeed(driveSpeed);
   forwardM();                                      // Move the robot forward
 }

 void forwardM() {
   rightMotorStep =  stepSpeed;                     // select direction of step only
   leftMotorStep  =  stepSpeed;                     // do not move motor
 }                                                  // actual stepping is done at end of loop()
 void leftM() {
   rightMotorStep =  stepSpeed;
   leftMotorStep  = -stepSpeed;
 }
 void rightM() {
   rightMotorStep = -stepSpeed;
   leftMotorStep  =  stepSpeed;
 }
 void reverseM() {
   rightMotorStep = -stepSpeed;
   leftMotorStep  = -stepSpeed;
 }
 void halt() {
   rightMotorStep =  0;
   leftMotorStep  =  0;
 }

```
> 2 votes

---
Tags: arduino-uno, programming, library, stepper, hc-sr04
---


# Question
Title: How to switch between multiple BMP180 sensors?
I have six **BMP180** sensors for measuring temperature and pressure. The problem is that I can get the value from one sensor but I need values from all six sensors using a single Arduino Mega board. How can I do that? I have already tried powering each sensor with `digitalWrite` but that didn't work. If you have a solution, can you also provide the code for that?

# Answer
The BMP180 uses the I2C bus and you cannot simply turn off the device, since that can block the I2C bus. Also it has only one, not changeable address. Thus you would need one I2C bus for every BMP180.

So know you have 2 ways to go:

* You could use a Software I2C library and define one I2C port for each BMP. That would use 12 digital pins and you need to find a fitting library, that supports multiple instances. Due to the timed nature of the I2C bus, you most likely will only be able to service one bus at a time.
* You could buy a multiplexer chip for both signal lines. Then you could switch the SCL and SDA lines to each BMP. For that you need the multiplexer chips, 2 pins for I2C and 3 digital pins for input of the multiplexer chips (assumes an 8-channel multiplexer)
> 1 votes

# Answer
If you have n-MOSFETs available, a simple multiplex solution would be: SCL directly from master to all slaves. SDA from master to Source of MOSFET (for each slave one MOSFET), Drain of MOSFET with pull-up resistor (e.g. 4.7k) will be the SDA signal. Gate of MOSFET to select slaves (active \<-\> Gate=high level). Make sure your MOSFET turns on based on your used voltage levels.
> 1 votes

---
Tags: arduino-mega
---


title: ESP32 IR remote

text:
# Question
Title: ESP32 IR remote
my board is a firebeetle esp32 that I am using as an IR remote.

After using the Ken Shirrif IRremote library for about 6 months successfully, then the time came to change a few things on the web front end. This has been a disaster.

I tried to recompile my working code that the board is currently using and got errors everywhere I turned.

So i switched libraries to this one;

https://github.com/ExploreEmbedded/Arduino-IRremote

Now it does compile successfully, with the only change between the two libraries was to pull out the pin I defined for IR tx in the Ken Shirriff library. For example; previously my code looked like this to work with the old library.

```
IRsend irsend(33);

```

Now it looks like this;

```
IRsend irsend;

```

As stated, it does compile; only issue is that IR doesn't work. It says in the library that pin 5 is defined as the tx pin for the ESP32 in boarddefs. Snip from boarddefs where I believe pin 5 is defining IR tx.

```
// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing
// them out in the common code, they are defined to no-op. This allows the code to compile
// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written
// for that -- merlin
// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100%
// reliability because the arduino code may be interrupted and cause your sent waveform to be the
// wrong length. This is specifically an issue for neopixels which require 800Khz resolution.
// IR may just work as is with the common code since it's lower frequency, but if not, the other
// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
// https://github.com/ExploreEmbedded/ESP32_RMT
#elif defined(IR_TIMER_USE_ESP32)
#define TIMER_CHANNEL       1
#define TIMER_LENGHT        8 //8-bit Timer
#define TIMER_PWM_PIN      5
#define TIMER_ENABLE_PWM    ledcAttachPin(TIMER_PWM_PIN, TIMER_CHANNEL);
#define TIMER_DISABLE_PWM   ledcDetachPin(TIMER_PWM_PIN);
#define TIMER_RESET
#define TIMER_ENABLE_INTR
#define TIMER_DISABLE_INTR
#define TIMER_INTR_NAME

//---------------------------------------------------------
// Unknown Timer
//
#else
#   error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
#endif

#endif // ! boarddefs_h

```

I know it says that IR with the ESP32 will not work, but it said the same thing for several libraries that i've used that do work, most notably the one by Ken; which appears to have moved here.

https://github.com/z3t0/Arduino-IRremote

Quick example of my code;

```
#include "IRremote.h"
  IRsend irsend;
int khz = 38;
String input;
  String tv;
void changehdmi() {
if (Server.args() > 0 ) {
  for ( uint8_t i = 0; i < Server.args(); i++ ) {
    if (Server.argName(i) == "input") {
      input = String(Server.arg(i));
      Serial.println("input is " + input);
    }
    if (Server.argName(i) == "tv") {
      tv = String(Server.arg(i));
      Serial.println("tv is " + tv);
    }

  }
}
if (input == "1" && tv == "1") {
  unsigned int irSignal[] = {9000, 4450, 600, 550, 550, 550, 600, 550, 550, 550, 600, 500, 600, 550, 550, 600, 550, 550, 600, 1650, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1650, 600, 1650, 550, 1700, 550, 550, 600, 550, 550, 1700, 550, 550, 600, 500, 600, 550, 550, 600, 550, 550, 600, 1650, 550, 1700, 550, 550, 600, 1650, 550, 1700, 550, 1700, 550, 1700, 550}; // NEC FF906F
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
}
else if (input == "2" && tv == "1") {
  unsigned int irSignal[] = {9000, 4500, 550, 550, 600, 550, 550, 550, 550, 600, 550, 550, 600, 550, 550, 550, 550, 550, 600, 1650, 600, 1700, 500, 1700, 600, 1700, 500, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 1700, 550, 550, 550, 1700, 550, 1700, 550, 1700, 550, 550, 550, 550, 600, 550, 550, 550, 600, 1700, 500, 600, 550, 550, 600, 500, 600, 1650, 600, 1650, 600, 1650, 550}; // NEC FFB847
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);
}

```

Has anyone gotten this to work recently? The libraries that are available seem to have lost support for this functionality.

# Answer
> 1 votes
For the ESP32, you should really check out IRremoteESP8266, which also works on your board, and is frequently updated, very widely used, and lets you use any compatible GPIO pin easily.

Here's a sample of a simple IR send demo:

```
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

#define IR_PIN 4

IRsend irsend(IR_PIN);  // Set the GPIO to be used to sending the message.

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

void loop() {
  Serial.println("NEC");
  irsend.sendNEC(0x00FFE01FUL);
  delay(2000);
}

```

This example will send an NEC code very 2 seconds. The library also has extensive support for other formats, as well as raw.

If you want to be extra safe, the creator of the project menions here that GPIO 4 and 18 are safe, but I know for a fact that many other ESP32 pins are okay to use as well.

---
Tags: ir, esp32
---


# Question
Title: Remap SPI functions to default pins Arduino Zero via software?
I am looking at the documentation for the Arduino Zero, and I am a little confused.

It indicates that pins 13, 12, and 11 can be used for CIPO, COPI and SCK, but using `SPI.begin()` puts the signals on the 6-pin header SPI pinout, which makes sense since it is designated for SPI.

Is there a way to switch to the digital pins via C code? Or do I need to edit the header files? We are using another board that can only attach to the digital pins.

# Answer
> -1 votes
EDIT: Provably wrong answer below, see comments from though.

---

Unfortuantely the Arduino Zero doesn't support remapping of SPI pins as far as I know. Many other modern boards do, like the ESP8266/ESP32, but not the Zero, at least as far as I can tell.

---
Tags: spi, pins, arduino-zero
---


# Question
Title: Elegant solution for refreshing TFT display content?
I'm currently drawing black boxes over old content before displaying constantly refreshing content on my display, so for instance to display temperature:

```
if (sensorTemp != nowTemp){
    nowTemp = sensorTemp;
    tft.fillRect(0,52,88,21,ILI9341_BLACK);
    return nowTemp;
}

```

If I don't do this the display will just overlay content until it becomes a white blob.

However, this solution leaves me with a black flickering on the display and I can't control exactly what is refreshed where. So for instance when I want to display the current time or date it has to refresh the date all the time, even though nothing changed.

```
void loop() {
  tft.setTextSize(2);
  tft.setCursor(0,0);
  tft.print(rtc.getDateStr());
  tft.fillRect(144,0,199,15,ILI9341_BLACK); //Black box drawn over 'old' time data
  tft.setCursor(144,0);
  tft.print(rtc.getTimeStr());  //Draw new time
  tft.setCursor(0,52);
  tft.print(tempCall());  //call function to check on temperature and draw new data if necessary
}

```

Is there a more elegant solution to this problem?

# Answer
The Adafruit GFX library has two functions for setting the text colour:

```
setTextColor(uint16_t c)
setTextColor(uint16_t c, uint16_t bg)

```

The first sets both the foreground and background to the same colour, and the second to two different colours. You may ask why you would want the foreground and background to be the same - well, the library handles that situation as a special case: it makes the background transparent.

By setting the foreground and background to different colours you force the library to draw that background colour in over whatever is already on the screen.

```
tft.setTextColor(ILI93481_WHITE, ILI9341_BLACK);

```

With that any background pixels in the text string will be coloured black and the text itself white. As long as the string you are printing is the same length as the text that is already there it will be replaced completely.
> 3 votes

# Answer
If you look in the "Adafruit\_GFX.cpp" you will see the following.

```
void Adafruit_GFX::setTextColor(uint16_t c) {
 // For 'transparent' background, we'll set the bg
 // to the same as fg instead of using a flag
 textcolor = textbgcolor = c;
}

void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
 textcolor   = c;
 textbgcolor = b;
}

```

If you only want to Draw the Character with a transparent background meaning you only write the character setTextColor in the prescribed pixels changing none of the surrounding pixels in the character block defined by x, y, setTextSize.

```
TFT.setTextColor(GREEN); //With Transparent Text Background not updating surrounding pixels.

```

If you want to Draw the Character with your background color, replace app pixels in the character block defined by x, y, setTextSize with your chosen text color and your background to be the same as your chosen background. This will overwrite all pixels with old character that are no longer used with the background color all at the same time preventing mess of pixels, and character flashing.

```
TFT.setTextColor(GREEN, BLACK); //With Text Background Color updating surrounding pixels.

```
> 5 votes

# Answer
This code works well and accounts for values of different length.

```
void textValue() {
  float newValue = @your input@;
  int numChars = String(newValue).length(); // Get the number of characters
  int valueWidth = numChars * 6 * 2.5;

  if (valueWidth != previousValue) {
    tft.fillRect(0, 55, previousValue, 30, ST77XX_BLACK);
    previousValue = valueWidth;
  }
  tft.setCursor(3,60);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
  tft.setTextSize(2.5);
  tft.print(newValue);
}

```
> 2 votes

# Answer
Hmm the solution is how the code is written...no fancy stuff...the KIWI way

```
//in setup function add tft.fillScreen(ST7735_GREEN);

void loop(){

  int lightIntensity = myBH1750.getLux();
  tft.setTextSize(3);
  tft.setCursor(10,10);
  tft.setTextColor(ST7735_RED);
  tft.print(lightIntensity);
  delay(3000);
  tft.setTextColor(ST7735_GREEN);
  tft.setCursor(10,10);
  tft.print(lightIntensity);
  tft.setCursor(10,50);
  tft.setTextColor(ST7735_BLUE);
  tft.print("LUX");
}

```
> 1 votes

---
Tags: arduino-uno, arduino-mega
---


# Question
Title: how to avoid an Arduino pro micro waking up a pc
I have an Arduino Pro Micro only sending data via com port, connected to a PC. I don't use the USB protocol and I think the Arduino send request with USB and it's the reason why my computer wakes up

I checked the device manager and there is no power management tab for the arduino, so I can't refuse the Arduino to wake the system up. Also my BIOS don't have any option to wake up on a particular key combination

# Answer
Assuming the computer is turning on due to the data received over the USB cable from the DEEJ box and not from simply plugging in the USB cable from the DEEJ box.

Consider, if this project otherwise works, re-writing the Arduino Sketch to not send out any data until after a specific digital GPIO pin goes from 1 to 0. Place a N.O. push button switch to ground on that digital GPIO pin. Remember to program that pin as a GPIO input with a pull up. If this works, not only will the DEEJ box control volumes, but might also be able to turn on the computer.
> 1 votes

# Answer
I just figured out window wakes up when the deej program is running with the Arduino connected,but when the Arduino is connected without the program running there is no problem. So trouble is deej
> -1 votes

---
Tags: usb, arduino-pro-micro, windows
---


# Question
Title: ArduinoJSON - How to check if array is empty
Parameters file defines the creation of entities and stored in flash. Its structure is given, and all fields ( keys & values ) are given. In current phase - those parameters are hard-coded in a `const char* cont_params`, as shown below.

My goal, is when array is empty, for example `RF_2entity` \- means that current MCU does not uses its RF abilities, and will not init any RF entities. The way `RF_2entity` is defined below, as empty array, `[]` , ArduinoJSON's `isNull()` function return `0` in that case.

How can I keep parameters file's structure and logic, rather that fill its values with `255` for example.

```
  Serial.begin(115200);
  StaticJsonDocument<1200> doc;
  const char *cont_params = "{\"entityType\": [1,1,1,1],\
                    \"SWname\": [\"SW_0\",\"SW_1\",\"SW_2\",\"SW_3\"],\
                    \"SW_buttonTypes\": [2,1,1,1],\
                    \"SW_timeout\": [10,11,12,13],\
                    \"SWvirtCMD\":[0,0,0,0],\
                    \"Winname\": [],\
                    \"WextInputs\": [],\
                    \"WinvirtCMD\":[],\
                    \"RF_2entity\": [],\
                    \"v_file\": 0.5}";
  DeserializationError err = deserializeJson(doc, cont_params);
  JsonArray array = doc["Winname"].as<JsonArray>();
  serializeJsonPretty(array,Serial);
  Serial.println(array.isNull());

```

output:

```
[]0

```

# Answer
> 1 votes
The method `isNull()` is not what you want. It tells you whether the instance holds an array at all or not. And of course, your specific instance holds an array, though an empty one. Therefore, the method correctly returns `false`, aka `0`.

As the API documentation shows, there are more methods to use.

What you want is `size()`, which returns the number of elements in the array. It will even return `0` on an instance without an array.

---
Tags: array
---


# Question
Title: How to package a 16 bit integer to send it with serial.write?
I am trying to display the values i get from reading a potentiometer (0-1023) in the program called 'processing'.

when I just use Serial.write(integer) and display the value on a line graph in 'processing' the line will max out at 256 and loop back around to 0 as i vary the potentiometer.

I understand that this is because the serial.write can only write in bytes(8 bits) so I would need to package the 16 bit integer into 2 bytes.

i was considering using a union but as you can probably guess i am very new to arduino so i haven't been able to make that work.

here is the code i have tried:

```
union Data{  uint16_t now; } data;

void setup() {   // put your setup code here, to run once:
    Serial.begin(9600);
    pinMode(A1, INPUT);

}

void loop() {   // put your main code here, to run repeatedly:
    uint16_t sensorVal = analogRead(A1);
     union Data data;

    data.now = sensorVal;

    Serial.println(data.now);

    //Serial.write(sensorVal);
    delay(10); }

```

# Answer
> 4 votes
Send the 16-bit value as two 8-bit values (with a start byte as per **JRobert**'s answer):

```
Serial.write(0xCC); // Send the start byte
Serial.write((sensorVal >> 8) & 0xFF); // Send the upper byte first
Serial.write((sensorVal & 0xFF); // Send the lower byte

```

# Answer
> 3 votes
You need to send the uint16\_t as the two the individual bytes it is composed of, one at a time, in whatever order your Arduino code and the code on the PC agree on: (MSB first, aka, big-endian; or LSB first, aka little-endian).

Since it would be possible for the two devices to get out of sync, you may also want to package up the two bytes with a third, or "start-byte". Pick some fixed value (such as 0xCC) that has a couple of its MSbits set, then the MSB, then the LSB. Your receiver can know to look for that fixed value, then the MSB (which it knows can't have those high bits set because the analog data is only 10-bits), then the LSB (which could have any value).

The PC should only accept a three-byte packet when it has received one that fits that scheme. Otherwise it waits for another 0xCC (or whatever value you choose), collects two more bytes, and tries again.

# Answer
> 2 votes
This may help Transmisor

```
int valor;
byte val;

void setup() {

Serial.begin(9600);
}

void loop() {

valor=analogRead(A0);
val=map(valor,0,1023,0,179);
Serial.println(val);
Serial.write(val);
delay(100);
}

```

Receptor

```
byte mensaje;
int valor;
void setup() {

Serial.begin(9600);
}

void loop() {

if (Serial.available()){
  mensaje=Serial.read();
  valor=mensaje;
  Serial.print(valor);
  Serial.println(" ");
}
}

```

# Answer
> 1 votes
I was checking out the documentation for Serial.write()

You can sent out an array of 2 8Bits in the form of Serial.write(buf, len)

Simply create an int buffer, and then use your original integer and do bit shifting. Notice the `& 255` used to make sure there are no values beyond 8 bits.

```
int data = 1000;
short int buf[2];
buf[0] = data & 255;
buf[1] = (data >> 8)  & 255;
Serial.write(buf, 4);

```

Also, in C, the name of an array is used as the pointer for the first element. So if you look at the documentation for `Serial.write(buf,len)` again, you will find that you can probably get the pointer for your int value, and write 2 bytes itself!

```
Serial.write(*data, 2);

```

or `Serial.write(&data, 2)`

---
Tags: arduino-due
---


# Question
Title: Data transmission rate of accelerometer mpu6050 to arduino uno vs Sampling rate of mpu6050
mpu6050 has sampling frequency of 1kHz (mentioned in datasheet). But when i interface it with arduino uno via I2C communication (400Khz bus speed), i only get 50 raw data (each of x,y,z). There is no delay in the program. why is this happening. Why am I not getting 1000 or at least 800 samples. What is the concept I am missing here. Please explain in detail. I have also attached the code and output for 1 second.

```
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
//#include <SoftwareSerial.h>
//SoftwareSerial BTserial(10,11);
MPU6050 accelgyro;
char ch;
int incomingbyte = 0;
int16_t ax, ay, az;
int16_t gx, gy, gz;

void setup() {

  Wire.begin();
  Serial.begin(115200);

  accelgyro.initialize();
  accelgyro.setXAccelOffset(542);
  accelgyro.setYAccelOffset(-835);
  accelgyro.setZAccelOffset(1651);
  accelgyro.setXGyroOffset(6);
  accelgyro.setYGyroOffset(-18);
  accelgyro.setZGyroOffset(23);
}
void loop()
{
  accelgyro.getAcceleration(&ax, &ay, &az);
  accelgyro.getRotation(&gx, &gy, &gz);

  Serial.print(ax); Serial.print("\t");
  Serial.print(ay); Serial.print("\t");
  Serial.println(az);
}

```

# Answer
The reason is that Serial.print() is mush slower compared to reading a sample from the sensor.

If you comment the print(), then read sensor data for a certain time repeatedly and calculate the output data rate accordingly, you will find that the sampling rate is indeed 1000 Hz.

If what you wanted is merely to store the data and use it afterwards (instead of real-time processing), you can store the sensor readings in a SD card, which is always much faster than serial printing. A useful trick is that do not write data to the sd card whenever you get a new sample, but use a software buffer (i.e., array) to store the samples (the buffer size depends on the RAM of microcontroller) and then write the whole buffer to the sd card when it's full.

However, as long as you want to store the data (either print in serial or write in a file), you'll always have to 'sacrifice' some data rate and cannot get 1kHz as mentioned in datasheet. Hope this helps.
> 1 votes

---
Tags: arduino-uno, mpu6050
---


# Question
Title: How to offset PWM output so it would also have negative amplitude?
So PWM goes from 0 to 5V. How could I do -2.5 - 2.5V? Basically I am asking how to add offset to PWM signal. Should I use operational amplifier? How would I use it? I never had to deal with them, but I have LM2904P laying around.

# Answer
Consider removing the average of the PWM voltage by subtracting the Direct Current (DC) component of the PWM output.

Often, between different audio amplifiers stages, the DC component of the signal is removed through the use of coupling capacitors. The above link offers these guide lines for picking the value of the capacitor:

> Below is a basic rough guideline of capacitors that can be used for various frequencies.
>
> For coupling a 100Hz signal, a 10μF capacitor can be used.
>
> For a 1000Hz signal, a 1μF capacitor can be used.
>
> For a 10KHz signal, a 100nF capacitor can be used.
>
> For a 100KHz signal, 10nF capacitor can be used.
>
> For a 1MHz signal, a 1nF capacitor can be used.
>
> For a 10MHz signal, a 100pF capacitor can be used.
>
> For a 100MHz signal, a 10pF capacitor can be used.
>
> This is a rough estimate that will be effective the majority of the time. The only variable that could affect the above values is the resistance in parallel to the capacitor.

Consider the last paragraph above when designing your circuit. The lower the input impedance of the circuit you are driving the more likely the possibility of unexpected results. At which point you might consider adding the OpAmp suggest in the question.
> 1 votes

---
Tags: pwm, op-amp
---


# Question
Title: Arduino Uno Gravitech Rev 3.0 with avrdude CLI (Mac OS) - Is my script correct?
I am dealing with an Arduino Nano board rev 3.0 from Gravitech. There is a program inside that I'd like to download to a HEX file. Thus I can upload it to other Arduino Nano boards.

I'm a newbie with Arduino. Therefore I've read much documentation on the internet and I came to the point to use `avrdude` in the command line as Arduino IDE does not provide a feature to perform a download to an HEX file (as far as I've understood).

I've installed all the necessary software on my Mac OS Mojave (avrdude v7.0 using 'Mac Ports'). And after powering up and connecting the Arduino Nano board to a USB port of my Mac, I launched the following command line:

`avrdude -p m328p -D -c arduino -P /dev/tty.usbserial-A9077L99 -U flash:r:programme_arduino.bin:r -v -x attempts=4`

I obtain the classical message

> stk500\_recv(): programmer is not responding

I've noticed that the 'Rx' led and the 'L' led were blinking during the attempts.

From your perspective, do the options look good (-p -c ...)?

# Answer
> 2 votes
Your first problem is the no-response complaint. You said "I've noticed that the 'Rx' led and the 'L' led blank during the attempts." Is "blank" a typo (i.e., the LEDs *do* blink?) or did you mean they do nothing? Are you using the same cable you used to program the nano? Can you swap with another cable? Test this cable with another nano? Is the port ID typed correctly (/dev/...etc)?

Double-check the programmer ID (-c option) and part number (-p option) by querying AVRDUDE (specify '?' instead of a valid value on each of those).

For the -U option, you'll want to name the output file with a .hex extension, and specify the file-format as 'i' for intel hex:
`-U flash:r:programme_arduino.hex:i`

Here is the AVRDUDE reference I used.

Update:

I agree that your port ID must be correct and the cable is working, since your LEDs are blinking. But you get an error message about "not responding". Does the Nano have a bootloader in it? Could the boot-loader have been damaged when you uploaded the code (e.g., the code is large enough to over-write some of the bootloader)?

Is binary code in the Nano the only copy, or do you have the source code for it? If you have the source, you can recompile it (if necessary) and retrieve the resulting .hex file. Would that solve your problem? By setting the IDE to produce verbose output, you'll see the path to the temporary files, including the .hex file. Then use Finder (or a Terminal command, if you are comfortable with that) to copy that temporary .hex file to someplace safe.

Update 2:

> Are bootloader ROM area and Flash ROM area two different memory areas?

Not separate - the boot-loader is placed at the top of Flash. It is possible for a large enough program to over-write it - I'm not sure whether that has to be specifically allowed, such as by setting fuses. If it does get over-written, it obviously becomes unusable.

I wonder if the flash can be read using a hardware programmer? Do note that these chips have lockout-fuses that can be set to prevent further programming or reading of the flash.

Since the code in this device seems valuable to you, I would suggest putting this Nano board aside, and only experiment with another, hopefully identical, board. On the new board -

* Upload a sketch to it;
* Copy the AVRDUDE command line used to by the IDE to upload it, and modify it as you've already described. Of course, this command will already have the board-specific parameters;
* Use the modified command to download the sketch to another file, and compare it to the file that was just uploaded.

Once you can do this successfully, apply that last step to copy the sketch from your valuable Nano, then put that board away again. Load and test the downloaded code on your experimental Nano. Don't forget to include the valuable Nano's EEPROM - it might contain some critical data.

---
Tags: arduino-uno, avrdude, mac-os, command-line
---


title: Power supply for Seeeduino Xiao

text:
# Question
Title: Power supply for Seeeduino Xiao
The Seeeduino Wiki claims that it can run on 3.3V/5V. It doesn't specify if it can step down higher voltages. I am looking to power the XIAO using a battery. It usually uses a USB-C cable which can provide 5V. Will I need to step the voltage down, or does it behave like a normal Arduino Nano and automatically step down the voltage?

# Answer
> 2 votes
If you scroll down on that page you link to you can see the power circuit. It uses an XC6206 voltage regulator which has a maximum input voltage of 7V and a dropout voltage that could be as high as 680mV.

So you can feed between about 4V and 7V in to the VIN pad and it will step it down to 3.3V. Anything below 4V and you will go "out of regulation" though the system may still run down to lower voltages. If you go above 7V you will blow it up.

# Answer
> 1 votes
A batch of 60 XAIO ESP32C3's will not power on using a 3.3V DC supply applied to pins 3V3 and GND. They only power on using a 5V input applied to pins 5V and GND. The test rig was a bench DC power supply. The XIAO ESP32C3 seems to power on as low as 4.1V DC applied to the 5V pin. No external component is required, just a direct connection from the bench power supply to the 5V pin. Therefore the posts somewhere on the internet about needing a diode in the path of the positive supply do not appear to be necessary. Note that the ESP32C3 were not programmed, ie. they arrived from the factory and were powered without downloading any code to them. Thus the posts about sleep mode are not applicable as the 3.3V and 5V behavior should then be identical, but they are not.

---
Tags: arduino-nano, battery, voltage
---


# Question
Title: How do I turn on 3 LEDs in a repetitive sequence where all three LEDs would then turn OFF when the push button used is released?
Basically, how do I modify my code listed below to turn **ON** each of the three LEDs one at a time in a repetitive sequence while keeping the push-button pressed?

* Red (3 sec),
* Yellow (1 sec), and
* Green (3 sec).

I'm trying to get all three LEDs to turn **OFF** when the push button is released.

The code I wrote that doesn't allow me to achieve what I'm trying to do (I'm not sure where I went wrong):

```
#define Button_Pin 2  //Push Button Pin
#define LED_Pin_1 11 //Red LED
#define LED_Pin_2 10 //Yellow LED
#define LED_Pin_3 9  //Green LED

byte Button_State;

void setup() {
  pinMode(Button_Pin, INPUT);
  pinMode(LED_Pin_1,  OUTPUT);
  pinMode(LED_Pin_2,  OUTPUT);
  pinMode(LED_Pin_3,  OUTPUT);

  Serial.begin(9600);
  Serial.println("Design Part B - Digital I-O Control");
  delay(1000);
}

void loop() {
  Button_State = digitalRead(Button_Pin);
  Serial.print("Button State: ");
  Serial.print(Button_State);

  if (Button_State == 1){
    digitalWrite(LED_Pin_1, HIGH);
    delay(3000); //Wait for 3 Secs
    digitalWrite(LED_Pin_2, HIGH);
    delay(1000); //Waits for 1 Sec
    digitalWrite(LED_Pin_3, HIGH);
    delay(3000);
    Serial.println(" --> Button Pressed --> LED ON");
  }
  else{
    digitalWrite(LED_Pin_1, LOW);
    digitalWrite(LED_Pin_2, LOW);
    digitalWrite(LED_Pin_3, LOW);
    Serial.println(" Button is Released --> LED OFF");
  }
}

```

# Answer
Having examined several sample sketches, including the recommended one, and watching instructional YouTube videos to grasp the fundamentals of Arduino programming, I am delighted to announce that my understanding of programming the Arduino and comprehending its functions has significantly improved, considering my novice status.

I can confidently assert that this question has been resolved, and I have enclosed the code that fulfills the initial requirements that was asked of me.

```
#define pushButton_pin 2
#define grn_LED_pin 9
#define yel_LED_pin 10
#define red_LED_pin 11

bool pushButton_state;

void setup() {
pinMode(pushButton_pin, INPUT);
pinMode(grn_LED_pin, OUTPUT);
pinMode(yel_LED_pin, OUTPUT);
pinMode(red_LED_pin, OUTPUT);

Serial.begin(115200);

Serial.println("Use push button (digital input) to control 3 LEDs (digital
output)");
delay(1000);
}

void loop() {
pushButton_state = digitalRead(pushButton_pin);
Serial.println(pushButton_state);
if (pushButton_state == 1) {
digitalWrite(grn_LED_pin, LOW);
digitalWrite(yel_LED_pin, LOW);
digitalWrite(red_LED_pin, HIGH);
Serial.println(" :push button state is 1, red LED is ON");
delay(2000);
digitalWrite(grn_LED_pin, LOW);
digitalWrite(yel_LED_pin, HIGH);
digitalWrite(red_LED_pin, LOW);
Serial.println(" :push button state is 1, yel LED is ON");
delay(1000);
digitalWrite(grn_LED_pin, HIGH);
digitalWrite(yel_LED_pin, LOW);
digitalWrite(red_LED_pin, LOW);
Serial.println(" :push button state is 1, grn LED is ON");
delay(2000);
} else {
digitalWrite(grn_LED_pin, LOW);
digitalWrite(yel_LED_pin, LOW);
digitalWrite(red_LED_pin, LOW);
Serial.println(" :push button state is 0, all LEDs OFF");
}
delay(500);
}

```
> 0 votes

# Answer
You need a state machine (to remember which LED is currently on) and use `millis()` to find the current time, in a loop, which is testing whether the switch is closed or not.

If the switch is closed you compare the time now (with `millis()`) to the time you turned that particular LED on. When the time is up you advance the "state" (eg. a counter) to the next one, and remember the new time that this state change happened.
> 1 votes

---
Tags: arduino-uno, programming, led, button
---


# Question
Title: How to produce a USB CDC serial port for Arduino nano 33 BLE?
I'm trying to program an Arduino Nano 33 BLE bare-metal to get some precise timing and size measurements. I've managed to upload the code to my card, but I cannot communicate with it. More specifically, when I upload the code, the port 'deactivates' after I upload the code, so the serial monitor prints a `cannot exec '/dev/ttyACM0'` error.

Can someone help me figure out how to make it work? I've seen tutorials online but they're for AVR microcontrollers, and I've been told that this specific board isn't. I've also been told that I must include some code in my `c/cpp` file to produce a USB CDC serial port, but I don't know how to do that.

# Answer
> 1 votes
The Nano 33 BLE board uses a NORDIC nRF52840 processor which contains the USB interface hardware inside the processor. The current Arduino Uno uses an Atmel (now owned by Microchip) processor and uses an external processor for USB communications. So any Arduino USB tutorial will be very different with respect to these two Arduino designs.

Normally, Arduino Sketches (Programs) are only part of all the software running on a processor. The preprogrammed software on a new Arduino board abstracts the more complex part of embedded programming from the average Arduino user. This likely includes a working USB port.

To do bare metal programming on a NORDIC nRF52840 processor, consider starting with the NORDIC Software Development Kit (SDK). Also, most vendors support their own development boards (provide example programs and libraries) better then development boards made else where. Consider this before committing to learning how to bring up a "bear metal" USB/CDC peripheral device using the Nano 33 BLE board.

An alternative approach: Many ports of Arduino occur on github.com. The adaptation of the Arduino code may offer insights as to how the host processor's hardware works. The Nano 33 BLE preprogrammed software comes from this github repository.

---
Tags: serial, arduino-nano-ble
---


title: Analogue input spikes

text:
# Question
Title: Analogue input spikes
i have a project where i read two analogue inputs from two sensors and a pro Mini. I have some spikes in my readings that are present when i'm powering the system using a powerbank step-up module. When i use a 7805 and a 9V battery, the results seem clear. The spikes appear every 600-650ms.

Is there any way to filter them out on a hardware level without using code?

The frequency of the spikes is about 1.5HZ, too slow for a typical ripple of a "dirty" dc converter i think. My first though was that the module was checking for sufficient load to stay powered on. I added a dummy load but nothing changed. The project is a datalogger and unfortunately i don't really want the code to do the filtering, as it's gonna cost me some speed.

# Answer
> 3 votes
On a hardware level, without a substantial delay, you could use active filters, such as active low-pass or band-pass filters, that can provide better control and customization over the filtering process.

---
Tags: analogread, filter
---


# Question
Title: Best buffering practice for continuous SD card writing
In a simplified example, I have a microcontroller functioning as a data acquisition device - sensor data is received over UART, and then saved to an SD card.

This received data is in the form of a 12 byte struct, received at 1kHz. The microcontroller receiving the data is an esp32, with an SD card connected over spi. Not an uncommon issue, but if a typical SD card write is triggered everytime new data is received, it will take longer than the gap between samples to write the data.

What is typically considered the best practice for this type of system, presuming the data will always be received faster than it can be written. I have seen examples of circular buffers, but presumably these will eventually fill completely and samples will be missed.

In my particular example, I have the bonus second cpu core in the esp32. Therefore, my thinking is to use 2 alternating buffers. Data will be received on core 1, and placed into the active buffer. When the buffer is full, incoming data will be written to the second buffer, and the first will be written to the SD card by core 2.

Is this a sensible solution to the problem? I am hesitant to implement anything that simply relies on an improvement in SD write speed, as I will likely need to increase the size of the data payload in the future and don't want to run into this issue again later on.

# Answer
> 3 votes
> Is this a sensible solution to the problem?

No, unfortunately not. The size of the buffer is limited by the available RAM on your chip. Jumping between multiple buffers or cores will not change that, since it is a hardware limitation.

> I am hesitant to implement anything that simply relies on an improvement in SD write speed, as I will likely need to increase the size of the data payload in the future and don't want to run into this issue again later on.

When you are continuously receiving faster than you can write, you only have 2 options:

* Improve write speed
* Reduce the needed data size

There is no other way, and that's a logical conclusion, not so much a programmical or hardware conclusion. It that situation the amount of "buffered" data will increase indefinitely, so you would need an infinite amount of memory. And that doesn't exist in real world. The same principle would apply to a high end PC with lots of memory, it will just be full after longer time, than with an ESP.

* Improving write speed:

+ On various sites I have read, that you can use the SD card with different SPI frequencies. A higher frequency would mean a higher transaction speed. You can investigate further at this point.
    + Writing a full 512 byte page at once and only closing and opening the file again, if really needed, will improve the overall speed.
* Reduce the needed data size

+ Maybe you can compromise with your data resolution and then pack those values as dense as possible (like packing two 4-bit values into a single byte of transmission).
    + You can research for compression code, so that you can compress your data lossless before transmitting it. Though the result will always depend on the kind of your data. Also mind, that in this case you are trading transmission size for computation time and RAM.

About buffers:

I would say, a normal circular buffer does not bring you much advantages here, since with the SD card you don't want to do bytewise data transmission. The 2 buffer approach, that you mentioned, seems good to me. Though doing handling with different cores does not make much sense to me. The UART receiving itself is done by hardware and some ISRs. You can do all the SD card transmissions in your main code, just making sure, that you regularly copy the received data from the Serial buffer into your buffer.

# Answer
> 2 votes
Buffers will help you if at some point the input stream stops, so the "slower" device (e.g. the SD card) can catchup. If *the data will always be received faster than it can be written* (note **always**) then no buffer will help you.

But I assume you meant that there times where you get bursts of input data at 1Khz, then it will stop. So, as long as the *average* input data rate is lower than the ability for the SD to persist the data, you will be fine.

The SD card library already has a buffer (as @Majenko pointed out), so most likely you won't need to do anything. Seem like something you can test relatively simply.

The 2 core approach sounds somewhat overkill (not to mention some synchronization issues you will have to deal with)

# Answer
> 0 votes
Forgive my non-technical analogy, but this is how my brain works. Hope you can get past the conclusion that "this isn't a technical answer", until you at least see it from this different perspective.

Buffers, input streams, and sampling rates, storage rates all relate strongly to filling up a bath. Taps, water, baths and plug holes? WTF?

Try slightly blocking the plug hole in your bath, and turn both taps on full.

The water that's drained away is the rate of which data is stored to the SD card. That's the storage-rate.

The remaining water which doesn't drain away fast enough causes the bath the fill up. The water is the sampling rate, the bath is the buffer.

If the taps remain on, and water is leaving the taps faster than the water can escape from the partially blocked hole will cause the bath to fill up with water.

So, if the blockage isn't cleared, the bath will eventually overflow.

Either you turn the taps down, use a bigger bath, or increase the drainage rate.

# Answer
> 0 votes
One approach would be to use Circular Buffering. It involves using a fixed-size buffer that wraps around itself, allowing data to be continuously written and overwritten. This approach eliminates the need for costly memory reallocation or shifting operations. As new data is written, older data is overwritten in a circular fashion. But, you will need to choose the appropriate buffer size. A larger buffer size can help handle bursts of data However, larger buffers also consume more memory.

If one buffer isn't enough, then you could use Two buffers instead. While one buffer is being written to the SD card, the other buffer can be used to receive new incoming data. Once the write operation is completed, the roles of the buffers are swapped. This technique can help improve efficiency by minimizing data transfer and write latency, which is the goal you aim at. I've used this type of buffer for audio data acquisition, and it worked well, got rid of the buffer overflow issues.

The other method would be to use DMA, if your microcontroller or system supports it, which I think it does, using DMA for SD card writing can offload the data transfer task from the CPU. DMA allows direct memory access without CPU intervention, enabling faster and more efficient data transfers. DMA can significantly reduce the overhead associated with continuous SD card writing.

For DMA, you might want to check this: https://github.com/RobTillaart/DAC8552/issues/8 and this: https://github.com/espressif/esp-idf/blob/master/examples/peripherals/spi\_master/lcd/main/spi\_master\_example\_main.c

---
Tags: esp32, uart, sd
---