text:
Using AccelStepper to move a set distance while a button is held down
I'm working on a project and using a nema 23 stepper motor and driver.

Need to be able to move the stepper 1/32 rotation when I press a button.

I need a small delay so I have time to release the button and not move the 1/32 rotation twice or more (its in a loop) before I can release the button.

I also want to the stepper to continue to move in 1/32 rotation increments as long as the button is held down.

I can get this to work with the move() and runToPosition() commands, but it accelerates and decelerates each time making the movement much slower then I need.   I would just use the runSpeed() command inside a while loop setting move() each time, but I need the acceleration as the pull in torque of the stepper is not great enough to start at the full speed needed.
Any ideas or suggestions would be greatly appreciated.

It is unclear to me, what your actual problem is. If the motor accelerates to slow, I think the AccelStepper library has a function to set the acceleration, so you could just set it to a bigger value. Or is the problem with reading the button for the described behavior?

it is absolutely simple ... do not move the motor when the button is pressed ... move the motor when the button transitions from not pressed to pressed

Currently If I press the button, the stepper moves 1/32 rotation using acceleration and deceleration.  If I press the button and hold it down, the stepper moves 1/32 rotation with acceleration and deceleration, delays for a short time (this is to allow me to release the button if I only want to move 1/32nd) and then goes into a while loop while the button is held down.  but since the commands i'm using are move(1/32) and moveToPosition() it accelerates and decelerates on each movement, and since each movement is short only 1/32 of a rotation it cant accelerate to much and so moves slow

Jsotola,     I understand what you are saying, but not sure how to implement that while retaining the needed 1/32nd step on a short press, and also the continues movement that I need to be in 1/32 steps while the button is held down.  What I want it to do is move one 1/32 rotation when I press the button and release it using acceleration and deceleration, but if I hold the button I want it to smoothly accelerate to maxSpeed, stay at maxSpeed until I releasethe button, and then stop on a even 1/32 rotation step with smooth deceleration.

If I understand your request properly (Move a little step for a short button press / Move continuously while pressed longer) you need to distinguish between long and short. This can only be detected when you release the button, or when the time distinguishing short/long has elapsed. -> You cannot start moving immediately when button is pressed.

