message:
What's wrong with this code..?

I want to make an 8*8 led matrix. I found this code on the web:

[![i ][1]][1]

```c++
    int latchPin = 12;  //Pin connected to ST_CP of 1st 74595
    int clockPin = 13;  //Pin connected to SH_CP of 1st 74595
    int dataPin = 11;   //Pin connected to DS of 1st 74595

    int latchPin2 = 6;  //Pin connected to ST_CP of 2nd 74595
    int clockPin2 = 7;  //Pin connected to SH_CP of 2nd 74595
    int dataPin2 = 5;   //Pin connected to DS of 2nd 74595

    void setup() {
      //set pins to output so you can control the shift register
      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);

      pinMode(latchPin2, OUTPUT);
      pinMode(clockPin2, OUTPUT);
      pinMode(dataPin2, OUTPUT);
    }

    void loop() {
      /************** Send HIGH to first Anode pin (16th pin) and LOW to all
      other anode pins (15, 11, 3, 10, 5, 6, 13) of LED matrix *************/

      // take the latchPin low so the LEDs don't change while you're sending in bits:
      digitalWrite(latchPin, LOW);
      //Send 0 0 0 0 0 0 0 1 (1) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 1st 74595
      shiftOut(dataPin, clockPin, MSBFIRST, 1);
      // shift out the bits:
      digitalWrite(latchPin, HIGH);

      /**************** Send LOW to the first cathode pin (4th pin) and HIGH to all
        other cathode pins (7, 2, 8, 12, 1, 14 and 9) of LED matrix *****************/

      // take the latchPin low so the LEDs don't change while you're sending in bits:
      digitalWrite(latchPin2, LOW);
      // Send 1 1 1 1 1 1 1 0 (254) to Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0 of 2nd 74595
      shiftOut(dataPin2, clockPin2, MSBFIRST, 254);
      // shift out the bits:
      digitalWrite(latchPin2, HIGH);
    }
```

I expected this code to turn on the first LED, but when I uploaded this code nothing lights up. I checked my rows and colum connections.

Also, I want to ask if a 74hc595 can output sink current?

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

body:
I can't add comment to your question so I post as an answer even though this is not much an answer. This is just a hint to solve your problem.

8x8 led matrix and 595s are pretty *low-level* stuff, so I assume you have some knowledge about electronics and programming in general.

I think your wiring is OK but I also think you misunderstand how 595 works.

Here is the flow taken from a library (ESP32) for 64x64 RBG LED panel using bunch of 595s:

    uint8_t data[8]; // data for one row

    digitalWrite(OE_PIN, HIGH); // disable output, 595 outputs go into high impedance state

    for (int i=0; i<8; i++)
      shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data[i]);  // dump data out

    digitalWrite(LATCH_PIN, LOW);  // pulse 1 clock
    delayMicroseconds(1); // note 2*
    digitalWrite(LATCH_PIN, HIGH); // latch is active high

    digitalWrite(OE_PIN, LOW); // Enable output

I think now you know how to fix your code.

Note 1: I find those names ***SER, SRCLK, RCLK*** (on TI's datasheet) are confusing. I prefer the names ***SERIAL DATA INPUT, SHIFT CLOCK, LATCH CLOCK*** (on ONSEMI MC74HC595 datasheet) or better ***DATA, CLK, LATCH, OE, RESET***.

Note 2: Check 74HC595 datasheet to see clock pulse width limit and speed limit. And if you are using UNO or MEGA (@16MHz), you are good without stretching the clock (data clock and latch clock). If you use higher speed MCU, e.g: ESP32@240MHz or STM32@72MHz, you have to consider clock stretching there and also inside shiftOut() function.

To improve your circuit, you should wire both OE of 595s to a Digital pin. You can also connect both latch pin into one digital pin. Every time you latch, botch 595 latch, and every time you enable output, both enable output.

So with your configuration, just shiftOut data normally for the 595 on the left and invert data for the 595 on the right, like this

    #define DATA_COL_PIN 11
    #define DATA_ROW_PIN 5
    #define CLOCK_COL_PIN 13
    #define CLOCK_ROW_PIN 7

    #define OE_PIN 4 //use digital pin 4 to enable output on both 595s
    #define LATCH_PIN 6 // or 12, but you must connect both latch inputs of both 595s together

    uint8_t col = 0b00000001; // for the left 595
    uint8_t row = 0b00000001; // for the right 595

    digitalWrite(OE_PIN, HIGH);
    shiftOut(DATA_COL_PIN, CLOCK_COL_PIN, MSBFIRST, col);
    shiftOut(DATA_ROW_PIN, CLOCK_ROW_PIN, MSBFIRST, ~row); // ~row = 0b11111110 = invert_bits(row)
    digitalWrite(LATCH_PIN, LOW);
    digitalWrite(LATCH_PIN, HIGH);
    digitalWrite(OE_PIN, LOW);

The code above is just for you to understand how it works. Normally, they would work on a buffer such as

    uint8_t row[8]; // each byte is one row

And they do row scanning, turn one row ON at a time and just flip each column ON and OFF following the byte data of that row.

I stop here as this is going off-topic. You just ask what is wrong with your code right?

BTW, 595 can sink/source 35mA on each pin (70mA in total). So if you want to light up one row at a time with your setup, you should choose each current limiter carefully so that not to exceed 70mA in total.

> 70mA / 8xLED = 8.75mA for each LED (assume red LED)
>
> (5v - 1v7) / 8.75mA = 377R

It's likely the resistors should be at least 377 ohm or 470 ohm for safety.


sender: user

message:
Why NVIC_EnableIRQ handler function only run once?

I have a code that spit out random number when the ISR register is ready:

    #define TRNG_KEY  0x524E47
    uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
    uint32_t msk = 0x1FE;

    void setup()
    {
      Serial.begin(9600);
      PIOC->PIO_PER = msk;
      PIOC->PIO_OER = msk;
      PIOC->PIO_OWDR = ~msk;

      PMC->PMC_PCER1 = PMC_PCER1_PID41;
      TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY);
      TRNG->TRNG_IER = 1 << 0;
    }

    void loop()
    {
      if (TRNG->TRNG_ISR == 1) {
      PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10];
      }
      delay(500);
    }

The code above works. However, when I tried to switch to internal interrupt:

    #define TRNG_KEY  0x524E47
    uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
    uint32_t msk = 0x1FE;

    void setup()
    {
      Serial.begin(9600);
      PIOC->PIO_PER = msk;
      PIOC->PIO_OER = msk;
      PIOC->PIO_OWDR = ~msk;

      PMC->PMC_PCER1 = PMC_PCER1_PID41;
      TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY);
      TRNG->TRNG_IER = 1 << 0;

      NVIC_EnableIRQ(TRNG_IRQn);
    }

    void loop()
    {

    }

    void TRNG_Handler(void) {
      PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10];
    }

The code only spit out one random number and then freezes, indicating TRNG_Handler(void) was only executed once. I cannot figure out why.

Thanks in Advance !

sender: assistant

body:
Two things:

1. Never use `delay()` inside an ISR. On *some* systems it may work, but on most it will just block. It's bad practice to have your ISRs run for more time that absolutely needed anyway.
2. You need to read the status register for the TRNG to clear the interrupt flag. You're doing that in your first code sample with `if (TRNG->TRNG_ISR == 1) {`.


message:
How do I get an HTTP_POST response?

I have a function for HTTP_POST responses but it is never called when I post to it. I get the webpage instead.

I call on it with

    server.on("/",HTTP_POST,response);

