body:
I use the following code to communicate with a display:

    void Display_HandleDC(spi_transaction_t* p_Transaction)
    {
        gpio_set_level((gpio_num_t)LCD_DC, (uint32_t)p_Transaction->user);
    }

    static void Display_SendCommand(const uint8_t Command)
    {
        spi_transaction_t t;

        memset(&t, 0, sizeof(t));

        t.length = 8;
        t.tx_buffer = &Command;
        t.user=(void*)0;

        assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);
    }

    static void Display_SendData(const uint8_t* p_Data, uint32_t Length)
    {
        spi_transaction_t t;

        if(Length == 0)
        {
            return;
        }

        memset(&t, 0, sizeof(t));

        t.length = Length * 8;
        t.tx_buffer = p_Data;
        t.user=(void*)1;

        assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);
    }

    static uint32_t Display_ReadID(void)
    {
        spi_transaction_t t;

        Display_SendCommand(0x04);

        memset(&t, 0, sizeof(t));
        t.length = 4 * 8;
        t.flags = SPI_TRANS_USE_RXDATA;
        t.user = (void*)1;

        assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);

        return *(uint32_t*)t.rx_data;
    }

    static void Display_Write(int ypos, uint16_t *linedata)
    {
        static spi_transaction_t trans[6];

        for(uint8_t x=0; x<6; x++)
        {
            memset(&trans[x], 0, sizeof(spi_transaction_t));
            if ((x&1)==0) {
                //Even transfers are commands
                trans[x].length=8;
                trans[x].user=(void*)0;
            } else {
                //Odd transfers are data
                trans[x].length=8*4;
                trans[x].user=(void*)1;
            }

            trans[x].flags = SPI_TRANS_USE_TXDATA;
        }

        trans[0].tx_data[0] = 0x2A;
        trans[1].tx_data[0] = 0;
        trans[1].tx_data[1] = 0;
        trans[1].tx_data[2] = 320 >> 8;
        trans[1].tx_data[3] = 320 & 0xFF;

        trans[2].tx_data[0] = 0x2B;
        trans[3].tx_data[0] = ypos >> 8;
        trans[3].tx_data[1] = ypos & 0xFF;
        trans[3].tx_data[2] = (ypos + 1) >> 8;
        trans[3].tx_data[3] = (ypos + 1) & 0xFF;

        // Write the data to memory
        trans[4].tx_data[0] = 0x2C;
        trans[5].tx_buffer = linedata;
        trans[5].length = 320 * sizeof(uint16_t) * 8;
        trans[5].flags = 0x00;

        for(uint8_t x = 0; x<6; x++)
        {
            assert(spi_device_queue_trans(_SPI, &trans[x], portMAX_DELAY) == ESP_OK);
        }
    }

    static void Display_Busy(void)
    {
        spi_transaction_t* rtrans;
        for(uint8_t x=0; x<6; x++)
        {
            assert(spi_device_get_trans_result(_SPI, &rtrans, portMAX_DELAY) == ESP_OK);
        }
    }

    esp_err_t Display_Init(void)
    {
        static uint16_t* Line;

        gpio_set_direction((gpio_num_t)LCD_DC, GPIO_MODE_OUTPUT);
        gpio_set_direction((gpio_num_t)LDC_RESET, GPIO_MODE_OUTPUT);
        gpio_set_direction((gpio_num_t)LCD_BACKLIGHT, GPIO_MODE_OUTPUT);

        if((spi_bus_initialize(HSPI_HOST, &_BusCfg, 0) != ESP_OK) || (spi_bus_add_device(HSPI_HOST, &_DevDcfg, &_SPI) != ESP_OK))
        {
            return ESP_FAIL;
        }

        Display_Reset();
        ESP_LOGI(TAG, "ID: X", Display_ReadID());

        uint32_t Commands = sizeof(_Init_Cmd_List) / sizeof(_Init_Cmd_List[0]);
        ESP_LOGI(TAG, "Loading initialization commands: %u", Commands);

        for(uint32_t i = 0x00; i < Commands; i++)
        {
            ESP_LOGI(TAG, "     Command %u / %u", i + 1, Commands);
            Display_SendCommand(_Init_Cmd_List[i].Command);
            Display_SendData(_Init_Cmd_List[i].Data, _Init_Cmd_List[i].Length & 0x1F);
            if(_Init_Cmd_List[i].Length & 0x80)
            {
                vTaskDelay(100 / portTICK_RATE_MS);
            }
        }

        Line = (uint16_t*)heap_caps_malloc(320 * sizeof(uint16_t), MALLOC_CAP_DMA);
        if(Line == NULL)
        {
            return ESP_FAIL;
        }

        for(uint32_t i = 0x00; i < 320; i++)
        {
            Line[i] = 0xF8;
        }

        Display_Write(0, Line);
        Display_Busy();
        free(Line);

        return ESP_OK;
    }

And this code results in the following error message:

    E (1833) spi_master: check_trans_valid(801): txdata transfer > host maximum
    assertion "spi_device_queue_trans(_SPI, &trans[x], portMAX_DELAY) == ESP_OK" failed: file "src/Peripherals/Display/display.cpp", line 225, function: void Display_Write(int, uint16_t*)
    abort() was called at PC 0x400e47a4 on core 1

    ELF file SHA256: bc86d952445723b2

    Backtrace: 0x4008e8c0:0x3ffb4b30 0x4008ecb9:0x3ffb4b50 0x400e47a4:0x3ffb4b70 0x400d170d:0x3ffb4ba0 0x400d1873:0x3ffb4bc0 0x400d13ea:0x3ffb4bf0 0x400d194b:0x3ffb4c20 0x40088601:0x3ffb4c40
      #0  0x4008e8c0:0x3ffb4b30 in invoke_abort at .platformio\packages\framework-espidf@3.40001.200521\components\esp32/panic.c:155
      #1  0x4008ecb9:0x3ffb4b50 in abort at .platformio\packages\framework-espidf@3.40001.200521\components\esp32/panic.c:172
      #2  0x400e47a4:0x3ffb4b70 in __assert_func at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)
      #3  0x400d170d:0x3ffb4ba0 in Display_Write(int, unsigned short*) at src/Peripherals/Display/display.cpp:225 (discriminator 1)
      #4  0x400d1873:0x3ffb4bc0 in Display_Init() at src/Peripherals/Display/display.cpp:288
      #5  0x400d13ea:0x3ffb4bf0 in setup() at src/Application/application.cpp:21
      #6  0x400d194b:0x3ffb4c20 in applicationTask(void*) at src/main.cpp:41
      #7  0x40088601:0x3ffb4c40 in vPortTaskWrapper at .platformio\packages\framework-espidf@3.40001.200521\components\freertos/port.c:143

But the error doesn´t occur when I change the DMA channel from `0` to `1`:

    if((spi_bus_initialize(HSPI_HOST, &_BusCfg, 1) != ESP_OK) || (spi_bus_add_device(HSPI_HOST, &_DevDcfg, &_SPI) != ESP_OK))
    {
        return ESP_FAIL;
    }

What´s the difference between both channels and why is only channel `1` working?

title: ESP32: spi_master: check_trans_valid(801) when using SPI

Answers: 1

body:
Your code initializes the SPI bus by calling the `spi_bus_initialize(HSPI_HOST, &_BusCfg, 0)` function. The last argument of this function (`int dma_chan`) defines the DMA channel to use, which can be 0, 1 or 2.