I think I mostly got what I need, but haven't figured out how to end exactly on a 1/32 rotational location.  I don't have the code in front of me at the moment, but its something like:
if (button == 0){
move(400/32)
runToPosition()
delay(150)
read button
if( button==0){
move(34000)
while button ==0{
run()
read button
if (button == 1){
stop()
runToPosition()
}}
that is close at least.  It moves 1/32 on a short press, and on a button press and hold accelerates to max speed, when I release the button it smoothly decelerates as I want, but I need it to stop on an increment 1/32


text:
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

You have:
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.  You later specify server.on("/",HTTP_POST,response); specifically for POST requests.  These are added to a request handler list in the order given.  And apparently consulted 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:
server.on("/",HTTP_POST,response);
server.on("/", handleRoot);
server.on("/test.svg", drawGraph);

That was it. For some reason it still return the URL instead of the response get returned to the client, but I definitely see the post request hit. I set both btw      server.on("/",HTTP_POST,response);
server.on("/",HTTP_GET, handleRoot);

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
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?

This error is normally shown while attempting to upload a sketch,  not during execution. Are you able to successfully load the sketch and the error only happens after the sensor has been read?

It happens during uploading(sorry I didn;t mention, edited).

What program and data sizes does the compiler show right after your sketch has been compiled?

Your code as posted doesn't compile. Please post the entire sketch. We cannot debug snippets.

Please provide the last lines of the output, where the program and data sizes are given.

What is SAMPLES defined as?

Okay everyone, I am posting the entire code here.

By using the F("") macro on the Serial.println(""); strings (storing them in Flash instead of copying them to RAM), I've been able to reduce the Global Variables to 2038 bytes, but that still leaves too little for running the code.

With all those floats, have you considered that an 8-bit micro with no FPU is not the optimal MCU for this.

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 Optimizing code to use less Flash Memory and SRAM

See my comment: string constants (such as those used in Serial.print("");) also take up valuable RAM. You can use the F("...") macro to reduce their footprint.

Consider using one of the Teensy family.  The latest Teensy 4.0 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.

Wouldn't comparing the memory available be the most helpful selling point for this question?

Too lazy to click on the link?

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Use HC05 and FTDI as Slave to Connect to control PC using HC05
Hi i just wanna ask if its possible to do this on HC05. So i can send some keyboard function?

and if yes can you tell me how. Thanks

"send some keyboard function?" - I guess you mean, that it should act as a keyboard on your PC. Thats not possible with an FTDI. It will only give you a Serial interface. But you could exchange the FTDI with an Arduino, that has a native USB interface, like the Micro (it can act as a HID device). Then you can program the micro to read data over Serial from the HC-05 and translate that to keyboard presses on the PC.

ok so i can do this with pro micro connecting to slave HC05?

Sure, if you program it to do this

Thanks. Now i have idea on what to do. Im noob sorry.


text:
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.

The problem may be that the input impedance of the WS2812 is low enough, as to pull the weak 35kOhm pull-up resistor below the voltage needed for the EEPROM to read as HIGH. I'd first give it another go with proper value pull-up resistors for I2C. Something as low as a 1kOhm. After that you could try adding a buffer circuit to the WS2812s input.

It seems like you have perfectly good answers already, but I am curious as to what you meant by "it proved an incorrect assumption."  Presumably, you did something that served as proof.  What exactly was that?

the circuit worked(could read the EEPROM) and then i added the LED and it stopped working(could no longer read EEPROM or control LED)

ps. thanks for all these replys, very interesting, ive not been able to test today but will get back to you as soon as i have)

Try the setClock fix suggestion in my "answer" and if that doesn't make one of the proper answers work for you.

I used your code with a 24LC02B, UNO, and 12 "NeoPixel" ring, which is the equivalent to what you have under this test.  On my setup, your code prints the first byte of EEPROM and then color cycles the first RGB LED.  So far as I can tell, this is the expected outcome.

Sth different: you know that the atmega328 has an internal eeprom, right? Do you have a reason to use an external eeprom? Just asking...

Do you actually have pullups on the bus lines? I see no reason why the eeprom should not be readable with the WS2812 connected, so that might be the root issue to solve

hi yes i am aware of that. i am using the eeprom as a means to identify swappable modules. i initially did have physical pullups but heard that the wire library uses internal pullups so i removed them and the circuit worked fine(for reading eeprom,before adding the pixel). i have just tried adding them again and the situation remains the same...

I can put my setup in answer if you want, but I doubt there's anything to be learned from it.  The UNO is pretty much electrically the same as Nano, at least in all the ways relevant to the test.  The 24LC02B I'm using has the same pin out, same I2C address, and same "commands" as your device.  It just has less memory.  I didn't bother putting pullups on the I2C bus because the internals were sufficient to make the code work to prove that it can be done.

Well i suppose theres no harm in trying. other than that the only thing i can think of is to buy that exact chip and try to replicate it. I only need the eeprom to use as a means to identify modules so any ic would do.

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 uses the same pinout and I2C address and command-sequences as your AT24C16.  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. 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

OK, thanks again for taking the time to do this, i am indebted to you! I tried your exact setup and....still didnt work! But....on a whim i decided to change the LED, and it worked! It turns out that i have 2 addressable LED strips, one is a 60 led / meter strip and the other 30 led / meter strip. the 60/m ones work and the 30/m ones dont! how flipping weird(and frustrating) is that!? so, this is now sloved, albeit in a rather convoluted fashion. Do you have any suggestions on how i should update this in the most helpful way? should i create another answer or is it a bit too rough?

Maybe this is all you're seeing.

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.

my initial thinking was that there may be some 'spurious outputs' from the led while the EEPROM is being read but since it only takes a short time it would be ok. unfortunately the EEPROM fails to read when the pixel is connected as per the schematic.

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.

hi there, thanks very much for this,I have updated my question in response.

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/

"Won't work with 24Cxx EEPROMS" - I think it does as I wrote in my answer

"the EEPROM to just vomit all its data to a bus without someone actively listening and ACK-ing" - no one will ACK here, WS2812 are no I2C devices and other I2C devices won't ACK if they don't get addressed

Yes, I misunderstood the intention. I thought the data for the WS2812 should be comming from the EEPROM directly via SDA. MCU telling EEPROM to output its data to the bus where WS2812 would listen.

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:
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 to divide-by-1 and left that way.  setClock calls twi_setFrequency, which calculates TWBR using this expression:
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.

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:

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:
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.

Thanks again for such a thorough investigation, its enormously appreciated. Unfortunately the problem still persists, I have updated my question in response.


text:
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?

That site reports to me different capacities for the two JSON documents. How exactly did you set the configuration?

@EdgarBonet, well sorry I have just realized that the I should have mentioned how I was trying to calculate the capacity. ESP8266/Deserialize/char *

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.

You helped me understanding how the things are calculated here, thank you!. Nevertheless, I found the actual problem, please check my answer.

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, 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

Good catch! Did you consider sending a bug report?

@EdgarBonet Thanks! I already did it https://github.com/bblanchon/ArduinoJson/issues/1488

Well, they fixed it now.


text:
Erratic behavior in String based functions
I've been working on a cipher based project, and I wanted to prep the encrypted string for use with the RF24 library. Since the payload size for the RF24 module is 32 bytes, I wanted to stick with that size permanently. The key number (against which the encryption keys are stored) has to be embedded at the end of the char array, and I was converting it to a char to embed. To make the message up to 31 bytes if it was smaller than 31 bytes, I am padding with zeroes.
The cipher functions themselves (namely loadInput(), cipherText() and originalText()), work perfectly; I have tested these by themselves numerous times.
However, the other two functions I wrote for padding and de-padding are behaving erratically.
My code:
const String keys[] = {
"TTZUZRZJHP",
"SUENIFKGAT",
"CEXGWKMCVQ",
"SIACAKRFM",
"CSMKSWSNLH",
"IPIJWROJBB",
"SZSGAMYJGJ",
"BIHLBNUIJS",
"UTFGSQAISS",
"SSPXJXURJV",
"XPDRYPOFAC",
"DROIFANPZE",
"DKTZXUQLAM",
"UDHAWMAJTG",
"HKTQMEPWXS",
"IRUQAHZSBP",
"ZHZAAGTMTN",
"EHORTISSLQ",
"NYZZQALWTP",
"PEEGDJLQLQ",
"UNQGHTXFSG",
"NOBSTVFLAX",
"GQJYEVUNCX",
"UTJDNOCLSP",
"XQNGBDOBEN",
"FURHLIZSIN",
"AAAPEIGRHI",
"QWQFCCVFPV",
"KZEFJHUJWB",
"NDJNLHURJO"
};

char readyToSend[32]; //global array, which is to be transmitted via RF24
char recieved[32]; // global array, which is to be recieved via RF24
int keyRecieved; //global key number, which is to be embedded as the last char recieved[]

String loadInput() { //this functions takes the input string and checks it's validity
  bool isValid = true;
  String(inputStr);
  do {
    Serial.println("Enter valid input. Only enter ALPHABETIC characters. ONLY 31 CHARS MAX.");
    Serial.println("Whitespaces are valid but commas and fullstops are not");
    while (Serial.available () == 0) {}
    inputStr = Serial.readString();
    int inputLength = inputStr.length();

    for (int i=0; i<inputLength; i++) {
      if (inputLength>31) {
        Serial.println("Input longer than 31 chars.");
        isValid = false;
        break;
      } else if (inputStr[i] > 95 && inputStr[i] < 123) {
        inputStr[i] -= 32;
      } else if (isWhitespace(inputStr[i])) {
      } else if (!isAlpha(inputStr[i])) {
        isValid = false;
        break;
      }
    }
  } while (isValid == true);

  inputStr.remove((inputStr.length()-2), 2);
  return inputStr;
}

String cipherText(String str,const String key) { //this function encrypts the message, and returns the encrypted version
  String cipher_text;
  for (int i=0; i<str.length(); i++) {
    if (isWhitespace(str[i])) {
      cipher_text += ' ';
    } else {
      char x = (str[i] + key[i%key.length()]) %26;
      x += 'A';
      cipher_text += x;
    }
  }
  Serial.println(cipher_text);
  return cipher_text;
}

String originalText( String cipher_text,const String key) { //this function decrypts the message, and returns the decrypted version
  String orig_text;

  for (int i=0 ; i<cipher_text.length(); i++) {
    if (isWhitespace(cipher_text[i])) {
      orig_text += ' ';
    } else {
      // converting in range 0-25
      char x = (cipher_text[i] - key[i%key.length()] + 26) %26;
      // convert into alphabets(ASCII)
      x += 'A';
      orig_text += x;
    }
  }
  return orig_text;
}

void prepForTransmit(String input, int keyNumber) { //this function makes pads the string upto 31 with '0', then embeds key
  input.toCharArray(readyToSend, 32);
  int zeroesStart = input.length();

  for (int i=zeroesStart; i<32; i++) {
    readyToSend[i] = '0';
  }

  char keyNumberAsChar = (char)(keyNumber + 65);
  readyToSend[31] = keyNumberAsChar;
  return;
}

String PrepForDecode() { //this function makes exctracts key, then removes padding
  keyRecieved = (recieved[31] - 65);
  String toEdit = String(recieved);
  toEdit.remove(31, 1);

  if (toEdit.indexOf('0') != -1) {
    toEdit.remove(toEdit.indexOf('0'), (31-toEdit.indexOf('0')));
  } else {
  }
  return toEdit;
}

void setup() { // TEST CODE
  Serial.begin(9600);
  randomSeed(analogRead(A0)); //SEED RANDOM FUNCTION
  String(text) = loadInput(); //GET INPUT
  Serial.println(text); //PRINT INPUT      <--------------------------------------
  int keynumber = random(25); //              |
  String encrypted_message = cipherText( text, keys[keynumber]);  //ENCRYPT THIs _|
  Serial.println("Using key number ");
  Serial.println(keynumber);

  prepForTransmit(encrypted_message, keynumber); // PADDING AND ADD KEYNUMBER
  Serial.println("Message to trasmit through radio is: ");
  Serial.println(readyToSend);  // PRINT PREPPED CHAR ARRAY
  for (int i=0; i<32; i++) {
    recieved[i] = readyToSend[i]; // COPY PREPPED ARRAY TO EMULATE RECEPTION FROM RADIO
  }
  String toDecode = PrepForDecode(); // PREP RECIEVED STRING FOR DECODING (REMOVE PADDING, EXTRACT KEY)

  Serial.println(originalText( toDecode , keys[keyRecieved])); // PRINT DECODED STRING
}

void loop() { //main program

My serial output:
22:18:59.596 -> Whitespaces are valid but commas and fullstops are not
22:19:08.255 -> THIS PROJECT IS A MESS
22:19:08.290 -> LPIU ZITVWKT IC F EMSU
22:19:08.325 -> Using key number
22:19:08.325 -> 3
22:19:08.325 -> Message to trasmit through radio is:
22:19:08.393 -> LPIU ZITVWKT IC F EMSU000000000D⸮!
22:19:08.428 -> THIS PROJECT IS A MESSLFRP HATTWAC WK F ECBP>8BJHJ@9ER:3

"LPIU ZITVWKT IC F EMSU000000000D⸮!" is very unexpected, since there should only be 32 chars, and here there are 34.
Furthermore, the behavior here: "THIS PROJECT IS A MESSLFRP HATTWAC WK F ECBP>8BJHJ@9ER:3" is something I absolutely cannot understand.
I am baffled, and I would really appreciate help. I apologize in advance if the error is something small or stupid, but I cannot understand what's going on here.

Two words: "Null termination". You haven't terminated your strings properly.

@Majenko I thought converting from char array to String meant it was automatically null terminated? And the reason I have been using char arrays is to not have to deal with the null termination char.

@Majenko You were right! Apparently the String constructor doesn't handle the null termination with a char array input. Null terminating the string fixed the problem! Thank you!

Well, there isn't actually a String constructor for an array of char. There's one for a pointer to const char, which is completely unaware of the size of the array that the pointer was formed from.

@timemage I didn't know that. Thank you! I'm sure someone else who's found himself in a corner like me will find this useful!

why store literals as String classes instead of cstrings? seems unnecessary....


text:
Getting Nrf24l01 modules to work!
I am at my wit's end with these Nrf24l01s. A bit of history: I have ordered about 25 of these, tried the adapter board, read every article, tried every sketch (including Robin's tutorial), powered the modules with a separate power supply.
Has anyone else had these issues? Is there anything anyone has discovered on getting these to work? I am 12 years old and am trying to use these for a science project. Any help is greatly appreciated!!
Tnx,
Ricky
edit:
I went back to just the simplest "hello world" sketch and I can't even get this to work: nothing received in serial monitor (I did notice the Tx LED is lit in the receiver, is this correct?) Sorry if I posted this wrong.
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(9, 8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

void setup()
{
  radio.begin();

  //set the address
  radio.openWritingPipe(address);

  //Set module as transmitter
  radio.stopListening();
}

void loop()
{
  //Send message to receiver
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));

  delay(1000);
}