But I only get the url in response.

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

        Serial.begin(115200);
    #if defined(__AVR_ATmega32U4__) || defined(SERIAL_USB) || defined(SERIAL_PORT_USBVIRTUAL)
        delay(2000); // To be able to connect Serial monitor after reset and before first printout
    #endif
        // Just to know which program is running on my Arduino
        Serial.println(F("START " __FILE__ " from " __DATE__));
        Serial.print(F("Ready to send IR signals at pin "));
        Serial.println(IR_SEND_PIN);

        pinMode(led_pin, OUTPUT);
        digitalWrite(led_pin, 0);
        Serial.begin(115200);
        WiFi.mode(WIFI_STA);
        WiFi.begin(ssid, password);
        Serial.println("");

        // Wait for connection
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
        }

        Serial.println("");
        Serial.print("Connected to ");
        Serial.println(ssid);
        Serial.print("IP address: ");
        Serial.println(WiFi.localIP());

        if (MDNS.begin("esp32")) {
          Serial.println("MDNS responder started");
        }

        server.on("/", handleRoot);
        server.on("/test.svg", drawGraph);
        server.on("/",HTTP_POST,response);
        server.on("/inline", []() {
        server.send(200, "text/plain", "this works as well");
        });
        server.onNotFound(handleNotFound);
        server.begin();
        Serial.println("HTTP server started");

    }

    void response(){
      //int khz = 38; // 38kHz carrier frequency for the NEC protocol

      if(server.hasArg("on") && (server.arg("on").length()>0)){ // TODO check that it's not longer than 31 characters
          Serial.print("Server was turned on:\t");
          Serial.println(server.arg("on"));

          ++CYCLE0;
          server.sendHeader("Location", String("/"), true); //how to do a redirect, next two lines
          server.send ( 302, "text/plain", "");
      } else if (server.hasArg("off") && (server.arg("off").length()>0)){
          Serial.print("Server was turned off:\t");
          Serial.println(server.arg("off"));

          ++CYCLE1;
          server.sendHeader("Location", String("/"), true);
          server.send ( 302, "text/plain", "");

       } else if (server.hasArg("up") && (server.arg("up").length()>0)){
          Serial.print("Server temp was turned up:\t");
          Serial.println(server.arg("up"));

          ++CYCLE2;
          server.sendHeader("Location", String("/"), true);
          server.send ( 302, "text/plain", "");

      } else if (server.hasArg("down") && (server.arg("down").length()>0)){
          Serial.print("Server temp was turned down:\t");
          Serial.println(server.arg("down"));

          ++CYCLE3;
          server.sendHeader("Location", String("/"), true);
          server.send ( 302, "text/plain", "");

      } else {
        server.send(400, "text/html", "
HTTP Error 400

Bad request. Please enter a value.
");
      }
    }

How do you get an http post response back instead of a webpage?

POST response:

     <meta http-equiv='refresh' content='5' />
     <title>ESP32 Demo</title>

Hello from ESP32!

Uptime: 00:05:32

Turn air condistioner on

AC has been cycled 0 times

     <form name='frm0' method='post'> <input type='text' name='on' value=8000>
      <input type='submit' value='Submit'>     </form>

Turn air conditioner off 0 times

      <form name='frm1' method='post'> <input type='text' name='off' value=8000>
       <input type='submit' value='Submit'>     </form>

Turn temperature up 0 times

       <form name='frm2' method='post'> <input type='text' name='up' value=8000>
        <input type='submit' value='Submit'>     </form>

Turn temperature down 0 times

        <form name='frm3' method='post'> <input type='text' name='down' value=8000>
         <input type='submit' value='Submit'>     </form>

Complete code

[long version][1]

  [1]: https://bpa.st/HSTQO

body:
You have:

```c++
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
server.on("/",HTTP_POST,response);
```

The first call using `handleRoot` species no particular method, and in this case it seems [any method is acceptable][1].  You later specify `server.on("/",HTTP_POST,response);` specifically for POST requests.  These are [added to a request handler list][2] in the order given.  And apparently [consulted][3] in the order given.

In short, you need to specify `HTTP_GET` for `handleRoot` or just specify your `HTTP_POST` for `response` first and let `handleRoot` catch non-`HTTP_POST` requests afterwards:

```c++
server.on("/",HTTP_POST,response);
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);
```

  [1]: https://github.com/espressif/arduino-esp32/blob/1.0.5-rc6/libraries/WebServer/src/WebServer.cpp#L250
  [2]: https://github.com/espressif/arduino-esp32/blob/1.0.5-rc6/libraries/WebServer/src/WebServer.cpp#L266
  [3]: https://github.com/espressif/arduino-esp32/blob/1.0.5-rc6/libraries/WebServer/src/Parsing.cpp#L116


message:
Code exceeds Uno board memory

I have been stuck for a long time on a piece of Arduino code that performs an FFT on a Photoplethysmogram signal and decides signal quality after that.

```
#include <math.h>
#include "arduinoFFT.h"
#include <EEPROM.h>

//N=10 pt moving average
//For bidmc data of first 10 patients, MA = 0.4613849
double baseline=0.4613849;
float lm=1.0; //amplitude threshold
float ref_voltage=1.0; //saturation reference voltage
float cutoff=4.0;
float fs=0.02;
float zero_amp=0.015;

float pi=3.14159265;  //Universal Constants
float e=2.71828;
const int flen=61;

#define SAMPLES 128           //Must be a power of 2
#define SAMPLING_FREQUENCY 50 //Hz, must be less than 10000 due to ADC

arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  Serial.begin(9600);
  sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void loop() {
  //float arr[]={0.43597,0.43206,0.42815,0.42424,0.42131,0.41838,0.4174,0.41642,0.41544,0.41447,0.41251,0.41153,0.40958,0.40762,0.40665,0.40665,0.40665,0.40762,0.4086,0.4086,0.41056,0.41153,0.41153,0.41056,0.4086,0.40665,0.40469,0.40469,0.40567,0.4086,0.41251,0.42033,0.43206,0.45259,0.4741,0.4956,0.51808,0.5347,0.55034,0.56403,0.57576,0.58456,0.59238,0.59629,0.59922,0.60117,0.60215,0.60313,0.60313,0.60117,0.59824,0.59335,0.58553,0.57771,0.57185,0.56207,0.54741,0.53372,0.52102,0.50929,0.50244,0.49756,0.4956,0.49462,0.49365,0.49365,0.49365,0.49169,0.48876,0.4868,0.48387,0.48094,0.47801,0.47507,0.47116,0.46823,0.46334,0.45846,0.45357,0.44868,0.44379,0.43891,0.435,0.43109,0.4262,0.42326,0.42033,0.41838,0.41642,0.41447,0.41447,0.41349,0.41251,0.41251,0.41251,0.41251,0.41251,0.41349,0.41544,0.4174,0.41935,0.42033,0.42131,0.42131,0.42033,0.41935,0.41642,0.41447,0.41349,0.41349,0.41642,0.42131,0.42815,0.43695,0.45064,0.46823,0.4868,0.50538,0.52395,0.54154,0.55816,0.57185,0.58162,0.58749,0.59042,0.59042,0.5914,0.59042,0.58944,0.58651,0.5826,0.57771,0.57087,0.56305,0.5523,0.54057,0.52884,0.51711,0.50733,0.49756,0.48778,0.47996,0.4741,0.47019,0.46823,0.46725,0.46628,0.46432,0.46041,0.4565};
  float arr[]={0.30303,0.29814,0.29326,0.28837,0.28446,0.28152,0.27859,0.27468,0.26979,0.26393,0.25806,0.25611,0.25904,0.27175,0.29521,0.32942,0.37341,0.42522,0.47116,0.51417,0.55914,0.6002,0.63539,0.66373,0.68622,0.70381,0.71652,0.72532,0.73118,0.73314,0.73314,0.73021,0.7263,0.72043,0.71359,0.70479,0.69501,0.68524,0.67351,0.6608,0.64614,0.6305,0.61388,0.59726,0.58065,0.56207,0.54252,0.52395,0.50538,0.48778,0.47312,0.46041,0.44868,0.43988,0.43304,0.42815,0.42522,0.42229,0.41935,0.4174,0.41544,0.41349,0.41056,0.40762,0.40469,0.40176,0.39785,0.39394,0.39003,0.38612,0.38221,0.37634,0.37146,0.36559,0.35973,0.35386,0.348,0.34213,0.33627,0.3304,0.32551,0.32258,0.31769,0.31281,0.30792,0.30303,0.29814,0.29423,0.28935,0.28446,0.27957,0.2737,0.26784,0.26393,0.261,0.26197,0.26882,0.28446,0.31183,0.34897,0.39589,0.44868,0.50147,0.55132,0.59629,0.6305,0.65591,0.67937,0.69795,0.71261,0.72434,0.73216,0.73607,0.73803,0.73803,0.73509,0.73021,0.72434,0.7175,0.70968,0.6999,0.69013,0.6784,0.66569,0.65103,0.63441,0.61681,0.59824,0.57771,0.55718,0.53959,0.52297,0.50635,0.48974,0.47507,0.46334,0.45259,0.44379,0.43695,0.43206,0.42815,0.42522,0.42229,0.42033,0.41838,0.41642,0.41447,0.41153,0.4086,0.40469,0.40078,0.39687,0.39198,0.3871,0.38221,0.3783,0.37439,0.3695,0.36364,0.35875,0.35288,0.348,0.34213,0.33724,0.33236,0.32747,0.32258,0.31769,0.31378,0.31085,0.30792,0.30401,0.3001,0.29619,0.29032,0.28446,0.27859,0.2737,0.2737,0.28055,0.29423,0.31672,0.35191,0.39785,0.45161,0.50733,0.56109,0.60899,0.65005,0.68328,0.7087,0.72727,0.74096,0.74878,0.75367,0.75562,0.7566,0.75464,0.75171,0.74585};
  //float arr[]={0.30303,0.28446,0.26979,0.25904,0.37341,0.55914,0.68622,0.73118};
  int len=sizeof(arr)/sizeof(arr[0]);

  /*for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)  //ppg data Array display
  {
    Serial.println(arr[i]);
    delay(50);
  }*/

  //SAMPLES=len;
  for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!
        vReal[i] = arr[SAMPLES];
        vImag[i] = 0;

        while(micros() < (microseconds + sampling_period_us)){
        }
    }

  /*FFT*/
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

  /*PRINT RESULTS*/
  //Serial.println(peak);     //Print out what frequency is the most dominant.

  for(int i=0; i<(SAMPLES/2); i++)
  {
       /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
       Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 2);
       Serial.print(" ");
       Serial.println(vReal[i], 1);  //View only this line in serial plotter to visualize the bins
       delay(50);
  }

  //delay(1000);  //Repeat the process every second OR:
  //while(1);       //Run code once
  Serial.println("Hello");
  //int freq_N=61;
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }

  /*double D[3][freq_N]; //1st row for frequencies, 2nd row for magnitude, 3rd row for phase
  for(int i=0;i<freq_N;i++)
  {
    D[0][i]=-(pi/2)+i*0.1;
    double *d=fourier_tran(arr,len,D[0][i]);
    D[1][i]=*(d+0);
    D[2][i]=*(d+1);
    Serial.println(i);
    delay(300);
  }*/

  int z_crsg=zero_cross(arr,len);
  //Serial.println(z_crsg);
  //delay(1000);
  float diff_arr[len-1];   //Differenced PPG signal
  for(int i=1;i<=len-1;i++)
  {
    diff_arr[i-1]=arr[i]-arr[i-1];
  }

  int rise=rise_count(arr,len);
  int fall=fall_count(arr,len);
  float fr=(float)fall/rise;      //fall/rise count ratio
  uint16_t m=max_amplitude(arr,len);   //maximum amplitude detection
  int sc[]={0,0,0};  //sensor connectivity vector
  if(fr>1.65 && fr<2.35)
  {
    sc[0]=1;
  }
  if(m<lm)
  {
    sc[1]=1;
  }
  if(m>zero_amp)
  {
    sc[2]=1;;
  }
  int sd=sig_saturation(arr,len);
  //Serial.println(sd);
  //Serial.print(sc[0]);
  //Serial.print(sc[1]);
  //Serial.print(sc[2]);

  if(sum(sc,3)>=2)
  {
    Serial.println("Sensor well connected");
  }
  else
  {
    Serial.println("Sensor not connected properly");
  }
  delay(500);
  if(base_drift(arr,len)>=0.4612 && base_drift(arr,len)<=0.4614)
  {
    Serial.println("Motion detected");
  }
  else
  {
    Serial.println("No motion artefacts problems");
  }
  delay(500);
  if(sd==0)
  {
    Serial.println("Saturated signal");
  }
  else
  {
    Serial.println("Non-saturated signal");
  }
  delay(500);

  int d_z_crsg=zero_cross(diff_arr,len-1);

}

//Sensor connectivity detection
int fall_count(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]>arr[i+1])
    {
      c=c+1;
    }
  }
  return c;
}
int rise_count(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]<arr[i+1])
    {
      c=c+1;
    }
  }
  return c;
}
int max_amplitude(float arr[],int l)
{
  float h=arr[0];
  for(int i=1;i<l;i=i+1)
  {
    if(arr[i]>h)
    {
      h=arr[i];
    }
  }
  if(h>lm)
  {
    return 0;
  }
  return 1;

}

//Noise segment detection
int zero_cross(float arr[],int l)
{
  int c=0;
  for(int i=0;i<l-1;i++)
  {
    if((arr[i]==0.0) && arr[i+1]!=0.0)
    {
      c=c+1;
    }
  }
  return c;
}
int local_maxima(float arr[], int l)
{
  int frame_len=15;
  int a=0;
  int frames=l/frame_len;
  int maxima[frames];
  for(int k=0;k<frames;k++)
  {
    uint16_t h=0;
    for(int i=a;i<a+frame_len;i++)
    {
      if(arr[i]>h)
      {
        h=arr[i];
      }
    }
    maxima[k]=h;
    a=a+frame_len;
  }
  for(int i=0;i<frames-1;i++)
  {
    if(maxima[i]>lm && maxima[i+1]>lm)
    {
      return 1;
    }
    if(i<=frames-4)
    {
      if(maxima[i]<lm && maxima[i+1]<lm && maxima[i+2]<lm && maxima[i+3]<lm)
      {
        return 1;
      }
    }
    if(i<=frames-3)
    {
      if(maxima[i]<lm && maxima[i+2]<lm)
      {
        return 1;
      }
    }
  }
  return 0;
}

//Saturation detection
int sig_saturation(float arr[],int l)
{
  int c=0;
  //uint16_t lev=200000;
  for(int i=0;i<l-1;i++)
  {
    if(arr[i]<10 && arr[i+1]<10)
    {
      c++;
    }

    if(arr[i]>lm && arr[i+1]>lm)
    {
      c++;
    }
  }
  if(c>=20)
  {
    return 0;
  }
  return 1;
}

//motion detection module
double base_drift(float arr[],int l)
{
  int N=10; //N pt moving average
  int frame=l-N+1; //number of frames
  float s=0;
  double sum=0;
  for(int i=0;i<frame;i++)
  {
   s=0;
   for(int j=i;j<N+i;i++)
   {
      s=s+arr[j];
   }
   sum=sum+(s/N);
  }
  double avg=sum/frame;
  return avg;
}

int sum(int n[],int l)
{
  float s=0;
  for(int i=0;i<l;i++)
  {
    s=s+n[i];
  }
  return s;
}

float butterworth(float f, float fc,int n)
{
  float h;
  h=1/sqrt(1+pow((fc/f),2*n));
  return h;
}

double *fourier_tran(float arr[],int n,float omega)
{
   double Xr=0.00;
   double Xi=0.00;
   double DTFT[2];
   for(int j=0;j<n;j++)
   {
     Xr=Xr+arr[j]*cos(omega*j);
     Xi=Xi+arr[j]*sin(omega*j);
   }
   float X=sqrt(pow(Xr,2)+pow(Xi,2));  //Fourier transform magnitude
   float ph=-atan(Xi/Xr);  //Fourier transform phase

   DTFT[0]=X;
   DTFT[1]=ph;
   double *p=DTFT;
   Serial.println(*p);
   delay(100);
   Serial.println(*(p+1));
   delay(100);
   return p;
}
float *inv_fourier(float DTFT[][flen],int l,int flen,int n) //n is the length of the time array
{
  float arr[n];
  for(int i=0;i<n;i++)
  {
    float X=0.000;
    for(int j=0;j<l;j++)
    {
      X=X+DTFT[1][j]*cos(DTFT[2][j]+DTFT[0][j]*n);
    }
    arr[i]=1/(2*pi) * X;
  }
  float *p=arr;
  return p;
}
```
When I upload the code, Right after performing the FFT, the code does not display anything more, implying it ceases to execute and shows an error message - ```Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.
data section exceeds available space in board```

I cannot remove either section of the code, so what do I need to change with this?

body:
Probably you use too much SRAM memory:

`float arr[]` seems to take 4 bytes (for float) * 128 = 512 bytes.

Then you have `vReal` and `vImage which takes 4 (double, float/doubles are the same in Arduino) * 128 * 2 (vReal/vImage) = 1024 bytes.

    double vReal[SAMPLES];
    double vImag[SAMPLES];

This already is 1536 bytes. The Arduino only has 2048 bytes so high likely you exceed it (including arguments passed and other globals).

`arr` seems to be a readonly array, so check into the use of F/PROGMEM to store them in Flash instead of SRAM (see StarCat's comment). This might get you well under the 2 KB Arduino Uno memory. Other possibilities are using a Mega which has 8 KB or use external SRAM memory but this decreases performance and takes more programming effort.

See also my anser at https://arduino.stackexchange.com/questions/67306/optimizing-code-to-use-less-flash-memory-and-sram


body:
Consider using one of the Teensy family.  The latest [Teensy 4.0][1] has an onboard FPU and lots of other goodies, and runs at 600MHz. Why drive a VW when you can jump into a Ferrari for very little money?

I've been using the Teensy 3.2/3.5 modules for years, and have found them to be very stable and easy to use.

  [1]: https://www.pjrc.com/store/teensy40.html


message:
Reading from EEPROM and writing to addressable LED with limited connections

**UPDATE**
Clock speed code has been tweaked as per the suggestion from @timemage due to inability for Wire library to reduce to below 30304Hz. Unfortunately problems still persist:
Nothing printed out to serial and LED working only after disconnecting and reconnecting the circuit(stops updating after reseting arduino)..

****UPDATE****
Thanks for all replys. I have left the circuit the same and have used the following code where i have tried to reduce the i2c clock speed to 1khz but unfortunately having no luck.The EEPROM returns nothing and the pixel fails to work initially, only when i disconnect the circuit(this is simple because i am using a magnetic USB connector) it seems to work fine(until i restart the arduino).
If the consensus is that i may have more luck if I alter the library then i may look into it although it sounds a bit out of my depth...

    #include <Wire.h>

    #define disk1 0x50    //Address of eeprom chip
    unsigned int address0 = 0; //address to store the data

    #include <Adafruit_NeoPixel.h>

    //pixels pin
    #define sda_pin A4
    #define scl_pin A5

    Adafruit_NeoPixel strip(1, sda_pin, NEO_GRB + NEO_KHZ800);

    void setup() {

      Serial.begin(9600);

      Wire.begin();

      ////UPDATED CODE TO REDUCE I2C CLOCK SPEED TO 1KHZ////
      TWSR |= 0x03; // chose divide-by-64 prescaler
      TWBR  = 0x80; // closest to 1 kHz from below at 16 MHz with /64 prescaler.

      Serial.println(readEEPROM(disk1, address0), DEC);
      Wire.end();
      pinMode(scl_pin, INPUT);

      strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
      strip.show();            // Turn OFF all pixels ASAP
      strip.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)

    }

    void loop() {
      rainbow(10);
    }

    void rainbow(int wait) {

      static unsigned long timer = 0;
      static long firstPixelHue = 0;

      if (millis() - timer > wait) {
        timer = millis();

        for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...

          int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());

          strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
        }
        strip.show(); // Update strip with new contents

        if (firstPixelHue < 5 * 65536) { //incrememnt
          firstPixelHue += 256;
        } else firstPixelHue = 0; //reset

      }
    }

    byte readEEPROM(int deviceaddress, unsigned int eeaddress )
    {
      byte rdata = 0xFF;

      const uint8_t i2c_base_address = 0x50;
      const uint8_t upper_three_eeprom_adress_bits = (eeaddress >> 8) & 0x7;
      const uint8_t i2c_address = i2c_base_address | upper_three_eeprom_adress_bits;
      Wire.beginTransmission(i2c_address);
      Wire.write(eeaddress & 0xFF); // address LSB

      Wire.endTransmission();

      Wire.requestFrom(deviceaddress, 1);

      if (Wire.available()) rdata = Wire.read();

      return rdata;
    }

**ORIGINAL POST:**

I have created a circuit which includes an AT24C16 EEPROM which I only need to read from and an addressable LED (WS2812 IC), which I will be talking to (Using an Arduino Nano).

My original intention was to attach the LED's DIN pin to either SCL or SDA. I thought that since I only needed to read the EEPROM once (and then control the LED), I would be able to share the connection. After creating the circuit, it proved an incorrect assumption.

I am limited to 4 (nets?) total due to the adapter I am using between the Arduino Nano and the rest of the circuit (repurposed magnetic 4 wire USB cable). **Could anyone propose a setup which would allow me with only these 4 connections, to read from the EEPROM and write to the LED?** As I mentioned, I only need a single read from the EEPROM to identify it and then I will only be writing to the pixel. Many thanks!

Attached is the schematic.

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

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

body:
The AT24C16 is an I2C bus device but the WS2812 is not.  If you can tolerate spurious outputs on the WS2812 LEDs, you can read the AT24C16 using I2C by addressing the device properly.  The WS2812 will "listen" and may display things as that traffic is flowing past it.

When you are finished with the AT24C16 you will probably need to disable the I2C controller (assuming you are using that) and then hold the SCL line HIGH and then communicate with the WS2812 using the SDA line only.  The AT24C16 will ignore this non-I2C traffic because the SCL line is static a this point.


body:
This is just a hacky idea how you could solve this.

Decrease the I2C frequency below 10kHz or - as you only want to read the eeprom once at start - even down to 1kHz. This way the WS2812 will see a series of low pulses with a duration >50us which it should take as a reset signal. Practically, the WS2812 will ignore such a signal.

But there's a different problem: the EEPROM will write to the bus occasionally whenever it receives something that looks like its address. This in turn can
  - interfere with WS2812 communication.
  - damage the EEPROM's I2C interface if you control the WS2812 with push/pull signal (by setting gpios HIGH/LOW).

It would be safe to drive the WS2812s with an open drain signal (switching between LOW and INPUT), but that might require modifications to the WS2812 library.
In any case you should use the SDA line to control the WS2812 and there must be no signal on SCL while controlling the light (the EEPROM won't communicate if it receives no clock signal). The easiest might be to deactivate I2C entirely once you don't need it anymore and explicitly set the SCL pin to input mode. You then should be fine using SDA in normal push/pull mode and the library should work just as normal.


body:
This won't work with 24Cxx EEPROMS.
The I2C bus works this way:
* Master writes out an address.
* Slave takes over the SDA line and pulls it high or low to indicate an ACK or NAK.
* Master writes out a command for reading from an address.
* Again Slave takes over SDA and ACKs the command.
* Master is continuing to pulse SCL while Slave puts out data to SDA.
* After every byte (or word) Master has to take over SDA to confirm the data has been received.

So there is no way to tell the EEPROM to just vomit all its data to a bus without someone actively listening and ACK-ing. Which in turn changes the data on the bus.

---

It might work with 25Cxx EEPROMS.

You would need something different which has a much simpler communication scheme.
An 25Cxx which uses SPI for example, supports reading in a sequence, without constant ACK-ing. You will have to just initialize the read and keep clocking on SCK. No back and forth.
The data will be output to MISO in sequence.

But then still you will have to get the timings right. WS2812 are not very forgiving in that regard. That is why most people use libraries that have handcrafted Assembler code in them to get the timinigs right.

And I know what I am talking about as I wrote some myself (not suitable for anyone but me).
https://kwasi-ich.de/blog/2019/11/15/pwm_rider/


body:
setClock(1000) Problem
----------------------

This is *sort of* answer material, but it's meant to be supplementary to the other answers that more directly address your question and quite well, I think, though I'm unable to test right now.  So if you find this helpful, vote it up, but mark **one of the others** accepted if this tweak makes it work.

Specifically to address this content in your update:

> I have tried to reduce the I2C clock speed to 1khz but unfortunately
> having no luck.

And your line:

```c++
Wire.setClock(1000);
```

I was curious to know exactly how `setClock` maps its argument onto the values of  clock rate generating parameters in the hardware registers and whether or not 1 kHz might not be too slow for an AVR running at 16 MHz.  That is, perhaps the lower bound might be say 50 kHz, at which I'd've suggested a bit-banging I2C library in a comment to your question; however that's not the case.

In investigating this, I found that `setClock` **fails spectacularly** to do anything sensible in the AVR Arduino core library if given an argument of below `30304`.  Requested rates below this figure wind up yielding rates much higher than this owing to how they're calculating the clock rate with the TWI/I2C/"Wire" prescaler (`TWPS1` and `TWPS0` in `TWSR`) and the bit-rate register (`TWBR`).

I dug in to see what causes `setClock` to behave poorly for low rates, and there's not a lot to it.  The I2C/Wire [prescaler is set][1] to divide-by-1 and left that way.  `setClock` calls [`twi_setFrequency`][2], which calculates `TWBR` using this expression:
```c++
TWBR = ((F_CPU / frequency) - 16) / 2;
```

At 30304 Hz and above, this generates something within 1% of the desired frequency.  Along the x-axis is the requested rate.  The y-axis shows the effective rate.  Unsurprisingly, roughly linear.
[![30304 Hz and above][3]][3]

But below 30304 Hz, things go sideways. Values of 30303 or less when fed into that expression try to calculate a TWBR of 256 or greater.  But, it's an 8-bit register, so it rolls over. To prevent that a different prescaler would need to be selected.  But, it isn't and the following craziness results:
[![Below 30304 Hz][4]][4]

What `setClock(1000)` is *actually* doing in your code is setting a **rate of 125 kHz**; I have verified this on a scope.

Suggestion
----------

You can get an approximation of a 1 kHz clock rate by manually setting the hardware registers yourself, replacing your `setClock` line with the following:

```c++
TWSR |= 0x03; // chose divide-by-64 prescaler
TWBR  = 0x80; // closest to 1 kHz from below at 16 MHz with /64 prescaler.
```

**This should give you a TWI/I2C rate of about 975.61 Hz.**  In the datasheet for the ATMega328P you'll see this is selecting the divide-by-64 prescaler, and taking 128 ticks of that. You can find the equation in the datasheet, that if you fill these values and your UNO clock rate into, gives the expression 16e6 / (16 + 2 * 0x80 * 64), which gives you the 975.61 figure above.  I've verified that it is approximately that on a scope.

**Give that a try.  See if when you do, whether or not one of the answers doesn't work for you.**  I expect one will.

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/Wire/src/utility/twi.c#L91
  [2]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/Wire/src/utility/twi.c#L139
  [3]: https://i.stack.imgur.com/cBCvS.png
  [4]: https://i.stack.imgur.com/12Sr2.png


body:
My working details, per-request
===============================

Setup
-----
So, the setup is the same as you what you have in its essentials:

* The code is your code with the near-1 kHz tweak.  That said, I believe I also tested it at the default rate and that worked as well.  In any case, the images that show the LED changing were taken while that 1 kHz adjustment was made.

* The UNO and Nano are functionally identical for this.  They use different serial transceivers which has nothing to do with anything.   The Nano will typically have a lower "5V" than the UNO when USB powered owing to the Nano using a diode where the UNO has a FET.  Which is unlikely to matter either.  They're otherwise the same device so far as the setup goes.

* The [24LC02B][1] uses the same pinout and I2C address and command-sequences as your [AT24C16][2].  It is a smaller memory, not that it makes a difference; we're reading from address 0.  I did not find I necessary to add external pull-up resistors and it worked, so it seemed unnecessary to add them to demonstrate that it can work since adding them should only improve it's chances for working correctly.

* The LEDs are the [Adafruit ADA1643 12 Neopixel Ring][3]. We're both using the first LED of a string, doesn't really matter how long the are.   We're only lighting one "pixel" so I just powered it from USB.  Have no idea what you're doing there.  But for one LED lit, I doubt a difference there would matter much.

* You'll see a resistor connecting SDA at the EEPROM to IN on the addressable LED(s).  I put that there in case by some chance the EEPROM could drive SDA low while the addressable LED code was driving the LED data line high. while.  I doubt that can happen, but it was a small thing to do.  For what it's worth, I did run it briefly without it in series, and it also worked fine that way as well.  I'm only telling you this so you have all the information and not because *I* think it matters; I don't.

Running
-------
It prints out 72.  This *is* the first value in my EEPROM. The 'H' of "Hello world" basically.  And then it goes on to cycle the first addressable LED of the set through all of the colors.

Configuration Pictures
----------------------

[![Overall setup][4]][4]
[![Top-down view of breadboard][5]][5]
[![Breadboard close-ups][6]][6]
[![Colors][7]][7]

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/24AA02-24LC02B-24FC02-Data-Sheet-20001709L.pdf
  [2]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8719-SEEPROM-AT24C16C-Datasheet.pdf
  [3]: https://www.adafruit.com/product/1643
  [4]: https://i.stack.imgur.com/PQ2yA.jpg
  [5]: https://i.stack.imgur.com/zzCSp.jpg
  [6]: https://i.stack.imgur.com/lJ0U8.jpg
  [7]: https://i.stack.imgur.com/QK5di.jpg


message:
Understanding ArduinoJson capacity calculation assistant

I am trying to figure out how `ArduinoJson` capacity can be calculated, therefore I came by the Assistant web application developed by the developer of the library https://arduinojson.org/v6/assistant/

Here what I do not understand is, why when I use either of the following two JSON strings, the helper shows me the same capacity? I would expect that the longer JSON values will result in a bigger capacity, but this does not seem to be the case.

    {
      "wifi": {
        "ssid": "S",
        "password": "P",
        "hostname": "H"
      },
      "administration": {
        "username": "U",
        "password": "P"
      }
    }

    {
      "wifi": {
        "ssid": "SSSSSSSSSSSSSSSSSSSSSSSSSSS",
        "password": "PPPPPPPPPPPPPPPPPPPPPPPPPP",
        "hostname": "HHHHHHHHHHHHHHHHHHHHHHHHHHHH"
      },
      "administration": {
        "username": "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
        "password": "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"
      }
    }

I am trying to calculate the capacity using the assistant using the following configuration:

*ESP8266 / **Deserialize** / char**

Could you anyone explain this to me? Apparently I understand the "reason" behind the capacity wrong?

body:
If you look at the details of the numbers reported, you should see:

    Data structures     112
    Strings             0
    Total (minimum)     112
    Total (recommended) 128

As you see, there are exactly zero bytes allocated for the strings. This
means that the library does not copy the strings, and instead references
them from the character array you provide as an input.

If you instead configure the library for `Stream` input, it will have to
store the strings, and the capacity is then very different for these two
documents.


body:
I found what the real problem is. In the assistant tool, when choosing `const char *` as the input type, it shows that the size of the string is 0, which is **wrong** according to the documentation of the library.

https://arduinojson.org/v6/api/json/deserializejson/

> // writable input => zero-copy
> DeserializationError deserializeJson(JsonDocument& doc, char* input);
> // read-only input => duplication
> DeserializationError deserializeJson(JsonDocument& doc, const char* input);

The assistant, if I see correctly, does **not** distinguish between these two cases, and thus gives the wrong capacity for this `const` case.

Accordingly, **in `const char *` it is not enough to only take the size of the structure, but also we need to consider the data stored in it.**

According to [the documentation][1], the reason why `const char *` cannot be a zero-copy is:

> 3.9.2 Duplication is required
As we saw in the previous section, in the zero-copy mode, ArduinoJson stores pointers
pointing inside the input buffer. We saw that it has to replace some characters of the
input with null-terminators.
With a read-only input, ArduinoJson cannot do that anymore, so it needs to make copies
of "hip" and "hop". Where do you think the copies would go? In the JsonDocument, of
course!

### UPDATE

After reporting this bug (see the link below), it has been quickly fixed!

https://github.com/bblanchon/ArduinoJson/issues/1488

  [1]: https://arduinojson.org/v6/doc/deserialization/


message:
Incorrect DateTime value constructed

I'm working on alarm clock project using Arduino Nano (v 3.0, clone) and RTC module ZS-042 (containing DS3231 and EEPROM AT24C32).

The intention is to load the hours and minutes from EEPROM on start-up, use current date (to avoid zero-date problems) and compose DateTime object in order to utilize the TimeSpan object, making time calculations easier than using plain integer math. The issue is, the value in DateTime object seems not constructed correctly, although all the components used for its construction seem OK.

With the following code
```
/* Hardware definitions */
//RTC using I2C, pins 4,5
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;

#include <extEEPROM.h>
extEEPROM e2p(kbits_32, 1, 32, 0x57);

DateTime  alarm1Time;

void setup(){
  Wire.begin();
  rtc.begin();
  Serial.begin(115200);
  uint8_t e2pStatus = e2p.begin(extEEPROM::twiClock400kHz);      //go fast!
  DateTime t = rtc.now(); //get current time from RTC
  Serial.print("t.year: ");  Serial.print(t.year());
  Serial.print(" t.month: ");  Serial.print(t.month());
  Serial.print(" t.day: ");  Serial.println(t.day());
  alarm1Time = (t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
  Serial.print("E2P : ");
  Serial.print(e2p.read(1));
  Serial.print(":");
  Serial.println(e2p.read(2));
  char buf1[] = "YYMMDD-hh:mm:ss";
  Serial.println(alarm1Time.toString(buf1));
}
```
I get on the serial monitor the following:
```
t.year: 2021 t.month: 1 t.day: 31
E2P : 7:15
060206-06:28:16
```
The date components (year, month, date) correspond to current date. As the bytes on address 1 and 2 in EEPROM read 7 and 15, I'd expect the Alarm1Time be 2021-01-31, 07:15, which isn't.
The output is constant, whatever the current date and the EEPROM stored time. Later in my code the alarm1Time parses into 6 hours and 28 minutes, in accordance with last line of the serial monitor output.

What could be (or better - where I'm) wrong? Thanks.

Libraries used:

**RTClib** (https://github.com/adafruit/RTClib)

**extEEPROM** (https://github.com/JChristensen/extEEPROM/blob/master/extEEPROM.h)

body:
Here:

```c++
alarm1Time = (t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
```

you are repeatedly using the comma operator, which essentially means
“discard all the values but the last one”. If you want to invoke the
`DateTime` constructor that takes these arguments, you should call it
explicitly:

```c++
alarm1Time = DateTime(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
```

or, better yet, you can declare and initialize `alarm1Time` at the same
time:

```c++
DateTime alarm1Time(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);
```


message:
I'm trying to upload a sketch to my arduino uno, but I get the Error-Message "avrdude: stk500_recv(): programmer is not responding"

```none
    Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
```

 - I selected the right board (Arduino Uno)
 - I selected the right port
 - I selected "USBasp" as programmer
 - I reset the board multiple times
 - I have uploaded to the same port multiple times before without getting an Error
 - I disconnected the USB-cable multiple times and used a different one
 - I don't get the Error Message on a different board (also Arduino Uno)
 - When I'm trying to upload with the serial Monitor open i see an orange lamp (RX lamp) blinking in the same speed the Errors are given
 - When I'm trying to "Burn Bootloader" I get following Error:

```none
Arduino: 1.8.13 (Linux), Board: "Arduino Uno"

avrdude: error: could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp'
Error while burning bootloader.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
```

body: The problem was an Bluetooth extension I connected to the board. I removed it, uploaded the program, reconnected it, and that worked!


message:
Float to int conversion not working right in method using varargs

I am trying to convert a floating point number to an integer, but it seems like the conversion is not working properly.

I am using the math library to calculate the power of 10 based on the number of varargs, where the first argument is the number of arguments followed by the varargs.

```
int charsToIntValue(int argc, ...) {
  int multiplier = (int) pow(10, argc - 1);
  va_list argp;
  va_start(argp, argc);
  Serial.println(multiplier);
  ...
  va_end(argp);
}
```
For some reason, `multiplier` is always stored as 1 less than the actual result.
e.g. If `charsToIntValue(4, 1, 2, 3, 4)` is executed, the multiplier is stored as 999 rather than 1000. However, when it is printed as a float, it does show 1000.00. And whenever I change it to a constant (`(int) pow(10, 3)`) it works fine, returning 1000.

I've tired storing the value of argc into a local variable but that didn't seem to change anything.

Full project is here for context: https://github.com/Pyrodron/charger-destination-board

File in question is charger-destination-board.ino; lines 32 to 51

body:
With some inspiration from timemage's comment, I decided in the long run to implement my own power function that takes two `int` arguments and returns an `int`. Rather than use the `pow` function in the `<math.h>` library which returns a `double` when I only need an `int`.
```
int power(int x, int y) {
  return y == 0 ? 1 : x * power(x, y - 1);
}
```
Now the program works as intended!


body:
As explained by @chrisl in a comment, the issue is that `pow()` does not
return an exact result, only an approximation. It works fine with
compile-time constants because in this case it is evaluated at compile
time, by the compiler, on you PC.

Simple solution: replace the cast to int with `round()`:

```c++
int multiplier = round(pow(10, argc - 1));
```

This works, but is awfully inefficient, as `pow()` involves the
computation of both an exponential and a logarithm, both very expensive
on an AVR-based Arduino. The int-only function in your own answer is
certainly better. However, it is generally advised to avoid recursion on
low-memory Arduinos like the Uno. Prefer an iterative algorithm if you
can.

Also, the complexity of you int-only function is O(y). There is a
well-known algorithm for integer powers that goes like O(log(y)):

```c++
int power(int x, int y)
{
    int z = 1;  // Invariant: result = x^y * z
    while (y) {
        if (y & 1) z *= x;
        y >>= 1;
        x *= x;
    }
    return z;
}
```

Maybe I am nitpicking, as your `y` cannot go beyond 5 without
overflowing the result...


message:
Cant find Sdl and Sca pins in lcd display

My project is of non contact temperature sensor.I am using RG1602A lcd display and mlx90164 temperature sensor.
But the problem is, there's no sdl , sca pins in my lcd display.

Is there any way, to overcome?

body:
You will need an [I2C adapter board][1] like this to interface your LCD 1602 via I2C.

  [1]: https://www.aliexpress.com/item/1005002070253348.html


message:
How to get a specific value from an unknown number of JSON representations?

I am using ArduinoJson and ESP8266HTTPClient.

Say I have a DynamicJsonDocument that has an unknown number of entries with information on different persons:

```
[
    {
        "ID": "12345",
        "name": "John Smith",
        "Address": "Street 1"
    },

    .
    .
    .

    {
        "ID": "00345",
        "name": "Paul Anderson",
        "Address": "Street 2"
    }
]

```

I would like to somehow store the values associated with the key "name" for all the different persons. For example, have something like:

```
String name1 = "";
...
String nameN = "";

.
.
.

Serial.println(name1);
...
Serial.println(nameN);

```

To print a list of all the names:

```
John Smith
Paul Anderson
```

The only information of the JSON I have beforehand is the keys each entry will have. I do not know how many entries there will be.

How can I go about this?

EDIT: Why I want to do this:

I am using the ESP as a client to get information from a server in the form of a JSON similar to what I wrote above. At the same time, I am serving a simple HTML website by doing `server.send(200, "text/html", HTML_code);` using the ESP as an AP. I was able to just cram the whole JSON into the HTML as text, but I would like to just have specific information from the JSON, as explained above.

I am aware what I am doing is far from elegant or the "correct way to do it", but I am learning all of this, so any criticism and help is more than welcome :)

body:
Directly from the [ArduinoJson Assistant](https://arduinojson.org/v6/assistant/):

```c++
// Stream& input;

StaticJsonDocument<384> doc;
deserializeJson(doc, input);

for (JsonObject elem : doc.as<JsonArray>()) {
  const char* ID = elem["ID"]; // "12345", "13244", "00345"
  const char* name = elem["name"]; // "John Smith", "Jason Statham", "Paul Anderson"
  const char* Address = elem["Address"]; // "Street 1", "Street 2", "Street 3"
}
```

See also:

* [How to use ArduinoJson with HTTPClient?](https://arduinojson.org/v6/how-to/use-arduinojson-with-httpclient/)
* [How to deserialize a very large document?](https://arduinojson.org/v6/how-to/deserialize-a-very-large-document/)


message:
Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using 'localhost:1.0' as the value of the DISPLAY variable

I have tried everything on this url

https://stackoverflow.com/questions/10165761/java-cant-connect-to-x11-window-server-using-localhost10-0-as-the-value-of-t

session output:

    root@whale:/home/kermit# echo $DISPLAY
    localhost:1.0
    root@whale:/home/kermit# cd dev/sht30/
    root@whale:/home/kermit/dev/sht30# arduino --upload sht30v1.ino --port /dev/ttyUSB0
    Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using 'localhost:1.0' as the value of the DISPLAY variable.
            at java.desktop/sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
            at java.desktop/sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:102)
            at java.base/java.security.AccessController.doPrivileged(Native Method)
            at java.desktop/sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:61)
            at java.base/java.lang.Class.forName0(Native Method)
            at java.base/java.lang.Class.forName(Class.java:315)
            at java.desktop/java.awt.GraphicsEnvironment$LocalGE.createGE(GraphicsEnvironment.java:101)
            at java.desktop/java.awt.GraphicsEnvironment$LocalGE.<clinit>(GraphicsEnvironment.java:83)
            at java.desktop/java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:129)
            at java.desktop/sun.awt.X11.XToolkit.<clinit>(XToolkit.java:231)
            at java.base/java.lang.Class.forName0(Native Method)
            at java.base/java.lang.Class.forName(Class.java:315)
            at java.desktop/java.awt.Toolkit$2.run(Toolkit.java:588)
            at java.desktop/java.awt.Toolkit$2.run(Toolkit.java:583)
            at java.base/java.security.AccessController.doPrivileged(Native Method)
            at java.desktop/java.awt.Toolkit.getDefaultToolkit(Toolkit.java:582)
            at processing.core.PApplet.<clinit>(Unknown Source)
            at processing.app.Preferences.save(Preferences.java:735)
            at processing.app.Preferences.init(Preferences.java:249)
            at processing.app.Base.main(Base.java:117)

How do you run arduino in headless mode on a raspberry pi?

body:
It is probably a non-existant or stale auth cookie in your .Xauthority file.  This sort of thing happens when you're running your X session with one user but trying to run your X application as different user.  Doing sudo or su root (or really any other user) is a common way to get in that situation.  Running the IDE as root usually mean something else has already gone sideways.  The typical reason for that is you're running as root instead of fixing your permissions to the Arduino serial device file.

---

That said, if you want to run headless builds and uploads of Arduino projects, what you're looking for is [arduino-cli][1].

```bash
cd /path/to/directory/containing/sht30v1.ino
arduino-cli -b arduino:avr:nano compile
arduino-cli -b arduino:avr:nano upload --port /dev/ttyUSB0
```

  [1]: https://arduino.github.io/arduino-cli/latest/


message:
Programming 328PB from Arduino IDE using Atmel-ICE to ICSP port

Updated question.  The original question was based on using 'Upload' from the Arduino IDE, instead of 'Upload Using Programmer' under 'Sketch'.  The problem in getting the Atmel-ICE to work with Arduino IDE appears now to be one of incorrect ICE drivers loaded when I installed Atmel Studio. [![Device Manager conflict][1]][1]

Arduino requires libusb-win drivers, which can be checked with Zadig.   Available here: [https://zadig.akeo.ie/][2]

This problem was 99% solved (with help) by selecting [![Install WCID driver][3]][3] and the libusb-win32 driver using Zadig.   I say 99% solved, because _my program now loads and runs!_ , but I do get the red 'X' there as the WCID status.

Apologies if this amendment to the original question is not in the correct context, this is new to me.   Thank You.
Jaco

  [1]: https://i.stack.imgur.com/4CAWp.jpg
  [2]: https://zadig.akeo.ie/
  [3]: https://i.stack.imgur.com/SCZCk.jpg

body:
Hello The 328 "PB" has major issues with running external clocks...(yes I have first hand experience with this PB model)... Try switching to the internal oscillator as I can testify first hand the the external clocks on the PB don't work correctly. They tend to sell the PB a few bucks cheaper because you will only buy them once and only once when you find out how bad the external crystal clock driver is. If you look at the latest datasheet for the PB they try and talk their way out of the bad driver by explaining how you need to match capacitors with the following snippet. I call BS as the 328p never needed such precision on it Xtal1 & 2 pins to run but to be fair they PB is meant to be low power.

This Crystal Oscillator is a low power oscillator, with reduced voltage swing on the XTAL2 output. It gives
the lowest power consumption, but is not capable of driving other clock inputs, and may be **more
susceptible to noise in noisy environments.**
The crystal should be connected as described in Clock Source Connections. When selecting crystals,
load capacitance must be taken into consideration. The capacitance (Ce+Ci) needed at each TOSC pin
can be calculated by using:
�� + �� = 2�� − ��
where:
• Ce - is optional external capacitors. (= C1, C2 as shown in Figure 11-2)
• Ci - is the pin capacitance in Table 11-3.
• CL - is the load capacitance specified by the crystal vendor.
• CS - is the total stray capacitance for one XTAL pin.
Table 11-


message:
Short circuiting GND and power pins

I have created an arduino shield and i want to measure the voltage between the GND pin and 5V pins, to see if i see a voltage difference between the two points, in order to test if my pcb is fine.

My concern is since these are right next to each other and my multimeter probes are thick.

If the multimeter probe that 5V pin touches the GND pin, in other words, if i short circuit the 5V and GND pins, then will my arduino be safe?

I am afraid of damaging the arduino.

body:
It all depends on how you are powering the board.

If you're running it from USB then the computer should shut off the power to the USB port. If it doesn't then the Arduino has a small self-resetting fuse on the USB power which should shut the power off for you.

However if you're powering through the barrel jack there's no protection. Worst case scenario: it will blow the voltage regulator, which then "fails short", meaning it passes the whole of the input voltage through to the microcontroller, which then kills it.

So yes, it's possible to damage the Arduino with a short circuit.

Most multimeters have a better way of testing the board though: either the "beepy" continuity test, or the resistance mode.  You can use that to test the continuity or resistance between your 5V and GND pins without having to connect the shield to the Arduino at all. 100% safe.


body:
No, shorting +5 to Gnd is not safe, although a brief short might not cause damage. If it persists, you could burn a trace, overheat the voltage regulator, or damage the computer USB if that is what powers your Arduino. Most computers will sense that short and disconnect power to that USB until the short goes away, but you don't want to count on it!

If your meter has probes with clip-ends, use those to clip two bread-board wires, and probe the Arduino pins by plugging the wires into your shield. If the shield has no pin sockets installed, at least the bread-board wires are small enough not to short adjacent pins.


body: mostly yes , mostly no . my old arduino got a little too much dusty and when i cleaned it with mild amount of water (nervously) and dried it partially . nothing happened to it . it was operating normally . but some beginner manuals tell not to short circuit it . dunno what's going on ...


message:
ESP-01 not responding to serial data while programming with esptool.py

I have a Arduino uno board, ESP-01 board and a logic level shifter (bidirectional) and to program the esp module i wired my Arduino and esp like this

>__Arduino uno(atmega328p removed)__  --> __level shifter__ --> __ESP-01__\
>5v --> highvolt\
3v3 --> lowvolt\
TX --> ch1 --> TX\
RX --> ch2 --> RX\
proper ground connections

but when i click upload the RX pin lights up indicating its receiving data but esp doesn't respond to that when i reset the module while its uploading the compiler throws this
```esptool.py v2.8
Serial port COM3
Connecting........_____....._____....._____....._____....._____....._____.....____Traceback (most recent call last):
  File "C:\Users\TRAJU\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4/tools/upload.py", line 65, in <module>
    esptool.main(cmdline)
  File "C:/Users/TRAJU/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool\esptool.py", line 2890, in main
    esp.connect(args.before)
  File "C:/Users/TRAJU/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool\esptool.py", line 483, in connect
    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header
_
the selected serial port _
 does not exist or your board is not connected
```

It as working fine yesterday and it stopped today :(

Please help and thanks in advance.

body:
I found my problem.

esptool.py uploads the firmware at 115200 baud rate, which my logic level converter couldn't handle.  I found this out after writing this question. I thought of connecting RX and RX directly to the ESP module's RX and TX and it uploaded the program. Maybe I am wrong.  Please, if any one know why this happened I am curios to know.  Thanks in advance. ;)


message:
Arduino analog input to iphone notification

I need some help :)
 1. Is it even doable?
 2. Is there anyone who wants to help me program it?

My wish:
I want to receive a iphone notification when 1 arduino analog input drop from 5 to 0 volt.

Then (later) when the voltage goes back to 5V i want another message.

It needs to be over Wifi (not BT).

Is there anyone that can help me with this?

Thanks in advance

body:
It is totally doable, but we cannot give detailed tutorials here, since this is a simple Q&A site. So I will point you to a direction, that can lead you to the solution.

When building IOT devices with Arduino (and thats exactly, what you are doing) there are 2 internet services, that are commonly used for getting information from the device to other devices (like your phone):

- Blynk
- IFTTT (means If This Then That)

Both have apps and can be used to push notifications, when your IOT device does a webrequest to the service. There are also libraries for Arduino available (at least for Blynk). There are many tutorials out there, so I suggest, that you search for yourself and try some of them.

For the hardware of your IOT device, I would suggest an ESP board, because they already have Wifi build in, for example the ESP32 gives you great IO capabilities.


message:
Arduino, problem with interrupt and SSD1306 OLED

I'm not that good at this. Calculates RPM through Peripheral Speed and Interrupt.

Everything works fine when I show this in the IDE with `Serial.print` without OLED. When I connect an SSD1306 OLED I2C, the interrupt stops working. No `serial.print`.

If I uncomment the `display.display()`, Same problem with `display.setRotation(90)`: everything is fine and `serial.print` starts working, but of course not the OLED.

In the code I have a `void` addressing, `visadisplay()`. If I put this addressing in `void loop ()` then everything works but then there is a risk of unsynchronization, wrong values. I have also removed `visadisplay();` without change.

Help...

```c++
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Function for serial display.
// Connections for Nano.
// Hall sensor connection: (Signal out) --- (D2).
// Display connection: (SDA) --- (4A) / (SCL) --- (A5)

volatile unsigned long PulsTid = 0UL;
volatile unsigned long StartTid = 0;
volatile unsigned long SlutTid = 0;
volatile unsigned long CalcTid = 0;
volatile float omkrets = 7.5;
volatile float HastighetPerferi = 0;
volatile unsigned long Rpm = 0;
volatile float Vinkel = 0UL;

void isr() { // interrupt service routine
  Vinkel = 0;
  StartTid = millis();
  CalcTid = SlutTid;

  detachInterrupt(0);             //detaches the interrupt while calculating

  PulsTid = (StartTid - SlutTid);
  HastighetPerferi = (omkrets / PulsTid);
  SlutTid = StartTid;
  Rpm = ((HastighetPerferi / (omkrets / 1000) * 60) / 2); // Calculate speed

  visadisplay();
  attachInterrupt(0, isr, FALLING);  //attaching the interrupt again
}

void visadisplay(void) {
  Serial.print("Varvtal: ");
  Serial.println(Rpm);

  display.setRotation(90);
  display.clearDisplay();
  display.setTextSize(1);              // Text size.
  display.setTextColor(SSD1306_WHITE); // White text.
  display.setCursor(0, 0);             // Start position
  display.println("RPM: ");
  display.setCursor(40, 10);
  display.setTextSize(2);
  display.print(Rpm);
  display.display();
}

void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr, FALLING);  //attaching the interrupt

  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
}

void loop(){
}
```

body:
Your problem is (most likely) that you are doing *everything* from an interrupt. That is not only bad practice, but on Arduinos it is generally impossible.

On small microcontrollers you typically only have one interrupt priority (occasionally two). That means that only one interrupt can run at a time, and if an interrupt is running then no other interrupt can interrupt it.

So anything that relies on interrupts to operate can never be used inside an interrupt service routine, or it will never function.

That includes things like `delay()` and, depending on the implementation, such things as `Wire` (I2C) and `SPI`.

Instead your ISR really should be as short as possible. It should at most do any short calculations and store results, and then indicate (through the use of a *semaphore*) to the main thread that it should do some work.

The simplest "fix" to your problem would be to move `visadisplay()` into `loop()` and in `isr()` simply set a `bool` flag when there is data to display. Your `loop()` then checks that flag and, if set, resets it and calls `visadisplay()`.

Also, you don't need to detach and re-attach the interrupt all the time - if the ISR is running then interrupts can't happen anyway.

```c++
// ... snip ...
volatile bool doDisplay = false;

void isr()          //interrupt service routine
{
  Vinkel = 0;
  StartTid = millis();
  CalcTid = SlutTid;

  PulsTid = (StartTid - SlutTid);
  HastighetPerferi = (omkrets/PulsTid);
  SlutTid = StartTid;
  Rpm = ((HastighetPerferi/(omkrets/1000)* 60)/2);  //Calculate speed

  doDisplay = true; // Signal to the main thread there's data to display
}

// ... snip ...

void loop() {
    if (doDisplay) {       // If there is something to display
        doDisplay = false; // then clear the flag for next time
        visadisplay();     // and display the data.
    }
}
```


body:
About rotating text on OLED, rotation codes are 0, 1, 2, 3
(see [Adafruit web site](https://learn.adafruit.com/adafruit-gfx-graphics-library/rotating-the-display)).

So your code should look like:
```c++
  Serial.print("Varvtal: ");
  Serial.println(Rpm);

  display.setRotation(1);
  display.clearDisplay();
 ```


message:
Arduino measuring high-voltage electric fence

I would like to know if someone has experience with measuring high voltages using an Arduino.

I know you can use resistors to lower the voltage, however.

I want to be able to measure the pulses of an electric fence used to prevent farm animals from escaping. These pulses are high-voltage and will not always be a similar voltage. I want to read these voltages, to scan for differences.

So, I wondered if someone has done something like that, and if the Arduino gets weird when it gets a voltage above 5 V at a low amperage on its analog port.

--here some possible solutions for those wanting to know the answer--
-mostly based on comments and answers below-

 - Using resistors as a voltage divider while keeping an eye on the maximum spark gap distance and capacitive coupling.
 - using a transformer/coils to reduce the voltage.
 - using a high voltage probe to measure it.
 - using neon bulbs or other light sources to measure it.
 - charging a capacitor and measuring discharge time with high resistance(only works for the total power)

-this list is meant as a summary of what is discussed further ideas and solutions are still welcome-

body:
You are talking about measuring 2 to 10 kV pulses, with about 1 to 5 J of energy per pulse.

The maximum current may be very low, but the voltages you want to measure are very high, and will very probably damage your Arduino without proper measures.

You will at least need a voltage divider to reduce the voltage the Arduino sees to 5 V (or 3.3 V for some Arduinos) to be able to make a measurement with the Arduino's ADC.

The voltages are high enough to bridge a fair distance with a spark; they could well bridge a physically small resistor or the distance between two connections on your breadboard or PCB.

To be honest, I think you shouldn't go anywhere near such voltages with an Arduino, unless you know exactly what you are doing when preparing the signal for an Arduino's ADC pin.


body:
When you say 'scan for differences', do you mean differences along the fence, or something else?  Do you plan to use the Arduino as a portable voltmeter?  If so, buying a HV probe for a standard voltmeter sounds a lot more practical.

However, if you plan to install multiple sensor points along the fence so that you can continually monitor pulse amplitudes along the fence, then that is a different kettle of fish, especially if you are thinking about outdoor use over a long fence length.

Can you elaborate a bit, please?


message:
What are the correct pins for TWAI (CAN) on ESP32?

compared to the microchip's PICs:

pic16f's does not have an onboard CAN peripheral. so you need an SPI - CAN controller (like MCP2515).

some PIC18f's have an onboard CAN controller, and only need a CAN transceiver. In these cases there are exclusive TX and RX pins to be used.

Are there specific pins to be used as a CAN bus on esp32?
peripherals like adc, i2c and others need to use specific pins. Does this happen with CAN too?

I'm using the following configuration:
2 ESP32 devboard boards - arduino on PlatformIO
Pin 5 as TX and pin 4 as RX (already in the CAN library),
2 Sn65hvd230 transceiver modules

I looked for information about it in the documentation, but I couldn't find it.

I appreciate any help.

body:
> I looked for information about it in the documentation, but I couldn't
> find it.

Well, some of [their documentation][1] says:

> The TWAI controller’s interface consists of 4 signal lines known as
> TX, RX, BUS-OFF, and CLKOUT. These four signal lines can be routed
> through the GPIO Matrix to the ESP32’s GPIO pads.

And that sort of seems to be backed up by their examples that make use of [TWAI_GENERAL_CONFIG_DEFAULT][2] to generate a structure with the arguments [filling fields that use `gpoi_num_t`.][3]

There is documentation to the GPIO Matrix generally in the [ESP32 technical reference][4].  It is described there as follows:

> The ESP32 chip features 34 physical GPIO pads. Each pad can be used as
> a general-purpose I/O, or be connected to an internal peripheral
> signal. The IO_MUX, RTC IO_MUX and the GPIO matrix are responsible for
> routing signals from the peripherals to GPIO pads. Together these
> systems provide **highly configurable I/O.**

(My emphasis in the above).

And also there is a table (Table 25) in Appendix 2 of the [ESP32 datasheet][5] for the GPIO matrix.

Many of the small chips, like the PIC16F series ones, have no internal routing for peripherals, except for deciding which of one or two special functions to use rather than GPIO and ADC channels.  Most of the of the ATTiny and ATMega series AVR chips that are not in the 0- and 1- series don't.  The 1- and 0- series an a few of the older series parts (e.g. ATTiny841) give you a fixed number (usually two) pre-determined destinations to chose from for some peripherals.

This sort of thing gets more flexible as you get into larger chips, but the having that "matrix" feature that lets choose more freely is *comparatively* rare.  Some of the Cypress "PSoC" labeled chips have this sort of feature.

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html
  [2]: https://github.com/espressif/esp-idf/blob/v4.2/components/driver/include/driver/twai.h#L43
  [3]: https://github.com/espressif/esp-idf/blob/v4.2/components/driver/include/driver/twai.h#L98
  [4]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#iomuxgpio
  [5]: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf


body:
When using arduino and the esp32 core, **any pin** can be assigned to the builtin TWAI controller.

If you use the esp32_can library [https://github.com/collin80/esp32_can][1]
you may change the pin assignment in the following file:

C:\Users\USER\Documents\Arduino\libraries\esp32_can-master\src\esp32_can.cpp

> //Set these to the proper pin numbers for you board. Set by default to correct for EVTV ESP32-Due

             //rxpin       txpin

ESP32CAN __attribute__((weak)) CAN0(**GPIO_NUM_16**, **GPIO_NUM_17**) ;

>//Select and uncomment the proper module you've got connected via SPI

//CS, INT

MCP2517FD __attribute__((weak)) CAN1(5, 27) ;

//MCP2515 __attribute__((weak)) CAN1(5, 27) ;

  [1]: https://github.com/collin80/esp32_can


message:
How to you initialize a reset on a sht30 digital thermometer?

I have a sht30 that will output correct temperature readings for about 5 min and then will drift off.

So I'm trying to hit the reset every few seconds to keep the readings accurate.

I am on a nano connecting d4 to the sht30 reset pin, but I don't appear to be resetting. My temp still drifts.

How do you correctly hit the reset on a sht30?

code:

    #include <Wire.h>

    // SHT31 I2C address is 0x44(68)
    #define Addr 0x45

    int reset_pin = 3; // reset pin is set to d4 on board.
    int counter = 0; //reset counter

    void setup()
    {
      // Initialise I2C communication as MASTER
      Wire.begin();
      // Initialise serial communication, set baud rate = 9600
      Serial.begin(115200);
      delay(300);
    }

    void loop()
    {
      unsigned int data[6];

      // Start I2C Transmission
      Wire.beginTransmission(Addr);
      // Send 16-bit command byte
      Wire.write(0x2C);
      Wire.write(0x06);
      // Stop I2C transmission
      Wire.endTransmission();
      delay(300);

      // Start I2C Transmission
      Wire.beginTransmission(Addr);
      // Stop I2C Transmission
      Wire.endTransmission();

      // Request 6 bytes of data
      Wire.requestFrom(Addr, 6);

      // Read 6 bytes of data
      // temp msb, temp lsb, temp crc, hum msb, hum lsb, hum crc
      if (Wire.available() == 6)
      {
        data[0] = Wire.read();
        data[1] = Wire.read();
        data[2] = Wire.read();
        data[3] = Wire.read();
        data[4] = Wire.read();
        data[5] = Wire.read();
      }
      // Convert the data
      int temp = (data[0] * 256) + data[1];
      float cTemp = -45.0 + (175.0 * temp / 65535.0);
      float fTemp = (cTemp * 1.8) + 32.0;
      float humidity = (100.0 * ((data[3] * 256.0) + data[4])) / 65535.0;

      // Output data to serial monitor
      Serial.print("Temperature in Celsius :");
      Serial.print(cTemp);
      Serial.println(" C");
      Serial.print("Temperature in Fahrenheit :");
      Serial.print(fTemp);
      Serial.println(" F");
      Serial.print("Relative Humidity :");
      Serial.print(humidity);
      Serial.println(" %RH");
      delay(500);
      if(counter == 25){
        digitalWrite(reset_pin, HIGH); // sets the digital pin 13 on
        delay(1000);            // waits for a second
        digitalWrite(reset_pin, LOW);  // sets the digital pin 13 off
        delay(1000);
        counter  = 0;

      }
      counter++;
      Serial.println(counter);
    }

body:
You need to give a brief LOW pulse, not a long HIGH pulse:

In setup:
```c++
pinMode(reset_pin, OUTPUT);
digitalWrite(reset_pin, HIGH);
```

When you want to reset:

```c++
digitalWrite(pin_reset, LOW);
delay(1);
digitalWrite(pin_reset, HIGH);
```


message:
Storing data from Arduino without Serial print- High Sample rate

For my work, I need to acquire data at a high sample rate (>100kSa/sec) using Arduino Portenta H7, which has 3 X 16-bit ADCs. Portenta H7 has STM32H747XI microcontroller. I don't want to use Serial.print command as I came to know that this command takes much time to execute, which makes achieving the targeted sample rate impossible.  What are the other possible ways to store the data from Arduino while maintaining this high sample rate? For example, saving the data and then printing them all at once at the end of testing( 3-5 second testing period). e.g. using an SD card or through saving in Arduino internal memory? Can you suggest techniques employed for high-sample rate data acquisition from Arduino?

body:
The [Portenta][1] has a beast of an  STM32H7 Cortex M7 and a minimum of 8M bytes of external SDRAM in addition to the 1M on-chip.

You need to capture 2channels x 2 bytes x 100K/s x 5s = 2M bytes of data, so storing it on the on-board RAM and spitting it out later seems like a viable and low-risk approach.

A slow serial link might take a few minutes to transmit 2M bytes of data, but you have various other options if that is objectionable.

  [1]: https://www.arduino.cc/pro/hardware/product/portenta-h7


message:
How to close/end a Wire.begin()?

I have an ESP32 cam, and I attached an i2c light sensor to it. I need to read the light level at startup, then I don't need the i2c connection again.
The problem is, the board uses 2 i2c connections I think (for the camera and such). So I use my custom pins for the sensor (15 and 16). It works well, I can read the light just fine, but then the camera fails because (I believe) the Wire.begin(15,16) changes the default pins and the camera gets confused.

So I would like to do something like Wire.end() to forget that I started the Wire.begin(). Any idea on how I can do that?

Here is the relevant code:

    #define I2C_SDA 16
    #define I2C_SCL 15
    BH1750 lightMeter (0x23);
    TwoWire I2Clightmeter= TwoWire(1);

    void setup()
    {
      I2Clightmeter.begin(I2C_SDA, I2C_SCL);
      lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,&I2Clightmeter);

      delay(1000);
      uint16_t lux = lightMeter.readLightLevel();

    //rest of the code

body:
There is a way of doing it that's ESP32 specific. However it means changing how you define your I2C object.

The ESP32 system is set up so that if the TwoWire instance is destructed the I2C bus is released. But you can't do that with the way you normally define the object. So instead you have to use dynamic allocation to control it:

```c++
TwoWire *I2Clightmeter;

void setup() {
    I2Clightmeter = new TwoWire(1);
    I2Clightmeter->begin(I2C_SDA, I2C_SCL);
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,I2Clightmeter);
    delay(1000);
    uint16_t lux = lightMeter.readLightLevel();
    delete I2Clightmeter;
    // rest of code
}
```

Another alternative is to keep the TwoWire object in a local scope so that it gets destroyed when you leave that scope - maybe with a special function for it:

```c++

uint16_t getLux() {
    TwoWire I2Clightmeter(1);
    I2Clightmeter.begin(I2C_SDA, I2C_SCL);
    lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE,0x23,&I2Clightmeter);
    delay(1000);
    return lightMeter.readLightLevel();
}

