body:
I have configured I2S to reproduce files with an ESP32 and a MAX98357A from and SD card. The problem is that it reproduces the files way too fast, like they are sped up * 100. Here is my (simplified) code:
```cpp
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26

void setup() {
// Start SD card and sqlite
  SPI.begin();
  if (!SD.begin()) {
    Serial.println("SD card not found");
    while (1) {};
  }
// Configure I2S
  i2s_config_t i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = 44100,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
      .communication_format = I2S_COMM_FORMAT_I2S_MSB,
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 2,
      .dma_buf_len = 1024,
      .tx_desc_auto_clear = true,
  };

  i2s_pin_config_t pin_config = {
      .bck_io_num = I2S_BCLK,
      .ws_io_num = I2S_LRC,
      .data_out_num = I2S_DOUT,
      .data_in_num = -1,
  };

  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
  i2s_set_sample_rates(I2S_NUM_0, 44100);
}

void loop() {
// Play the audio file
  string filename = "/audios/" + text + ".wav";
  File file = SD.open(filename.c_str());
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }

  const size_t buffer_size = 512;
  uint8_t buffer[buffer_size];
  size_t bytes_read;
  size_t bytes_written;
  while (file.available() && (bytes_read = file.read(buffer, buffer_size)) > 0) {
    i2s_write(I2S_NUM_0, buffer, bytes_read, &bytes_written, portMAX_DELAY);
    if (bytes_read == 0) break;
  }
  file.close();
}
```

How do I configure it correctly?

title: How to configure I2S with ESP32 and MAX98357A to reproduce wav files?

Answers: 1

body:
So I figured it out (a somewhat long time ago) but forgot to post here hahaha.

Basically, the `i2s_config_t` was not properly configured. Here's a corrected version:

```cpp
i2s_config_t i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = 44100,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
      .communication_format = I2S_COMM_FORMAT_I2S_MSB,
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 8,
      .dma_buf_len = 1024,
      .use_apll = false,
      .tx_desc_auto_clear = true,
  };
```

If you compare, the `.channel_format` configuration changes from `I2S_CHANNEL_FMT_RIGHT_LEFT` to `I2S_CHANNEL_FMT_ONLY_LEFT`. This is important because when using `RIGHT_LEFT` and only using one amplifier, 2 sound outputs were sent but only one amp was receiving them, causing the sound to play at twice the speed. Now, the `.dma_buf_count` was increased to 8, and added the `.use_apll` config, because I saw it somewhere else, I don't really know what it does hahaha.

There are other things.
In the setup for the i2s communication, I didn't include

```cpp
i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
i2s_set_sample_rates(I2S_NUM_0, 44100);
```

And created a new function, `play_sound`.

Here's the complete code:

```cpp
// sound.cpp

#include <sound.h>

bool parseWavHeader(File &file, WavHeader &header) {
  if (file.read() != 'R' || file.read() != 'I' || file.read() != 'F' || file.read() != 'F') {
    Serial.println("Invalid WAV file");
    return false;
  }

  file.seek(22);
  header.num_channels = file.read() | (file.read() << 8);
  header.sample_rate = file.read() | (file.read() << 8) | (file.read() << 16) | (file.read() << 24);
  file.seek(34);
  header.bits_per_sample = file.read() | (file.read() << 8);
  file.seek(44);  // Skip to the audio data
  return true;
}

void setup_sound() {
  i2s_config_t i2s_config = {
      .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = 44100,
      .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
      .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
      .communication_format = I2S_COMM_FORMAT_I2S_MSB,
      .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
      .dma_buf_count = 8,
      .dma_buf_len = 1024,
      .use_apll = false,
      .tx_desc_auto_clear = true,
  };

  i2s_pin_config_t pin_config = {
      .bck_io_num = I2S_BCLK,
      .ws_io_num = I2S_LRC,
      .data_out_num = I2S_DOUT,
      .data_in_num = -1,
  };

  i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
}

void play_sound(std::string text, fs::FS &SD) {
  std::string filename = "/audios/" + text + ".wav";
  File file = SD.open(filename.c_str());
  if (!file) {
    Serial.println("Failed to open file for reading");
    while (1) delay(1);
  }

  WavHeader header;
  if (!parseWavHeader(file, header)) {
    Serial.println("Invalid WAV file");
    return;
  }

  i2s_set_sample_rates(I2S_NUM_0, header.sample_rate);

  const size_t buffer_size = 512;
  uint8_t buffer[buffer_size];
  size_t bytes_read;
  size_t bytes_written;
  while (file.available() && (bytes_read = file.read(buffer, buffer_size)) > 0) {
    i2s_write(I2S_NUM_0, buffer, bytes_read, &bytes_written, portMAX_DELAY);
    if (bytes_read == 0) break;
  }

  file.close();
}
```

```cpp
// sound.h

#ifndef SOUND_H
#define SOUND_H

#include <SD.h>
#include <driver/i2s.h>

#define I2S_DOUT 25
#define I2S_BCLK 33
#define I2S_LRC 26

struct WavHeader {
  uint32_t sample_rate;
  uint16_t bits_per_sample;
  uint16_t num_channels;
};

bool parseWavHeader(File &file, WavHeader &header);
void setup_sound();
void play_sound(std::string text, fs::FS &SD);

#endif  // SOUND_H
```

Hope it helps you not go through the struggle I went through!


body:
Arduino UNO R3

My error code:
avrdude: ser_open(): can't set com-state for "\\.\COM3"
An error occurred while uploading the sketch

This has been mentioned several times before here in the Stack.  I have been through several of them and followed the steps to delete/reinstall the CH340G Serial driver, change cables, and changed the USB port selection on the computer, all without success.  The computer will 'see' the UNO.

I use Windows 11.  I also learned that the card is a counterfeit from LAFVINTECH.COM.
At the moment, I have no answers.  I've tried everything I know of except taking it to the gun range.

title: OEM Arduino UNO not seen by COM port

Answers: 0


body:
I'm trying to use a library function in my ISR function that uses the internal timer to trigger every 1 ms. The chip that I'm using is an ESP32-C3-MINI. Here is my current code:

***main.cpp***

    #include <Arduino.h>
    hw_timer_t *_timer = NULL;
    myClass a();

 void IRAM_ATTR isr()
 {
  a.incrementCount();
 }

    void setup()
 {
     coin_timer = timerBegin(0, 80, true);
     timerAttachInterrupt(_timer, &isr, true);
     timerAlarmWrite(_timer, 1000, true);
     timerAlarmEnable(_timer);
    }

***myClass.h***

    #include <Arduino.h>

    class myClass
    {
    private:
     unsigned long count;

 public:
  myClass();
  ~myClass();

  void incrementCount();
    }

***myClass.cpp***

    #include <Arduino.h>
    #include "myClass.h"

    myClass::myClass(){

    }

    void myClass::incrementCount(){
     count++;
    }

This is just an example of the code that I wrote. In reality, the incrementCount function is a little more complicated and involves multiple variables and arrays within the library. This current code compiles and works without an issue. However, I would like to know if this method is bad practice or can cause problems in certain situations. Secondly, I notice if I declare count variable as volatile, the MCU just crashes and enters a reboot cycle.

title: Using library functions in timer ISR ESP32

Answers: 0


body:
I'm working on a school project where I'm building a small convyeor belt using an ARDUINO, DC motor and IR sensor for moving object detection so my color sensor can read color value.

I'm using single mosfet IRFZ44N to control DC motor. I can control DC motor using mosfet normally as turning it ON/OFF using digitalWrite using an arduino.

So, I want to stop convyeyor belt for 500ms when IR sensor detects HIGH and let color sensor read color of object and then let object move ahead normally on belt.
I have written below code but the IR sensor detect object but motor never stops running.
```
#define IR_COLOR 34

const int MOTORpin = 32;
const long onDuration = 1000;// OFF time for LED
const long offDuration = 1000;// ON time for LED
int MOTORState =HIGH;// initial state of LED

boolean MOTOROnFlag          = true;

long rememberTime=0;

void setup() {
  pinMode(IR_COLOR, INPUT);
  pinMode(MOTORpin,OUTPUT);// define MOTORpin as output
  digitalWrite(MOTORpin,MOTORState);// set initial state
}

void loop() {

  int state = digitalRead(IR_COLOR);

 if( state == false )
 {
    if( (millis()- rememberTime) >= onDuration){
    MOTORState = LOW;
    rememberTime=millis();
    }
 }
 else if(state == true)
 {
    if( (millis()- rememberTime) >= offDuration){
    MOTORState =HIGH;// change the state of LED
    rememberTime=millis();// remember Current millis() time
    }
 }

 digitalWrite(MOTORpin,MOTORState);// turn the LED ON or OFF

}// loop ends

```

title: ARDUINO DC Motor Control over IR Sensor INPUT

Answers: 1

body:
You have the general idea.

Your code looks a bit cluttered. Comments are not part of the program, keep them away from the code.

The `if` statements reduce to `if (true)`, that means that `== true` part is redundant.
All you need is `if(state)`. The `if` block will execute when `state` is true.
Conversely `if (!state)` tests for `state` being false

When there are only two possible values, then `else if(state == true)` can be simply `else`.

Identical code that is in both parts of the `if-else` block should be moved to outside of the block, `rememberTime=millis();` should be moved to after the closing brace `}` of the `if-else` block.

Here is some code that does what you want.

This code has not been tested on a hardware device.

https://wokwi.com/projects/364353854313747457