Receiver:
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//create an RF24 object
RF24 radio(9, 8);  // CE, CSN

//address through which two modules communicate.
const byte address[6] = "00001";

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

  radio.begin();

  //set the address
  radio.openReadingPipe(0, address);

  //Set module as receiver
  radio.startListening();
}

void loop()
{
  //Read the data if available in buffer
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }
}

Has anyone else had these issues? ... you did not describe any issues  .... Is there anything anyone has discovered on getting those to work? ... many people use them, so yes

please describe what you are doing with the modules and describe how your attempts fail .... and, please ask specific questions that do not have a simple yes/no answer

I am building a remote temperature/ humidity sensor. I am using 2 Arduino unos, dht22 sensor and of course the nrf24l01.  On the transmitter uno I can open up the serial monitor and see that the temp/ humidity is being displayed correctly so that part is working.  I am using the dht22 sensor libarary and the Tmrh24 libarary as recommended.  I seem at times to get some Random characters.  It seems when I touch the uno the board led tx does flash and acts differently when I hold the uno in my hand vs not. I am using male to female etc wires for connecting. I have also tryed the nrf24l01+ w ant 2

temperature and humidity values are irrelevant to the communication problem ... reduce your code to transmit and to receive only a single character .... remove the dht22 sensor ... get communication working first ... add the temperature code after .... add the wiring diagram, code and a description of any errors to your post at top of this page.