void setup() {
    uint16_t lux = getLux();
    // rest of code
}
```


message:
RN42 Bluetooth HID KEYBOARD sketch by silverball

How can I use **RN42** sketch by silverball

    /*
      RN42_HIDRaw_Arduino.cpp - Roving Netowrks RN42 Bluetooth HID raw library
      Developed by Chris Leitner - 2012

      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
      License as published by the Free Software Foundation; either
      version 2.1 of the License, or (at your option) any later version.

      This library is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Lesser General Public License for more details.

      You should have received a copy of the GNU Lesser General Public
      License along with this library; if not, write to the Free Software
      Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

      RN42 HID raw report format:
      |start(1 byte)|length(1 byte)|descriptor(1 byte)|data(length - 1 [for the descriptor])
      Keyboard:
      |0xFD|9|1|modifier|0x00|code 1|code 2|code 3|code 4|code 5|code 6
      Keyboard modifier bits (sent as one byte)
      bit 7  |bit 6   |bit 5  |bit 4 |bit 3 |bit 2 |bit 1  |bit 0
      rt GUI |rt alt  |rt shift |rt ctrl|lt GUI |lt alt |lt shift |lt ctrl

      You must initialize the Serial library in your code before you call any of these functions.
      The default speed for the RN42 is 115200 - add this in the setup function Serial.begin(115200);
      */

    #include <stdlib.h>
    #include <string.h>
    #include <inttypes.h>

    #include "RN42_HIDRaw_Arduino.h"

    RN42_HIDRaw_Arduino::RN42_HIDRaw_Arduino(){
    }

    //Sends a raw report for a keyboard HID
    void RN42_HIDRaw_Arduino::SendKeyboardRaw(char raw_data[], uint8_t mod_bit){

     //write the RN42 Keyboard raw header
     Serial.write((uint8_t)0xFD); //start byte indicator for RN42
        Serial.write((uint8_t)0x09); //length of the raw report (how many bytes)
        Serial.write((uint8_t)0x01); //descritptor byte see the RN42 HID manual for details 0x01 is keyboard
        Serial.write((uint8_t)mod_bit); //modifier bit (indicates shift, control, and other keys (see comments above)
        Serial.write((uint8_t)0x00); //unused always send 0x00
     //write the key press data
     //each of these should be an ASCII keycode indicating a keypressed
     //example 0x04 is an 'a' see the RN42 HID manual for a list of codes
     Serial.write((uint8_t)raw_data[0]);
        Serial.write((uint8_t)raw_data[1]);
        Serial.write((uint8_t)raw_data[2]);
        Serial.write((uint8_t)raw_data[3]);
        Serial.write((uint8_t)raw_data[4]);
        Serial.write((uint8_t)raw_data[5]);
    }

    //This function just send a raw report with no keys or modifiers pressed
    void RN42_HIDRaw_Arduino::SendKeyboardRawBlank(void){

     //write the RN42 Keyboard raw header
     Serial.write((uint8_t)0xFD);
        Serial.write((uint8_t)0x09);
        Serial.write((uint8_t)0x01);
        Serial.write((uint8_t)0x00);
        Serial.write((uint8_t)0x00);
     //write the key press data
     Serial.write((uint8_t)0x00);
        Serial.write((uint8_t)0x00);
        Serial.write((uint8_t)0x00);
        Serial.write((uint8_t)0x00);
        Serial.write((uint8_t)0x00);
        Serial.write((uint8_t)0x00);
    }

    //Sends a raw report for a gamepad
    void RN42_HIDRaw_Arduino::SendGamepadRaw(char x_left, char y_left, char z_pos, char rot_pos, uint8_t buttons1, uint8_t buttons2)
    {
     //write the header part for RN42
     Serial.write((uint8_t)0xFD); //start byte
     Serial.write((uint8_t)0x06); //length of the descriptor
     //gampad positions and buttons
     //on a gamepad there typically is two analog joysticks one is typically used to
     //indicate x/y position and one is for z/rotation.
     Serial.write((uint8_t)x_left); //value between -127 to 127 indicating the x postition
     Serial.write((uint8_t)y_left); //value between -127 to 127 indicating the y postition
     Serial.write((uint8_t)z_pos); //value between -127 to 127 indicating the z postition
     Serial.write((uint8_t)rot_pos); //value between -127 to 127 indicating the rotation postition
     //one bit for each button pressed there can be a total of 16 buttons one byte in each
     //set the bit to show a button pressed and clear the bit to indicate not pressed
     Serial.write((uint8_t)buttons1);
     Serial.write((uint8_t)buttons2);
    }

    void RN42_HIDRaw_Arduino::SendMouseRaw(uint8_t buttons, uint8_t x_stop, uint8_t y_stop, uint8_t wheel){
     //write the header part for RN42
     Serial.write((uint8_t)0xFD);
     Serial.write((uint8_t)0x05);
     Serial.write((uint8_t)0x02);
     //gampad positions and buttons
     Serial.write((uint8_t)buttons);
     Serial.write((uint8_t)x_stop);
     Serial.write((uint8_t)y_stop);
     Serial.write((uint8_t)wheel);
    }

And act Like Keyboard.h do ? just simply putting `keyboard.press;`

JUst noob question.

body:
if you are using an Arduino, I recommend you to use the BPlib, it's a free arduino library that contains functions that are similar to the Keyboard.h.

The following link is from the Arduino website: https://www.arduino.cc/reference/en/libraries/bplib/

When you download the Lib, take a look at the examples given by the creator of the Library, all the example code have the explanation of each funcition used, and you can also check for some documentation online. I hope that this help you!


message:
Switch on the piezo emitter for a short time

I need a short beep for every minute of change. I wrote a separate function. The signal duration should be 50 ms, the rest of the time the emitter connected to the A1 contact should be silent.

A really working sketch is shown below:

    uint32_t mysound; // Variable for storing time (duration of the sound signal)
    uint32_t myTimer1;
    uint32_t t; //Time that always increases
    byte seconds; // Seconds
    byte minutes; // Minutes
    int k = 1;
    void setup()
    {
      DDRC = B00000010; // Set pin A1 as output
      //      76543210
      Serial.begin(9600);
      myTimer1 = millis();
    }

    void loop()
    {
      t = (millis() - myTimer1) / 1000; // Time in seconds
      seconds = t % 60; // when 60 seconds are reached, it is reset to zero
      minutes = t / 60 % 60; // Counts the minutes and drops to zero when 60 minutes are reached
      Serial.println(seconds);
      if (seconds == 0 && k)
      {
        sound();
      }
      if (seconds > 0) k = 1;
    }

    void sound()
    {
      mysound = millis();
      while (millis() - mysound < 50)
      {
        PORTC = B00000010; // We set high voltage on pin A1 for a time of 50 ms
      }
      k = 0;
      PORTC = B00000000;
    }

body: Your `myTimer1` in `t = (millis() - myTimer1) / 1000;` is not set


body:
In addition to Qareke's answer, you also have a problem with the `mysound` variable. You only set this timestamp to `millis()` inside your `millis()` if statement. `mysound` is global and thus will be implicitly initialized with zero. So, by the time, that the code reaches the if statement, the difference between `millis()` and `mysound` is most likely already too big, thus the timestamp gets never set.

**Solution:** You need to move 2 lines around in your code:

- Move the `mysound = millis();` statement up into the `if (seconds == 0)` statement.
- Move the `sound();` statement outside of the if statement directly into the `void loop()` function (for example directly after the `if (seconds == 0)` statement).

Now the `sound()` function will always be executed, but it will only do a sound, if the timestamp was set to `millis()` previously, and then only for 50ms. Now we only need to make sure, that the timestamp variable `mysound` will only be set once, when the seconds get zero. You could either introduce a new flag variable for that, or you could just use the timestamp itself and check, if more than 1s passed since the last time the timestamp was set. So you need to change

    if (seconds == 0)

to

    if (seconds == 0 && millis() - mysound > 1100)

I used `1100` (1.1s) here, to make sure, that there is no bad edge case happening. Since `seconds` will only get zero every minute, that shouldn't be a problem.


message:
I2C_anything from Nick Gammon. Value of two senders to be received and printed by receiverslave

Following the suggestion of Fiendish to post here:
Hello

Nick, thank you very much for this I2C-anything library that works a treat with two arduinos (one sender, one receiver).

Is there any suggested method or at least an example sketch of having two different sender arduinos send their floats to the receiver  e.g. by alternating slave adresses in the receiver loop? With a simple re-insertion of the section (but with a different address) into the receiver sketch restarting with Wire.begin() and then Wire.begin(new address) things are botched up.

In addition: if I define -float f in sender A- and -float e in sender B- the receiver keeps on printing the float e value in the serial.Print ("float value e"); serial.println(e); -postion, no matter if I swap from Sender A to sender B -by changing the SCL/SDA connections,  and the serial.Print ("float value f");serial.println(f); prints fancy numbers.

If at least the swapping would cause the floats to be printed in the correct position I could maybe switch the respecive senders I2C down in turns....

Of course hotplugging /hotswitching SDA and SCL from senders causes the senders sketch to be blocked at times.

The idea of sending data from Sender B to Sender A, and from Sender A to to receiver left me frustrated the last few hours, due to the fact that Im a total noob and/or that its simply not possible to have two masters send to one slavereciver without running into i2C conflicts. Unless some unknown acrobatics is performed.

The ultimate idea is to have two separate megas (with i2c sensors attached to them) execute feedbackloops and still be able to transfer these values and other values to a display via I2C. the alternate way could be that a dac is used to translate the I2C values into voltages that hardware....)

Any help greatly appreciated
Best
Daniel

body:
Dear Chrisl and Sim Son

Please accept my apologies for not replying earlier, am still recovering form a timbering accident and have limited painless access to my laptop.

thinking in boxes: BOX 1 = Arduino Mega number one regulates the pressure of proportional valves (via I2C conected quaddac MCP4728 to 0-10V) based on the flowvalues of 4 I2C-connected FLowsensors.

BOX 2= Arduino Mega number two does the same with a second set of 4 flowsensors and 4 analog proportional valves.

Splitting this to two arduinos was originally because a) i was unable figure out how to get 2 DACS on the same I2C line and handle the LDAC address fiddling which turned out to be a good approach because the total number of required GPIO pins exceeds the available number of pins of one Mega (many rotary encoders attached, TTL signal delayer for 8 channels, pots to set values, status LEDS.

Both arduinos are supposed to send the values for the flow-setpoints, actual pressure values, actual flow values, other sensor data to a third arduino MEGA =BOX 3 that displays all kind of things on a large TFT. (for what its worth, this third Mega has some inputs from a different set of other I2C sensors that basically provide TTL signal outputs, if event-criteria have been met. the latter TTL are fed back to the first two arduinos to provide decision criteria in if loops)

So, i learn from you that the multimaster approach unlikely to be fun at all, especially given my limited knowledge and loathing /ignorance to handle and send strings. You will at least laugh at me now but i saved quite some time the on day i wrote to you by simply translating all the flow etc values of BOX 1, Box 2-Ardinos (pressures, flowsetpoints and actual flow values into voltages with the help of additional multiplexed DACs, then I pick up the the voltages with I2C-ADCs hooked to the Arduino with the SPI-display (BOX 3) that in turns translates into the true values and prints to the TFT. Any delay and inprecision at the displays side is acceptable so far, analog value fluctuation has been smoothed, the additional hardware is no issue at this stage of the project.

I am sorry that his original issue regarding I2C led me astray to oldfashioned analog data processing

BUT: if you have any hints or pointers to libraries as how two arduinos that act already as I2C Masters can send their data (a bundle of floats) via UART/RXTX, or any other bus to a receiver that handles these as printable variables: more than welcome, i will try to keep abreast of what you suggest.

Best
Daniel


message:
Firmata: strings sent from the computer become damaged after Arduino

I have a Python program that acts as a `Firmata` client. This program connects to the Arduino at a user-specified COM-port (with `Firmata` onboard, the sketch can be seen below), sends the user-requested string message to the Arduino, and awaits Arduino's reply. If the reply is present, the program prints it out as a list of ASCII symbol codes.

I expect the program and the sketch to work this way (block scheme is below), but the strings coming from the Arduino are damaged. They don't contain all symbols which were sent, but they contain only the first symbols in some random order, with a `\0` symbol present after each character in the string. For example,

| String sent to the Arduino |  Received as ASCII symbol codes | Received as a string |
| -------- | -------------- | -- |
| `A`    | `(65, 0)` | `A\0`
| `AB` | `(65, 0)` *where is the `B`?* | `A\0`
| `ABC` | `(65, 0, 67, 0)` *the `B` lacks presence* | `A\0C\0`
| `ABCD` | `(65, 0, 67, 0)` *the received data length remains the same, but `B` and `D` aren't present* | `A\0C\0`
| `ABCD(10)` | `(65, 0, 67, 0, 40, 1, 48, 1)` *WHAT IS THIS?* | `A\0C\0(\10\1`
| `DHTt(4)` | `(68, 0, 84, 0, 40, 0, 41, 1)` | `D\0T\0(\0)\1`

Program's screenshot:

[![Screenshot][1]][1]

Awaited work algorithm block scheme:
[![Block scheme][2]][2]

Python program code:

```python
import pyfirmata, time

class CustomArduino(pyfirmata.Arduino):
    def __init__(self, port: str):
        pyfirmata.Arduino.__init__(self, port)
        self.iterator = pyfirmata.util.Iterator(self)
        self.iterator.start()

        self.add_cmd_handler(0x71, self.receiveString)

    def receiveString(self, *args, **kwargs):
        print(f'Received: {args}')

    def sendString(self, data):
        self.send_sysex(0x71, bytearray(data, 'utf-8'))

    def send_sysex(self, sysex_cmd, data=[]):
        """
        Sends a SysEx msg.
        :arg sysex_cmd: A sysex command byte
        : arg data: a bytearray of 7-bit bytes of arbitrary data
        """
        msg = bytearray([pyfirmata.pyfirmata.START_SYSEX, sysex_cmd])
        msg.extend(data)
        msg.append(pyfirmata.pyfirmata.END_SYSEX)
        self.sp.write(msg)

print('STRING TESTER\nPlease input your COM port: ', end = '')
myCom = str(input())
device = CustomArduino(myCom)

while True:
    device.sendString(input('Send: '))
    time.sleep(1)
```

Arduino sketch:
```c++
#include <Firmata.h>

void stringCallback(char *myString)
{
  //The function accepts one charset.
  Firmata.sendString(myString); //send the *same* charset  back
}

void sysexCallback(byte command, byte argc, byte *argv)
{
  Firmata.sendSysex(command, argc, argv);
}

void setup()
{
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback); //when there is a STRING incoming to the Arduino, call 'stringCallback'
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
  pinMode(13, OUTPUT);
}