```lang-cpp
const int     sensor_blocked  = LOW;              // define sensor values
const int     sensor_clear    = HIGH;

const int     motor_on        = HIGH;
const int     motor_off       = LOW;

const int     master_enable   =  2;
const int     motor_pin       =  3;
const int     sensor_pin      = 12;

int           sensor_state;
int           sensor_previous = sensor_clear;
int           motor_state     = motor_on;

unsigned long millis_previous = 0;
unsigned long millis_now;

const long    interval        = 500;

void setup() {

  pinMode(master_enable, INPUT_PULLUP);
  pinMode(sensor_pin,    INPUT_PULLUP);
  pinMode(motor_pin,     OUTPUT);

}

void loop() {

  sensor_state = digitalRead( sensor_pin );

  // ---------------------------------------------------------------------------------------------------

  if ( sensor_state != sensor_previous ) {             // only run this code when sensor state changes
    sensor_previous = sensor_state;                    // remember new sensor state

    if ( sensor_state == sensor_blocked ) {            // sensor became blocked
      motor_state = motor_off;                         // turn off motor
      millis_previous = millis();                      // start of "motor off" interval
    }
    delay(20);                                         // debounce sensor
  }

  // ---------------------------------------------------------------------------------------------------

  if ( motor_state == motor_off ) {                    // timer check is relevant only when motor is off
    millis_now = millis();
    if ( millis_now - millis_previous >= interval ) {  // check if timer expired
      motor_state = motor_on;                          // enable motor
    }
  }

  // ---------------------------------------------------------------------------------------------------

  if ( digitalRead( master_enable ) != LOW ) motor_state = motor_off;     // master switch

  // ---------------------------------------------------------------------------------------------------

  digitalWrite(motor_pin, motor_state);                // translate motor state into action

}

```


body:
I have a potentiometer connected to an ADC input of an Arduino Leonardo.
The ADC resolution is 10-bit (0..1024), while I need just 7-bit (0..127).

I use a simple filter to reduce the noise and then a `map` to cut the unused bits:

    #define ADC_CH                18
    #define ADC_FILTER            0.90

    uint16_t value;

    uint16_t adc = analogRead(ADC_CH);
    value = (uint16_t) ((float) ADC_FILTER * adc + (1. - ADC_FILTER) * value);

I show `value` on an LCD. It's very stable, but it may happen that if the adc readings are in the nearby of two values, there is nothing that could prevent a change in the final value, even if the noise is of just few LSBs.

Is there a simple way to implement an hysteresis for each low-res value?

In this way the change between N and N+1 happens on a different ADC reading than between N and N-1, improving the noise rejection without increasing the filter delay (that would only increase the change interval).

title: Avoid 1-LSB noise on ADC readings

Answers: 1

body:
When you reduce the resolution from 10 bits to 7 bits, every possible
output corresponds to an interval of inputs. If you add some hysteresis,
then those intervals should overlap. Below is a representation of the
input intervals corresponding to outputs 0, 1,… 6, for an
hysteresis width of 4:

```text
input: 0    5   10   15   20   25   30   35   40   45   50   55   60
       └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴
       ├─────0────┤
           ├───────1──────┤
                   ├───────2──────┤
                           ├───────3──────┤
                                   ├───────4──────┤
                                           ├───────5──────┤
                                                   ├───────6──────┤
```

To implement this in code, you have to remember the last output, and
change it only if the input lies outside the interval assigned to this
output. Here is an example implementation:

```c++
const int hysteresis = 4;  // tune to taste

/* Remove 3 bits of resolution while adding some hysteresis. */
int resample(int adc)
{
    static int value;  // last output
    if (adc < (value<<3) - hysteresis) {
        value = (adc + hysteresis) >> 3;
    } else if (adc >= ((value+1)<<3) + hysteresis) {
        value = (adc - hysteresis) >> 3;
    }
    return value;
}
```

Note that a `static` local variable keeps its value between successive
calls to the function.


body:
As a volunteer for Public Invention, I have developed an Atmega328 based design in which I thought I was largely duplicating the Arduino UNO.
Unlike the UNO, I did choose a CH340 USB to UART chip as that was a part on some UNO clones I have purchased.

Our project, the General Alarm Device, is at:
https://github.com/PubInv/general-alarm-device

In the summer of 2022 We built up 15 Verion 1 assemblies.
When we went to put boot loader into them we found we could put the Duemilanove bootloader but not the UNO.  We do not know why.

Even with the Duemilanove bootloader we from time to time have problems uploading code. Some times the IDE reports a problem but the code uploaded.  And perhaps some times we had to try to load more than once.
Here is an issue written up after one user had some difficulty with firmware upload:
https://github.com/PubInv/general-alarm-device/issues/127

Related questions,
Is their a way to check which boot loader is in a board?

Could our root problem have been due to which boot loader was on the UNO we were using as the ICP?

title: Why Did I Have To Program Duemilanove Bootloader?

Answers: 1

body:
> Related questions, Is their a way to check which boot loader is in a board?

I wrote some code to detect chip signatures a while ago which also reports on known bootloaders: <http://www.gammon.com.au/forum/?id=11633>

It really is too long to post here. The code however is at <https://github.com/nickgammon/arduino_sketches> in particular in the **Atmega_Board_Detector** folder.

It's the same processor chip, you shouldn't have problems uploading, provided you use the appropriate clock speed and baud rate.

See my answers here:

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

* https://arduino.stackexchange.com/questions/15936/what-happens-when-code-is-uploaded-using-the-bootloader/15937#15937

---

> Where do I learn what is appropriate?

Well, the bootloaders have hard-coded into them the speed at which they expect the serial data to arrive. In the case of Optiboot it is 115200 baud, some other bootloaders may use 9600, 57600 or other speeds.

Now this baud rate is also dependent on the clock rate of the processor, because the baud rate is derived from the system clock.

So for example, on a Uno, Optiboot "expects" (in the sense that a computer can expect anything) that it will be running on a board at 16 MHz, and that the communication will be at 115200 baud.

So, if you are running at 8 MHz (half that speed) then the baud rate will naturally be 57600. However you can compensate for that by editing the file `boards.txt` in your Arduino installation and changing the baud rate, eg.

    uno.name=Arduino Uno

    uno.vid.0=0x2341
    uno.pid.0=0x0043
    uno.vid.1=0x2341
    uno.pid.1=0x0001
    uno.vid.2=0x2A03
    uno.pid.2=0x0043
    uno.vid.3=0x2341
    uno.pid.3=0x0243

    uno.upload.tool=avrdude
    uno.upload.protocol=arduino
    uno.upload.maximum_size=32256
    uno.upload.maximum_data_size=2048
    uno.upload.speed=115200

    uno.bootloader.tool=avrdude
    uno.bootloader.low_fuses=0xFF
    uno.bootloader.high_fuses=0xDE
    uno.bootloader.extended_fuses=0xFD
    uno.bootloader.unlock_bits=0x3F
    uno.bootloader.lock_bits=0x0F
    uno.bootloader.file=optiboot/optiboot_atmega328.hex

    uno.build.mcu=atmega328p
    uno.build.f_cpu=16000000L
    uno.build.board=AVR_UNO
    uno.build.core=arduino
    uno.build.variant=standard

Change the line "uno.upload.speed" to read 57600 in this case. That way the program (avrdude) which uploads to the board will upload slower, and since you are running at a slower speed, all will be well.

---

So, to make it all work:

* Find which bootloader you have (by comparing signatures) or simply upload a new bootloader of a known type. I have a [page about uploading bootloaders](http://www.gammon.com.au/forum/?id=11635) which might help you there.

* Look up (eg. in that file) what the baud rate this particular bootloader uses (eg. 115200 for Optiboot).

* Set your processor to run at that clock speed with a crystal or resonator. (see the line "uno.build.f_cpu" which is 16000000 in this case).

* If you choose to run the processor at a different speed (eg. using the internal clock, at 8 MHz) then either use a bootloader designed for 8 MHz, or change the upload speed baud rate line in the file as mentioned above. I suggest copy/pasting an existing entry, changing for example "uno" at the start of each line to "myboard" or something like that, and the "name" line as well, so it will appear in the drop-down menu of available boards).


body:
I'm trying to follow [Serial Input Basics][1] to build a program which receives commands over serial like `"<led:12,34,21>"` but i'm stuck on receiving the characters from serial...

I have copied the code from the example for `receiveWithStartAndEndMarkers` but it does not show that i received all the characters over serial

```
const int kMaxCommandSize=30;
char receivedChars[kMaxCommandSize + 1];
char command[kMaxCommandSize + 1];
boolean newData = false;

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

void loop() {
  recvWithStartEndMarkers();
  if(newData){
    ProcessCommand();
    newData = false;
  }
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

 // if (Serial.available() > 0) {
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= kMaxCommandSize) {
                    ndx = kMaxCommandSize - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        } else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void ProcessCommand() {
  Serial.println("Received:");
  Serial.println(receivedChars);
}

```

But when i send `<123>` i am consistently seeding
```
Received:
1
Received:
1
Received:
1
```

or when i send `<asdf1234>` i see
```
Received:
a
Received:
a
Received:
a

```

EDIT: it looks like sometimes the full transmission works... But not often i just sent `<123>` four times and got
```
Received:
123
Received:
12
Received:
1
Received:
123
```

  [1]: https://forum.arduino.cc/t/serial-input-basics/278284/2

title: Serial does not receive all chars

Answers: 0


body:
So i wanted to flash my Nodemcu esp8266 v3.4 with esp8266 deauther code: [script-github][1]
i did everything said. First i plugged in my nodemcu. Windows detected it and drivers for ch340 where already installed. I tried using the Nodemcu firmware programmer programm for flashing, but when starting flashing in the log there it was just stuck on "begin finding esp8266". then i tried using the arduino ide, again i did everything the github wiki said. but i got this:

```
Sketch uses 829464 bytes (79%) of program storage space. Maximum is 1044464 bytes.
Global variables use 32132 bytes (39%) of dynamic memory, leaving 49788 bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.8
Serial port COM5
Traceback (most recent call last):
  File "C:\Users\jakob\AppData\Local\Arduino15\packages\deauther\hardware\esp8266\2.7.5/tools/upload.py", line 65, in <module>
    esptool.main(cmdline)
  File "C:/Users/jakob/AppData/Local/Arduino15/packages/deauther/hardware/esp8266/2.7.5/tools/esptool\esptool.py", line 2889, in main
    esp = chip_class(each_port, initial_baud, args.trace)
  File "C:/Users/jakob/AppData/Local/Arduino15/packages/deauther/hardware/esp8266/2.7.5/tools/esptool\esptool.py", line 237, in __init__
    self._port = serial.serial_for_url(port)
  File "C:/Users/jakob/AppData/Local/Arduino15/packages/deauther/hardware/esp8266/2.7.5/tools/pyserial\serial\__init__.py", line 88, in serial_for_url
    instance.open()
  File "C:/Users/jakob/AppData/Local/Arduino15/packages/deauther/hardware/esp8266/2.7.5/tools/pyserial\serial\serialwin32.py", line 78, in open
    self._reconfigure_port()
  File "C:/Users/jakob/AppData/Local/Arduino15/packages/deauther/hardware/esp8266/2.7.5/tools/pyserial\serial\serialwin32.py", line 222, in _reconfigure_port
    'Original message: {!r}'.format(ctypes.WinError()))
serial.serialutil.SerialException: Cannot configure port, something went wrong. Original message: PermissionError(13, 'Ein an das System angeschlossenes Ger�t funktioniert nicht.', None, 31)
Failed uploading: uploading error: exit status 1
```

  [1]: https://github.com/SpacehuhnTech/esp8266_deauther

title: cant flash my nodemcu esp8266

Answers: 0


body:
I have a PC speaker with it's owner power supply (no amplifier needed). It just uses a standard AUX jack.

Most [examples][1] sketches use an amplifier like the MAX98357A. I have explored some libraries too, such as [ESP8266Audio][2].

I just want to find a simple example that emits audio (not just noise). This is my setup:

[![enter image description here][3]][3]

[![enter image description here][4]][4]

I thought an audio program would use the internal DAC to create the CODEC? Or am I not understanding something?

    const int  DAC_CH1 = 25; // or 26

    void setup()
    {
    //    dacWrite(DAC_CH1, 255); // ~3v3
    //  dacWrite(DAC_CH1, 192); // ~2.5
    //  dacWrite(DAC_CH1, 128); // ~1.7
    }

    void loop(){}

# Edit

I found the [PlayMODFromPROGMEMToDAC][5] example, which uses pin 25 DAC:

    #include <Arduino.h>
    #include "AudioFileSourcePROGMEM.h"
    #include "AudioGeneratorMOD.h"
    #include "AudioOutputI2S.h"
    #if defined(ARDUINO_ARCH_RP2040)
        #define WIFI_OFF
        class __x { public: __x() {}; void mode() {}; };
        __x WiFi;
    #elif defined(ESP32)
        #include <WiFi.h>
    #else
        #include <ESP8266WiFi.h>
    #endif

    // enigma.mod sample from the mod archive: https://modarchive.org/index.php?request=view_by_moduleid&query=42146
    #include "enigma.h"

    AudioGeneratorMOD *mod;
    AudioFileSourcePROGMEM *file;
    AudioOutputI2S *out;

    void setup()
    {
      WiFi.mode(WIFI_OFF); //WiFi.forceSleepBegin();
      Serial.begin(115200);
      delay(1000);

      audioLogger = &Serial;
      file = new AudioFileSourcePROGMEM( enigma_mod, sizeof(enigma_mod) );

       /* HERE! */
       // ↓
       // ↓
       out = new AudioOutputI2S(0, 1); //Uncomment this line, comment the next one to use the internal DAC channel 1 (pin25) on ESP32
       // ↑
       // ↑
    //  out = new AudioOutputI2S();
      mod = new AudioGeneratorMOD();
      mod->SetBufferSize(3*1024);
      mod->SetSampleRate(44100);
      mod->SetStereoSeparation(32);
      mod->begin(file, out);
    }

    void loop()
    {
      if (mod->isRunning()) {
        if (!mod->loop()) mod->stop();
      } else {
        Serial.printf("MOD done\n");
        delay(1000);
      }
    }

Although, still no sound (besides noise) can be heard.

  [1]: https://circuitdigest.com/microcontroller-projects/i2s-communication-on-esp32-to-transmit-and-receive-audio-data-using-max98357a
  [2]: https://github.com/earlephilhower/ESP8266Audio/tree/master/examples
  [3]: https://i.stack.imgur.com/noa9u.png
  [4]: https://i.stack.imgur.com/30Omp.png
  [5]: https://github.com/earlephilhower/ESP8266Audio/tree/master/examples/PlayMODFromPROGMEMToDAC

title: What is the most simple sketch to confirm the DAC works for audio on a speaker with it's own amplifier for an ESP32?

Answers: 0


body:
I've built the attached circuit with the following changes:
1. I used Arduino Nano
2. I used 10K pot
3. 12V is connected to VIN pin (instead of RAW)
4. the Arduino was connected to the PC by USB for the use of serial communication.

[![enter image description here][1]][1]
I used 12V 4Pin fan (C25704-002)