Posted in answer

Move the modules further apart, or change the power output in code (radio.setPALevel(RF24_PA_MIN)).

Try using one of the TMRh20's library's examples and get communication working there first.

Thanks to all who commented and provided advise. I did go to TMRH20 examples I tryed the simple transmit receive node sketch


text:
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)

Here:
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:
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:
DateTime alarm1Time(t.year(),t.month(),t.day(),e2p.read(1),e2p.read(2),0);

You are absolutely right I'm incorrectly using the constructor. Am I so stupid or so tired? Hmmm. Probably it's because I'm neebie to C++, after years of using other languages.
Regarding the declaration and initialization at once - I need to declare it global, not withing setup(), otherwise I'd do it as you suggest. Thanks.


text:
I'm trying to upload a sketch to my arduino uno, but I get the Error-Message "avrdude: stk500_recv(): programmer is not responding"
    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:

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.

I guess you don't have an USBasp programmer, so you get that error message on bootloader burning. Do you habe anything connected to the board, when trying to upload? What other board did you try? Are you able to open the Serial Monitor with the selected com port? If you then send something, is the RX LED on the Uno lighting up shortly?

Have you ever successfully uploaded to this board?

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

So please mark this question as answered since you solved the problem.

I have to wait another hour, then I'll of course do it :)


text:
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

A minimal test setup around your charsToIntValue doesn't show me what you're talking about.  I don't think this has anything strictly to do with variadic function support.  Nor Arduino.  I will just add that pow(10, argc - 1); could be better written as a small function that takes an int, returns an int, and consists of a switch statement with no float at all.

I'm currently not sure, if pow() returns a float. If yes, that that behavior seems normal. Floats can only save an aproximation of the wanted number. The actual float value, that is calculated  might be something like 999.99. When you them convert to an int, the digits behind the decimal point get thrown away, leaving 999. Thats something, that you would need to accept, when you want to work with floats. And thats one reason, why it is often better, to just use an integer representation.

@timemage I took inspiration from your comment and implemented my own power function rather than using the math.h library. It works now!

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!

I'd had some doubt about this actually solved the problem, because I'd tested the handful of exponent values you were using to see if the pow() happened to produce the values you wanted.  Turns out avr-gcc will use higher precision if the optimizer can determine at compile time irrespective of whether it's doing this is a constexper context, meaning so much as having an argument something volatile qualified will cause pow() to evaluate at lower precision.  Just more reason to not use float on an AVR.

When the optimizer kicked in pow(10, 4)'s result had significand field 0b00111000011111111111110 and where the optimizer couldn't determine the exponent at compile time a significand field of 0b00111000100000000000000.  The former converts to int with the expected (for certain values of "expected") 10000 while the latter produces a value closer to 9984.  Something also you should be aware of is that in avr-gcc, there really is no double.  It's a distinct type for overload purposes, but it's implemented as single precision float.

@timemage all helpful information. Thank you

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():
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)):
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...