Selecting DMA channel "0" will actually not select a DMA channel at all ([which is explained in the Espressif documentation](https://docs.espressif.com/projects/esp-idf/en/release-v3.0/api-reference/peripherals/spi_master.html#_CPPv418spi_bus_initialize17spi_host_device_tPK16spi_bus_config_ti)):

* **dma_chan**: Either channel 1 or 2, *or 0 in the case when no DMA is required*. Selecting a DMA channel for a SPI bus allows transfers on the bus to have sizes only limited by the amount of internal memory. *Selecting no DMA channel (by passing the value 0) limits the amount of bytes transfered to a maximum of 32.*

The reason you get an error when your ESP32 tries to do an SPI transfer when no DMA channel is selected (option 0), is that the transfer apparently is larger than 32 bytes.

The error produced is "*E (1833) spi_master: check_trans_valid(801): txdata transfer > host maximum*", which reflects that.

The reason DMA channel 1 works correctly, is because that is an actual DMA channel and it has no limit on the amount of bytes transferred (only limited by the amount of internal memory).


body:
The code I use probably has a math problem since an Arduino can only count a 16 bit integer. This problem is with the WeekDelay() function.
The project is for an Aerogarden. It pumps water into the garden every week from information based on my collected data. It writes on the LCD information like if it is pumping, waiting (it should have the timer here and display on the LCD), and it can show when it is going to pump with a beep warning. After beeping, pumping, and waiting for a few times I run out of information and do a loop and show a warning message, blinking the LCD and pumping a set amount.
More specifically WeekDelay() should be a delay for a week. It clears the LCD, Sets the cursor to 0,0 and prints "Waiting one week". It should then have a countdown of 24 hours on the screen and then just how many days it is waiting. It does that through clearing the LCD, Setting the cursor, printing days and waiting.

Because of the glitch it does not display any days even though it should show 7. It displays 04:09:36. Somebody was helping me out and said this:

*Ah, it is the integer math interacting with the size of days. 04:09:36 = 4*3600+9*60+36 = 14976 which happens to be equal to 7*24*3600 % 32768. See gammon.com.au/forum/?id=12146 and https://wiki.sei.cmu.edu/confluence/display/c/INT35-C.+Use+correct+integer+precisions for what's happening.*

This is some cut-down version of my code:
```
int beeper_pin      = 2; //Naming buzzer pin
int resetGarden_pin = 3; //Naming the warning led pin
int pump_pin        = 6; //Naming the pump pin

#include <LiquidCrystal_I2C.h> // Driver Library for the LCD Module

LiquidCrystal_I2C lcd(0x27, A4, A5);

void clearLCDLine(int line)
{
  lcd.setCursor(0, line);
  for (int n = 0; n < 20; n++) // 20 indicates symbols in line. For 2x16 LCD write - 16
  {
    lcd.print(" ");
  }
}

void beepWarning() {            //Makes beeping a subroutine

  lcd.setCursor(0, 0);
  lcd.print("WARNING");
  delay(100);
  lcd.setCursor(0, 1);
  for (int x = 0; x < 3; x++) {

    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE.");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE..");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE...");
    delay(100);
    clearLCDLine(1);
  }

  lcd.setCursor(0, 1);
  lcd.print("WATER PUMP ACTIVE...");

  for (int x = 0; x < 3; x++) {   //Repeats 3 times

    digitalWrite(beeper_pin, HIGH); //Turn on buzzer
    delay(100);                     //Delay of 400 milliseconds
    digitalWrite(beeper_pin, LOW);  //Turns off buzzer
    delay(100);                     //Delay of 400 milliseconds

  }
}

void SOSWarning() {            //Makes SOS a subroutine

  clearLCDLine(1);
  lcd.setCursor(0, 0);
  lcd.print("WPA Reset Aerogarden");

  for (int x = 0; x < 3; x++) {   //Repeats 3 times

    for (int d = 0; d < 3; d++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(200);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(200);                     //Delay of 400 milliseconds
    }

    for (int a = 0; a < 3; a++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(400);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(400);                     //Delay of 400 milliseconds
    }

    for (int d = 0; d < 3; d++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(200);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(200);                     //Delay of 400 milliseconds
    }

    delay(500);                     //Delay of 500 milliseconds
  }
}

void weekDelay() { //Makes waiting for a week a subroutine
  clearLCDLine(1);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting One Week");

  unsigned long start = millis();
  unsigned long week_secs = 7 * 24 * 3600;
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = week_secs - (millis() - start)/1000){
     char buff[80];
     int countdown_day = countdowntime_seconds / 3600 / 24;
     int countdown_hour = (countdowntime_seconds / 3600) % 24;
     int countdown_minute = ((countdowntime_seconds / 60) % 60);
     int countdown_sec = countdowntime_seconds % 60;
     sprintf(buff," days, d:d:d",
            countdown_day,
            countdown_hour,
            countdown_minute,
            countdown_sec
            );
     Serial.print(buff);
     clearLCDLine(1);
     lcd.setCursor(2, 1);
     lcd.print(buff);
     delay(1000);
     }
}

void pumpOn() {               //Makes turning on the pump a subroutine
  clearLCDLine(1);
  lcd.setCursor(0, 1);
  lcd.print("PUMPING");
  delay(100);
  digitalWrite(pump_pin, HIGH); //Turning on the pump
}

void pumpOff() {              //Makes turning off the pump a subroutine
  digitalWrite(pump_pin, LOW);  //Turning off the pump
  clearLCDLine(1);
  lcd.setCursor(0, 1);
  lcd.print("WATER PUMP OFF");
  delay(1000);
}

void setup() {
  //run once:
  lcd.backlight();
  lcd.init();

  lcd.setCursor(4, 0);//////////////////////////////////////////////////////
  lcd.print("HH:MM:SS"); //////////////////////////////////////////////////

  lcd.clear(); // Clear the screen
  lcd.setCursor(0, 0);
  lcd.print("Aero_Pump V3");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print("By Alex");
  delay(1000);
  pinMode (beeper_pin,      OUTPUT); //Setting outputs
  pinMode (resetGarden_pin, OUTPUT); //Setting outputs
  pinMode (pump_pin,       OUTPUT); //Setting outputs
  lcd.clear(); // Clear the screen

  digitalWrite(resetGarden_pin, LOW); //Turning off the reset garden light

  beepWarning(); //Beeps a warning
  pumpOn();      //Turns on the pump
  delay(3000);  //Adds a delay of 24000 milliseconds
  pumpOff();     //Turns off the pump
  weekDelay();   //Waits a week

  beepWarning(); //Beeps a warning
  pumpOn();      //Turns on the pump
  delay(12000);  //Adds a delay of 24000 milliseconds
  pumpOff();     //Turns off the pump
  weekDelay();   //Waits a week
}

void loop() {

  SOSWarning(); //Beeps an SOS warning
  pumpOn();      //Turns on the pump
  delay(48000);  //Adds a delay of 48000 milliseconds
  pumpOff();     //Turns off the pump

  for (int x = 0; x < 3024000; x++) {
    lcd.backlight(); // turn on backlight.
    delay(100);
    lcd.noBacklight(); // turn off backlight
    delay(100);
  }
  lcd.backlight(); // turn on backlight.
}
```

This is the function that needs to be fixed:

```
void weekDelay() { //Makes waiting for a week a subroutine
  clearLCDLine(1);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting One Week");

  unsigned long start = millis();
  unsigned long week_secs = 7 * 24 * 3600;
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = week_secs - (millis() - start)/1000){
     char buff[80];
     int countdown_day = countdowntime_seconds / 3600 / 24;
     int countdown_hour = (countdowntime_seconds / 3600) % 24;
     int countdown_minute = ((countdowntime_seconds / 60) % 60);
     int countdown_sec = countdowntime_seconds % 60;
     sprintf(buff," days, d:d:d",
            countdown_day,
            countdown_hour,
            countdown_minute,
            countdown_sec
            );
     Serial.print(buff);
     clearLCDLine(1);
     lcd.setCursor(2, 1);
     lcd.print(buff);
     delay(1000);
     }
}
```

title: I am trying to add a countdown to my Arduino code but it does 0 days, 04:09:36 instead of starting at 7 days

Answers: 1

body:
As the comment already tells, you are trying to calculate a constant with `int` literals that overflows:

`unsigned long week_secs = 7 * 24 * 3600;`

This is 604800 (0x93A80), but since `int`s are just signed 16 bits numbers (with your compiler system), only the lower 16 bits are taken into account. Fortunately these lower 16 bits are positive in two's complement, and so you get 14976 (hex 0x3A80).

The correct statement uses at least one `unsigned long` value, and the integer promotion rules make sure that all values are converted to that type, too.

`unsigned long week_secs = 7UL * 24 * 3600;`


body:
I'm trying to use a SD card with my ESP32 in order to save some variables in a txt file. Each variable uses 1 byte, so they can be represented by an 8 bit extended ASCII character.

The issue is it seems that the SD.h library has only 3 open modes (Read only, `FILE_WRITE`, `FILE_APPEND`), and I cannot figure out how to use random access for writing a specific byte of the file.

Imagine the situation: I have a file called `myFile.txt` which initially has a size of 5 bytes, and its content is:
```abcde```

The code I'm using is the following:

```c++
#include <SPI.h>
#include <SD.h>

#define SD_CS_PIN 5

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Initializing SD card...");

  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  myFile = SD.open("/myFile.txt", FILE_WRITE);
  myFile.seek(3);
  myFile.write('a');
  myFile.close();

}

void loop() {}
```

But after running the code, the file has an unexpected behaviour, its size changes from 5 bytes to 4 bytes, and its content is:
```abca```
instead of the expected
```abcae```

I know it happens because when writing into the file I'm using the open mode `FILE_WRITE` which uses the `FILE_APPEND` mode internally, so when doing `myFile.seek(3);`, I'm truncating the file to 4 bytes since the `FILE_APPEND` mode needs to point to the end of the file.

So, my question is, how can I open a file in random access mode with SD.h, or another library?

Thanks in advance!

title: Random access to SD card using SD.h or another library (ESP32)

Answers: 1

body:
**Solved!**

The solution was to migrate from the `SD` library to [`mySD`](https://github.com/nhatuan84/esp32-micro-sdcard), which seems to be a `SdFat` wrapper for ESP32.

You can see in the file [`mySD.h`](https://github.com/nhatuan84/esp32-micro-sdcard/blob/master/mySD.h#L30) that the `FILE_WRITE` mode is defined as:

```c++
#define FILE_WRITE (F_READ | F_WRITE | F_CREAT)
```

Which means that it allows random access to the file for writing (`F_WRITE` instead of `FILE_APPEND`).

**PS:** I want to remark @Juraj comment since the forum is mainly for Arduino board questions
> the SD library in ESP32 boards support package is different than the standard Arduino SD library


body:
I am trying to turn my incandescent bulb gradually,say its brightness should  go from zero to 100% in 10 mins. In doing so I found the following code and it works well but it's not as gradual as I want so  I hope to achieve my goal by modifying it. I thought I could change the delay in ```void loop()``` and that's it! but doing so makes no significant result.
``` #include  <TimerOne.h>          // Avaiable from http://www.arduino.cc/playground/Code/Timer1
volatile int i=0;               // Variable to use as a counter volatile as it is in an interrupt
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 9;                // Output to Opto Triac
int dim_level = 0;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int inc=1;                      // counting up or down, 1=up, -1=down

int freqStep =75;    // This is the delay-per-brightness step in microseconds.
                      // For 60 Hz it should be 65
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want.
//
// Realize that there are 2 zerocrossing per cycle. This means
// zero crossing happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply.

// To calculate freqStep divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps.
//
// (120 Hz=8333uS) / 128 brightness steps = 65 uS / brightness step
// (100Hz=10000uS) / 128 steps = 75uS/step

void setup() {                                      // Begin setup
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  attachInterrupt(0, zero_cross_detect, RISING);    // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  Timer1.initialize(freqStep);                      // Initialize TimerOne library for the freq we need
  Timer1.attachInterrupt(dim_check, freqStep);
  // Use the TimerOne Library to attach an interrupt
  // to the function we use to check to see if it is
  // the right time to fire the triac.  This function
  // will now run every freqStep in microseconds.
}

void zero_cross_detect() {
  zero_cross = true;               // set the boolean to true to tell our dimming function that a zero cross has occured
  i=0;
  digitalWrite(AC_pin, LOW);       // turn off TRIAC (and AC)
}

// Turn on the TRIAC at the appropriate time
void dim_check() {
  if(zero_cross == true) {
    if(i>=dim_level) {
      digitalWrite(AC_pin, HIGH); // turn on light
      i=0;  // reset time step counter
      zero_cross = false; //reset zero cross detection
    }
    else {
      i++; // increment time step counter
    }
  }
}

void loop() {
  dim_level+=inc;
  if((dim_level>=128) || (dim_level<=0))
    inc*=-1;
  delay(600);
}
```

**Edit 1**: Working on  [the first sketch suggested by Juraj][1], I put a light bulb as its load and because the `period` was initialized by `FADE_MIN` I expect the light should instantly glow in full brightness first and then gradually lose its brightness and so on, but it's not what happens and instead it takes some time to achieve its full brightness.

  [1]: https://arduino.stackexchange.com/questions/63631/fan-regulator-control-from-arduino/63674#63674

title: 220v lightbulb gradual dimmer

Answers: 0


body:
I'm learning how to use the Arduino HC-05 Bluetooth module. After pairing to it with my laptop I saw that I was getting two serial links, COM4 and COM5, as can be seen from the picture below.

On COM4 everything is working fine, but on COM5 nothing is happening. Can somebody explain why this is so?

NOTE: I only have one Bluetooth device (the HC-05).

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

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

title: HC-05 Bluetooth module; two serial ports, COM4 and COM5

Answers: 1

body:
I found [this answer in Microsoft Technet][1] helpful:

> - when connecting your terminal program to the first you are actually instructing Windows to attempt to establish the Bluetooth connection to the remote paired device, and if the connection is established the RFCOMM channel will be opened for the exchange of data
> - when connecting your terminal program to the second you are actually instructing Windows to load the SPP SDP record and to remain waiting for incoming connections from the remote paired device.

  [1]: https://social.technet.microsoft.com/Forums/en-US/58f690e5-1939-43c2-a2d3-245a527c678b/bluetooth-serial-port-settings-for-windows10-pc?forum=win10itprohardware


body:
I get this code output on my Serial when the IR receiver gets a signal:

``` cpp
Protocol  : GREE
Code      : 0x01C02350000000E0 (64 Bits)
Mesg Desc.: Model: 1 (YAW1F), Power: Off, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, Swing(V) Mode: Manual, Swing(V): 0 (Last), Swing(H): 0 (Off), Timer: 23:00, Display Temp: 0 (Off)
uint16_t rawData[279] = {...
````

When I convert `0x01C02350000000E0` to binary, however, it usually comes out to less than 64 bits. I'm assuming it has to do with the parameters of my IR receiver and not normal.

title: When using the IRremote library- why does it say 64 bits when after converting the hex to binary it comes out to be less?

Answers: 1

body:
You are confusing the data size and the value size.

Yes, your value can be represented using fewer than 64 bits, but the data size that is used to contain that value is 64 bits in size.

It's like saying that "4" is stored in a 6 digit storage space.  It only needs 1 storage slot, but the allocated space is 6 digits. So what is actually stored would be "000004".

As humans we tend to throw away the leading zeroes because they are meaningless. That's because we are able to use flexible storage sizes in our brains. The computer, though, works on fixed sizes - 8 bit, 16 bit, 32 bit, 64 bit, etc.

You can't store that value in a 32 bit variable, but you can in a 64 bit one. It may be wasteful for that specific value, but it's the smallest size that is available that is big enough.


body:
I am new to the world of Arduino and need a little bit of help. I have an Arduino Uno and I am trying to supply 5V to an actuator using the digital pins. It is my understanding that the board I have is capable of doing that. But I can't seem to get 5V from my digital pins.

I would really prefer to not have to use the 5V power pin because I need to supply multiple sources with 5V in an alternating pattern, which I know I can do with the digital pins.

Could I use the analog pins to help with this? Could I supply more power using a battery? Etc.

Thank you in advance.

title: Digital Pins Question

Answers: 2

body:
The digital pins of the Arduino are rated to reliably deliver up to
20 mA. Their _absolute maximum rating_ is 40 mA. Anything
above that risks destroying the microcontroller.

If your device is supposed to pull from 0.24 to 0.38 A, that is too
much for your Arduino pins. With such a high current, you are seeing a
significant voltage drop caused by the internal resistance of the output
transistors. Or it could be that you already fried those transistors.

body:
The most common solution is to use the digital output to turn on a MOSFET that supplies separate power to a high-current device that needs more current than the 20 mA that an ATmega328 microcontroller can safely supply.

The MOSFET is chosen based on the desired current and with the need for a logic-level input.

A typical circuit:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/nhBoy.png)

<!-- End schematic -->

D1 is needed for an inductive load like a motor. It protects other components.

You might get away without using the resistors (connecting D1 directly to the MOSFET's gate) but the 10 K "pull-down" resistor R1 ensures that the load is off when the Arduino is powering up. Resistor R2 is probably mainly useful for noisy or high-frequency applications..


body:
I'm writing code so that, every time a hall monitor senses, my code additively measures 5 liters of volume as it prints each detection. Then, this data is sent via Bluetooth to a phone. (This is for a tipping bucket device that distributes 5 liters of water every time it tips). However, my code keeps the volume measurement at 0.00 no matter how many times the hall effect is sensed, and I also can't figure out where to insert my delay statement so it does not double count the tips. Any suggestions?

```c++
int hall_pin = 2;

// set number of hall trips for RPM reading (higher improves accuracy)
float hall_thresh = 1000000000.0;

// BLE Battery Service
BLEService Vol_valServ("180F");

// BLE Battery Level Characteristic
BLEUnsignedCharCharacteristic VolumeChar("2A19",  // standard 16-bit characteristic UUID
        BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

long previousMillis = 0;  // last time the volume level was checked, in ms

void setup() {
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);

    while (!Serial);

    pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected

    // begin initialization
    if (!BLE.begin()) {
        Serial.println("starting BLE failed!");
        while (1);
    }

    /* Set a local name for the BLE device
       This name will appear in advertising packets
       and can be used by remote devices to identify this BLE device
       The name can be changed but maybe be truncated based on space left in advertisement packet
    */
    BLE.setLocalName("VolumeMonitor");
    BLE.setAdvertisedService(Vol_valServ); // add the service UUID
    Vol_valServ.addCharacteristic(VolumeChar); // add the battery level characteristic
    BLE.addService(Vol_valServ); // Add the battery service

    /* Start advertising BLE.  It will start continuously transmitting BLE
       advertising packets and will be visible to remote BLE central devices
       until it receives a new connection */

    // start advertising
    BLE.advertise();

    Serial.println("Bluetooth device active, waiting for connections...");
}

// the loop routine runs over and over again forever:
void loop() {
    // preallocate values for tach
    float hall_count = 1.0;
    float start = micros();
    bool on_state = false;

    // counting number of times the hall sensor is tripped
    // but without double counting during the same trip
    while (true) {
        if (digitalRead(hall_pin) == 0) {
            if (on_state == false) {
                on_state = true;
                hall_count += 1.0;
            }
        } else {
            on_state = false;
            float Volume = (hall_count - 1) * 5.0; // this is the liters per tip
            Serial.print(Volume);
            Serial.println(" Volume");

            // wait for a BLE central
            BLEDevice central = BLE.central();

            // if a central is connected to the peripheral:
            if (central) {
                Serial.print("Connected to central: ");
                // print the central's BT address:
                Serial.println(central.address());
                // turn on the LED to indicate the connection:
                digitalWrite(LED_BUILTIN, HIGH);

                while (central.connected()) {
                    long currentMillis = millis();
                    if (currentMillis - previousMillis >= 200) {
                        previousMillis = currentMillis;
                        Serial.print("Volume is now: ");
                        Serial.println(Volume);;
                    }
                }
                digitalWrite(LED_BUILTIN, LOW);
                Serial.print("Disconnected from central: ");
                Serial.println(central.address());
            }
            if (hall_count >= hall_thresh) {
                break;
            }

            // print information about Time and RPM
            float end_time = micros();
            float time_passed = ((end_time - start) / 1000000.0);
            Serial.print("Time Passed: ");
            Serial.print(time_passed);
            Serial.println("s");

            delay(10000);
            // delay in between reads for stability
        }
    }
}
```

title: How to input delay and increase volume measurements with hall sensor detection

Answers: 0


body:
I'm writing code so that, every time a hall monitor senses, my code additively measures 5 liters of volume as it prints each detection. Then, this data is sent via Bluetooth to a phone. (This is for a tipping bucket device that distributes 5 liters of water every time it tips). I am using the LightBlue app for the bluetooth connection. My code connects to the bluetooth app, but the LightBlue log does not show what's being printed on my serial monitor. Does anyone have any suggestions?

        // https://makersportal.com/blog/2018/10/3/arduino-tachometer-using-a-hall-effect-sensor-to-measure-rotations-from-a-fan
    #include <ArduinoBLE.h>
    // digital pin 2 is the hall pin

    int hall_pin = 2;

    // set number of hall trips for RPM reading (higher improves accuracy)

    float hall_thresh = 1000000000.0;

    // BLE Battery Service
            BLEService Vol_valServ("180F");

            // BLE Battery Level Characteristic
            BLEUnsignedCharCharacteristic VolumeChar("2A19",  // standard 16-bit characteristic UUID
                BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

            long previousMillis = 0;  // last time the volume level was checked, in ms
    void setup() {

      // initialize serial communication at 9600 bits per second:

      Serial.begin(9600);

       while (!Serial);

              pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected

              // begin initialization
              if (!BLE.begin()) {
                Serial.println("starting BLE failed!");

                while (1);
              }

              /* Set a local name for the BLE device
                 This name will appear in advertising packets
                 and can be used by remote devices to identify this BLE device
                 The name can be changed but maybe be truncated based on space left in advertisement packet
              */
              BLE.setLocalName("VolumeMonitor");
              BLE.setAdvertisedService(Vol_valServ); // add the service UUID
              Vol_valServ.addCharacteristic(VolumeChar); // add the battery level characteristic
              BLE.addService(Vol_valServ); // Add the battery service

              /* Start advertising BLE.  It will start continuously transmitting BLE
                 advertising packets and will be visible to remote BLE central devices
                 until it receives a new connection */

              // start advertising
              BLE.advertise();

              Serial.println("Bluetooth device active, waiting for connections...");

    }

    // the loop routine runs over and over again forever:

    void loop() {

      // preallocate values for tach

      float hall_count = 0.0;

      float start = micros();

      bool on_state = false;

      // counting number of times the hall sensor is tripped

      // but without double counting during the same trip

      while (true) {

        if (digitalRead(hall_pin) == 0) {

          if (on_state == false) {

            on_state = true;

            hall_count += 1.0;

          }

        } else {

          on_state = false;
          float Volume = (hall_count) * 5.0; // this is the liters per tip

          Serial.print( "hall_count");
          Serial.print( hall_count);
          Serial.println(" Volume");
          Serial.print(Volume);

            // wait for a BLE central
            BLEDevice central = BLE.central();

            // if a central is connected to the peripheral:
            if (central) {
              Serial.print("Connected to central: ");
              // print the central's BT address:
              Serial.println(central.address());
              // turn on the LED to indicate the connection:
              digitalWrite(LED_BUILTIN, HIGH);

              while (central.connected()) {

    if (digitalRead(hall_pin)==0){

    if (on_state==false){

    on_state = true;

    hall_count+=1.0;

    }

    } else{

    on_state = false;
    float Volume = (hall_count)*5.0; // this is the liters per tip

    Serial.println( Volume);

    Serial.println("Volume");
    VolumeChar.writeValue(Volume);

    delay(2000);
            // delay in between reads for stability

                }
              }

              digitalWrite(LED_BUILTIN, LOW);
              Serial.print("Disconnected from central: ");
              Serial.println(central.address());

              }

              if (hall_count >= hall_thresh) {

                break;

              }

            // print information about Time and RPM

            float end_time = micros();

            float time_passed = ((end_time - start) / 1000000.0);

            Serial.print("Time Passed: ");

            Serial.print(time_passed);

            Serial.println("s");

    delay(2000);
            // delay in between reads for stability
          }
        }
      }

title: LightBlue to Arduino connection log does not display serial monitor printed data

Answers: 0


body:
I'm facing a lot of issues with Arduino Nano BLE Sense.
I'm aware about the port switching between bootloader (when the yellow LED pulses) and application.

**First issue**
Sometime when I power up the board (i.e. pluggin in the USB cable or turn on the PC) it starts in bootloader mode, even if there's a working sketch inside.
This is very bad, because I didn't find a way to recover from this situation without pressing the reset button, and of course this is not doable in a real environment.

**Second issue**
Even when it starts the application and I can successfully open the serial port, it does not receive or send any data. To recover, again, I need to press the reset button. The sketch is very simple and I also tried with default examples. Anyway, here how I open the serial port i Arduino:

    void setup()
    {
      Serial.begin(115200);
      while (!Serial);
      Serial.setTimeout(10);
      Serial.flush();
    }

Please note, that once it starts in the correct way it works without any problem!

Questions:

1. is there a way to software reset the board to force the application to start when in bootloader mode? I tried with `ard-reset-arduino.py --caterina /dev/ttyACM1` with no luck (i.e. it remains in bootloader mode).

2. do you have any suggestion how to avoid the serial issues I'm facing? I tried with several Arduino boards (I have 10 on my desk) and 3 different PCs.

title: Arduino Nano 33 BLE Sense starts in bootloader mode on power up

Answers: 0


body:
This sketch only displays about nine images (when there are more). Does this mean the ESP32 is limited amount of Base64 images able to be displayed?

    #include <WiFi.h>
    #include <WebServer.h>

    const char* ssid = "ESP32";
    const char* password = "12345678";

    IPAddress local_ip(192,168,1,1);
    IPAddress gateway(192,168,1,1);
    IPAddress subnet(255,255,255,0);

    WebServer server(80);

    // Used for determining the selected pattern and HTML to display:
    int pattern = 0;
    int selectedPattern = 0;

    String circleString = "<img src=\"data:image/png;base64,[encoded data, 6912 characters]\" alt=\"NAME\" style=\"width:100%\">\n";

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

      WiFi.softAP(ssid, password);
      WiFi.softAPConfig(local_ip, gateway, subnet);
      delay(100);

      server.on("/", handle_OnConnect);
      server.onNotFound(handle_NotFound);

      server.begin();
      Serial.println("HTTP server started");
    }
    void loop()
    {
      server.handleClient();

    }

    void handle_OnConnect() {

      server.send(200, "text/html", SendHTML(selectedPattern));
    }

    void handle_NotFound(){
      server.send(404, "text/plain", "Not found");
    }

    String SendHTML(int pattern)
    {
        String ptr = "<!DOCTYPE html> \n";
        // Instance of class String (not a pointer)

        ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
        // <meta> viewport element makes the web page responsive in any web browser
        // https://www.w3schools.com/css/css_rwd_viewport.asp

        ptr += "\n";

        ptr +="\n";
        ptr +="\n";

          /*  */
          ptr += "
\n"; // 1
            ptr += circleString;
          ptr += "
\n";

          ptr +="1\n";

          ptr += "
\n"; // 2
            ptr += circleString;
          ptr += "
\n";

          ptr +="2\n";

          ptr += "
\n"; // 3
            ptr += circleString;
          ptr += "
\n";

          ptr +="3\n";

          ptr += "
\n"; // 4
            ptr += circleString;
          ptr += "
\n";

          ptr +="4\n";

          ptr += "
\n"; // 5
            ptr += circleString;
          ptr += "
\n";

          ptr +="5\n";

          ptr += "
\n"; // 6
            ptr += circleString;
          ptr += "
\n";

          ptr +="6\n";

          ptr += "
\n"; // 7
            ptr += circleString;
          ptr += "
\n";

          ptr +="7\n";

          ptr += "
\n"; // 8
            ptr += circleString;
          ptr += "
\n";

          ptr +="8\n";

          ptr += "
\n"; // 9
            ptr += circleString;
          ptr += "
\n";

          ptr +="9\n";

          ptr += "
\n"; // 10
            ptr += circleString;
          ptr += "
\n";

          ptr += "
\n"; // 11
            ptr += circleString;
          ptr += "
\n";

          ptr += "
\n"; // 12
            ptr += circleString;
          ptr += "
\n";

          ptr += "
\n"; // 13
            ptr += circleString;
          ptr += "
\n";

        ptr +="\n";
        ptr +="\n";

        return ptr;

    }

>Sketch uses 726230 bytes (55%) of program storage space. Maximum is 1310720 bytes.
>Global variables use 39384 bytes (12%) of dynamic memory, leaving 288296 bytes for local variables. Maximum is 327680 bytes.

title: Is an ESP32 HTTP web server limited to a certain number of Base64 images?

Answers: 1

body:
You build up the HTML website by concatting strings together by hand in the code. I know this is done in many code throughout the internet, but this is only really practical, if you need to change the website content with every request. Normally it is better to use SPIFFS (or now LittleFS) to store the files and let a fitting webserver library serve them as static files. Additionally you are making Swiss cheese out of your heap memory when you concat `String` variables this often and you might run out of RAM.

I'm not used to LittleFS, so I will write this answer using SPIFFS. But I'm sure you can use LittleFS in a very similar way. I will leave it to you to determine how it fits in with code for SPIFFS.

Have a look at the [ESPAsyncWebServer][1] library and its simple server example. I've used this library for my projects. Try the examples, read the documentation and get an idea how this library is working.

Then have a look at the documentation where it says "Serving static files". I think you want to serve your static files from a directory. That way the library will look for requested files in that complete directory inside of the SPIFFS. Inside that directory you will have your HTML website (named as `index.html`) and all the images as binary data in a format, that a webbrowser can read (like jpg, png, ...). In your HTML website you reference the images with their path. Since in this scenario they all lie in the root directory the path is only the filename (+ the files extension).

When the webbrowser requests the `index.html` from the ESP, the library will serve it from SPIFFS. The webbrowser interprets the site and sees the references to the images. It than tries to load these images, meaning it sends requests to the ESP with the path of the images. The library will search for these files in SPIFFS, will find them and serve them to the webbrowser, who will then display them on the website.

Something like this:

    #include "ESPAsyncWebServer.h"
    #include "SPIFFS.h"

    AsyncWebServer server(80);

    void setup(){
      Serial.begin(115200);
      while(!SPIFFS.begin()){
        Serial.println("Could not mount SPIFFS");
        delay(500);
      }
      server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
      server.begin();
    }

    void loop(){
    }

Note:
- I've left out all Wifi related stuff. You need to add that yourself.
- I've not tested this code, just put it together from one of my working bigger programs.
- You still need to upload the actual files to the ESP SPIFFS. There are many tutorials on how to do that. Just place your files in the root directory of SPIFFS.

  [1]: https://github.com/me-no-dev/ESPAsyncWebServer


body:
I'm trying to build a GUI that sends the data from processing to arduino via serial. With the help of a couple of guys on here, I have come up with a basic framework that sends a variable ID, variable value and termination character (\n). So far so good!

However, the [arduino reference][1] advises to only use `char` for storing characters. How would I send a `byte` or `int` over serial, while still being able to use a termination character to ensure everything is working as expected?

**edit:**
Using the arduino code from Edgar's answer below and the following processing code, I get the "could not parse value" error.

    import processing.serial.*;

    SerialConnection serialConnection;

    boolean data_processed = false;
    char[] var_array = new char[31];
    char var_id;
    char var_val;
    char space = ' ';
    char termchar = '\n';

    void setup() {
      serialConnection = new SerialConnection(this, 9600);
    }

    void draw() {
      serialConnection.startSerialCommunication();

      if (serialConnection.isReady) {
        var_id = 'a';
        var_val = 127;
        serialConnection.serialPort.write(var_id);
        serialConnection.serialPort.write(space);
        serialConnection.serialPort.write(var_val);
        serialConnection.serialPort.write(termchar);

        delay(50);
        while (serialConnection.serialPort.available() > 0) {
          for (int i = 0; i < 30; i++) {
            char inchar = serialConnection.serialPort.readChar();
            var_array[i] = inchar;
            print(var_array[i]);
          }
        }
      }
    }

title: How to send non char variables over serial

Answers: 1

body:
If you want to send numeric values to your Arduino, the simplest option
is to send them formatted as ASCII text. Thus you end up simply sending
characters.

Let's assume for example a simple text-based protocol of the form

```text
foo 42
bar 5678
baz -12
```

Each message is made of a variable name followed by its numeric value.
The name and the value a separated by a space. Each message is
terminated by a line feed (`'\n'`).

In order to parse a message, you first have to split it at the space
character. The [`strsep()`][strsep] function comes handy for this. Then,
you have to parse the second part of the message (the value) as an
integer. I would use [`strtol()`][strtol] for this job. Putting all
together:

```c++
void process(char *message) {
    char *name = strsep(&message, " ");  // split at the space
    if (!message) {
        Serial.println("Error: no value given");
        return;
    }
    char *endp;  // end of the numeric value
    long value = strtol(message, &endp, 0);
    if (endp == message) {
        Serial.println("Error: could not parse value");
        return;
    }
    /* Successfully parsed. */
    Serial.print(name);
    Serial.print(" received value ");
    Serial.println(value);
}
```

Note there are some sanity checks in order to make sure the message does
match the expected format. Obviously, you have to replace the last three
lines by something more meaningful to your application.

Example sketch using this:

```c++
void setup() {
    Serial.begin(9600);
}

void loop() {
    static char buffer[40];
    static size_t buffer_pos = 0;
    while (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {  // end of message
            buffer[buffer_pos] = '\0';  // terminate the string
            process(buffer);
            buffer_pos = 0;  // reset for next message
        } else if (buffer_pos < sizeof buffer - 1) {
            buffer[buffer_pos++] = c;  // buffer the character
        }
    }
}
```

[strsep]: https://man7.org/linux/man-pages/man3/strsep.3.html
[strtol]: https://man7.org/linux/man-pages/man3/strtol.3.html


body:
I'm new to electronics but I have a Rigol DS1054Z oscilloscope and I'm experimenting to help learn.  I've created an incredibly simple sketch using an ESP32 and Arduino IDE:

    void setup() {
      pinMode(32, OUTPUT);
    }

    void loop() {
      delayMicroseconds(10);
      digitalWrite(32, LOW);
      delayMicroseconds(10);
      digitalWrite(32, HIGH);
    }

However, the square wave is incredibly "shaky" or unstable looking.  Why is that?

[![oscilloscope ][1]][1]

  [1]: https://i.stack.imgur.com/hrobV.gif

title: Why does oscilloscope trigger look shaky when using delayMicroseconds?

Answers: 3

body:
This isn't an answer, but you could compare it to hardware PWM to test the limits of the rest of the system.

### Simple ESP32 PWM per https://www.electronicshub.org/esp32-pwm-tutorial/

    int freq = 48000;
    int ledChannel = 0;
    int resolution = 8;  // 48000*2^8 < 80Mhz on channel 0 per https://www.electronicshub.org/esp32-pwm-tutorial/

    void setup() {

      ledcSetup(ledChannel, freq, resolution);
      ledcAttachPin(32, ledChannel);
      ledcWrite(ledChannel, 127);
    }

    void loop() {
    }

body: Jitter like that is usually caused by the different amount of time it takes to go through loop(). Remember that the tick timer takes time away from loop() at an interval that is not synchronized to the loop() time.

body: The display moving is what we call jitter. It is normal with the Arduino  and expected. The pulses are not even because of the background tasks such as the interrupt service routine (that does the millies etc whether you use them or not). When an interrupt occurs it causes the processor to stop, save its state, do a new task, then restore its state and continue. During the interrupt service routine (ISR) the processor uses time to execute instructions, this delay causes the jittering. Trust your scope, as usual it is correct. If you use one of the timer outputs the jitter will go away because they are not normally adjusted the just keep going. PWM is one of the more common modes of doing this but there are many others you can also use.


body:
I'm a beginner in Arduino and recently i got myself an Ultrasonic sensor (HC-SR04).

I looked up tutorials on how to measure distance with the sensor and the code I'm using is:

    const int trigPin = 8;
    const int echoPin = 7;

    long duration;
    int distance;

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

    void loop() {
      // put your main code here, to run repeatedly:
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2); //why do we delay 2 microseconds

      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10); //why do we delay 10 microseconds
      digitalWrite(trigPin, LOW);

      duration = pulseIn(echoPin, HIGH);
      distance = duration*0.034/2;
      Serial.print("Distance: ");
      Serial.println(distance);
    }

I would like to know why do we add delays in the loop function? Appreciate if anyone could explain it.

title: Why do we add delay when using ultrasonic sensors?

Answers: 1

body:
We need to provide the HC-SR04 with a fitting trigger signal. When you read the [datasheet of the HC-SR04][1] you will see that it needs a 10us trigger pulse.

The first delay of 2us is to make sure we are at an established LOW level on the trigger pin, since the pin might have been HIGH before that. We are delaying here to make sure, that the HC-SR04 actually registered the level as LOW, even if it was HIGH before. If we would change from HIGH to LOW and back to HIGH as fast as we can, then the HC-SR04 might not have enough time to actually see the pin going low. Its mostly a measure to ensure the code working correctly here.

The second delay is for the actual trigger pulse. The datasheet specifies it as 10us length, so that is what we delay here. After that we go back to LOW to end the trigger pulse and wait for the echo pulse to come.

You might have read that it is bad to use delays in your code, since they are blocking. That is correct in principle, but normally really short delays in the microsecond range don't really matter for the program flow. Just be away to keep the total delay time in your code low enough to not miss any important events (like button presses).

  [1]: https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf


body:
I'm writing a MIDI - to square wave converter designed to interface between a MIDI instrument and a musical Tesla coil. Essentially, this should act like a monophonic MIDI synthesiser, but the requirements are slightly different to most projects:

 - I only want to generate (audible frequency) square waves.
 - It is *essential* that the pulse on time not exceed a configurable constant value, e.g. 160 microseconds.
 - I'd like to map the 'velocity' of a given note to the duty cycle, scaled appropriately.
 - Ideally, I'd like to generate envelopes for the pulse width with configurable attack, decay, sustain, release parameters.
 - I'd like to write the audio generation code "from scratch" for the sake of my own understanding of how timing registers work.

The gist of what I want is this (untested) sketch, but it obviously doesn't allow for control of the on time.

    #include <MIDI.h>

    MIDI_CREATE_DEFAULT_INSTANCE();
    const static int out_pin = 9;

    void handleNoteOn(byte channel, byte pitch, byte velocity)
    {
        tone(out_pin, pitch);
        digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    }

    void handleNoteOff(byte channel, byte pitch, byte velocity)
    {
        noTone(out_pin);
        digitalWrite(13, LOW);   // turn the LED off
    }

    void setup() {
      MIDI.setHandleNoteOn(handleNoteOn);
      MIDI.setHandleNoteOff(handleNoteOff);

      MIDI.begin(MIDI_CHANNEL_OMNI);
    }

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

My question is essentially, what the best way to achieve this kind of musical pulse-width control is. The ideas I had were either
a) A large number of manual register-sets to bit-bang the required signal out at the highest frequency I can get, probably in the kHz
b) Create each pulse using a custom pulseOut function, using timer0 for microsecond delays

I'd also be open to using external analog circuitry, e.g. a voltage controlled pulse shortener.

The load here is an LED, so no special allowances need to be made for its behavior.

title: Modify duty cycle of tone on AVR

Answers: 1

body:
I would recommend using a hardware PWM signal generated by Timer 1, or
another 16-bit timer if you have more than one (like on the Mega). The
16 bits provide both a decent frequency range and a good time
resolution. This should provide jitter-free timings, unlike any
software-based method. This will also avoid unduly loading the CPU.

The first thing to do would be to choose the prescaler and the operating
mode. These choices will impact both the lowest available frequency and
the time resolution. The latter affects the accuracy of the
highest-pitched notes. Assuming your Arduino is clocked at 16 MHz,
some sensible choices are:

* prescaler = 64, normal PWM
* prescaler = 8, phase correct PWM
* prescaler = 8, normal PWM

|prescaler|PWM mode|time resolution|lowest freq.|lowest note  |
|----------|----------|-----------|-----------|---------------|
|    64    | normal   |   4 µs    |  3.81 Hz  |  C−1 (MIDI 0) |
|   8 | phase correct |   1 µs    | 15.26 Hz  |  B0 (MIDI 11) |
|     8    | normal   | 0.5 µs    | 30.52 Hz  |  B1 (MIDI 23) |

For the sake of having accurate notes, I would go for the lowest time
resolution that is compatible with the music you want to play.

Once this is configured, you can control the music by writing to three
registers:

* TCCR1A turns the PWM on and off
* the register holding TOP (OCR1A or ICR1, depending on the mode)
  controls the frequency (the pitch)
* a compare match register (OCR1A or OCR1B, depending on the channel)
  controls the duration of the pulses

Your program would then need to set the frequency as a function of the
requested note, then continuously adjust the pulse duration in order to
create the desired envelope while obeying the requested velocity and
ensuring the value of 160 µs is never exceeded.

The main code does not even need to be synchronized with the timer: the
PWM modes guarantee glitch-free PWM even when you change the duty cycle.
Be careful though when changing the frequency: you may get huge glitches
when increasing the frequency. It is safer to stop, clear and restart
the timer when changing notes.


body:
I am using Grove - Mech Keycap as a counter but if I continue pressing the keycap the counter continues to run. Any idea how to program it to increase counter by one only after releasing and pressing again?

    #define BUTTON_PIN   8

    bool oldState = LOW;
    long timecheck;
    int i = 1;

    void setup() {
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      Serial.begin(9600);
    }

    void loop()
    {

      // Get current button state.
      bool newState = digitalRead(BUTTON_PIN);

      // Check if state changed from low to high (button press).
      if (newState == HIGH && oldState == LOW) {
        timecheck = millis();
        // Short delay to debounce button.
        delay(200);
        // Check if button is still low after debounce.
        newState = digitalRead(BUTTON_PIN);

        if (newState == HIGH) {
          Serial.println("HIGH");
          Serial.println(i);
          i = i + 1;
        }
      }
    }

title: Grove - Mech Keycap counter

Answers: 0


body:
I have two identical (but with different software) Arduinos connected to Linux box. Their serals are identical

    # udevadm info -a -n /dev/ttyUSB1 | grep '{serial}'
        ATTRS{serial}=="0000:00:1d.0"

    # udevadm info -a -n /dev/ttyUSB0 | grep '{serial}'
        ATTRS{serial}=="0000:00:1d.0"

Can I make these Arduinos to differ somehow programmatically?

title: How to distinguish identical Arduinos from Linux?

Answers: 1

body:
You can't change the USB information programmatically. The fact that you're referencing `/dev/ttyUSB*` means you have hardware USB interface chips (CH340, PL2302, FT232, etc) which you can't change from your sketch (some can be adjusted using tools provided by the chip manufacturer though, so you may be able to tweak it using that).

Instead your only option is to have some kind of "fingerprint" that software on your computer can request from your firmware. If you stick to a common serial protocol for all your firmwares you can implement a standard "Firmware Version" command which will respond with what code and version you have installed.

It's up to you to decide how best to implement such a system, of course.


body:
***Edit, this question has been answered in the comments by chrisl, and also after retesting the code with delay() which showed I forgot to update my lastupdate variable(eerst), I have answered it in the comments and chrisl possibly also will post their findings in a answer***
*TLDR- 28BYJ-48 unipolar 5v not working only whining. run using transistors and code in the bottom of the post. transistors connected to 5V and resistors ranging from 100ohm to 1000ohm tried from Arduino to the transistors Trigger/Gate. - END TLDR*

More Detailed
I have some 5v and 12v 28BYJ-48 unipolar stepper motors,(I only connect one to the Arduino at a time) the common(tested with resistance meter) is connected to +, and I the other pins are connected to one BC336 transistor per pin so 4 in total. these transistors should handle 0.8A a piece and I measured the maximum amperage used by the coils to be 0.2+-0.02A for the 5v version at 5v, and 0.045 +- 0.001A for the 12v version at 5v. it makes sense if the 12v version doesn't work at 5v, I just wanted to test it to have an ultra-low-power stepper motor. however the 5v version should work, My setup allows a higher voltage drop in the coils in the motor and can handle a higher amperage than a normal driver however this is limited by the motors resistance ofcource.
I drive it according to the steps in the datasheet with the standard method. and simplified my code to leave out all extra things and even hardcoding the values but still it only whiles and doesn't run the motor. I use the Arduino 5v to run the stepper motor but according to the datasheet and my measurements, you could drive more than one stepper motor on the 5v pin, even when running from USB power. I also set it really slow so that it should work(based on datasheet). I want to get this working like this because I am working on a custom budget stepper driver for Arduino which allows much simpler control, and which is much cheaper than the current drivers as well as that it by default can run higher voltage stepper motors as well, and one very specific functionality which almost everyone who has ever used one stepper motor or more has hoped that their stepper motor driver had.

I used pin 8 9 10 and 11
**Broken Code:**

    unsigned long eerst=0;
    unsigned long nu=0;
    int state=0;
    byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//made hardcoderd aray to make sure fault wasn't in the cyclic bitshifting

    void setup() {
      //0b76543210 portD <-- direction right is low num left is high num, keep confusing this since it differs on some platforms and not having used arduino for a while
      DDRB=DDRB | 0b00001111;//only set 8,9,10, 11 as output do not change resst.
      PORTB=0b00000000;//simplified from only turning of 8,9,10,11 to turning of all of portb
      delay(1000);
      eerst=millis();
    }

    void loop()
    {
      nu=millis();
      if(nu-20>=eerst)
      {
//forgot to update here
        PORTB=vals[state];
        state++;
        if(state>7)//resets state
          {
            state=0;
          }
      }
    }

**Working Code (might be changed for the long overflow stabilizing), changed variable names to make it clearer for others to read:**

    unsigned long TimeOfLastStep=0;
    unsigned long CurrentTime=0;
    int step=0;
    byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//made hardcoderd aray to make sure fault wasn't in the cyclic bitshifting

    void setup() {
      DDRB=DDRB | 0b00001111;//only set 8,9,10, 11 as output do not change resst.
      PORTB=0b00000000;
      CurrentTime=millis();
    }

    void loop()
    {
      CurrentTime=millis();
      if(CurrentTime-2>=TimeOfLastStep)//increased speed from 20ms delay to 2 ms
      {
        TimeOfLastStep=CurrentTime;//forgot this
        PORTB=vals[state];
        state++;
        if(state>7)//resets state
          {
            state=0;
          }
      }
    }

title: arduino 28BYJ-48 stepper only whining, not rotating

Answers: 1

body:
I found the problem(s) in my design, everything was right but I forgot to add eerst=nu;(first=now;, used a different language because now is used by the arduino ide).
Also I didn't read the datasheet properly and so assume 100step/revolution causing me to use delays which where to large, and so even if it worked the movement would be super slow and possibly missed.

New working code:

    unsigned long eerst=0;
    unsigned long nu=0;
    int state=0;
    byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//made hardcoderd aray to make sure fault wasn't in the cyclic bitshifting.
    //in PortB you have the pins 8,9,10,11,12,13. you start at the back of the byte, so if 0b00000001 then only pin 8 is on. if 0b00000010, then only pin 9 is on, if 0b00000011 then pin 8 and 9 are on. PortB has 8 bits, but only 6 settable pins, so do not change the first 2 bits. you can do it more secure this should be done when using port D since that one is connected to serial. however for simplicity I did not add that code here, you can ask for it and I will probably respond with it.

    void setup() { since it differs on some platforms and not having used arduino for a while
      DDRB=DDRB | 0b00001111;//only set 8,9,10, 11 as output do not change resst.
      PORTB=0b00000000; // disabling all port B outputs
      eerst=millis();//eerstm means first, set first to milis to have delay without pausing the code.
    }

    void loop()
    {
      nu=millis();//nu is now, store this lets the code know for how long the arduino ran in milliseconds, needed for non blocking delay, only one now/nu is needed.
      if(nu-2>=eerst)// if 2 milliseconds have passed(have been waited), execute the following code.
      {
        eerst=nu;//reset the non blocking delay timer
        PORTB=vals[state];//Hardcoded values in the array above, this turns on and off pins and is much faster than digital write, selects item at number [state] of aray.
        state++;//go to next state/step
        if(state>7)//resets state
          {
            state=0;//resets state/back to state 0(1 of 8)
          }
      }
    }

edit: solution was also referenced to in the comments below the post. it was really a problem about having it in mind but forgetting to type something down. anyway I will probably soon start to test with that custom driver don't know how to publish it, but will probably link it back here if I remember it. will be open source probably if I find the proper methods.


body: I have recently bought an arduino uno R3 (the type where the atmega328 is surface mount and not removable on a mainly blue PCB); the board has two crystals on it one for the clock for the USB serial and the other for the atmega328 clock. Suppose I have built a fully completed circuit using the arduino (this means the arduino needs not to be further connected to a PC).  Will my arduino uno based circuit still work if I  simply replace (desolder) the 16Mhz (for the atmega328)  crystal with a 12Mhz crystal (soldered in its place)? The circuit doesn't use the serial ports or the the crystal for USB serial. Actually the circuit is simply the blink LED example built into the IDE.  I am guessing it will still work but blink slower-but I don't know the answer for sure.

title: Will the arduino uno still work if I replace the onboard 16Mhz crystal with a 12Mhz crystal?

Answers: 2

body:
Assembling an answer from the comments. Ever-terse *@jsotola* points the OP to page two of the [data sheet][1] which *@Dave X* summarizes as saying that yes, the chip will operate at 0 to 16 MHz. There is a caveat though, [discussions][2] on the Arduino forum suggest that the reduction in clock speed proposed by OP might interfere with the boot loader. The same discussion provides guidance for compiling for lower speed operation.

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
  [2]: https://forum.arduino.cc/t/arduino-with-internal-oscillator-on-1mhz/24547/4

body: Sure the device will work, but all time related peripherals won't behave. The USART will run at the wrong baud rate, the millisecond timer's intervals will be too long, and so on.


body:
I am trying to use the [Neato xv11 lidar](https://web.archive.org/web/20160513114247/http://xv11hacking.wikispaces.com/LIDAR+Sensor) with an ESP32. This should output packets of 22 bytes with the starting byte 0xFA. The communication is 8N1 and the baud rate is 115200.

When I connect the Lidar TX to the ESP32 RX2 pin, I get data that does not make sense as I get the start byte every 9 (and sometimes 8) bytes. However, when I run the same code on an Arduino Nano, I get the correct 22 byte packages. I even connected both at once and logged the results in Putty. This is the data I got.

```c
// Arduino Nano Code
void setup() {
  Serial.begin(115200);
  Serial1.begin(115200);
}
void loop() {
  while (Serial1.available()) {
    Serial.println(Serial1.read(),HEX);
  }
}
```

```c++
// ESP32 Code
void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
}

void loop() {
  while (Serial2.available()) {
    Serial.println(Serial2.read(),HEX);
  }
}
```

ESP32
```
FA
A8
0
35
6D
11
17
71
3D
FA
A9
0
3D
12
97
12
10
D1
41
FA
AA
0
E1
E
14
12
E7
1F
FA
AB
```

Arduino Nano
```
FA
D8
74
35
6B
3
3D
1
7B
3
3B
1
8C
3
2B
1
9F
3
1C
1
A
1D
FA
D9
74
35
B2
3
```

title: Arduino Nano and ESP32 Read Different Values over Serial

Answers: 0


body:
Using Nano's for small programmes I get compilation reports about the amount of space taken by global variables.

On a typical progamme it says something like Sketch uses 16316 bytes (53%) of program storage space. Maximum is 30720 bytes. Global variables use 1798 bytes (87%) of dynamic memory, leaving 250 bytes for local variables. Maximum is 2048 bytes. Low memory available, stability problems may occur.

If I count up the number of bytes taken by the declared global variables it is 126 bytes, depending on how bool's take up memory ( one bit or one byte ).

Can I get the compiler to give me a dump of what it is actually assigning as global variable space to reconcile the difference between 126 bytes and 1798 bytes.  Then I could change the programme to get round the memory problem and keep using the Nano's.

Thanks in advance for any useful insights.

Thanks to those who commented for the help.

Checking the memory requirement for the global variables, includes and begins still only used 34% so I realised that something in the main loop was using extra memory.  Then the penny dropped, I had print messages left over from tracing problems and these become stored constants when compiled.  Moved these to a conditional compile section so they are only compiled during tracing for bugs. Problem solved. Once again thanks for the helpful hints.

title: Space taken by Global Variables

Answers: 1

body:
RAM is precious on a microcontroller, PROGMEM (program memory) not quite as much so. On the Arduino Uno and the Nano (using an Atmega328P) you have:

*    1 kB of EEPROM
*    2 kB of RAM
*    32 kB of PROGMEM

Clearly, there is a lot more program memory than RAM.

Variables are copied into RAM at program startup

The problem with constants in general (including string constants like "hello") is that the compiler generates code to copy them into RAM at program startup, because most C functions do not expect to find data in PROGMEM. (It has to generate different instructions to access PROGMEM).

# Benchmark memory use

To test memory use, I'll start off with a sketch that simply returns how much memory is free, without doing anything else. Tested on IDE 1.0.6, Arduino Uno, on Ubuntu.

    #include "memdebug.h"

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

    void loop () { }

Output:

    Free memory = 1702

Since we started with 2048 bytes of RAM, already we have used 2048 - 1702 = 346 bytes. These are used as follows:

    34 bytes for the HardwareSerial instance (Serial)
    64 bytes for the Serial transmit buffer
    64 bytes for the Serial receive buffer
    4 bytes for the Serial transmit buffer head and tail pointers
    4 bytes for the Serial receive buffer head and tail pointers
    9 bytes for keeping track of millis / micros
    4 bytes for memory allocation (__malloc_heap_start, __malloc_margin)
    128 bytes for the heap safety margin
    6 bytes for a few nested function calls (main -> setup -> getFreeMemory)
    16 bytes for the compiler vtable for HardwareSerial
    4 bytes for variables __brkval and __flp (used in memdebug)
    2 bytes pushed onto the stack in main (to save registers)
    2 bytes pushed onto the stack in setup (to save registers)
    4 bytes pushed onto the stack in getFreeMemory (to save registers)
    1 byte because the stack pointer starts at 0x8FF rather than 0x900

(That's 346 bytes accounted for)

# Tips

The stack starts at the highest possible address and grows downwards. Each function call would add 2 bytes to the stack (the return address) plus any local (auto) variables would be allocated there.

The heap safety margin is a buffer between the top of the heap and the bottom of the stack. Without it, if you did a "malloc" and got all available memory, there would be no memory left for function calls and local variables in functions.

The vtable is used by the compiler to generate late bindings for virtual functions used by classes.

The compiler generates code to push registers onto the stack when you call a function (the registers used inside that function) so that if the same register was used by the calling function, it would not be corrupted.

# Printing constants

Let's print a constant by adding this line:

      Serial.println ("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo");

Output is now:

    Free memory = 1630
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo

So the free RAM has gone down by 72 bytes, which happens to be be how long that string is (allowing one byte for the 0x00 terminator at the end).

Why? Because the string was copied from PROGMEM, where it must be when the Arduino is turned off, into RAM.

The first thing we can do is use the F() macro, which cunningly expands out to print directly from PROGMEM, thus saving RAM. So we change the line above to read:

      Serial.println (F("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo"));

Output:

    Free memory = 1702
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo

Back to 1702 bytes of free memory. So, lesson #1 is to use the F() macro as illustrated above whenever printing constants.

# More information

I have more information on [my page about RAM usage](http://www.gammon.com.au/forum/?id=12615) which discusses putting arrays of constants into PROGMEM as well as what I mention above.


body:
I am making some SimPit panels and SimRacing devices, and I've run into an annoying issue. I have  multiple Arduinos (Leonardos and ProMicros) that show up as the same "Controller Names" (See Image)

EDIT: **In the Game Controllers (joy.cpl) windows of Windows 10**, where does the name "Arduino Leonardo" come from?, so that I can rename each, so they show up listed as something different like: Leonardo 1, Leonardo 2, Leonardo 3?

I imagine this is a change to the boot-loader and nothing to do with anything via Arduino IDE?

Thank you for your time, and let me know if more info/explanation is needed.

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

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

title: Multiple Arduinos, same name - Windows 10 Game Controllers

Answers: 1

body:
Windows is likely assigning the inbox driver to use based on the VID/PID of the USB device.  Take care changing those values, as you may not be able to easily reprogram the devices.

There is a Device Firmware Update (DFU) technique where if a pin is low at startup / USB init, the VID/PID are returned as different values


body:
I have one display screen, and 5 Arduino Nanos. They are checking to see if passwords in a text file hash to a specific hash, then display it on the screen when found.

Since they aren't all sending signals to the screen, is it possible to wire it so that all of them are connected to one screen, and then have the one that finds the correct password send the signal to the screen, and how would I go about doing this?

title: Multiple Arduinos connected to one display

Answers: 1

body:
It should be possible to connect all nanos to the display, just like you would if there was only one nano as long as there is only one nano that *actively drives* the bus (what ever bus that is). All the other nanos need their bus pins to be inputs (not configured for the bus). So you could have them being inactive by default and only access the bus once they found a matching hash.

**But**: if multiple nano's are configured for bus usage at a time, communication would be corrupted. In case the display uses a push-pull bus (SPI, UART, ...) this is even electronically an issue, because their bus pins would short the supply voltage and possibly get destroyed. So you need some kind of protection in that case, a current limiting resistor in the easiest form.

As mentioned in comments, the "clean" solution is to have one dedicated controller to be the coordinator.

Some thoughts:

  - there is a real (not just a hypothetic) chance for bus contentions, because multiple passwords lead to the same hash and you even want to compare hashes for multiple passwords. The occurence of such a collision needs to be expected, though it is not predictable *when* or *if* it actually happens.

  - you probably want to configure the cluster, e.g. to distribute the hash of interest among the Nanos or to stop the cluster when a match is found. Those things would be easier if there's one dedicated master which you can communicate with directly.

  - the coordinator would always have control over the display. What if you wanted to continously display information on the screen, e.g. a progress bar? That would be difficult to implement afterwards when there's no master.


body: So I have 5 Nanos all trying to crack a password, the idea is each one has one fifth of the list so they can test 5 at a time, then when it is found, I want it to be displayed on a screen I have, the idea is to connect them all to a hub which would be the arduino uno, the Uno would then take the char was sent, and send it to the screen, it does not know which Arduino will send the char and the idea is to use serial.write but I am open to other options. What is the best way to go about accomplishing this task, is there some way I can have it reading the serial from all 5 Nanos, and can this be done without it being plugged into a computer?

title: reading strings from multiple Arduinos

Answers: 2

body: The Nano devices can be wired in a daisy chain. Any character coming in must be immediately sent out. The chain would end where it connects to the Arduino.

body:
Presumably you will avoid having two Nanos try the same item from the
list. Then, only one Nano can find the answer, and only one will try to
transmit data at any given time. In such a situation, yes, you could
connect all five Nanos to the same serial link:

* Connect the Uno's TX directly to the RX each Nano. They will all
  receive the data transmitted by the Uno.
* Connect the Uno's RX to the TX of each Nano through this circuit:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/pPEaC.png)

<!-- End schematic -->

As long as at most one Nano tries to `Serial.print()` (or
`Serial.write()`) at any given time, the Uno will receive the data just
fine, although it will not be able to tell which of the Nanos sent it.


body:
I am wanting to make a simple circuit that takes input from a movement sensor and plays a sound response.

To do this I think an ESP32 microcontroler would be optimal?

But how does one go about identifying parts and making sure they are compatible before buying?

For example I have no idea what sensor, speaker or battery sources to use. How does a total noob go about finding all this out in an efficient way?

title: How to pre-design circuit before buying?

Answers: 1

body:
 - Step #1: Steal! Search engines are your friend.
 - Step #2: (see step #1).

Look for published projects using parts that you want to use or to find out what parts someone else used, and how they connected them & coded for them.

Look up the datasheets for the parts you propose to use and read at least the introductions, to decide if they meet your needs. If you're project is for learning, not going into a bigger project (yet), you may not need this step if someone else's project has shown you the way. When you eventually come to designing your own, this step will be important.

As a beginner, copying from others is really the best/quickest way to 1) make stuff happen; and 2) not (or be less likely to...) blow up parts that cost money and take time to replace.

Once you've built a couple of projects you'll start to see common techniques of coding and of building circuits, that will lead you to more questions. (See step #1 above).

There's more, like learning some basic electrical and electronic theory and practice, if you haven't already, but that can come a little later and will make more sense when you have some hands-on experience.


body:
I flashed my ATTINY85 Digispark v3.0 with micronucleus firmware 2.6.1 and it works fine, the onboard led lights up and the another led blinks twines every 500ms (not sure way but it seams like everything is working correcly). But now I don't understand how to activate the "flash" mode to upload my program or upload a new bootloader.

I'm familiar with pull-up resistor but have never used it on a USB pins before (If I'm not mistaking the bootloader is activated to receiver programing when USB Data minus have a pull-up resistor and the board is reset and not only powered on).

Below are the condition to enter bootloader, text copied from micronucleus github page. https://github.com/ArminJo/micronucleus-firmware#entry_d_minus_pullup_activated_and_entry_ext_reset-entry-condition

**ENTRY_D_MINUS_PULLUP_ACTIVATED_AND_ENTRY_EXT_RESET**

*Activate the bootloader only if the D- pin is high, i.e. a pull-up resistor is attached and powered and we have an ENTRY_EXT_RESET condition. Useful if the pull-up is powered by USB V+ and NOT ATtiny VCC to save power. In this case often a schottky diode is connected between V and VCC.*

I have tried using a resistor from USB V+ to USB D- and resetting it using PIN 5 to ground but the leds just blinks to indicate a reset but no connection to is establish.

So if someone knows how this should work let me know.

[![USB pin's - ATTINY85 Digispark v3.0][1]][1]

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

title: Micronucleus firmware 2.6.1 - Activate bootloader put D- pin to high

Answers: 0


body:
I know we can connect 4 [ADS1115](https://www.ti.com/lit/ds/symlink/ads1115.pdf)s to an Arduino Mega 2560.

Is there any limit on the number of ADS1115s we can connect to the Mega giving each a different address? I have to connect at least 36 ADS1115s.

title: How many ADS1115 ADCs can I connect to a single Arduino Mega 2560

Answers: 1

body:
256(+?)

With 8 [TCA9548A][1] 1-to-8 I2C Multiplexers on different I2C addresses, it is a multiplication problem: You can expand the Arduino Mega's I2C port on Digital Pins 20&21 to 8 multiplexers *  8 multiplexer ports * 8 ADS1115 addresses to 256.

It might be possible to go much further if you can wire and code multiple levels of multiplexers.

  [1]: https://www.ti.com/lit/ds/symlink/tca9548a.pdf?ts=1639975466543


body:
How can I get some constantly changing values from a separate C++ program entered and uploaded into the Arduino?

I notice when I upload code to the Arduino in the IDE it takes about a second to start moving. This is also a problem. I would like there to be no delay after instructions to the motor change.
My goal is to get a trained neural network model from the PyTorch C++ version to control the motor's spin and speed. I would assume the IDE does not allow one to import PyTorch?

I tried looking around on the Arduino website for this, but it seems like the IDE is the only option. My solution would be something that imports the Arduino library into a C++ program just like I import the PyTorch library into my C++ program.

My ficticous C++ code. Just written to illustrate what I would like to happen.

    import pytorch
    import arduino

    // if I had an encoder on the motor giving position readings as inputs (I know this isn't how it's done in real code)
    sensors = arduino_encoder_sensors

    // trained model
    m = pytorch.load_torch_model('model')

    // model taking sensors as inputs and outputting desired speed and distance executions to the motor
    speed, dist = m(sensors)

**Arduino Code:**

    const int stepPin = 8;
    const int dirPin = 9;

    void setup() {
      // Sets the two pins as Outputs
      pinMode(stepPin,OUTPUT);
      pinMode(dirPin,OUTPUT);
    }
      digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
      for(int x = 0; x < dist; x++) {
        digitalWrite(stepPin,HIGH);
        delayMicroseconds(speed);
        digitalWrite(stepPin,LOW);
      delay(1000); // One second delay
    }

title: How can I get an external program to change values inside the Arduino C++ code?

Answers: 1

body:
Your question seems very confused, so I will try to shine a light on some basic distinctions.

> How can I get some constantly changing values from a separate C++ program entered and uploaded into the Arduino?

In your whole question you seem to confuse program and data. The program on the Arduino doesn't need to change with every changing of the values. Instead you would have a constant program, which receives changing values from the PC.

So it seems you want to send data from your python program on your PC to the Arduino. This data doesn't have anything to do with the actual program on the Arduino. The program just should use the data to act accordingly. You can use any of the communication interfaces that are usable with Arduinos and PCs, though the simplest option would be the `Serial` interface, which gets bridged to your PC via the USB port. The `Serial` interface is what you see in the Serial Monitor.

How to use a serial port in python can be googled quite easily. For the Arduino side there are many tutorials and examples about it online. You would also need to think about your communication protocol, which you want to impose on the `Serial` byte stream. For example you could use ASCII encoded text, each message delimited to the next by a newline character `'\n'`, each message containing first the command and then needed parameters. Since only you know what exactly you want to send to the Arduino, you need to design this yourself.

> I notice when I upload code to the Arduino in the IDE it takes about a second to start moving. This is also a problem.

This is due to the bootloader. When you upload a program this is done via the `Serial` interface. Normally microcontrollers can only be programmed over specialized interfaces (like ISP). But Arduinos (and other microcontrollers) can be programmed with a bootloader. That is a program sitting on the microcontroller, which runs anytime you power the microcontroller on your reset it. On Arduinos it will listen on the `Serial` port for a moment in the case that you want to upload a new code. If yes, then it handle the communication and write the new code to the Arduinos flash memory. If not, it will execute whatever program currently is saved in flash.

So you cannot avoid this delay without changing or deleting the bootloader. Deleting it would mean that you need a programmer board to upload new code (another Arduino can do that). Changing it would also require a programmer board, because you would need to write the new bootloader version to the Arduino with it.

I would debate if this delay is really a problem. It only appears on a reset, like when you upload new code. And why would you want to reset the Arduino or upload new codes that fast? For doing your motor movement you don't need new programs on the Arduino for every movement; you need a code that will move according to data send through the `Serial` interface. And that doesn't require resetting. And it works fast.

That said, with your current code (ignoring the obvious syntax problems most likely from copy and past errors) you will still have delays, even when you implement `Serial` communication. In general you shouldn't use long `delay()` calls. You use `delay(1000)`, which makes the Arduino twiddle its thumbs for one whole second each loop iteration. Instead use the non-blocking coding style shown in the `BlinkWithoutDelay` example that comes with the Arduino IDE. It uses the `millis()` function as a clock, checking it regularily for the time to do something. There are many tutorials about that online.

> My goal is to get a trained neural network model from the PyTorch C++ version to control the motor's spin and speed. I would assume the IDE does not allow one to import PyTorch?

No, it doesn't. It is based on Java, not on python. As described above you need to write your own python program and use a fitting serial port python module for the communication over the `Serial` interface. In that python program you can import `PyTorch`, do your  neural network processing and then send the resulting commands over `Serial` to the Arduino.

> I tried looking around on the Arduino website for this, but it seems like the IDE is the only option. My solution would be something that imports the Arduino library into a C++ program just like I import the PyTorch library into my C++ program.

It is not really clear what you mean here. For communicating with an Arduino over `Serial` you can use any program that can interface with a serial port on your PC. There are many programs dedicated for this. Since you want to do your neural networking stuff in python, just use a fitting python module that handles serial port connections.

If you talk about writing programs for Arduinos and uploading them: This can be done in many other IDEs other than the Arduino IDE. Dave Newton mentioned some in his comment: VS Code and CLion. I also remember the Atom IDE. Or you can write your code in any text editor of your liking and then compile and upload the code with the Arduino CLI tool (that's what I do mostly).

---

I hope this clears up the confusion a bit so that you now can work toward a working solution.


body:
I'm trying to adapt the [MeteorRain animation from Tweaking4All][1] to work on segments of [my light string][2] (vs using the entire string) and I'm getting an error in FastLED.show() (on a line that is used repeatedly with the same variables before it crashes the "ESP32 DEVKIT V1"). The decode of the ESP32 shows an error in clockless_rmt_esp32.h (which is about as far as I have visibility and ability to troubleshoot the problem.)

Looking through Google results, I find people who have the same error, usually related to memory allocation, but I can't make a connection to FastLED.

The code:
```lang-cpp
#define FASTLED_INTERNAL // add this before including FastLED.h
#include <FastLED.h>

#define LED_PIN     12
#define COLOR_ORDER RGB
#define CHIPSET     WS2811
#define PIXELSECTIONS 2     // there are two segments of christmas lights
#define HORZPIXELS 5        // with 5 lights across connected to
#define VERTPIXELS 12       // 7 lights that hang vertically
#define NUM_LEDS (HORZPIXELS + VERTPIXELS) * PIXELSECTIONS
#define NUM_COLS PIXELSECTIONS
#define NUM_ROWS VERTPIXELS + HORZPIXELS
#define BRIGHTNESS  50

CRGB rawleds[NUM_LEDS];
CRGBSet leds(rawleds, NUM_LEDS);

unsigned long animationsCycleStartTime = millis();
int genericCounter=0;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(115200);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);

  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(rawleds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness( BRIGHTNESS );
}

void loop() {
   meteorRain(0xff,0xff,0xff,10, 64, true, 30);
}

void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {

  int metaNUM_LEDS = (HORZPIXELS + VERTPIXELS);
  for(int i = 0; i < metaNUM_LEDS+metaNUM_LEDS; i++) {

    // fade brightness all LEDs one step
    for(int j=0; j<metaNUM_LEDS; j++) {
      if( (!meteorRandomDecay) || (random(10)>5) ) {
        metaFadeToBlack(j, meteorTrailDecay );
      }
    }

    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j <metaNUM_LEDS) && (i-j>=0) ) {
Serial.print("i=" + String(i) + ";j=" + String(j) + ";i-j=" + String(i-j));
        metaSetPixel(i-j, red, green, blue);
Serial.println(" done");
      }
    }
Serial.println("to show");
    FastLED.show();
Serial.println("to wait");
    delay(SpeedDelay);
  }
  genericCounter = (genericCounter>=PIXELSECTIONS) ? 0 : genericCounter+1 ;
}