void loop()
{
  while (Firmata.available()) {
    Firmata.processInput();
  }
}
```
How I can deal with this?

  [1]: https://i.stack.imgur.com/14QwH.jpg
  [2]: https://i.stack.imgur.com/d0xcb.png

body:
You have to understand the Firmata protocol to write your own client library. The spec is here: https://github.com/firmata/protocol.

In this particular case, you need to know that data that is sent (the string in this case) can never use bit 7 of the data, since these values have special meanings. Therefore, Firmata sends every byte as two bytes, first bits 0-6 and second bit 7 as bit 0 of the next byte. Therefore, the conversion to UTF-8 is not sufficient. You need to do a two-byte-per-8-bits encoding. The same applies for the reply.


body: Alternatively, if you want a system without Firmata's baggage of ancient MIDI constraints, like its bizarre 7-bit limit, you might consider DaqPort <https://www.daqarta.com/dw_rraa.htm>


body:
Instead of using the `UTF-8` encoding,
```python
def receiveString(self, *args, **kwargs):
    print(f'Received: {args}')

def sendString(self, data):
    self.send_sysex(0x71, bytearray(data, 'utf-8'))
```
it is necessary to use the `pyfirmata` special bytearray manipulation methods: `two_byte_iter_to_str` and ` str_to_two_byte_iter`:
```python
def receiveString(self, *args, **kwargs):
    print(f'Received: {pyfirmata.util.two_byte_iter_to_str(args)}')

def sendString(self, data):
    self.send_sysex(0x71, pyfirmata.util.str_to_two_byte_iter(data))
```