"works fine with compile-time constants because" as I said in the the comments on the O.P.'s own answer, it's actually more complicated than that.  It has nothing to do with whether or not they're technically "constant".  You can elicit the difference in this behaviour without crossing between constant expressions and non-constant expressions.  The standard makes provisions for differences in precision between the two cases.  So that is fin.  But, the fact that it will give two completely different results outside the constexpr context is probably a bug.


text:
Unexpected and incorrect HEX codes coming from IR remote, but only in second function..?
Hello:) I'm working on a lil project with some NeoPixels being controlled by an IR remote, and with there being multiple strips, I felt it would be best to first select the desired strip, and then the colour. The code is getting there, albiet with a few bugs. I've set the serial monitor up for debugging.
When a strip is selected (I call them 'shift buttons', like on a keyboard), the program and serial monitor detect it flawlessly, every time. However, when I press ONLY a colour button to test the input, a seemingly random, HEX code pops up on the serial monitor which changes with each press. This seems to cause the whole code not to function past selecting a strip.
Would anyone be able to give me a hand as to why this incorrect code might be popping up please? I've tested the function of the buttons on a IR remote testing script and the buttons correlate to the HEX displayed everytime so I know the physical route to the Arduino isn't flawed
TL:DR:
One function with IR information works flawlessly, other function using the same info returns random(?) HEX codes
Below is the code:
#include <IRremote.h> //include IR library
#include <Arduino.h>
#include <FastLED.h> //include LED library
#define NUM_LEDS1 18 //say how many leds is in row 1
#define NUM_LEDS2 17 //say how many leds is in row 2
#define NUM_LEDS3 20 //say how many leds is in row 3
const int RECV_PIN = 8; //say what pin IR sensor is plugged into
const int LEDPIN = 13;//say what pin blue STATUS led is plugged into

IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
int shiftbutton = 0;

CRGB leds1[NUM_LEDS1]; //link leds1 with how many leds are in it
CRGB leds2[NUM_LEDS2]; //link leds2 with how many leds are in it
CRGB leds3[NUM_LEDS3]; //link leds3 with how many leds are in it
size_t NumLeds[3] = { NUM_LEDS1, NUM_LEDS2, NUM_LEDS3 };
CRGB* strips[3] = { leds1, leds2, leds3 };

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

  irrecv.enableIRIn(); //Enables IR
  irrecv.blink13(true); //Flashes onboard LED when IR input detected
  pinMode(LEDPIN, OUTPUT); //set signal led as an ourput
  FastLED.addLeds<NEOPIXEL, 5>(leds1, NUM_LEDS1); //setup for row 1
  FastLED.addLeds<NEOPIXEL, 3>(leds2, NUM_LEDS2); //setup for row 2
  FastLED.addLeds<NEOPIXEL, 6>(leds3, NUM_LEDS3); //setup for row 3
}

void loop()
{
  readIR();
  ShiftButtons();
  LEDStrip();
}

void readIR()
{
  if (irrecv.decode(&results))
  {
    // debug
    Serial.println("processing received IR");
    // if not repeat key
    if (results.value != 0XFFFFFFFF)
    {
      key_value = results.value;

      // debug
      Serial.print("using new value ");
      Serial.println(key_value, HEX);
    }
    else
    {
      // nothing to do
      // key_value still contains the result of the previous read

      // debug
      Serial.print("using old value ");
      Serial.println(key_value, HEX);
    }
    irrecv.resume();
  }
}

void ShiftButtons()
{
  switch (key_value)
  {
    case 0xFF30CF:
      shiftbutton = 1;
      break;
    case 0xFFB04F:
      shiftbutton = 2;
      break;
    case 0xFF708F:
      shiftbutton = 3;
      break;
  }

  // debug
  Serial.print("shiftbutton set to ");
  Serial.println(shiftbutton);
}

void setStrip (size_t index, CRGB color)
{
  fill_solid(strips[index], NumLeds[index], color);
  FastLED.show();
}

void LEDStrip()
{
  if (shiftbutton == 0) return; // no strip selected

  // debug
  Serial.print("LEDStrip: using key value ");
  Serial.println(key_value, HEX);

  CRGB color = CRGB::Black;
  switch (key_value)
  {
    case 0xFF1AE5:
      color = CRGB::Red;
      // debug
      Serial.println("color set to red");
      break;
    case 0xFF9A65:
      color = CRGB::Green;
      // debug
      Serial.println("color set to green");
      break;
    case 0xFFA25D:
      color = CRGB::Blue;
      // debug
      Serial.println("color set to blue");
      break;
  }

  setStrip(shiftbutton - 1, color);
  shiftbutton = 0;  // reset the flag
}

Hopefully I’ve attached that code right!
Thanks

What are you getting in decode_type of the results?

do the LEDs shine onto the IR sensor?

19:44:59.050 -> LEDStrip: using key value FF30CF//meaning  (shift selected)
19:44:59.050 -> processing received IR//red pressed here
19:44:59.096 -> using new value 5A9FB1CA //picks up this or many other random codes
19:44:59.096 -> shiftbutton set to 0//resets shift select button even though successful colour hasn’t been selected

Also, no light shines directly into the sensor - it is working flawlessly when only the buttons to select strips are pressed, however when colours are introduced random numbers in the serial monitor start appearing instead of the set colour codes. Thanks