void fadeToBlack(int ledNo, byte fadeValue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
    // NeoPixel
    uint32_t oldColor;
    uint8_t r, g, b;
    int value;

    oldColor = strip.getPixelColor(ledNo);
    r = (oldColor & 0x00ff0000UL) >> 16;
    g = (oldColor & 0x0000ff00UL) >> 8;
    b = (oldColor & 0x000000ffUL);

    r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
    g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
    b=(b<=10)? 0 : (int) b-(b*fadeValue/256);

    strip.setPixelColor(ledNo, r,g,b);
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[ledNo].fadeToBlackBy( fadeValue );
 #endif
}

// this method transposes the relative pixel to the actual pixel
// for example, on the second pass of loop the code says to use
// pixels 0-16 but since the genericCounter is at 1 this method
// activates pixels 17-33
void metaSetPixel(int metaPixel, byte red, byte green, byte blue) {
  int actualPixel = (genericCounter * (HORZPIXELS + VERTPIXELS)) + metaPixel;
  setPixel( actualPixel, red, green, blue);
}

void metaFadeToBlack (int metaPixel, byte meteorTrailDecay) {
  int actualPixel = (genericCounter * (HORZPIXELS + VERTPIXELS)) + metaPixel;
  fadeToBlack(actualPixel, meteorTrailDecay );
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
   // FastLED
   rawleds[Pixel].r = red;
   rawleds[Pixel].g = green;
   rawleds[Pixel].b = blue;
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}
```

The raw error from Serial console trace:

```
13:50:53.499 -> ⸮⸮�⸮�⸮⸮⸮�@#P#⸮N⸮1h⸮0,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
13:50:53.499 -> mode:DIO, clock div:1
13:50:53.499 -> load:0x3fff0018,len:4
13:50:53.499 -> load:0x3fff001c,len:1044
13:50:53.499 -> load:0x40078000,len:10124
13:50:53.499 -> load:0x40080400,len:5856
13:50:53.499 -> entry 0x400806a8
13:50:55.042 -> i=0;j=0;i-j=0 done
13:50:55.042 -> to show
13:50:55.076 -> to wait
13:50:55.076 -> i=1;j=0;i-j=1 done
13:50:55.076 -> i=1;j=1;i-j=0 done
13:50:55.076 -> to show
13:50:55.110 -> to wait
...[snip]...
13:51:01.299 -> to show
13:51:01.299 -> to wait
13:51:01.334 -> i=0;j=0;i-j=0 done
13:51:01.334 -> to show
13:51:01.334 -> /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:1443 (xQueueGenericReceive)- assert failed!
13:51:01.334 -> abort() was called at PC 0x40085e41 on core 1
13:51:01.334 ->
13:51:01.334 -> ELF file SHA256: 0000000000000000
13:51:01.334 ->
13:51:01.334 -> Backtrace: 0x40084e74:0x3ffb1df0 0x400850e9:0x3ffb1e10 0x40085e41:0x3ffb1e30 0x400d1371:0x3ffb1e70 0x400d171d:0x3ffb1e90 0x400d1801:0x3ffb1ed0 0x400d11bb:0x3ffb1f10 0x400d125b:0x3ffb1f80 0x400d2231:0x3ffb1fb0 0x400860f9:0x3ffb1fd0
13:51:01.372 ->
13:51:01.372 -> Rebooting...
13:51:01.372 -> ets Jun  8 2016 00:22:57
13:51:01.372 ->
13:51:01.372 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
13:51:01.372 -> configsip: 0, SPIWP:0xee
13:51:01.372 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
13:51:01.372 -> mode:DIO, clock div:1
13:51:01.372 -> load:0x3fff0018,len:4
13:51:01.408 -> load:0x3fff001c,len:1044
13:51:01.408 -> load:0x40078000,len:10124
13:51:01.408 -> load:0x40080400,len:5856
13:51:01.408 -> entry 0x400806a8
```

The decoded error:
```
Decoding stack results
0x40084e74: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 156
0x400850e9: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 171
0x40085e41: xQueueGenericReceive at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c line 1443
0x400d1371: ClocklessController12, 77, 77, 154, (EOrder)10, 0, false, 5>::showPixels(PixelController(EOrder)10, 1, 4294967295u>&) at /Users/jaireaux/Documents/Arduino/libraries/FastLED/platforms/esp/32/clockless_rmt_esp32.h line 288
0x400d171d: CPixelLEDController(EOrder)10, 1, 4294967295u>::show(CRGB const*, int, CRGB) at /Users/jaireaux/Documents/Arduino/libraries/FastLED/controller.h line 408
0x400d1801: CFastLED::show(unsigned char) at /Users/jaireaux/Documents/Arduino/libraries/FastLED/controller.h line 90
0x400d11bb: meteorRain(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, bool, int) at /Users/jaireaux/Documents/Arduino/libraries/FastLED/FastLED.h line 500
0x400d125b: loop() at /Users/jaireaux/Documents/Arduino/temp/temp.ino line 33
0x400d2231: loopTask(void*) at /Users/jaireaux/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/cores/esp32/main.cpp line 23
0x400860f9: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143
```

  [1]: https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain
  [2]: https://www.amazon.com/gp/product/B08DFH99ZB/

title: xQueueGenericReceive error on ESP32 (using FastLED which relies on FreeRTOS) for adapted MeteorRain LED animation

Answers: 0