Here is the code, I used:

        const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to

    int sensorValue = 0;        // value read from the pot
    int outputValue = 0;        // value output to the PWM (analog out)

    void setup() {
       // Configure Timer 1 for PWM @ 25 kHz.
        TCCR1A = 0;           // undo the configuration done by...
        TCCR1B = 0;           // ...the Arduino core library
        TCNT1  = 0;           // reset timer
        TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
               | _BV(COM1B1)  // same on ch; B
               | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
        TCCR1B = _BV(WGM13)   // ditto
               | _BV(CS10);   // prescaler = 1
        ICR1   = 320;         // TOP = 320

        // Set the PWM pins as output.
        pinMode( 10, OUTPUT);

    }

    // PWM output @ 25 kHz, only on pins 9 and 10.
    // Output value should be between 0 and 320, inclusive.
    void analogWrite25k(int value)
    {

        OCR1A = value;

    }

    void loop() {
        // read the analog in value:
        sensorValue = analogRead(analogInPin);

        // map it to the range of the analog out:
        outputValue = map(sensorValue, 0, 1023, 0, 320);

        analogWrite25k(outputValue);

I have the following questions:
1. The circuit was working for couple of minutes but then I smelled the famous electronic components barbecue smell, so I disconnected the GND power line and when I did I felt that the GND line was hot, I think I fried the Arduino, Do you have an idea what can fry the Arduino?
2. The Potentiometer (10K) was not sensitive, It worked only on some range of the knob, What resistance should I use?

Thanks.

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

title: Troubleshoot/Diagnose Arduino circuit

Answers: 0


body:
The task is: after five clicks on OK, the built-in LED starts flashing with a frequency of 5Hz using an interrupt. After the eighth click on OK, the flashing (and glowing) should stop.Why is flashing not working

    bool ledState = false;
    volatile bool ledOn = true;

    void setup(){
    TCCR2A = 0;
      TCCR2B = 0;
      TIMSK2 = 0;
      TCNT2 = 0;
      OCR2A = 77;
      TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
      TIMSK2 |= (1 << OCIE2A);
     pinMode(13, OUTPUT);
    }

    void loop(){
     if(button5.buttonPressedCount >= 5 && button5.buttonPressedCount < 8){
        ledState = true;
      }

      if(button5.buttonPressedCount > 7){
        ledState = false;
      }
    }

    ISR(TIMER2_COMPA_vect){
      if(ledState){
      digitalWrite(13, ledOn);
      ledOn = !ledOn;
      }
    }

title: How to make the built-in LED blink with a frequency of 5 Hz using interrupts

Answers: 1

body:
On the Uno (ATmega328P microcontroller), timers 0 and 2 are 8-bit only:
they cannot count beyond 255. Timer 1, on the other hand, is 16-bits.
This is the most convenient timer for generating low frequencies.

Speaking of frequencies... One LED period involves two toggles (turn on,
then turn off). Thus, if you want the LED to blink at 5 Hz, the toggle
action should happen at 10 Hz. Given that the CPU is clocked at 16 MHz,
this means you have to toggle the LED every 1,600,000 CPU cycles.

If you set the prescaler to 1,024, you then you have to count
1,600,000/1,024 = 1,562.5 timer cycles. You cannot count a non-integer
number of cycles, but you probably do not care about such accuracy. If
you do care, set the prescaler to 256 and count 1,600,000/256 =
6,250 timer cycles by setting the compare match register to 6,249.

One last issue: keep in mind that, in normal counting mode, the timer
counts up to its maximum value (65,535, or 255 on an 8-bit timer) and
then restarts at zero. If you want it to count only up the value set in
the compare match register, you should choose the appropriate waveform
generation mode: the fast PWM mode that lets you control the TOP value
with OCR1A.


body:
I'm running a dc motor using esp32 and mosfet by taking readings of IR.

Program works fine when used delay() but same program doesn't work when uploaded using millis().

```
//This uses fixed delay()

// Pin definitions
const int irSensorPin = 34;  // IR sensor connected to GPIO 2
const int motorPin = 32;     // DC motor connected to GPIO 4

// Variables
bool isObjectDetected = false;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Set pin modes
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  // Check if object is detected
  if (digitalRead(irSensorPin) == LOW) {
    if (!isObjectDetected) {
      // Object detected for the first time
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Stop the motor
      delay(500);                   // Wait for 500ms
      Serial.println("Resuming motor.");
      digitalWrite(motorPin, HIGH); // Start the motor
    }
  } else {
    if (isObjectDetected) {
      // Object is no longer detected
      isObjectDetected = false;
    }
  }
}

 ```

```
//This uses millis()

// Pin definitions
const int irSensorPin = 34;  // IR sensor connected to GPIO 34
const int motorPin = 32;     // DC motor connected to GPIO 32

// Variables
bool isObjectDetected = false;
unsigned long motorStopTime = 0;
const unsigned long motorDelayTime = 500;  // Delay time in milliseconds

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Set pin modes
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);

  // Initialize motor state
  digitalWrite(motorPin, HIGH);  // Start the motor
}

void loop() {
  // Check if object is detected
  if (digitalRead(irSensorPin) == HIGH) {
    if (!isObjectDetected) {
      // Object detected for the first time
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Stop the motor
      motorStopTime = millis();     // Record the stop time
    }
  } else {
    if (isObjectDetected) {
      // Object is no longer detected
      isObjectDetected = false;
      unsigned long currentTime = millis();
      if (currentTime - motorStopTime >= motorDelayTime) {
        Serial.println("Resuming motor.");
        digitalWrite(motorPin, HIGH); // Start the motor
      }
    }
  }
}

```

title: Program work when used Delay() but same program doesn't work with millis()

Answers: 1

body:
I am not sure I quite understand what the requirements are for this
program. However, they do not do the same thing. I tried to represent
their behavior as [state diagrams][], and here is what I got:

Version using `delay()`:

[![state diagram][1]][1]

Version using `millis()`:

[![state diagram][2]][2]

In the above diagrams, states with a gray background are those where the
motor is off. As can be seen here, the first version never keeps the
motor off for more than 0.5 s, where the second one can keep the
motor indefinitely off if the sensor remains HIGH.

I suggest you start by drawing the state diagram corresponding to the
behavior you actually want. Then, use the technique outlined in this
[tutorial on finite state machines][fsm] to turn the diagram into code.
Note that finite state machines work well with `millis()`-based timing.

[state diagrams]: https://en.wikipedia.org/wiki/State_diagram
[fsm]: https://majenko.co.uk/blog/finite-state-machine

  [1]: https://i.stack.imgur.com/gl1I6.png
  [2]: https://i.stack.imgur.com/VCS0S.png


body:
I running the following code with Seeeduino Cortex M0, DC fan  and Grove - I2C Motor Driver (TB6612FNG) but I get error ,any idea why?

Code:

    #include "Grove_Motor_Driver_TB6612FNG.h"
    #include <Wire.h>

    MotorDriver motor;

    void setup()
    {
        // join I2C bus (I2Cdev library doesn't do this automatically)
        Wire.begin();
        Serial.begin(9600);
        motor.init();
    }

    void loop()
    {
        // drive 2 dc motors at speed=255, clockwise
        Serial.println("run at speed=255");
        motor.dcMotorRun(MOTOR_CHA, 255);
        delay(1000);

    }

Errors:

    c:\Users\alirazi\Desktop\libraries\Grove_-_Motor_Driver_TB6612FNG\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readBytes(uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)':
    c:\Users\alirazi\Desktop\libraries\Grove_-_Motor_Driver_TB6612FNG\I2Cdev.cpp:276:62: error: 'BUFFER_LENGTH' was not declared in this scope
                 for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
                                                                  ^~~~~~~~~~~~~
    c:\Users\alirazi\Desktop\libraries\Grove_-_Motor_Driver_TB6612FNG\I2Cdev.cpp:276:62: note: suggested alternative: 'REG_DSU_LENGTH'
                 for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {
                                                                  ^~~~~~~~~~~~~
                                                                  REG_DSU_LENGTH
    c:\Users\alirazi\Desktop\libraries\Grove_-_Motor_Driver_TB6612FNG\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readWords(uint8_t, uint8_t, uint8_t, uint16_t*, uint16_t)':
    c:\Users\alirazi\Desktop\libraries\Grove_-_Motor_Driver_TB6612FNG\I2Cdev.cpp:416:70: error: 'BUFFER_LENGTH' was not declared in this scope
                 for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) {
                                                                          ^~~~~~~~~~~~~
    c:\Users\alirazi\Desktop\libraries\Grove_-_Motor_Driver_TB6612FNG\I2Cdev.cpp:416:70: note: suggested alternative: 'REG_DSU_LENGTH'
                 for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) {
                                                                          ^~~~~~~~~~~~~
                                                                          REG_DSU_LENGTH

    exit status 1

    Compilation error: exit status 1

title: I2C Motor Driver (TB6612FNG) and DC fan error

Answers: 0


body:
I successfully programmed an RFID card reader to switch lights on and off if any rfid card is presented.  I have tested this and it works, with the lights continually switching on and off if any rfid enabled card is is presented.

I tried to add a command that if two specific cards are read (identified by their UID numbers) then only those cards would reset the lights to "off" no matter what the state they were currently in - like a reset button.

The problem is that once one of those cards is presented, the light goes off but the system stops responding and presenting one of the other cards no longer turns the light on and off.

I am fairly new to programming Arduino, as well as with RFID technology, but it seems like the loop does not reset to the beginning properly, or my IF statement somehow leaves the system in a state where the beginning code can't be run.

My code is below.  Any thoughts would be appreciated.

`

    #define r1 A0
    int relay1 = LOW;

    #include <SPI.h>
    #include <MFRC522.h>

    #define SS_PIN 10
    #define RST_PIN 9
    MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

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

      Serial.begin(9600);   // Initiate a serial communication
      SPI.begin();      // Initiate  SPI bus
      mfrc522.PCD_Init();   // Initiate MFRC522
      Serial.println("Approximate your card to the reader...");
      Serial.println();
    }

    void loop()
    {
      // Look for new cards
      if ( ! mfrc522.PICC_IsNewCardPresent())
      {
        return;
      }

    // Select one of the cards
      if ( ! mfrc522.PICC_ReadCardSerial())
      {
        return;
      }

      //Show UID on serial monitor
      Serial.print("UID tag :");
      String content = "";
      byte letter;
      for (byte i = 0; i < mfrc522.uid.size; i++)
      {
        Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
        content.concat(String(mfrc522.uid.uidByte[i], HEX));
      }
      Serial.println();
      Serial.print("Message : ");
      content.toUpperCase();

      if ((content.substring(1) == "23 49 1F BE") || (content.substring(1) == "CB CB 2C E3")) //change here the UID of the card/cards that you want to give access
      {
       Serial.println("Staff access");
        Serial.println();
        relay1 = HIGH;
        digitalWrite(r1, relay1);
        delay(500);
      }
      else
      {

        Serial.println("Authorized access");
        Serial.println();
        relay1 = ~ relay1;
        digitalWrite(r1, relay1);
        delay(500);
      }
    }

`

title: RFID card read loop seems to stop

Answers: 1

body:
The problem is the inappropriate use of the tilde (~) , which is a bitwise NOT operator, against the `int` variable `relay1`.
It appears to work correctly when relay1 starts with LOW which has the value 0. That is, relay1 has the internal value 0b0000000000000000.  If now the statement `relay1 = ~relay1` is executed, relay1 has the internal value 0b1111111111111111. This is treated as a HIGH in the expression `digitalWrite(r1, relay1);` So it appears to work correctly.
If again the statement `relay1 = ~relay1` is executed, relay1 has the internal value 0b0000000000000000 This is treated as a LOW in the expression `digitalWrite(r1, relay1);`
So that would also appear to work continuously, turning the relay on and off.

The problem comes when you explicitly set relay1 to HIGH here: `relay1 = HIGH;`. HIGH has the value 1, that is relay1 now has the intenal value 0b0000000000000001 and again that works, however, the next execution of the statement `relay1 = ~relay1` gives relay1 the internal value
0b1111111111111110 which is also treated as HIGH. So, from now on, the statement `relay1 = ~relay1` will always result in relay1 having a value which is interpreted as HIGH. So the relay appears to be stuck.

The solution, which already appears in a comment, is to change the statement `int relay1 = LOW;` to `bool relay1 = LOW;` and change this statement `relay1 = ~ relay1;` to `relay1 = ! relay1;`


body:
I have a custom board based on Arduino Leonardo (`ATmega32u4`).
As usual I used the Arduino IDE to burn the bootloader with my Atmel ICE ISP programmer.

This time it failed complaining about some errors writing the fuse bits.
So I tried to manually set them with `avrdude` but it turns out it can't.

I first dumped out the current values:

    avrdude: Device signature = 0x1e9587 (probably m32u4)
    avrdude: safemode: lfuse reads as 5E
    avrdude: safemode: hfuse reads as D8
    avrdude: safemode: efuse reads as F3

    avrdude> d lock
    >>> d lock
    0000  ff

Then I tried to change, say, `lfuse` to `0xFF`:

    avrdude "-C/home/mark/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" -v -patmega32u4 -catmelice_isp -Pusb -Ulfuse:w:0xff:m

here the output:

    avrdude: reading input file "0xff"
    avrdude: writing lfuse (1 bytes):

    Writing | ################################################## | 100% 0.09s

    avrdude: 1 bytes of lfuse written
    avrdude: verifying lfuse memory against 0xff:
    avrdude: load data lfuse data from input file 0xff:
    avrdude: input file 0xff contains 1 bytes
    avrdude: reading on-chip lfuse data:

    Reading | ################################################## | 100% 0.00s

    avrdude: verifying ...
    avrdude: verification error, first mismatch at byte 0x0000
             0x5e != 0xff
    avrdude: verification error; content mismatch

    avrdude: safemode: lfuse reads as 5E
    avrdude: safemode: hfuse reads as D8
    avrdude: safemode: efuse reads as F3
    avrdude: safemode: lfuse changed! Was ff, and is now 5e
    Would you like this fuse to be changed back? [y/n] y

But it failed:

    avrdude: safemode: Wrote lfuse to ff, read as 5e. 9 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 8 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 7 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 6 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 5 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 4 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 3 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 2 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 1 attempts left
    avrdude: safemode: Wrote lfuse to ff, read as 5e. 0 attempts left
    avrdude: and COULD NOT be changed
    avrdude: safemode: Fuses not recovered, sorry

I can program the MCU with a firmware (using the ISP programmer) and it works, so it's not damaged. What can I do in order to fix this writing issue on the fuse bits?

title: Cannot change fuses on ATmega32U4

Answers: 0


body:
Project 5 of the Arduino Starter Kit [book](https://www.uio.no/studier/emner/matnat/ifi/IN1060/v21/arduino/arduino-projects-book.pdf) (page 63) involves wiring up a potentiometer to control a servomotor (see diagram). The book also recommends wiring up decoupling capacitors as shown in the diagram:

> When a servo motor starts to move, it draws more current than if it were already in motion. This will cause a dip in the voltage on your board. By placing a 100uf capacitor across power and ground right next to the male headers as shown in Fig. 1, you can smooth out any voltage changes that may occur. You can also place a capacitor across the power and ground going into your potentiometer.

Since the book doesn't explicitly warn against it, I decided to do this whole project without the capacitors just to see what would happen. It seemed to work fine, I didn't notice any erratic behavior. Is there some experiment I could do to actually measure these voltage "dips"?

I thought maybe I could try to measure the voltage drop across the servo, so I wired it in series with a resistor and connected the A0 ADC pin between the servo and the resistor. I did measure a drop, but the servo didn't work... I'm guessing it wasn't getting enough power because of the resistor?

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

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

title: How can I observe the "voltage dips" the starter kit talks about in Project 5?

Answers: 1

body:
> I'm guessing it wasn't getting enough power because of the resistor?

Yes, that is probably what happened (you didn't specify what value your resistor had). When the servo tries to draw more current, more current has to flow through the resistor. This means more voltage over the resistor and less for the servo, which then doesn't have enough to to powerful or even run at all (depending on the resistors value).

> Is there some experiment I could do to actually measure these voltage "dips"?

You tried to measure the dips with the Arduino. Since the servo is connected directly to the 5V line of the Arduino, so its own Vcc, you cannot measure it the same way as the potentiometer. By default `analogRead()` uses Vcc as reference, meaning the max value. Instead you can configure it to use the internal 1.1V fixed reference (which doesn't depend on Vcc)(refer to [`analogReference()`][1]) and divide down Vcc with a fixed voltage divider (so that the voltage on the analog input pin would not exceed 1.1V).

Though to see the dips you still would need to measure the data points fast enough to catch them. Without knowing how long the dips might be it is difficult to say, if you can easily catch them. There are ways to do analog measurements relatively fast, but for a beginner (and specifically for a beginner book) that is a bit much.

The easier, but also more expensive solution (in terms of tools) is to measure Vcc with an oscilloscope. As entry a USB oscilloscope might be fitting (in the range of maybe 50$). If you don't wanna buy, you might be able to get access to one at the next makerspace or university. Some schools also might have some oscilloscopes.

> Since the book doesn't explicitly warn against it, I decided to do this whole project without the capacitors just to see what would happen. It seemed to work fine

Dips in your supplied voltage might cause the Arduino to reset. But that only happens, when the dip is too big. And that depends on multiple factors:

- How much current can be drawn from your power supply. USB ports on a PC won't give you more than 500mA for example. And some battery types have a big series resistance, meaning that the voltage will drop significantly, when you draw too much current from them.
- Sometimes, when working on a breadboard, the contacts might also have a significant resistance to them. This can lead to a voltage loss there.
- How strong the motor is. In starter kits you typically have these cheap and small SG90 micro servos. These don't draw a lot of power generally and are not really strong.
- How much load is on the motor. A motor draws different amounts of current depending on its load. When it runs feely the currently is the smallest. When its starting, then it needs to fight against its own inertia, thus needing more current. The most current is used, when the motor stalls, because it is not powerful enough to push against the load.

The last two points affect the motor current, which might cause a voltage dip, if the power supply cannot provide that much current with the specified voltage.

The capacitors are a precaution in this case. I think the author wanted to explain this to make sure that it would work for everyone and that students would already know about this, when moving to bigger, more power hungry projects.

  [1]: https://reference.arduino.cc/reference/en/language/functions/analog-io/analogreference/


body:
So I just got my first Arduino Uno board and the output on the serial monitor doesn't make sense to me. For this code

    int counter = 0;

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

    }

    void loop() {
      counter++;
      Serial.println(counter);
      delay(1);
    }
I'm expecting to see an increment once every 1ms. But what I see from the console is odd[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/4AFWH.png
First, I'm expecting to see the timestamp like this: 27.270, 27.271, 27.272...
Second, from 27.301 to 27.334, I only saw the counter increase by 7 instead of ~30.

title: Arduino uno weird behavior on a simple counter program

Answers: 1

body:
If you do something like

```c++
Serial.println(580);
```

that is 5 characters printed (3 digits, then CR and LF to end the
line). Each character takes ten bits worth of transmission time (one
start bit, 8 data bits and one stop bit). The whole message is then
50-bit long on the serial line. At 9600 bits per second, this takes
about 5.2 milliseconds.

Note that the PC seems to be buffering the data, which is displayed in
batches, each batch having a single timestamp. Thus you see that, on
**average** there are 5.2 ms between increments.


body:
I see that they arduino nano ble 33 support USB 2.0. Is there a way for us to create a USB mass storage of about 200kb for convenient storage of configuration files and history files?
I see example arduino has UsbMassStorage but by default it only creates 1 disk with 512KB capacity. Which 512KB + 200KB bootloader is my chip error.
Is there a way to reconfigure the capacity for UsbMassStorage?
Thank you so much.

        /*
       This example exposes the second half (512KB) of Nano 33 BLE flash
       as a USB disk.
       The user can interact with this disk as a bidirectional communication with the board
       For example, the board could save data in a file to be retrieved later with a drag and drop
    */

    #include "PluggableUSBMSD.h"

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

      // write a file with some data
      // a+ means append, so every time the board is rebooted the file will grow by a new line
      FILE *f = fopen("/fs/data.txt", "a+");
      String hello = "Hello from Nano33BLE Filesystem\n";
      fwrite(hello.c_str(), hello.length(), 1, f);
      fclose(f);
    }

    void loop() {
      delay(1000);
    }

title: how to config size USB mass storage arduino nano ble 33?

Answers: 0


body:
in addition to the standard LED_BUILTIN, MKR 1010 WIFI comes with a built-in **RGB LED**.

This RGB LED fails when used along the on-board BLE, no matter what program sequence I test.

To reproduce the issue, turn on the LED and then start BLE which will turn the LED off.

```
#include <WiFiNINA.h>
#include <utility\wifi_drv.h>
#include <ArduinoBLE.h>

void setup() {

  const int ledPin = 27;  //R=26 G=25 B=27

  WiFiDrv::pinMode(ledPin, OUTPUT);

  WiFiDrv::digitalWrite(ledPin, HIGH);

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

  if (!BLE.begin()) { // ble.begin trun the led off
    Serial.println("BLE Failed");
    while (1);
  }

  Serial.println("BLE started"); // last line shown on console

  WiFiDrv::digitalWrite(ledPin, HIGH);

  // program never gets here

}

void loop() {}
```

The RGB LED is connected to NINA’s GPIO pins. Two of them (green and blue) are part of the UART, and another one is used for system control signals (red).

I assumed that BLE.begin uses the UART to communicate with the processor and therefore avoided the red pin and added delays between commands hoping to separate the actions, but it didn’t work.

My goal is to use the RGB LED to indicate BLE states without adding three sets of MOSFETs and resistors. Ideas?

title: MKR 1010 WIFI Built-in RGB LED not working with BLE

Answers: 1

body:
The ArduinoBLE library resets the NINA firmware to BLE mode ([code here][1]). In this mode the NINA firmware just sets ESP32 SDK (IDF framework) to handle the BLE commands.

The RGB LED is handled by the part of the Arduino NINA firmware which [handles the commands][2] from the WiFiNINA library. These commands are communicated over SPI and are not handled if the firmware is in BLE mode.

  [1]: https://github.com/arduino/nina-fw/blob/c84aa3406717af771653733fb9c3480bdf5e1a64/main/sketch.ino.cpp#L108
  [2]: https://github.com/arduino/nina-fw/blob/c84aa3406717af771653733fb9c3480bdf5e1a64/main/sketch.ino.cpp#L197


body: I'm trying to connect sesnor that use RS485 (I'm almost sure that's modbus). The sensor has RX/TX and +/- wires. Do I still need a component between the RX/TX pin from the Arduino UNO and the sensor itself? All the libraries I reviewed have an additional control pin. Or do I need, for example, a MAX485? Is it possible to simply connect RX of sensor to RX of UNO, TX of sensor to TX of UNO and + to 5V of UNO, and - to - ?

title: Arduino RS485 do I need MAX485?

Answers: 0


body:
I am looking to see if I can change the attached sketch which controls 8 stepper motors to just switching 8 relays for a weaving loom which we have, unfortunately making this change is well above my paygrade lol. I am using an arduino mega and 8 channel relay board which will in turn trip the solenoids which the loom already has attached, thanks for any help

This is the Sketch im trying to alter

```lang-c++

// Loom interface for Ashford Dobby interface (using 8 stepper motors):
// Arduino lines 0 & 1 to USB interface
// line 13 Is foot pedal
// 14-43 are motor controls

// General definitions:
#define MAX_CHARS 80
#define DEBUG 0
#define MOTORS 8
#define IDENTITY "Generic Dobby Interface (Jones Stepper Motor Dobby)\n"

// Data controlling motor positions, states, etc:
const long MOTOR_DELAY=900;                                                      // Time delay between motor steps (reduce till shafts move reliably)
const long  SHAFT_UP=8*170, SHAFT_DOWN=0 ;                                       // Number of motor steps required to raise the shafts
unsigned long shaft_state=0x00000000, shaft_cue=0xffffffff;                      // tracking current & next desired states of shaft controls
long MotorActual[MOTORS], MotorWant[MOTORS];                                     // Current & desired position for each of the motors

// Definition of which Output pins connect to which motor
char MotorPin[MOTORS][4]=                                                        // Motors 1,3,5,7 on right, 2,4,6,8 on left: left side reverses direcion
              { {14,15,16,17}, {18,21,20,19}, {22,23,24,25}, {26,29,28,27},      // Motors 1-4
                {30,31,32,33}, {34,37,36,35}, {38,39,40,41}, {42,45,44,43}};     // Motors 5-8

unsigned long NextMotorUpdate=0;                                                 // Timer for when next motor step occurs
const int ADVANCE  =13;                                                          // input pin for footswitch (has pullup, switch contact only)

// Serial (USB) interface
// Serial interface is a "Generic" dobby interface:
// Host sends which shafts should be activated for current shot
// Shafts will raise when the foot switch is activated
// Shafts return when foot switch is released, and the "Advance" command returned to host
// Also responds to "?" with the "IDENTITY" identified above, shows host who's out here

int serial_chars=0;                                                              // Number of characters in the serial input buffer
char serial_string[MAX_CHARS]="";                                                // Serial input buffer
char Message[MAX_CHARS]="";                                                      // Output message buffer
long serial_time=0;                                                              // Used to close serial string on timeout (timer)
const int serial_timeout=100;                                                    // Digest Serial string after timeout
char serial_idle=1;                                                              // Tracks activity on the serial bus
char HostPresent = 1;                                                            // set when some host is identified
int Button_state=1;                                                              // tracks changes in floor-switch state

////////////////////////////////////////////////////////////////////////
// Send shaft controls to hardware
////////////////////////////////////////////////////////////////////////
    void set_motor(char m,char state)                                            // Lowest level function to handle step in motors
    {
//   sprintf(Message,"M %d @ state %d\n",m,state);
//   Serial.write(Message);
     switch(state)
     {
      case 0:                                                                    // Set motor inactive
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 1:                                                                    // Set motor State 1
      digitalWrite(MotorPin[m][0], 1);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 2:                                                                    // Set motor state 2
      digitalWrite(MotorPin[m][0], 1);    digitalWrite(MotorPin[m][1], 1);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 3:                                                                    // Set motor state 3
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 1);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 4:                                                                    // Set motor state 4
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 1);
      digitalWrite(MotorPin[m][2], 1);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 5:                                                                    // Set motor state 5
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 1);    digitalWrite(MotorPin[m][3], 0);
      break;

      case 6:                                                                    // Set motor state 6
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 1);    digitalWrite(MotorPin[m][3], 1);
      break;

      case 7:                                                                    // Set motor state 7
      digitalWrite(MotorPin[m][0], 0);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 1);
      break;

      case 8:                                                                    // Set motor state 8
      digitalWrite(MotorPin[m][0], 1);    digitalWrite(MotorPin[m][1], 0);
      digitalWrite(MotorPin[m][2], 0);    digitalWrite(MotorPin[m][3], 1);
      break;
     }
    }

   char set_motors()                                                            // Set all motors to new motor state - called for each motor step on any motor
    {                                                                            // return indicates if any motor is still active
     int m=0;
     long setting, entry_setting;
     char active=0;

     while(m<MOTORS)
     {
                                                                                // Check for necessary directional movement
      entry_setting=setting=MotorActual[m];
      if(setting==MotorWant[m])       setting=setting;
      else if(setting<MotorWant[m])   setting++;
      else                            setting--;
                                                                                // Send update setting controls
      if((entry_setting!=MotorWant[m]))
      {
       active=1;
       MotorActual[m]=setting;                                                   // update actual for move in progress
       setting=(setting&7)+1;                                                    // set_motor state 0 is inactive, 1-8 are active
       set_motor(m,setting);                                                     // Set new motor state
      }
      m++;                                                                       // Next motor
     }
     if(active==0)
     {                                                                           // If done kill power to the motors that are back in passive state
      m=0;
      while(m<MOTORS)
      {
       if(MotorActual[m]==SHAFT_DOWN)set_motor(m,0);                             // set motor inactive
       m++;
      }
     }
     return active;
    }

    char run_motors()                                                            // Higher level function to set motors to desired positions
    {                                                                            // return indicates if motors are active or idle
     char active=1;
     if(micros()>=NextMotorUpdate)
     {                                                                           // time to update the motor positions
      active=set_motors();                                                       // Update all motors
      NextMotorUpdate=micros()+MOTOR_DELAY;                                      // set clock for next update
     }
     return active;
    }

    void set_shafts(unsigned long shafts)                                        // Called to set desired motor positions based on which shafts were requested
    {                                                                            // This assumes all shafts move the same amount, they really don't need to
     unsigned long bit_mask=1;
     int i=0;
     while(i<MOTORS)
     {
      if(shafts&bit_mask)MotorWant[i]=SHAFT_UP;
      else               MotorWant[i]=SHAFT_DOWN;
//    sprintf(Message,"M %d @ want %d\n",i,MotorWant[i]>>8);
//    Serial.write(Message);
      i++;
      bit_mask=bit_mask<<1;
     }
    }
////////////////////////////////////////////////////////////////////////
// Preset- Called on initialization
////////////////////////////////////////////////////////////////////////
    void preset()                                                                // Could raise all shafts to show it's working, etc.
    {                                                                            // This version doesn't do anything, default will lift all shafts when the foot switch is pressed before anything else is requested
    }

//////////////////////////////////////////////////
// SERIAL INTERFACE (USB) FUNCTIONS
//////////////////////////////////////////////////
                                                                                // USB input commands:
                                                                                // 1,2,3,n            Set shafts 1,2,3,n
                                                                                // ?                  ID request, respond with ID
    unsigned long get_shafts(char* command)                                      // Input is series of numbers, comma seperated, for shafts to raise
    {                                                                            // returns word indicating which shafts were identified in string
     int chars=strlen(command);                                                  // Number of characters in input string
     int i=0;
     unsigned long shafts=0, bits;                                               // Sets bits for shafts indicated
     char shaft=0, digit=0, character;

     while(i<=chars)                                                             // loop through all characters in command
     {
      character=command[i];

      if((character==',')||(i==chars))
      {                                                                          // have field seperator or end of string, not shaft desired
       if((shaft>0)&&(shaft<=32))
       {                                                                         // 'shafts' notes this shaft is required
        bits=1<<shaft-1;
        shafts|=bits;
        shaft=0;
       }
      }
      else if(('0'<=character)&&(character<='9'))
      {                                                                          // have digit
       character&=0x0f;                                                          // reduce to decimal
       shaft=shaft*10+character;
      }
      else if((character==' ')||(character=='\n'));                              // ignore spaces/returns
      else
      {
       Serial.println("Invalid Character detected in command:");                 // debug display of command extracted
       Serial.println(command);                                                  // debug display of command extracted
       i=chars;                                                                  // quit, got crap
      }
      i++;
     }
     return shafts;
    }

    void digest_serial(char* command)                                            // Main serial response function
    {
     int chars=strlen(command);                                                  // Number of characters in command

     if(chars>0)
     {                                                                           // If something to do go digest the input
      HostPresent=1;                                                             // note that there's something out there talking to me
      if(('0'<=command[0])&&(command[0]<='9'))                                   // go number, should be shafts
       shaft_cue=get_shafts(command);                                            // convert ASCII string to binary word
      else  if((command[0]=='c')||(command[0]=='t'))                             // test command to cycle valves
       preset();                                                                 // cycle through the valves (nothing defined for this loom, could implement shaft self test, etc)
      else if(command[0]=='?')
      {                                                                          // Have a "Who are You?" kind of command, tell host who we are
       char message[256]=IDENTITY;                                               // Build primary Identity command
       message[strlen(message)-1]=0;                                             // delete return in line
       sprintf(message,"%s  [Solenoid state = 0x%3x]\n",message,shaft_state);    // note what we'll do when button is pressed
       Serial.write(message);                                                    // Send identity with current switch state to host (for troubleshooting)
      }
     }
    }

    void serial_input()
    {                                                                            // High level Serial processing
     char inChar;
     char command[MAX_CHARS]="";

     while((Serial.available()>0))
     {                                                                           // Get serial command from host (character by character)
      inChar=char(Serial.read());
      serial_string[serial_chars]=inChar;
      serial_chars++;
      serial_string[serial_chars]=0;
      serial_time=millis();
     }
     if((serial_chars>0)&&(serial_idle)&&((serial_string[serial_chars-1]=='\n')||(millis()>(serial_time+serial_timeout))))
     {                                                                           // If have a command, go digest it
      serial_idle=0;
      strcpy(command,serial_string);
      serial_chars=0;
      serial_string[0]=0;
//    Serial.println(command);                                                   // debug display of command extracted
      digest_serial(command);
                                                                                // done with last command, clear the input buffers
      serial_idle=1;                                                             // ready for more serial input
     }
    }

////////////////////////////////////////////////////////////// /
// Foot Switch monitor  - set shafts/tell host to advance
////////////////////////////////////////////////////////////// /
    void monitor_button()
    {                                                                            // check for button push to advance, sent only when button pushed (not held)
     char state=digitalRead(ADVANCE);                                            // read state of foot switch (0=active, 1=inactive)

     if(state==0)
     {                                                                           // button is pressed,
      set_shafts(shaft_cue);                                                     // Set motor desired states from the list of shafts desired for this shot
      run_motors();                                                              // Go run the motors to make it happen
     }
     else
     {                                                                           // button is not pressed,
      set_shafts(0);                                                             // Set motor desired states back to reset condition
      run_motors();                                                              // Make it happen
      if(Button_state!=state)
       Serial.write("ADVANCE\n");                                                // Send "Advance" when foot switch is released
     }
     if(state!=Button_state)                                                     // Check if button has changed state
      delay(500);                                                                // Wait half a second on changes to debounce switch
     Button_state=state;                                                         // Track current state of the button to look for changes
    }

//////////////////////////////////////////////////
// TOP LEVEL FUNCTIONS - SETUP & LOOP                                                                                //
//////////////////////////////////////////////////
    void setup()
    {
     char m;                                                                     // Motor indicator

                                                                                // USB Interface to host computer
     Serial.begin(9600);                                                         // start serial port at 9600 bps:
     Serial.print(IDENTITY);                                                     // print message on serial monitor

                                                                                // Motor Controls
                     // set motor controls for all motors
     m=0;
     while(m<MOTORS)
     {
      digitalWrite(MotorPin[m][0], LOW);                                         // set low
      digitalWrite(MotorPin[m][1], LOW);                                         // set low
      digitalWrite(MotorPin[m][2], LOW);                                         // set low
      digitalWrite(MotorPin[m][3], LOW);                                         // set low
      pinMode(MotorPin[m][0], OUTPUT);                                           // Set as output bit
      pinMode(MotorPin[m][2], OUTPUT);                                           // Jumble order to keep motor from moving
      pinMode(MotorPin[m][1], OUTPUT);                                           // Set as output bit
      pinMode(MotorPin[m][3], OUTPUT);                                           // Set as output bit
      MotorWant[m]=MotorActual[m]=0;                                             //
      m++;
     }

      pinMode(ADVANCE, INPUT_PULLUP);                                            // Set as input pin to handle the foot switch
      preset();                                                                  // "self test" - note it's alive
      unsigned long T0=millis();                                                 // Note start up time
     }

    void loop()
    {
     serial_input();                                                             // check the serial interface, handle if it comes in
     monitor_button();                                                           // check for button push
    }
```

title: change sketch from controlling 8 stepper motors to 8 solenoids

Answers: 2

body:
 * The assumed goal is to automate a Weaving Loom using solenoids instead of steppers.

 * [This video][1] claims a 3kg pull is necessary. It may be difficult to find an appropriate / economical solenoid with that kind of pull, stroke distance & rated for continuous duty (hold its position for a prolonged period of time without harming its self from heat related problems).

 * If sourcing such a solenoid is not a problem, there are only 2 functions in the above code that control the steppers. "set_motor" and "setup". Change those to activate / deactivate solenoids.

 * Also, this might be harder, remove the code that cycles the steppers into / out-of position. You don't need that w/the solenoids.

  [1]: https://youtu.be/YcQjRLs0cXc

body:
I would first figure out what each stepper motor code segment is doing, in overview. Think of viewing the process while standing back from it and describe the _reason_ that code segment is there, more than what, specifically, it does - what it's relationship is to the process, not to the motor.

Move those motor segments into functions, and put function calls where the motor segments used to be.

Now replace the motor code inside each function with solenoid code. This is why we wanted an abstract overview of those motor segments. In each function, you'll write solenoid-specific code that has that same relationship to the overall process as the motor code did, but you'll tailor the specifics to the solenoids.


body:
I have Arduino MEGA with Ethernet Shield and a SD card connected to a RUT950 GSM router. Then, I also have two sensors connected to the router and they run a TCP server that sends measurements character after character with a "\n" to terminate the measurement.

    I got this from the uSonic Wind Sensor:
        $WIMWV,000.0,R,00.0,M,A*10\n
        $WIMTA,022.8,C*23\n
        $WIMHU,083.3,,019.8,C*05\n
        $WIMMB,,,1006.8,B*0F\n

Sensor 1, local IP: 192.168.1.200, port 1649
Sensor 2, local IP: 192.168.1.201, port 1647
Router: 192.168.10.1
Arduino: 192.168.10.100

My program reads from the two TCP servers, store the readings in a char buf[] and then it saves them into a SD card. Then, the program load the file and sends it to the FTP server.

This works fine sometimes, other times it crashes or it starts receiving the data from the two sensors but after some minute, it appears to received only from one sensors or it receives nothing at all. It is very strange! Sometimes, it sends the file only the first time and so on. It has a really random behaviour and I cannot understand why!
Can you help me please?
The sensors have only a public ip address so you can try the code on your pc, if you want to (I can give you the public ip address).

    // Library includes
    #include <SD.h>
    #include <FTP.h>
    #include <RTC.h>
    #include <Ethernet.h>

    // Set Ethernet properties of our PLC
    uint8_t mac[] = { 0xDE, 0xAD, 0x4E, 0x55, 0xFE, 0xED };
    IPAddress ip(192, 168, 10, 100);
    IPAddress netmask(255, 255, 255, 0);
    IPAddress server(2, 45, 150, 21);

    byte server_svs60[] = { 192, 168, 10, 201 };  // Touchberry Pi Server
    int tcp_port_svs60 = 4197;
    byte server_wind[] = { 192, 168, 10, 200 };  // Touchberry Pi Server
    int tcp_port_wind = 4196;
    EthernetClient client_svs60;
    EthernetClient client_wind;

    const byte numChars = 32 * 4;
    char receivedChars[numChars + 1];
    char tempChars[numChars + 1];  // temporary array for use when parsing

    const byte numChars_wind = 32 * 4;
    char receivedChars_wind[numChars + 1];
    char tempChars_wind[numChars + 1];  // temporary array for use when parsing

    byte lineCount = 0;

    IPAddress time_server(147, 156, 7, 26);  // es.ntp.pool.org
    unsigned int udpPort = 2390;
    EthernetUDP udp;
    const int NTP_PACKET_SIZE = 48;      // NTP time stamp is in the first 48 bytes of the message
    byte packetBuffer[NTP_PACKET_SIZE];  //buffer to hold incoming and outgoing packets

    // Variable to save the hour and second
    int savedHour;
    int savedSecond;
    char datetime[50];
    // Variables to manage the SD card
    Sd2Card card;
    SdVolume volume;

    bool flag_wind = false;
    bool flag_svs60 = false;

    // Define the variables for FTP management
    EthernetClient ftpControl;
    EthernetClient ftpData;
    FTP ftp(ftpControl, ftpData);

    // Setup function
    void setup() {
      // Set the speed of the serial port
      Serial.begin(9600);

      // Init the SD Card
      if (!SD.begin(53)) {
        Serial.println("Card failed, or not present");
        while (true)
          ;
      }

      // Configure the ethernet protocol in our PLC
      Ethernet.begin(mac, ip, netmask);
      Serial.print("IP address: ");
      Serial.println(Ethernet.localIP());

      if (client_svs60.connect(server_svs60, tcp_port_svs60)) {
        Serial.println("Connected to the SVS60 server");
        client_svs60.println();
      } else {
        Serial.println("Connection to the SVS60 TCP Server failed");
      }
      delay(1000);

      if (client_wind.connect(server_wind, tcp_port_wind)) {
        Serial.println("Connected to the Wind server");
        client_wind.println();
      } else {
        Serial.println("Connection to the Wind Server failed");
      }

      int c = ftp.connect("2.45.150.21", "geoatlas", "Datiboa2023@");
      while (!c) {
        delay(1000);
        c = ftp.connect("2.45.150.21", "geoatlas", "Datiboa2023@");
      }

      udp.begin(udpPort);
      sendRequest();
    }

    // Loop function
    void loop() {
      Serial.println("parsePacket");
      if (udp.parsePacket()) {

        udp.read(packetBuffer, NTP_PACKET_SIZE);

        unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
        unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
        unsigned long secsSince1900 = highWord << 16 | lowWord;
        const unsigned long seventyYears = 2208988800UL;
        unsigned long epoch = secsSince1900 - seventyYears;

        RTC.setTime(epoch);
        RTC.write();
      }
      Serial.println("rtc read");
      if (!RTC.read()) {
        Serial.println("Read date error: is time set?");
      } else {
        //filename_sd = String(RTC.getYear() + String("") + RTC.getMonth() + String("") + RTC.getMonthDay() + String(".txt"));

        sprintf(datetime, "d-d-d d:d:d",
                RTC.getYear(), RTC.getMonth(), RTC.getMonthDay(),
                RTC.getHour(), RTC.getMinute(), RTC.getSecond());
      }
      // Serial.println(datetime);
      Serial.println("svs60");
      if (client_svs60.available()) {
        Serial.println("dentro svs60 sensor");
        char c = client_svs60.read();
        Serial.println(c);
        strncat(tempChars, &c, 1);
        if (c == '\n') {
          strcpy(receivedChars, tempChars);
          strcpy(tempChars, "");
          Serial.println("I got this from SVS60: ");
          Serial.println(receivedChars);
          logToSd_svs60(receivedChars);
          sendToFTP();
         // memset(0, receivedChars, sizeof(receivedChars));
        }
      }
     Serial.println("wind sensor");
      if (client_wind.available()) {
        Serial.println("dentro wind sensor");
        char c1 = client_wind.read();
        Serial.println(c1);
        strncat(tempChars_wind, &c1, 1);

        if (c1 == '\n') {
          if (++lineCount == 4) {
            strcpy(receivedChars_wind, tempChars_wind);
            strcpy(tempChars_wind, "");
            lineCount = 0;
            Serial.println("I got this from the uSonic Wind Sensor: ");
            Serial.println(receivedChars_wind);
            logToSd_wind(receivedChars_wind);
           // memset(0, receivedChars_wind, sizeof(receivedChars_wind));
          }
        }
      }

      delay(200);
    }

    // Function to save information to SD
    void logToSd_svs60(char value[]) {
      File dataFile = SD.open("datalog.txt", FILE_WRITE);
      if (dataFile) {
        Serial.println("Saving SVS60 to SD");
        dataFile.println("Sensore Ondametrico: ");
        dataFile.println(datetime);
        dataFile.println(value);
        dataFile.close();
      } else {
        Serial.println("Error opening datalog.txt");
        while (true)
          ;
      }
    }

    // Function to save information to SD
    void logToSd_wind(char value[]) {
      File dataFile = SD.open("datalog.txt", FILE_WRITE);
      if (dataFile) {
        Serial.println("Saving Wind to SD");
        dataFile.println("Dati sistema: ");
        dataFile.println(datetime);
        dataFile.println(value);
        dataFile.close();
      } else {
        Serial.println("Error opening datalog.txt");
        while (true)
          ;
      }
    }

    unsigned long sendRequest() {
      memset(packetBuffer, 0, NTP_PACKET_SIZE);

      packetBuffer[0] = 0b11100011;  // LI, Version, Mode
      packetBuffer[1] = 0;           // Stratum, or type of clock
      packetBuffer[2] = 6;           // Polling Interval
      packetBuffer[3] = 0xEC;        // Peer Clock Precision
      packetBuffer[12] = 49;
      packetBuffer[13] = 0x4E;
      packetBuffer[14] = 49;
      packetBuffer[15] = 52;

      //Serial.println("I check the time server");

      if (!udp.beginPacket(time_server, 123)) {
        Serial.println("Begin packet error");
      } else {
        udp.write(packetBuffer, NTP_PACKET_SIZE);
        if (!udp.endPacket()) {
          Serial.println("End packet error");
        }
      }
    }

    void sendToFTP(void)
    {
      Serial.println("SD.open");
      // Open the SD file
      File dataFile = SD.open("datalog.txt");

      // Check if the file was succesfully open
      if (dataFile)
      {
            Serial.println("Sending trough FTP connection");
            ftp.store("datalog.txt", dataFile);
            dataFile.close();

      }
      else
      {
            Serial.println("Error opening2 datalog.txt");
            while (true)
              ;
      }
    }

title: Arduino MEGA crashes with Ethernet shield to connect to two TCP servers

Answers: 0


body:
I wrote simple program to test debug macros, but it gives me compilation error

**Program:**
```
#include <Arduino.h>

#define DEBUG

#ifdef DEBUG
  #define DPRINT(...)    Serial.print(__VA_ARGS__)
  #define DPRINTLN(...)  Serial.println(__VA_ARGS__)
#else
  // define blank line
  #define DPRINT(...)
  #define DPRINTLN(...)
#endif

void setup() {
  // put your setup code here, to run once:
  String str ="Hello MrNams";
  DPRINT("Here is my string %s",str);
}

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

```

**Compilation Error:**

src/main.cpp: In function 'void setup()':
src/main.cpp:7:50: error: no matching function for call to 'HardwareSerial::print(const char [21], String&)'
   #define DPRINT(...)    Serial.print(__VA_ARGS__)
                                                  ^
src/main.cpp:19:3: note: in expansion of macro 'DPRINT'
   DPRINT("Here is my string %s",str);
   ^~~~~~
In file included from C:/Users/<User Name>/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.h:26,
                 from C:/Users/<User Name>/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:177,
                 from src/main.cpp:2:
C:/Users/<User Name>/.platformio/packages/framework-arduinoespressif32/cores/esp32/Print.h:81:12: note: candidate: 'size_t Print::print(const __FlashStringHelper*)'
     size_t print(const __FlashStringHelper *);
            ^~~~~
C:/Users/<User Name>/.platformio/packages/framework-arduinoespressif32/cores/esp32/Print.h:81:12: note:   candidate expects 1 argument, 2 provided
C:/Users/<User Name>/.platformio/packages/framework-arduinoespressif32/cores/esp32/Print.h:82:12: note: candidate: 'size_t Print::print(const String&)'
     size_t print(const String &);

title: Debug Macro Not working

Answers: 0


body:
I'm using an arduino connected to 2 DC motors through L298N. the arduino is powered by a 9V battery, and the L298N is powered by 4 AA batteries. there's also a switch that starts the movement.

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

    1                          // switch state. 1  means off.
    loop                       // start of loop statement
    1
    loop
    0                          // switch state changed to on
    0                          // added another switch check after the if
    Forward for: 5 seconds     // motors on
    setup                      // reset for some reason
    loop                       // start of loop
    0                          // switch still on
    setup                      // another reset
    loop
    0
    0
    Forward for: 5 seconds     // motor starts again
    setup                      // another reset
    loop
    0
    0
    Forward for: 5 seconds     // stuck with the motors on, no more resets
its not always this bad, sometimes it runs once or twice correctly (for five seconds) and then off. some times it gets stuck on without reseting. also, sometimes it starts reading the switch value as 1 after a few seconds of reading the correct value, even though the switch wasen't moved. also, when I remove one of the motor batteries so they don't get power everything works great.
What causes the reset and the freezing? How can I fix that?

this is my code:

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

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

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

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

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

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

[![circuit scheme][1]][1]

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

title: Arduino resets or stuck during run, only when DC motors are connected

Answers: 2

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

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


body:
I have a very wierd behavior using two different ArduinoJson (6.17.3) objects on my ESP32. I was not able to reproduce it in a small example but could track it down to some extent.

From MQTT I receive a json string `payload` (actually it is a const char*) looking like this:
```
{"getLog": {"BOOL": false}, "restartESP": {"BOOL": false}, "config": {"M": {"cRI": {"N": "1200000"}, "cST": {"N": "120000"}, "SSID": {"S": "smartabell"}, "cAL": {"BOOL": true}, "PW": {"S": "smartabell"}}}, "OTA": {"S": "99"}, "time": {"S": ""}, "updateConfig": {"BOOL": false}, "MAC": {"S": "84:CC:A8:00:E7:94"}}
```
I store it in
```
DynamicJsonDocument mqttJsonDoc(MY_MQTT_MAX_PACKET_SIZE);
deserializeJson(mqttJsonDoc, payload);
```
for further parsing, which works fine at the beginning. However, when I call the following function to ACK the MQTT package (it is called in the same function where `mqttJsonDoc` is created):
```
bool ackDDBAction(const char *new_val, const char *ack_pub_topic)
{
 /* JSON settings */
 DynamicJsonDocument ackJsonDoc(MQTT_MAX_ACK_SIZE);
 ackJsonDoc["MAC"] = MAC_str;
 ackJsonDoc["ACK"] = "";
    ackJsonDoc["updateConfig"] = new_val;
 /* Calculate buffer length */
 size_t jsonSize = measureJson(ackJsonDoc) + 1;
 char jsonBuffer[jsonSize];
 /* Serialize json object into a char array */
 serializeJson(ackJsonDoc, jsonBuffer, jsonSize);
 /* Send ack */
 ack_success = client.publish(ack_pub_topic, jsonBuffer);

 return ack_success;
}
```
Somehow my original json object `mqttJsonDoc` is corrupted and looks like:
```
{"getLog":{"BOOL":false},"restartESP":{"BOOL":false},"config":{"M":{"cRI":{"N":"1200000"},"cST":{"N":"120000"},"SSID":{"S":"smartabell"},"cAL":{"BOOL":true},"PW":{"S":"smartabell"}}},"OTA":{"S":"99"},"time":{"S":""},"updateConfig":{"BOOL":false},"MAC":{"S":"84:CC:A8:00:E7:94"}}{"ub{\"MAC\":\"84CCA800E794\",\"ACK\":\"\",\"getLog\":\"0\"}0000":{"\":\"84CCA800E794\",\"ACK\":\"\",\"getLog\":\"0\"}0000":false},"CCA800E794\",\"ACK\":\"\",\"getLog\":\"0\"}0000":{",\"ACK\":\"\",\"getLog\":\"0\"}0000":false},"\":\"\",\"getLog\":\"0\"}0000":{"etLog\":\"0\"}0000":{"Log\":\"0\"}0000":{":\"0\"}0000":"0\"}0000"},"cST":{"N":"120000"},"SSID":{"S":"smartabell"},"cAL":{"BOOL":true},"PW":{"S":"smartabell"}}},"OTA":{"S":"99"},"time":{"S":""},"updateConfig":{"BOOL":false},"MAC":{"S":"84:CC:A8:00:E7:94"}}
```
The beginning is similar, but in the middle, fragments of the other jsonDocument `ackJsonDoc` appear. Besides, it is full of escape chars `\`. After some debugging, I found out that **only** when the line `serializeJson(ackJsonDoc, jsonBuffer, jsonSize);` is executed `mqttJsonDoc` gets corrupted.

I played around with dynamic and static json document but it didnt change the behavior, besides out of curiosity, I created another json object to see if somehow there was a memory overlap.
```
 DynamicJsonDocument mqttJsonDoc2(MY_MQTT_MAX_PACKET_SIZE);
 deserializeJson(mqttJsonDoc2, payload);
```
But this additional dynamic json document holding the payload as well, is corrupted when `ackDDBAction()` is called, too. Increasing any of the json objects by size did not lead to an improvement as well.

I was looking for known issues and cavities but didnt find anything in the documentation https://arduinojson.org/v6/api/json/serializejson/.

But maybe someone has an idea or faced this issue before - I could do some work arounds but they would be ugly and I would like to understand what is happening here.

title: ArduinoJson buffer corruption

Answers: 0


body:
I want to give different PWM (D11) signals based on how much voltage is input (A7). How can I change PWM for different analog values?

```c++
#include <LiquidCrystal.h>
#include <ezButton.h>

ezButton button(7);
int count;
int count1;

const float Pin0=A0;
const float Pin1=A1;
const float Pin2=A2;
const float Pin7=A7;

float valueA;
float valueB;
float valueC;
int valueD;

const float rs = 1, en = 2, d4 = 3, d5 = 4, d6 = 5, d7 = 6;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  TCCR2B = 0b00000001; // x1
  TCCR2A = 0b00000011; // fast pwm
  pinMode(11, OUTPUT);
  pinMode(9, OUTPUT);
  button.setDebounceTime(5); // set debounce time to 50 milliseconds
  button.setCountMode(COUNT_FALLING);
  lcd.begin(16, 1);
  pinMode(Pin0, INPUT);
  pinMode(Pin1, INPUT);
  pinMode(Pin2, INPUT);
  pinMode(Pin7, INPUT);
}

void loop() {
  float a;
  float b;
  float c;

  valueD = analogRead(Pin7);

  digitalWrite(9, HIGH);
  digitalWrite(9, LOW);
  valueA = analogRead(Pin0);
  digitalWrite(9, HIGH);

  a = valueA * 5 / 1023;
  b = valueB * 5 / 1023 * 1.91 - a;
  c = valueC * 5 / 1023 * 0.182;

  valueB = analogRead(Pin1);
  valueC = analogRead(Pin2);

  button.loop();
  int count = button.getCount();
  count1 = constrain(count, 0, 4);
  if (count1 == 0) {
    lcd.print("Bal-Chg");
  }
  if (count1 == 1) {
    lcd.print("V1: ");
    lcd.print(a);
    lcd.print("V");
  }
  if (count1 == 2) {
    lcd.print("V2: ");
    lcd.print(b);
    lcd.print("V");
  }
  if (count1 == 3) {
    lcd.print("I:");
    lcd.print(c);
    lcd.print("A");
  }
  if (count1 == 4) {
    button.resetCount();
  }

  delay(500);
  lcd.clear();
}
```

title: how to change output PWM based on analog input

Answers: 1

body:
The [`map()` function][1] can help. Supply it the minimum and maximum possible values of the A/D output, and the minimum and maximum inputs to the PWM. (This as assuming you expect the full range of inputs and want the full range of outputs.) It will do the calculations for you. You'll have to code reading the A/D and writing the PWM.

  [1]: https://reference.arduino.cc/reference/en/language/functions/math/map/