I would say, this code can not work at all. You read a value from the IR, then you check for "shiftbutton pressed" (1-3). In the next function you skip if no shiftbutton is pressed or you use the same key_value to select the color. But this is still the code for one of the shiftbuttons; not a color code.  So it would not match. Then the shifbutton is reset to 0. You allready have pressed the color key which might be in a queue. The loop starts from the beginning. Now (much too late) the color key is read. It does not match a shift button; shiftbutton stays with 0. And so on

But why the random values? Perhaps there is a unwanted shift when the bytes are tranfered induced by delayed reading. You could simply write a little test program. Use only the readIR method, but delete the else block (that would print too much output ;-) ). Then press the keys on the sender and see if the values are still random. Do you press the shift and color keys one after another or at the same time? (As a shift key would be suspected).


text:
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?

Why should there be SDA/SCL pins? That display doesn't have an I2C interface, but the standard parallel interface.

Yes, is there any way I can use other pins to connect with Arduino and sensor.

Of course you can still connect that display to the Arduino, you just need more pins as with an I2C display. There are tons of tutorials out there about that and the standard LiquidCrystal library supports that communication mode. Have you troed some of those tutorials?

No, I will check now, tq

You will need an I2C adapter board like this to interface your LCD 1602 via I2C.


text:
Am I maximising my A0 readout rate with this peak-detection code?
I have a pulse going into A0 on a Nano, and want to detect the peak voltage.  With low-pass filtering to slow down the input pulse I'm still reading marginally too slow.
The code overall inhibits a laser except for 50ms after a button is pressed.  During that 50ms I read A0 to look for the peak voltage/laser pulse energy.  The pulse is negative, several volts, and is AC-coupled into A0, pulled up to a 5V baseline.
The monitoring loop is simple:
while (millis() < (PulseStart + LaserPulseWidth)) { // monitor ADC (PbSe amplified photodiode with negative output, AC coupled and pulled up
  if (V_in <= V_old) {
    V_old = V_in;
  } // this will report the minimum voltage seen on the monitor pin.  Should be near enough proportional to the pulse energy.
  V_in = analogRead(MonitorPin);
}

Outside the monitoring loop, but in the main loop, I toggle various status LEDs etc.  The resulting laser pulse energy is sent using softwareSerial to (a Raspberry Pi in) the box with the trigger button, about 12m away. softwareSerial requires interrupts, but anyway so does millis()

Channel 1 (yellow) is measured at A0.  Channel 2 is the unfiltered output from the PbSe amplified IR photodiode, and is used to trigger the scope.  Note the timebase is 100us, close to the nominal readout time of A0; I thought this would effectively average over approximately 1 division, which might be OK, but taking some rough calibration data suggests otherwise.
Here's my circuit:

A simplified version of the whole code follows. I've removed some status outputs (LEDs, beeps, USB serial transmssion) from the main loop and the code to set them up; the ADC read-in loop is unmodified from my running code.
#include <SoftwareSerial.h>

int MonitorPin = A0;
int FireButton;
int stopbutton;
int lastFireButton = LOW;
int V_in;
int V_old;
char message[8];
int V_base;
int LaserPulseWidth = 50; //in ms.  50 ms should be right for 20 Hz laser

SoftwareSerial mySerial = SoftwareSerial(2, 3); // RX, TX

void setup() {
  pinMode(pin7, INPUT_PULLUP);  // fire laser
  pinMode(pin8, INPUT_PULLUP);  // disable
  stopbutton = digitalRead(8);
  FireButton = digitalRead(7);
  pinMode(LaserPin, OUTPUT); // Laser trigger pin
  Serial.begin(9600); // for comms to a host PC (includes debug info)
  mySerial.begin(9600); // for comms to RPi
  mySerial.println("Second serial port");
  interrupts();
}

void loop() {
  stopbutton = digitalRead(8);
  FireButton = digitalRead(7);
  while (stopbutton == HIGH) { // not actually used, but implemented in case we want to suppress firing (pin internally pulled up so just ground to suppress)
    lastFireButton = FireButton;
    stopbutton = digitalRead(8);
    FireButton = digitalRead(7);
    V_old = 1024; // initialise to max so anything we read is less

    if (FireButton != lastFireButton && FireButton == LOW) { // detect negative edge
      digitalWrite(13, true); // flash the onboard status LED on
      V_old = 1024;
      for (int i = 0; i < 10; i++) {
        V_in += analogRead(MonitorPin); // read ADC before firing to provide a baseline
      }
      V_base = V_in / 10;
      digitalWrite(LaserPin, true); // laser trigger on
      PulseStart = millis();
      while (millis() < (PulseStart + LaserPulseWidth)) { //monitor ADC (PbSe amplified photodiode with negative output, AC coupled and pulled up
        if (V_in <= V_old) {
          V_old = V_in;
        } // this will report the minimum voltage seen on the monitor pin.  Should be near enough proportional to the pulse energy.
        V_in = analogRead(MonitorPin);
      }
      digitalWrite(LaserPin, false); // laser trigger on

      int V_peak = V_base - V_old;
      sprintf(message, "ADC=%d", V_peak);
      mySerial.println(message);
    }
  }
}

Sidenote; to handle millis rollover, use while ( (millis()-PulseStart) < LaserPulseWidth)  instead.

Do you have a schematic, and an oscilloscope picture of the pulse as it is, and as it arrives at the Arduino pin? Just to get some idea of what "a little too fast" is. analogRead() is quite slow by default, but can be sped up.

You could you do like, say, 20 measurements, and store those in an array. Then afterward see which value was the peak value. That way your code doesn't have to do a millis call, and two comparisons, making it run a bit faster. If that's not enough, you'd have to change the prescaler of the ADC, to get a faster Analog to Digital conversion.

@Gerben the pulse can occur anywhere within a window of 50ms (the laser has a 20Hz rep rate; I allow emission for 1/20 s to get one pulse).  I don't think I've got enough storage to read flat out for 50ms then post-process.

@ocrdu I'll get a scope trace with the latest circuit.  I've been building a low-pass filter this morning, since posting.  My schematic needs updating.  It was a simple block diagram before I started AC-coupling and low-pass filtering

Actually (@Gerben) I'm right on the edge of having enough storage.  The compiler says I've got 1103B free for local variables, which is enough for 550 ints or 55ms if I read every 100us.  I'm not sure if all that is actually free, but I could free up some more.

@ocrdu I've added the circuit; it's more of an electronic lab-book sketch but hopefully clear enough

"On ATmega based boards (UNO, Nano, Mini, Mega), it takes about 100 microseconds (0.0001 s) to read an analog input". Your pulse only takes 50µs. So you need to increase the ADC speed, by changing the prescaler.

What is it you are trying to measure? The peak-voltage, or the time till the peak occurs?

@Gerben I've been looking into that and will almost certainly do so.  What's not clear to me is how much is settling time (effectively averaging? or so I hoped) and how much is dead time.  Also my scope's  negative peak width measurement is unhelpful.  This trace has a "?" after it, not all do, but the number is always >~100us.  I'm after peak V; I'll add that to the Q.... I think it was clearer before one of my edits

The ADC averaging time is not specified, but probably tiny compared to the conversion time. Have you considered using a diode-based peak detector?

@EdgarBonet previous tests had showed this to be a rather slow (several hundred us) photodiode so I had expected not to need a significant sampling circuit.  Partly it's because I'm designing/building my electronics at home and testing/using them in work (the laser takes up most of a room, but we're supposed to work from home where possible).  The former slowness may be a thermal effect as the photodiode is sensitive out to 4.8um.  The laser pulses are a few picoseconds BTW.  The photodiode amplifier is internal. Changing the clock prescale is looking helpful so far.

I could also use an MCP3002 over SPI; that's faster and I've got some on rather large boards I'm not using

There's also a way to put the ADC into free-running mode, and it will sample into an array at the maximum possible speed all on its own. There's an adafruit tutorial on it, but I've never done this myself. I believe this part does not require external hardware: https://learn.adafruit.com/wave-shield-voice-changer/principles-of-operation


text:
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 :)

You may want to make it clear why you want to do this.  Because, as is, it sounds like you're just duplicating data for no reason.  And if there is a good reason for doing this, it will likely give some shape to the answer.

You know the size from JsonArray::size() so just iterate over the array getting each object in turn. It's also recommended to use iterators instead of a for loop.

I added an edit explaining just that, maybe now it is more clear?

your explanation seems to suggest that you are thinking that the webpage HTML needs to exist in its entirety before the webpage can be served ... you can serve the webpage in pieces ... serve the ... then iterate the JSON
 put name here
, then serve

for simple extractions like that, in the past I've just plucked the values from the JSON as text, using something like strstr(json, "\"key\"") and then strchr(thatString, ',') to get the span from that key's starting point. You could use String methods too, but those tend to cause problems if over-used.

Directly from the ArduinoJson Assistant:
// 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?
How to deserialize a very large document?

Thank you, I will try this. How would I access for example "Jason Statham" inside the "name" char*?

Serial.println(name);  // prints "Jason Statham"

Wouldn't that print all the names and not a specific one?


text:
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?

I know this doesn't solve your problem with the Arduino IDE, but if you want to do headless development on a raspberry pi, you might want to look into PlatformIO, which does not need a GUI and can be used from the CLI. (https://platformio.org/ and https://docs.platformio.org/en/latest/core/index.html).

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.
cd /path/to/directory/containing/sht30v1.ino
arduino-cli -b arduino:avr:nano compile
arduino-cli -b arduino:avr:nano upload --port /dev/ttyUSB0

What version is arduino-cli in? I am 1.8.13

I'm not sure offhand what the latest version is.  Mine has been installed for some time now, I'm not sure its version will tell you anything.  The thing is though, the IDE version and the arduino-cli versions don't necessarily need to be related.  And the version number that largely affects your project is the version number of the (AVR) core, currently at 1.8.3. It's version number is also only-so-related to the IDE or arduino-cli.  Run the latest AVR core with the latest arduino-cli and you should be fine.

Just to give you a bit more info, I just ran their installer script (the curl to shell pipe) on their page to install the latest.  arduino-cli version now reports version 0.15.0 commit 0a034d73.  Again, this number has not a lot do with the others.

It looks like you've skipped over the command-line for compiling, the first of two in the answer.

I can get the sketch compiled and export the .hex files but it won't upload https://bpa.st/HYXCG

It is possible you need to use the the specific cpu option for the "old" nano, which connects at 57600 baud during bootloading.  In which case your -b option would need to be -b arduino:avr:nano:cpu=atmega328old

I honestly cannot tell if it worked or failed.  https://bpa.st/OXPQ I think it worked but I see a failure. Yes, it is an older boot nano

Let us continue this discussion in chat.


text:
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.
Arduino requires libusb-win drivers, which can be checked with Zadig.   Available here: https://zadig.akeo.ie/
This problem was 99% solved (with help) by selecting  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

i think rhat the yellow exclamation mark in the device manager is an indication that windows cannot talk to the device ... try finding the correct drivers ... your post is unrelated to the arduino, so it is off topic here

Are you choosing "Upload" or "Upload using programmer"?

I'm pretty sure AVRDude needs that the Atmel-ICE has libusb drivers loaded to be able to interface with it (like in https://cyansensors.wordpress.com/portfolio/setting-up-atmel-ice-with-platformio-using-atmega328p/). What happens when you use https://zadig.akeo.ie/ to load libusb-win32 drivers? Also, the upload should happen via a USB device and not a COM port, so make sure to choose "Upload using programmer" when uploading. If that does not help, go to File -> Settings and enable "Verbose Upload" and post the log.

I think Maximilian you have put me on the right path.  Device Manager is happy with   the ICE now appearing under libusb-win32 devices.     I had indeed posted the error from 'Upload', which was in haste, as I had been using Upload Using Programmer.   Now the error is:   "avrdude: usbdev_send(): wrote -22 out of 7 bytes, err =
avrdude: jtag3_send(): failed to send command to serial port
avrdude: failed to sync with the JTAGICE3 in ISP mode"    So it appears the Arduino IDE uses the JTAG mode, not the ICSP protocol?    An Auduino IDE configuration option?   Thank You.

I guess I was too subtle about this before, so I'm going to mention it one last time before disappearing: The things you did to solve the problem go in an answer and not the question.  Someone who discovers this later should be able to see a question (that they can understand, at least if they have the same problem) and separate from that an answer.

Apologies Timeage, I thought the answers were other users responses.   Will make corrections today.   Need here to get a fetter feel for how it's supposed to work.  Again, apologies, I mistakenly thought I understood.

For reference, you said that it works 99% fine except that it won't load WCID driver (which I don't think is very ciritical?), but how did you resolve the error avrdude: usbdev_send(): wrote -22 out of 7 bytes, err = avrdude: jtag3_send(): ?

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-


text:
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.

When I want to be sloppy with taking a ground point on Arduino I typically use the USB shield; it's hard to miss.  Is this all there is to the question or am I missing something?

My question is: If i short circuit the 5V pin, with the GND pin, will this damage my arduino?

@timemage The shield of the USB socket shouldn't be connected directly to ground. The Arduino breaks the specs by doing that. Instead it should be connected to ground via a large (1MΩ) resistor. This is so that when the plug is inserted the shield connects first and a current-limited path between the grounds is created first to balance the two ground levels. Only once that is done should the main power and ground be connected. So relying on the shield of a USB socket is not always a good idea...

how does testing the power supply voltage test the board? ... you would get 5 V without any board

@Majenko, I'm aware of how it is and can be grounded, e.g. that is often connected by capacitor as well.  All I'm getting it, is that in practice it makes a real easy to place to set a negative probe.

@timemage as long as you know your schematic it's fine. Yes, on the Arduino it's convenient. Except when it's covered with a shield ;) Or the great huge lump of metal shorts against pins on the shield above it...

@Majenko, it sounds like you want to have a conversation about this. =)

@timemage No, not a conversation. Just a moan about Arduino's shoddy design practices...

@Majenko i mean the 5V pin and the gnd pin. The shield is connected to them because the male header pins, go inside the female header pins of the arduino. I did not understand the 1MΩ part...

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.

I am powering the board therough the computer's USB. However, you seem to have misunderstood. I did not explain this correctly. I don't want to test continuity. I want to measure between the GND pin and the 5V pin, to see if my voltage is indeed 5V (i was worried my shield pins do not touch the board).

Then again you can do that without power - test the continuity of the pins from the shield to the board.

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.

I hope i did not damage the arduino then. If i did damage it, then the arduino would not work at all? Because i did make a connection. How would i know if everything is ok?

If it was a brief contact, the board may well have survived. The most basic test is to load and run the blink.ino example. One that I use regularly is to write one that blinks each pin in sequence, then probe each pin with an LED and resistor to check that it works.

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 ...

I'm thinking you mean "partly" rather than "mostly". For what it's worth, pure water doesn't conduct all that well at all.  So if you haven't gotten sufficient salt, finger oils, soaps, or any other impurities, it may operate completely submersed.  I am not recommending that you try it.

oh , yes . that is why it didn't explode ...


text:
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
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.

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. ;)

Please accept this as the soulution, because the question is answered now.

It will take a day or two before you can do that.

Re: "if any one know why this happened", I would put a scope on it an look at the signals, particularly the rising edges because you may have something based roughly on this design.  Questions about that belong more squarely on ASE, though you can probably work it out if my suspicions about the relevance of the appnote happen to be correct.  You should be doing something to address 5V -> 3.3V, rather than nothing in any case.

@timemage if i had a scope i wouldn't post this question at all, i could debug it myself (i wish i had a scope) and ya it says it takes around two days to accept my answer


text:
Arduino analog input to iphone notification
I need some help :)

Is it even doable?
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

Thanks guys,
I already have the pushsafer app installed, so that comes in quitte handy. You say there is alot to be found for The kind of thing i wanna do.
But what do i search for? And where do i look?
Could you provide me with websites or links?
Or mabye forums where people could help me build the code? Greetings :)

Regarding your "Could you provide ... Or mabye[sic] forums where people could help me build the code?"  There is an official Arduino forum.

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.

If you only need to send a push-message, you can also use Prowl, Pushbullet, or Pushsafer.