text:
Stopwatch stop/start button and reset
i am trying to make a stop watch with a stop/start button and a reset button
i have made this
#include "RTClib.h"
//Setup the Real Time Clock, DS3231
RTC_DS3231 rtc;

const byte SQWinput = 2;  // Must be External Interrupt

volatile uint32_t  MillisecondsAtStartOfSecond = 0;

 unsigned long secondss=0 ;
 unsigned long minutess=0 ;

 unsigned long  hourss =0;
 unsigned long ms;

boolean passed_second=true;
boolean start=true;

const byte ledPin = 13;

const byte startButton = 7;

const byte resetButton = 3;
// Instantiate another Bounce object

const char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// The SQW pin, when set to 1 Hz mode, has a falling edge at the beginning of every second.
void SQWFallingISR()
{
  MillisecondsAtStartOfSecond = millis();
}

void setup ()
{
  Serial.begin(9600); // Set Serial Monitor to 115200
  delay(200);

  pinMode(7, INPUT);
  digitalWrite(7, HIGH);
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);

  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (rtc.lostPower())
  {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2022, 4, 03, 21, 14, 0));
  }

  // Configure SQW pin on the DS3231 to output a 1Hz squarewave
  rtc.writeSqwPinMode(DS3231_SquareWave1Hz);

  // Get MillisecondsAtStartOfSecond on the falling edge of SQW.
  attachInterrupt(digitalPinToInterrupt(SQWinput), SQWFallingISR, FALLING);
}

void loop ()
{
  DateTime now = rtc.now();

    ms = millis();

  noInterrupts();
  // How long since the second started?

  ms -= MillisecondsAtStartOfSecond;
  interrupts();

  if(digitalRead(7) != HIGH)   //START BUTTON
{    displayTime (now, ms);
     Serial.println("stopwatch  ");

  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
}

 if(digitalRead(3) != HIGH)   //RESET BUTTON
{
     Serial.println("stopwatch  ");

  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.println(0);
  ms=0;
}
 // displayTime (now, ms);
  /*Serial.println("stopwatch  ");

  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
  Serial.println("*********************************");
  Serial.println("Clock & Date  ");*/

  }

void displayTime(DateTime &now, unsigned long ms)
{
  ms = ms % 1000;  // Ignore full seconds

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  if (now.minute() < 10)
    Serial.print('0');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  if (now.second() < 10)
    Serial.print('0');
  Serial.print(now.second(), DEC);
 // Serial.println();
  Serial.print(':');
  if (ms < 100)
    Serial.print('0');
  if (ms < 10)
    Serial.print('0');
  Serial.print(ms, DEC);
  Serial.println();
  Serial.println("*********************************");

  if(ms>998) {
      secondss++;

  }
    if(secondss>59) {
     secondss=0;
      minutess++;

    }
    if(minutess>59) {
     minutess=0;
      hourss++;}

    }

but it is not working properly
the time is not incrementing after ms reaches 999
what is causing this?

What do you mean by “it is not working properly”? What behavior do you see? How is it different from the behavior you expect?

the time is not incrementing after ms reaches 999

declare now in setup() ... DateTime now; .... then use now = rtc.now(); in loop()

This code is quite confusing, as you are using both millis() and an
RTC as time sources.
Your problem may come from here:
ms -= MillisecondsAtStartOfSecond;

If the internal clock of your Arduino is a bit off, it may happen that
an RTC second is only 999 milliseconds from millis(). If that happens,
then ms will never hit 999, and will instead go straight from 998
to 0.
Or maybe it's here:
ms = ms % 1000;  // Ignore full seconds
// ...
if (ms > 998) {
    secondss++;
}

If you sketch is busy (maybe it is communicating with the RTC), it may
not run this code precisely at millisecond 999. And 999 is the only
value of ms that can possibly increment secondss.
For a stopwatch, you don't really need the RTC data. You can implement
it entirely on the basis of millis(), and that would simplify things:
bool stop_watch_running;
uint32_t stop_watch_last_update;
uint16_t stop_watch_ms;
uint8_t stop_watch_s;
uint8_t stop_watch_min;
uint8_t stop_watch_h;

void stop_watch_reset() {
    stop_watch_running = false;
    stop_watch_ms = 0;
    stop_watch_s = 0;
    stop_watch_min = 0;
    stop_watch_h = 0;
}

void stop_watch_start() {
    stop_watch_last_update = millis();
    stop_watch_running = true;
}

// Call this periodically.
void stop_watch_update() {
    if (!stop_watch_running)
        return;
    uint32_t now = millis();
    stop_watch_ms += now - stop_watch_last_update;
    stop_watch_last_update = now;
    while (stop_watch_ms >= 1000) {
        stop_watch_ms -= 1000;
        stop_watch_s++;
        if (stop_watch_s >= 60) {
            stop_watch_s = 0;
            stop_watch_min++;
            if (stop_watch_min >= 60) {
                stop_watch_min = 0;
                stop_watch_h++;
            }
        }
    }
}

void stop_watch_stop() {
    stop_watch_update();
    stop_watch_running = false;
}

If you know a bit about C++ classes, you may want to turn this into a
class, and replace the stop_watch_ prefix with StopWatch::.

Hello Edgar
Thank u v much for your code
RTC is used to get sq wave output


text:
I’m having trouble getting a motor to run for 10 seconds and then reverse direction every time push button is pushed down
i am brand new to arduino and was looking for a little help. i am looking to activate a motor once the button is pushed for 10 seconds and then have it stop. then the next time the button is pushed, it runs in reverse for ten seconds and stops. i need it to continue this cycle everytime the button is pushed. button push 1 = forward 10 seconds, button push 2 = reverse ten seconds, button push 3 = forward 10 seconds and so on... i believe i am very close to accomplishing this task however like i said i am new to all this and i could be miles away. any help would be appreciated. i am using a mega 2560 even though the picture shows an UNO. i dont think itll matter as long as i use the correct pins.
link to tinkercad.com
int BUTTON = 9;
int DIRA = 3;
int DIRB = 4;
int FOR = true; //forward - reverse
int ENABLE = 5;

void setup() {
  //---set pin direction
  pinMode (ENABLE, OUTPUT);
  pinMode (BUTTON, INPUT_PULLUP);
  pinMode(DIRA,OUTPUT);
  pinMode(DIRB,OUTPUT);
  Serial.begin(9600);
}

void loop() {
 if (digitalRead(BUTTON) == HIGH) {
   digitalWrite(ENABLE, HIGH);
   if (FOR == true) {
    digitalWrite(DIRA,HIGH); //on forward
    digitalWrite(DIRB,LOW);
    delay(10000);
    FOR = false;
    digitalWrite(ENABLE,LOW);  //stop
   } else {
    digitalWrite(DIRB,HIGH); //on reverse
    digitalWrite(DIRA,LOW);
    delay(1000);
    FOR = true;
    digitalWrite(ENABLE,LOW); //stop
  }
 }
}`

you did not fully describe the desired behavior ... what should happen if the button is pressed and held? .... what about pressed, released and pressed again after one second?

And what is the problem with your code? Does it behave differently than expected? Then please describe in detail what you expected and what actually happened.

thanks for the replies. i hadnt even thought about different types of button presses. what i would like is that no matter if the button is pressed once, pressed and held, or pressed multipliple times, id like it to complete its cycle before the button can be pressed again. so on the push down it starts the cycle, and doesnt stop until the cycle is complete.
nothing happens when i push the button with my code and circuit as is.

the description of the problem belongs in the question at top of this page ... this site is not a forum ... reduce your code to only a push button that lights an LED when pressed ... does that work as expected?

Yes I I can get the push button to work without the motor controlling a simple RGB LED

next, write very simple code to test the motor ... run one direction for 2 seconds. stop for 2 seconds, run in other direction for 2 seconds, stop

Yes I did that already, I was able to get it to work without the L293D chip but can’t seem to get it to work with it

If you bypass the Arduino and just connect the motor wires to +5V & GND, does the motor spin? Can you get the motor to go in reverse by switching the wires?  If you can verify that then the next step would be to bypass the Arduino and  just use manual jumper wires to provide the correct voltages to the driver chip.  If this works, then you have eliminated everything except your code (assuming no dead Arduino pins).  Then replace the motor and driver chip with a simple resistor-LED combination on your output pins to provide a visual indication for output pin activity.

source: Stack Exchange

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

sort: votes


text:
Inconsistant compilation error
It is s a bit complicated to ask such question, but what may be the reason that one time  compilation passes and other fails without any changes in code? surely debugging this way is very hard (one time commenting out one part of code seems to stop this problem and later it returns even if commenting out was canceled).
I suspect it has to do with some changes in code regarding some ArduinoJson functionality
Sketch was was tested on 2 different platforms, Linux and Mac, and error occurs on both.
What troubles me is compilation inconsistentancy rather than some bugs in my code.
Error message:
/home/guy/snap/arduino/70/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: sketch/inFlash_Parameters.ino.cpp.o: in function `_Z17updateTopicsFlashRN18ArduinoJson6171_9112JsonDocumentE':
/home/guy/Documents/Dropbox/Arduino/libraries/myIOT2/examples/inFlash_Parameters/myIOT_settings.h:46: undefined reference to `_ZN6myIOT223extract_JSON_from_flashEPcRN18ArduinoJson6171_9112JsonDocumentE'
/home/guy/snap/arduino/70/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/guy/Documents/Dropbox/Arduino/libraries/myIOT2/examples/inFlash_Parameters/myIOT_settings.h:44: undefined reference to `_ZN6myIOT228update_vars_flash_parametersERN18ArduinoJson6171_9112JsonDocumentE'
/home/guy/snap/arduino/70/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: sketch/inFlash_Parameters.ino.cpp.o: in function `_ZN18ArduinoJson6171_9110MemoryPoolC4EPcj':
/home/guy/Documents/Dropbox/Arduino/libraries/myIOT2/examples/inFlash_Parameters/myIOT_settings.h:52: undefined reference to `_ZN6myIOT223extract_JSON_from_flashEPcRN18ArduinoJson6171_9112JsonDocumentE'
/home/guy/snap/arduino/70/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: sketch/inFlash_Parameters.ino.cpp.o: in function `_Z22readParameters_inFlashv':
/home/guy/Documents/Dropbox/Arduino/libraries/myIOT2/examples/inFlash_Parameters/myIOT_settings.h:52: undefined reference to `_ZN6myIOT228update_vars_flash_parametersERN18ArduinoJson6171_9112JsonDocumentE'
/home/guy/snap/arduino/70/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/guy/Documents/Dropbox/Arduino/libraries/myIOT2/examples/inFlash_Parameters/myIOT_settings.h:57: undefined reference to `_ZN6myIOT223extract_JSON_from_flashEPcRN18ArduinoJson6171_9112JsonDocumentE'
/home/guy/snap/arduino/70/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld: /home/guy/Documents/Dropbox/Arduino/libraries/myIOT2/examples/inFlash_Parameters/myIOT_settings.h:59: undefined reference to `_ZN6myIOT223extract_JSON_from_flashEPcRN18ArduinoJson6171_9112JsonDocumentE'
collect2: error: ld returned 1 exit status
Multiple libraries were found for "WiFiUdp.h"
 Used: /home/guy/snap/arduino/70/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/libraries/ESP8266WiFi
 Not used: /home/guy/Documents/Dropbox/Arduino/libraries/arduino_648747
 Not used: /home/guy/Documents/Dropbox/Arduino/libraries/WiFiNINA
 Not used: /snap/arduino/70/libraries/WiFi
Multiple libraries were found for "ArduinoJson.h"
 Used: /home/guy/Documents/Dropbox/Arduino/libraries/arduino_215091
 Not used: /home/guy/Documents/Dropbox/Arduino/libraries/arduino_892158
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

Sharing function that are mentioned in error to make the picture clearer:
void updateTopicsFlash(JsonDocument &DOC)
{
    for (uint8_t i = 0; i < 3; i++)
    {
        sprintf(topics_gen_pub[i], DOC["pub_gen_topics"][i]);
    }
    for (uint8_t i = 0; i < 3; i++)
    {
        sprintf(topics_pub[i], DOC["pub_topics"][i]);
    }
    for (uint8_t i = 0; i < 2; i++)
    {
        sprintf(topics_sub[i], DOC["sub_topics"][i]);
    }
}

void readParameters_inFlash()
{
    StaticJsonDocument<1250> DOC;

    iot.extract_JSON_from_flash(parameterFiles[0], DOC);
    iot.update_vars_flash_parameters(DOC);
    DOC.clear();

    iot.extract_JSON_from_flash(parameterFiles[1], DOC);
    updateTopicsFlash(DOC);
    DOC.clear();

    iot.extract_JSON_from_flash(parameterFiles[2], DOC);
    DOC.clear();
}

calling 2 functions from lib:
bool myIOT2::extract_JSON_from_flash(char *filename, JsonDocument &DOC)
{
    File readFile = LITFS.open(filename, "r");
    DeserializationError error = deserializeJson(DOC, readFile);
    readFile.close();

    if (error)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
void myIOT2::update_vars_flash_parameters(JsonDocument &DOC)
{
    useWDT = DOC["useWDT"];
    useOTA = DOC["useOTA"];
    useSerial = DOC["useSerial"];
    useFlashP = DOC["useFlashP"];
    useDebug = DOC["useDebugLog"];
    debug_level = DOC["debug_level"];
    useResetKeeper = DOC["useResetKeeper"];
    useNetworkReset = DOC["useNetworkReset"];
    noNetwork_reset = DOC["noNetwork_reset"];
    useBootClockLog = DOC["useBootClockLog"];
    ignore_boot_msg = DOC["ignore_boot_msg"];
}

Copy the files out of Dropbox and try again.

@romkey Can you explain why?

I think @romkey is observing that in the error messages you posted each of the references to files at Dropbox locations produced an Undefined reference error. It seems logical to move those files locally and see if the error behavior becomes more consistent.

@RowanP I was thinking about this factor after @romkey mentioned it. Still, .ino file, and .h file are local, and haven't changed at that point of re-compile ( I'll surely try what romkey suggested)

You're saying that you don't get the same results when you compile twice. That doesn't happen and you're confused by it. A large chunk of your files are resident on a file synchronization service, which can change your files without you being aware of what it's doing. If you want to debug this that's the obvious thing to take out of the equation.

Not related to the problem you are facing, but I looks at the data that you are retrieving from flash, instead of using json, it would be much more easier to deal with and much more efficient to store by using a struct.

The OP question looks very similar to this bug report https://github.com/arduino/Arduino/issues/2574

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


text:
STK8231 accelerometer, getting two axis (x & y data) but not z, also in 0-255
Here is the datasheet I followed: https://lcsc.com/product-detail/Motion-Sensors-Accelerometers_SENSORTEK-STK8321_C966924.html
We are trying the following code:
#include <Wire.h>

int ADXLAddress = 0x0F; // Device address in which is also included the 8th bit for selecting the mode, read in this case.

#define X_Axis_Register_DATAX0 0x03 // Hexadecima address for the DATAX0 internal register.
#define X_Axis_Register_DATAX1 0x02 // Hexadecima address for the DATAX1 internal register.

#define Y_Axis_Register_DATAX0 0x05 // Hexadecima address for the DATAX0 internal register.
#define Y_Axis_Register_DATAX1 0x04 // Hexadecima address for the DATAX0 internal register.

#define Z_Axis_Register_DATAX0 0x07 // Hexadecima address for the DATAX0 internal register.
#define Z_Axis_Register_DATAX1 0x06 // Hexadecima address for the DATAX0 internal register.

int X0, X1, X_out;
int Y0, Y1, Y_out;
int Z0, Z1, Z_out;

void setup() {
  Wire.begin(); // Initiate the Wire library
  Serial.begin(115200);
  Wire.beginTransmission(ADXLAddress);
  Wire.endTransmission();
}

void loop() {

  ArduinoOTA.handle();

  Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor
  //Ask the particular registers for data
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers

  Wire.requestFrom(ADXLAddress, 2); // Request the transmitted two bytes from the two registers
  if (Wire.available() <= 2) { //
    X0 = Wire.read(); // Reads the data from the register
    X1 = Wire.read();
  }

  Serial.print("\n   X0= "); Serial.print(X0); Serial.print("         X1= "); Serial.print(X1);

  delay(100);

  Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor
  Wire.write(Y_Axis_Register_DATAX0);
  Wire.write(Y_Axis_Register_DATAX1);
  Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers

  Wire.requestFrom(ADXLAddress, 2); // Request the transmitted two bytes from the two registers
  if (Wire.available() <= 2) { //
    Y0 = Wire.read(); // Reads the data from the register
    Y1 = Wire.read();
  }

  Serial.print("   Y0= "); Serial.print(Y0);  Serial.print("       Y1= "); Serial.print(Y1);

  delay(100);

  Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor
  Wire.write(Z_Axis_Register_DATAX0);
  Wire.write(Z_Axis_Register_DATAX1);
  Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers

  Wire.requestFrom(ADXLAddress, 6); // Request the transmitted two bytes from the two registers
  if (Wire.available() <= 6) { //
    Z0 = Wire.read(); // Reads the data from the register
    Z1 = Wire.read();
  }

  Serial.print("    Z0= "); Serial.print(Z0); Serial.print("         Z1= ");  Serial.print(Z1);

  delay(200);
}

Please help us to get the final X, Y, and Z.
Raw values of X and Y are somewhat correct, but Z always shows - 0.
Also, we are not able to calculate correctly X, Y, and Z to get the final G-force value.
Main point of datasheet :

The acceleration data of STK8321 is 12 bits and is given in two's complement format. The MSB in each axis will be stored in register XOUT2/YOUT2/ZOUT2 (0x03, 0x05, 0x07) individually, and the LSB will be stored in register XOUT1/YOUT1/ZOUT1 (0x02, 0x04, 0x06) individually. The NEW_X/NEW_Y/NEW_Z bit in register XOUT1/YOUT1/ZOUT1 (0x02, 0x04, 0x06) is used for new data flag, and it will be set to 1 if the data is updated, and reset if either the corresponding MSB or LSB is read. Reading the acceleration data registers shall always start with the LSB part due to the data protection function. When data protection function is enabled, the content of an MSB register will be updated by reading the corresponding LSB register.

pls ignore OTA handle line , ArduinoOTA.handle();

why don't you remove it from the code listing instead of writing a comment about it?

if (Wire.available() <= 2) {X0 = Wire.read(); X1 = Wire.read();} typo here, I think (<= vs >=). Mirrored in other places in the code. I would fix them in the code in the question on the assumption that it is not actually just a typo you're encountering.

Thanks, guys, i the got correct values by shifting 4 bit left & 4 bit right of each axis for both frames


text:
Servo not moving with PIR motion sensor
I am working on this code to turn a servo when the PIR motion sensor detects no motion, but it is not working.
Some symptoms include:

Servo is turning extremely slowly
PIR is not turning the servo
Servo is turning to incorrect angles

I have tried test programs, and when I type in the serial monitor, the servo turns (slowly and inaccurately) (I coded the serial monitor to do this). I have input from the PIR sensor but it is constantly high, even after waiting 2 minutes for it to initialize. My code and schematic are shown below.

My code:
#include <Servo.h>
Servo servo;

void setup() {
  // put your setup code here, to run once:
  servo.attach(13);
  pinMode(2, INPUT);
  Serial.begin(9600);
  Serial.println("Please wait");
  delay(60000);
}

void ifMos() {
  if (digitalRead(2) == HIGH) {
    int USER = 270;
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  int USER = Serial.parseInt();
  servo.write(USER);
  Serial.println(USER);
  ifMos();
  delay(10000);
}

firget about the servo for now ... write the simplest code that lights an LED when motion is detected

firget about the servo for now ... write the simplest code that lights an LED when motion is detected –
-jsotola

It worked! Thank you so much.
All I had to do was add the servo library, write to the servo and upload it. Only 21 lines of code! Final code:
#include <Servo.h>
Servo servo;

void setup() {
  // put your setup code here, to run once:
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  servo.attach(13);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(2) == HIGH) {
    digitalWrite(3, HIGH);
    servo.write(270);
  }
  else {
    digitalWrite(3, LOW);
    servo.write(0);
  }
}

Thank you to everyone. This was my first time posting on stack exchange, and it was a huge success. Thank you again!


text:
Return json from AsyncWebserver
I am using ESPAsyncWebServer ArduinoJson (6.19.4)
 server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
    {
      AsyncJsonResponse  *response = request->beginResponseStream("application/json");
      DynamicJsonDocument doc(1024);
      doc["deviceType"] = deviceType;
      for (uint8_t i = 0; i < NUM_RELAYS; i++)
      {
        doc[String(i)] = !configJSON["devices"][i]["ledState"];
      }
      serializeJson(doc, *response);
      request->send(response);
    });

the above code works fine but seems the response doesnt ends, any subsequent calls also doesnt work on the same URL.
Any help please.

check developer tools in your web browser to see what is wrong


text:
pointing to array of chars
I'm trying to pass a list of files (located in sketch) to be read using a library I write. List can have different filenames and vary in number of files.
How to pass a this array to my library?
for example:
char *parameterFiles[3] = {"/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"};
EDIT_1
To explain more clearly what are my needs:
Let's say that my library has a class name myIOT2. That class holds an array that contains a list of all filenames (what shown here is not all class). Those names are different from one use of the library to the other, and it might not have all 4 files ( can be also 0 files stored ).
I wish to have the flexibilty not to hard code exact filename in advance, but to pass that array as part of my sketch, as show prior to EDIT_1.
class myIOT2
{
public:
const char *parameter_filenames[4] = {nullptr, nullptr, nullptr, nullptr};

};

You mean a library of your own that you are currently writing?

@EdgarBonet - Sorry, Yes

@EdgarBonet please see my comment for  you answer

I saw the comment. It doesn't seem like something for which you would expect a response.

@EdgarBonet please explain - adding those variables is critical for the answer. Hope it was explained why.

Explain what? If you need to add some variables, I see no problem with that. If you have a question, please formulate it as clearly as you can, by editing the question here. Imagine you are talking to someone quite dumb (I am not very good at extrapolating a valid question from very partial information).

@EdgarBonet please see EDIT_1

You have to pass both a pointer to the list, and the length of the list
as an extra argument. The signature of the function may be something
like:
void processFiles(const char *fileList[], int fileCount);

Note that const char *fileList[] is just a fancy way of writing
const char **fileList. I find the former more readable, but that is
completely subjective.
Here is a small test code showing this in action:
void processFiles(const char *fileList[], int fileCount)
{
    for (int i = 0; i < fileCount; ++i) {
        Serial.print("Processing file ");
        Serial.println(fileList[i]);
    }
}

const char *parameterFiles[3] = {
    "/myIOT_param.json",
    "/myIOT2_topics.json",
    "/sketch_param.json"
};

void setup() {
    Serial.begin(9600);
    processFiles(parameterFiles, 3);
}

void loop() {}

Alternatively, you may put a “sentinel” at the end of the list: a null
pointer that signifies that the list ends there:
void processFiles(const char *fileList[])
{
    for (const char **p = fileList; *p; ++p) {
        Serial.print("Processing file ");
        Serial.println(*p);
    }
}

const char *parameterFiles[] = {
    "/myIOT_param.json",
    "/myIOT2_topics.json",
    "/sketch_param.json",
    nullptr
};

void setup() {
    Serial.begin(9600);
    processFiles(parameterFiles);
}

void loop() {}

Edit: Answering to EDIT_1.

[My library's] class holds an array that contains a list of all
filenames

First of all, you have to decide who is responsible for storing those
file names: the library or its client. When you write:
const char *parameterFiles[3] = {
    "/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"
};

you are creating 4 arrays: an array of 3 pointers named
parameterFiles, and three arrays of characters holding the file names.
Note that those 3 arrays are anonymous: they are not array
variables. If the client code tries to pass this parameterFiles to
your library, the array identifier will decay to a pointer, and your
library will receive that pointer. What should it do with it?

The library could just keep a copy of the pointer. The client is then
responsible for ensuring that it remains valid for as long as the
library may need it. This practically implies that parameterFiles
should be a global variable, and should not be modified once given to
the library.

The library could make a copy of the array. Then the client is freed
from this responsibility. However, it is still responsible for
ensuring that the pointers that were copied from the array remain
valid, i.e. that the file names stay in the same place in memory.

The library could copy the file names themselves. Then the client
doesn't have any responsibility about keeping pointers valid.

If you choose option 2 or 3, the library will have to hold one or more
arrays. You will then have to choose whether you allocate them
statically, or dynamically with new. Dynamic allocation is more
efficient when the arrays can vary greatly in length, but it can raise
issues of memory fragmentation in RAM-constrained devices.
I cannot tell you which option is best: it depends on your use case. In
any case, whatever you choose, you should document it: the user of the
library should know whether they are responsible for keeping any
pointers valid.
In the following, I will assume option 2 with static allocation. This is
consistent with the code snippets in your question. Also, if the client
provides the file names as string literals, then pointers to these
strings remain always valid.
Here is a toy implementation of the myIOT2 class, where the list of
file names is copied by the constructor into the class:
class myIOT2 : public Printable
{
public:
    static const int maxFileCount = 4;

    myIOT2(const char *fileList[], int count) {
        if (count > maxFileCount)
            count = maxFileCount;  // discard extra files
        fileCount = count;
        for (int i = 0; i < fileCount; i++)
            filenames[i] = fileList[i];
    }

    size_t printTo(Print& p) const {
        size_t count = p.print(F("myIOT2["));
        for (int i = 0; i < fileCount; i++) {
            count += p.print('"');
            count += p.print(filenames[i]);
            count += p.print('"');
            if (i < fileCount - 1)
                count += p.print(", ");
        }
        count += p.print(']');
        return count;
    }

private:
    const char *filenames[maxFileCount];
    int fileCount;
};

Note that, the array of file names being statically allocated, there is
a hard maximum on the number of files that can be stored. I made the
class Printable only for debugging convenience.
And here is an example of this class in use:
const int fileCount = 3;

const char *parameterFiles[fileCount] = {
    "/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"
};

myIOT2 iot(parameterFiles, fileCount);

void setup() {
    Serial.begin(9600);
    Serial.println(iot);
}

void loop() {}

This test sketch prints:
myIOT2["/myIOT_param.json", "/myIOT2_topics.json", "/sketch_param.json"]

great idea with "sentinel". Never encountered use of such for loop

To complete my original question - lib will contain fileList and fileCount to have a pointer for later uses, and Edgar's function can be:
`void processFiles(const char *_fileList[], int _fileCount)
{
fileCount=_fileCount;
for (int i = 0; i < fileCount; ++i) {
Serial.print("Processing file ");
fileList[i]=_fileList[i];
Serial.println(fileList[i]);
}
}`


text:
Arduino Uno Analog pot values are not smooth
I have tired Arduino smoothing example but mine analog value are not staying constant even when I don't rotate the potentiometer. I am mapping the values from 0 -> 1024 to 0-> 100. I have tried exponential filter also but the result is same.
Values change 2 to 3 point mostly. Any idea how can I make the readings much more smooth.

Welcome to Arduino:SE. You might find this post on our Meta site helpful: How to ask a good question for Arduino Stack Exchange.

please include a diagram of the circuit ... include the pot value

Dividing a normal (270 degree linear) potentiometer into 100 sectors is pushing to the limit. You can add hysteresis so it does not wander between adjacent values. Better is to use a rotary encoder.

Without seeing your filtering code we cannot say why they didn't smooth the values enough. Please share your code. It also depends on the noise your circuit is receiving (and its frequencies)

@6v6gt can you guide me or share the link how Can I add the hysteresis?

@chrisl I will add the code to today

@Arslan Hysteresis. https://forum.arduino.cc/t/hysteresis/506190  It includes an example with a potentiometer but, from experience, 100 sectors is the outer limit of what can be achieved.

Help yourself by helping us help you. Post a Schematic, not a frizzy picture showing how it is wired including power, and grounds. Include links to technical information to each of the hardware items. Reason for the links is many, it helps us to understand the part you have, there are many items with the same name but are not electrically the same. Second it saves a lot of time looking and guessing is that the correct one. We want to help but we need yours to accomplish that. Thanks st2000!

I will share rest of the details soon

There will always be noise in the output an Analog to Digital Converter (ADC).

An ADC converts a continuous-time and continuous-amplitude analog
signal to a discrete-time and discrete-amplitude digital signal. The
conversion involves quantization of the input, so it necessarily
introduces a small amount of error or noise.

All one can do is mitigate the noise.  Consider cleaning up your power supply.  Make sure your voltage reference is well filtered.  Inspect these power rails with an oscilloscope if one is available.  Also consider keeping all wiring as short as possible and avoid using Bread Boards as they tend to introduce noise in sensitive circuits.
When using exponential averaging consider the equation / code can be modified easily to accommodate very noisy signals at the sacrifice of responsiveness.  If the application can tolerate the delay, the decay of historical samples can be lowered such that what most consider noise can be filtered out.  One can do this by picking very small values for alpha in the following equation found on wikipedia.org:


text:
What does the .ino file extension mean
What does the .ino file extension mean?
We have .cpp meaning C++, .py meaning Python, .exe meaning executable and so-on.They're obvious. The .pde file type that sketches previously used, I think, comes from processing development environment (the arduino IDE being based* on / inspired by processing).  But what does .ino mean?
There's plenty that explains what such files are, but nothing explains what those three letters mean, if anything.
* source wikipedia

The last 3 letters of Arduino?

Arduino

That's all there is to say about that really.

As commented in the source code

The file extension for sketches has changed from .pde to .ino, to avoid
conflicts with the Processing software ("ino" are the last three letters
in "Arduino").

A citation, if anyone cares to have one.

@timemage Very good! Thanks for the citation.

Nice one @timemage I've added that to the answer.

And .ard was probably already taken https://fileinfo.com/amp/extension/ard

"Arduino" is an Italian word, and "ino" is the suffix which lends itself well to a filename extension.
From Google Translate of Italian ino:

ino

Suffisso alterativo di aggettivi e sostantivi; nei primi ha valore diminutivo-vezzeggiativo, talvolta con sfumatura ironica ( biondino, carino ), oppure significa appartenenza etnica ( alessandrino, cadorino ), collegamento con materie ( argentino, salino ); nei secondi, oltre ad avere valore diminutivo-vezzeggiativo ( gattino, pensierino ), indica pure un mestiere ( ciabattino, tamburino ), uno strumento o arnese o apparecchio ( cerino, lavandino ); in alcuni casi è applicato a verbi ( imbianchino, accendino ).
In chimica organica, suffisso che nella nomenclatura ufficiale indica gli idrocarburi acetilenici, cioè gli alchini ( etino ).

Alterative suffix of adjectives and nouns; in the former it has a diminutive-pet name, sometimes with an ironic tinge (blond, cute), or it means ethnic affiliation (Alexandrian, Cadore), connection with materials (Argentine, saline); in the latter, in addition to having a diminutive-pet name (kitten, little thought), it also indicates a trade (cobbler, drummer), an instrument or tool or apparatus (match, sink); in some cases it is applied to verbs (painter, lighter).
In organic chemistry, suffix that in the official nomenclature indicates acetylenic hydrocarbons, i.e. alkynes (ethin).


text:
SNMP Manager - Multiple IP address -issue
I have multiple SNMP devices on the same network and I am trying to request, via OID numbers, each SNMP device and assign the response into an array.
When I request a single IP, I get the correct response as expected.
Problem:
If I run the same code in a for loop (multiple ip's 192.168.1.150, 192.168.1.151, etc), I get duplicate info.
I might be using the wrong callback method, or the SNMP Manager can not dynamically change the ip address..
I have researched a lot of topics and tried many avenues, but I can't get past this point.
If anyone can assist me, it would help a lot!!

Example Output:
The model name and serial should be different on each ip
----------------------
192.168.8.150
KONICA MINOLTA bizhub C658
A79J021002278
----------------------
192.168.8.151
KONICA MINOLTA bizhub C658
A79J021002278
----------------------
192.168.8.152
KONICA MINOLTA bizhub C658
A79J021002278
----------------------
192.168.8.153
KONICA MINOLTA bizhub C658
A79J021002278
----------------------
192.168.8.154
KONICA MINOLTA bizhub C658
A79J021002278

Here is the code
#if defined(ESP8266)
#include <ESP8266WiFi.h> // ESP8266 Core WiFi Library
#else
#include <WiFi.h>        // ESP32 Core WiFi Library
#endif

#include <string.h>
#include <WiFiUdp.h>
#include <Arduino_SNMP_Manager.h>

//************************************
//* Your WiFi info                   *
//************************************
const char *ssid = "Workmin_Sales";
const char *password = "workmin92429242";
//************************************

//************************************
//* SNMP Device Info                 *
//************************************
const char *community = "public";
const int snmpVersion = 1; // SNMP Version 1 = 0, SNMP Version 2 = 1
// OIDs
const char *oidModelName = ".1.3.6.1.2.1.25.3.2.1.3.1";               // OctetString SysName
const char *oidSerialNumber = ".1.3.6.1.2.1.43.5.1.1.17.1";              // OctetString SysName
//************************************

//************************************
//* Settings                         *
//************************************
int pollInterval = 20000; // delay in milliseconds
//************************************

//************************************
//* Initialise                       *
//************************************
// Variables
char *modelNameArray[5];
char *serialNumberArray[5];

char modelName[50];
char *modelNameResponse = modelName;
char serialNumber[50];
char *serialNumberResponse = serialNumber;

// Blank callback pointer for each OID
ValueCallback *callbackSerialNumber;
ValueCallback *callbackModelName;
//************************************

unsigned long pollStart = 0;
// SNMP Objects
WiFiUDP udp;                                           // UDP object used to send and receive packets
SNMPManager snmp = SNMPManager(community);             // Starts an SMMPManager to listen to replies to get-requests
SNMPGet snmpRequest = SNMPGet(community, snmpVersion); // Starts an SMMPGet instance to send requests

//************************************
//* Function declarations            *
//************************************
void getSNMP();
//************************************

void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to SSID: ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  snmp.setUDP(&udp); // give snmp a pointer to the UDP object
  snmp.begin();      // start the SNMP Manager
}

void loop()
{
  // put your main code here, to run repeatedly:
  snmp.loop();
  if (millis() - pollStart >= pollInterval)
  {
    pollStart += pollInterval; // this prevents drift in the delays

    getSNMP();
    // doSNMPCalculations(); // Do something with the data collected
  }
}

void getSNMP()
{
  for (int i = 0; i < 5; i++) {
    // Build a SNMP get-request add each OID to the request
    IPAddress router(192, 168, 8, i + 150);

    // Get callbacks from creating a handler for each of the OID
    callbackSerialNumber = snmp.addStringHandler(router, oidSerialNumber, &serialNumberResponse);
    callbackModelName = snmp.addStringHandler(router, oidModelName, &modelNameResponse);

    snmpRequest.addOIDPointer(callbackSerialNumber);
    snmpRequest.addOIDPointer(callbackModelName);

    snmpRequest.setIP(WiFi.localIP()); // IP of the listening MCU
    // snmpRequest.setPort(501);  // Default is UDP port 161 for SNMP. But can be overriden if necessary.
    snmpRequest.setUDP(&udp);
    snmpRequest.setRequestID(rand() % 5555);
    snmpRequest.sendTo(router);
    snmpRequest.clearOIDList();
    delay(1000);

    modelNameArray[i] = modelNameResponse;
    serialNumberArray[i] = serialNumberResponse;
    Serial.print("192.168.8.");
    Serial.println(i + 150);
    Serial.println(modelNameArray[i]);
    Serial.println(serialNumberArray[i]);
    Serial.println("----------------------");
  }
}

I think I see multiple issues with the example above.

The snmpRequest.sendTo(router); will send the SNMP packet out. But you need to call snmp.loop() to read the incoming replies to your request. So you need to restructure the code so that you can call loop() potentially many times in order to wait for the incoming replies before you read and store the values.
serialNumberResponse is a pointer to a character array serialNumber (likewise for the model). If the callback returned serial number 123ABC the first time, and the next device was called 1XD then the array would have a value of 1XDABC. So if you plan to re-use the variable, you'll need to clear it between uses something like: memset(serialNumber, 0, sizeof(serialNumber));
As you might not always get a successful response, or a response within the time allowed, the value may be still blank, if you're looking to store the values in another variable, you may want to ensure they aren't empty, as this would overwrite the value you may have had back on a previously successful call. If you were dealing with numbers, the value might also be that of a previous call. As pointed out in the answer above, you're dealing with pointers, so if you want to store the value you need to copy the value out, otherwise, you'll just point to the same pointer.

I hope this helps point you in the right direction. I've added an example to the library to show how multiple devices can be queried and the results stored in an array, see: https://github.com/shortbloke/Arduino_SNMP_Manager/tree/master/examples/ESP_Multiple_SNMP_Device_Polling. It stores the responses directly into the array. This might cause values to be cleared in the event of a timeout, I've not tested it completely.
Martin

Thank you so much, Martin. I tried the example and it is working seamlessly! When I get money, I am gonna buy you a few beers :)

You're not storing the data in your array, you're storing a pointer to the storage where the callback stores its data. So every entry gets the same pointer to the same storage, which gets its content changed. So all the array entries see the same (last) content.
It took me many years to properly get my head around C pointers.
Instead of just assigning (=) the value you need to copy the content.
Since you just have an array of pointers that can be done with strdup() which allocates a new block of RAM and copies the contents to it. Be sure to use free() on that allocated block when you've finished with it.

strdup


text:
Stream data using Firebase Realtime Database rest api with nodeMCU client
I have data on firebase rtdb, which i want to listen in my nodemcu. I know there are libraries available like this one which provides listeners, but i want to do it using REST API streaming as mentioned in firebase documentation for rest api streaming.
So far i have successfully tested with curl on cmd as shown
My curl command is:
curl -v https://<name of rtdb>.firebaseio.com/SD0001/Up.json -H "Accept:text/event-stream"

I want to do the same thing on ESP8266 using ESP8266HTTPClient library. The firebase documentation states "Set the client's Accept header to text/event-stream" (which i added in header), "Respect HTTP Redirects, in particular HTTP status code 307" (which i am still struggling).
So far, my code is somewhat like this
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>

const uint8_t fingerprint[20] = {<<<<fingerprint of rtdb database>>>>};
HTTPClient https;
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
void setup()
{
  Serial.begin(115200);
  WiFi.begin("SSID", "PASSWORD");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP()); // successful Connection of ESP8266,

  client->setFingerprint(fingerprint);

  if (https.begin(*client, "https://<name of rtdb>.firebaseio.com/SD0001/Up.json"))
  {
    https.addHeader("Accept", "text/event-stream", false, true);
    https.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
    int httpCode = https.GET();
    Serial.println(httpCode);

    Serial.println(https.getString());
    //    Serial.println(https.getLocation());
    //    Serial.println(https.header("Location"));
    //https.end();
  }

}

void loop()
{
  //  Serial.println(https.getStream());
  //  Serial.println(https.getString());
  //  Serial.println(https.getLocation());
  //  delay(1000);
}

My code GETs the respone with 200 code, but there is no "Location" to redirect in the response header (at least i can't find any). Should i do http GET in the loop everytime? If so, where will i get my redirection url?
It would be really helpful if any solution is provided or any documentation to guide me in the right way.
Edit: I have put the text versions of curl command and the code in the post alongwith the screenshots. This is my first post here, so please bear with me.

please remove the screenshot of the code and replace it with the code text ... do the same with the first screenshot also

@jsotola i have put the actual code in text form. Please look into it. any help is appreciated as i am completely at sea here


text:
Prevent Resetting of Null Weight when using HX711 with a load cell
Helllo,
I am using the HX711 module and load cell with an arduino uno for force measurements.
I am using this library.
I first use the example "Calibration" code for calibration with a 200 g weight.
Then I save the calibration constant to the eeprom (choosing yes on the serial monitor).
Then the load cell is able to measure weights accurately.
After that I remove the weight from the load cell and run this code after uncommenting the last line of this part of the above code:
LoadCell.begin();
  //LoadCell.setReverseOutput();
  float calibrationValue;
  calibrationValue = 696.0;
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512);
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // I have uncommented this

The weights are measured accurately.
But when before powering the arduino, if I keep a weight on the load cell that weight is taken to be 0.
For this I have done the following change to the code:
boolean _tare = false;

But I get the following output on the serial monitor (Note: The following output is obtained on startup when there is/there is no weight on the load cell):

Questions:
What is the use of the following line:
calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch

Is it useless for the code I am using above? Because I am using the calibration value from the eeprom.
Q2) Why is it showing -39000 as an output value?
And how to correct it?
Alternate Statement:
In other words, I want to use the HX711 module with the arduino and a load cell. I will first calibrate it with a known weight and save the calibration value.
Before powering up the arduino I will keep a weight on the load cell. After powering up the weight value should be the absolute value instead of making the Weight Null.
EDIT1:
I incorporate the changes suggested in the answers by @Edgar Bonet and also make the problem more clear just in case.
According to suggestions I have made the corresponding changes to the calibration code. Then I run that and the values are saved to eeprom. Code changes:
const int calVal_eepromAdress = 0;
const int tare_eepromAdress = sizeof(float);

and
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
        EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.commit();

Now, I wish to run the second script and for this to display the correct weights.
This should work in all cases regardless of whether a weight has not been kept on the load cell or has been kept and should be independent of the weight that has been kept.
To this script I have made the following changes:
const int calVal_eepromAdress = 0;
const int tare_eepromAdress = sizeof(float);

and
// Inside void setup()
void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  float tareValue;
  calibrationValue = 696.0; // uncomment this if you want to set the calibration value in the sketch
  tareValue = 0;
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
  EEPROM.get(tare_eepromAdress, tareValue);

  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = true; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    LoadCell.setTareOffset(tareValue);
    Serial.println("Startup is complete");
  }
}

EDIT2:
#if defined(ESP8266)|| defined(ESP32)
        EEPROM.begin(512);
#endif
        EEPROM.put(calVal_eepromAdress, newCalibrationValue);
        EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());

        Serial.println(newCalibrationValue);
        Serial.println(LoadCell.getTareOffset());

Output:
-206.90
8368790

In the second script:
#if defined(ESP8266)|| defined(ESP32)
  //EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
  EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
  EEPROM.get(tare_eepromAdress, tareValue);
  Serial.println(calibrationValue);
  Serial.println(tareValue);

Output:
-206.90
0.00

I am uploading my codes onto Github just in case. They can be found here.
Q) What is happening here?
EDIT3:
The following changes make it work like a charm:
In the "Calibration" script:
long tareValue = LoadCell.getTareOffset(); // Instead of float tareValue

Similarly in the second script:
long tareValue; // Instead of float tareValue

Have you checked which value the calibrationValue has before you write to EEPROM and after you read it from EEPROM? Just to check if the storage of the value works correctly. And you need to begin the EEPROM for it to work correctly

@chrisl yes, it is being read correctly.

see the library example file Persistent_zero_offset.ino.

In order to convert the raw ADC readings to a weight, the library needs
two coefficients:

a “tare offset”, which is the raw reading when there is no weight on
the scale
a gain, or “calibration factor”, which is the ratio of a change in the
ADC reading to the corresponding change in weight.

The examples provided with the library use the EPPROM to store and
retrieve the calibration factor, but not the tare offset. This makes
sense as, in common usage, a weight scale is always zeroed at power up,
or right after power up. This is usually desirable as one would often
place an empty container on the scale which should not affect the
displayed weight.
If you do not want to zero the scale at power-up, then you need your
sketch to remember the tare offset in addition to the calibration
factor. For this, you can use the methods of LoadCell:
// Get the tare offset (raw data value output without
// the scale "calFactor").
long getTareOffset();

// Set new tare offset (raw data value input without
// the scale "calFactor").
void setTareOffset(long newoffset);

Now, to the more specific questions:

What is the use of the following line:
calibrationValue = 696.0;

None. It is just an example. You are supposed to either replace this
number with your measured calibration factor, or remove this line and
read calibrationValue from the EEPROM.

Why is it showing -39000 as an output value?

Because the tare offset has not been set, so it presumably defaults to
zero.

Edit: Answering extra questions in comment.

Do I need to store this value to the eeprom when running the
calibration script?

You can store it whenever it is convenient to you. The calibration
script seems a good place.

I am not able to get this into code. I read the source files but I am
unsure about what changes to make.

What you may try (untested):

right after the line
const int calVal_eepromAdress = 0;

add this:
const int tare_eepromAdress = sizeof(float);

Right after this:
EEPROM.put(calVal_eepromAdress, newCalibrationValue);

add this:
EEPROM.put(tare_eepromAdress, LoadCell.getTareOffset());

Thanks that makes sense. Do I need to store this value to the eeprom when running the calibration script? I am not able to get this into code. I read the source files but I am unsure about what changes to make to the calibration and the second script. Any help is greatly appreciated.

I have made the changes you suggested and have added changes to the second script as well. I clarify the changes in the original question. Please have a look

Regarding your changes, you should probably set _tare to false in order to avoid setting the tare offset twice. You cal also get rid of the if (LoadCell.getTareTimeoutFlag()) part and unconditionally set both the calibration factor and the tare offset.

It's still not working. I get -40000 on the Serial Monitor. I show the changes and the results here.

Ok it seems the right value is not being stored for the tare value. I show this in EDIT2 in my post.

@Atharva: Re “EDIT2”: The method getTareOffset() returns a long, and that is what you are storing in the EEPROM. In LoadCell_Read.ino, you EEPROM.get() that value into a float. This is basically reinterpreting the bit pattern of the long as if it was a float. The resulting value is about 1.17e-38, which gets printed as “0.00”.


text:
Is there a way to connect two Arduinos, when one of them has all of its pins occupied?
I want to connect an Arduino Uno to an Arduino Nano, so that it can send signals. The problem is that the Arduino Uno has a motor shield connected to it, and it takes up all pins of the Arduino.
This is a picture of the whole motor shield contraption if it helps:

Does anybody know any solution for this?

Just because a shield sticks pins into the Arduino it doesn't follow that it uses all those pins. Read the shield schematic or manual to see what is actually used and what is not used. Chances are only a few pins are actually used.

Yeah, i figured that out, but its not really possible to keep only one side of it plugged in. Can i solder wires from the arduino to the pins that are not being used?

Of course you can. Or you may find there are connections on the top that just connect direct to the Arduino pins.

On the image it looks like you can solder pin headers to the shield to connect the other pins from there. Though to say for sure we would need to have a look at the shields datasheet/product page. Can you provide a link for it?

https://5.imimg.com/data5/PX/UK/MY-1833510/l293d-based-arduino-motor-shield.pdf

Pins 0 and 1 are serial pins which are also connected to usb, and you use them when you are programming your board or when you send anything to serial. It is unlikely that any shield uses it unless it has to and it although has a benefit of being able to listen to what the Arduino sends.
I think hitching a ride on pins 1 and 0 (rx/tx) would be the easiest. SO you can print or write to them the same way as you respond to yourself.
Just a warning that when you are sending data between two boards and Print numbers they come as symbols of the numbers, not the numbers themselves So Serial.print(7) would arrive to the next arduino as number 55 or symbol '7'. If you are sending numbers between two arduinos you can use write Serial.write(7); which does not change data, but your serial monitor on a computer wont read it right, or you can send them as symbols, but then the arduino listening may have to convert number symbol to the number. (sooner or later you will have to create yourself a simple function to convert symbols to numbers in your project...


text:
Code does not run when Arduino is powered by AC adapter
I'm trying to implement the circuit as shown with an Arduino Nano. The project runs fine when powered via the USB port of the Arduino. However, the code freezes when connected to an AC adapter. When switched back to power supply via USB, the code does not run and resetting the board has no effect. The board starts to work again only when the code is re-uploaded.
Tried the following to troubleshoot the issue with no success:

Changed the power supply
Tried with a blink sketch and an example code of U8glib
Eliminated the MOSFET's Q1 & Q2 to simplify further

The only other component in question seems to be the buck converter connected between the AC adapter and the Nano board, but it is rated for 5 V, 3 A and should not be of concern I believe. I appreciate your inputs.
I uploaded a blink sketch to the Nano. It works OK over the USB power, but it starts resetting randomly when connected to the power supply. I swapped the buck converter with an LDO and it seems to work flawlessly. The output of the buck converter reads about 5.18 V and according to the ATmega328p datasheet, it can accept up to 5.5 V.
Could the problem be associated with the switching frequency of the buck converter (the stated switching frequency is about 500 kHz).
P.S. I'm using the Nano clone. I'm not sure if it adheres to the original parameters as stated in the ATmega datasheet.

what happens if you unplug the nano from the circuit?

Unfortunately, can't uplug the nano as it is soldered onto the PCB.

That the code has to be re-uploaded to get it to work sounds strange. Maybe show your software. Does it have a line like while ( ! Serial ) ;  ?

I'm using the same code as given in the following link.https://github.com/nppc/Heater12VControl/blob/master/Arduino/HeaterControlV2/HeaterControlV2.ino However, the problem persists even with simpler codes as well.

What is the rating of the power supply. What is the power supply and converter voltages when running off power supply?

Power supply is rated 15V, 65W. This voltage is stepped down to 5V using a buck converter(CN3903).

so is the Nano powered over Vin with 12 V or directly over 5 V pin?

The nano is powered over the 5V pin

Uploaded a blink sketch to the nano. Works ok over the USB power. But it starts resetting randomly when connected to the power supply. Swapped the buck converter with an LDO and it seems to work flawlessly. The output of the buck converter reads about 5.18V and according to the Atmega328p datasheet, it can accept upto 5.5V. Could the problem be associated with the switching frequency of the buck?(The stated switching frequency is about 500kHz) P.S- I'm using the nano clone. Not sure if it adheres to the original parameters as stated in the Atmega datasheet.

I assume you have this in your setup:  pinMode (D6, OUTPUT); If not it will remain an input.

Yes, D6 is defined as an output

You should use a decoupling capacitor on the nano board (something as 10uF//100nF). On the OP original picture, eventually, replace D1 or add a serial resistor (100 Ohm or more, see current needed ?)

Is the buck converter properly filtered?
Many ebay/amazon supplies are done too cheaply. While LEDs will run from practicaly anything with at-least some sign of correct specs, combination of back converter trying to keep-up with changing current and compensate to achieve correct voltage, while voltage regulator is adjusting and as such changing the consumption characteristics... dependant on buck converters changes.
MCU requirements for clean supply are lot greater them that of LEDs.
Bunch of suitable capacitors after the buck converter, but before the arduino might do it. Hopefuly somebody better then me in that area might advice you bout capacitor values. mine rough guess would be 100nF of about 20V.

I think the buck converter module has a capacitor at the output. According to the datasheet, it's rated around 20uF-60uF.

try holding ones legs next to the input (its normal for Amazon/ebay sellers to take description from other listing without checking)


text:
Pro Micro COM port disappeared after upload
I uploaded a sketch to my Pro Micro and it stopped showing in serial ports. Other Arduinos show up just fine.
I've tried to detect serial devices using pyserial and it's also not seeing anything. I've tried to reset the board by connecting the reset pin to ground twice in quick succession but it's not doing anything.
The board might be broken, but it seems unlikely to me as it's not connected to anything high powered.
The sketch I uploaded does use serial, but that hasn't been a problem before.
Any ideas on how to recover the board?

If it's a variety of pro micro that takes a micro-b cable, make sure you've not been trying to connect it with a power-only type of USB cable.

@timemage It's a mini usb and I've checked a few cables. Couldn't really be the issue as it worked before. I'm afraid it just decided to die on me :/

I wasn't there to observe that the same cable being used twice. "not connected to anything high powered" I would update with details on what happens if it's connected to nothing at all, except USB. If that is impractical I would update a volt meter reading of the 5V/VCC pin. Whether or not your "Other Arduinos" are also of Pro Micro type may be helpful. When you say "does use serial" are you referring to Serial1 (USART) or Serial (as in over USB). If you're leaving it all connected, clear images and wiring diagrams/schematics.

Since Pro-Micro comes as 3.3V and 5V, see past Q of mine

The Pro Micro uses a single processor (ATmega32U4) unlike some of the other Arduinos which have a separate processor for USB communications.
When reset, it will appear as a USB device for a couple of seconds, and then if the sketch does not use Serial, or uses it inappropriately, it could stop responding. For example, if the code went into a loop.
It is highly unlikely that the board just "broke". I suggest keeping the processor in Reset (tie Reset to Ground) while you compile a new sketch, and then release Reset when it tells you it is starting to upload.
You haven't posted your code, but it quite possibly is the problem. For example, you might have disabled interrupts.


text:
Send HEX number over serial
I have a RS232 device that I am able to communicate with using RealTerm on a windows PC.
The device is expecting a hex string like AA BB 03 01 03 EE

How would I send the equivalent string from an arduino? (I feel confident the arduino is wired correctly since I can see incoming uart data)
Things I have tried
void setup() {
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop() {
      Serial.println('AA BB 03 01 01 EE', "OCT");
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.print('0xAA 0xBB 0x03 0x01 0x01 0xEE', "DEC");
      delay(3000);
      Serial.print('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.print('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.print('AA BB 03 01 01 EE', "DEC");
      delay(3000);
      Serial.println('AA BB 03 01 01 EE', HEX);
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE', HEX);
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE');
      delay(3000);
      Serial.println('0xAA 0xBB 0x03 0x01 0x01 0xEE', HEX);
      delay(3000);
      Serial.write('AA BB 03 01 01 EE');
      delay(3000);
      Serial.write('0xAA 0xBB 0x03 0x01 0x01 0xEE');
      delay(3000);
}

I've also tried using double quotes as mentioned in the comments
     Serial.write("AA BB 03 01 01 EE");
     delay(3000);

     Serial.write("0xAA 0xBB 0x03 0x01 0x01 0xEE");
     delay(3000);

     Serial.write("101010101011101100000011000000010000000111101110");
     delay(2000);

Additionally I've tried writing the serial one line at a time
  Serial.write(0xaa); // AA
  Serial.write(0xbb); // BB
  Serial.write(0x03); // 03
  Serial.write(0x01); // 01
  Serial.write(0x01); // 01
  Serial.write(0xee); // EE
  Serial.write(0x0d); // \r
  Serial.write(0x0a); // \n
  delay(3000);

Additional Information

controlling projector using arduino
Adding \r\n to hex sent over arduino

'AA BB 03 01 01 EE'  This is a multi-character literal (a different thing from a string literal) and won't play a role in your answer. I don't know whether or not it's relevant to the question. If not, you probably intended to have double quotes here.

The device is expecting a hex string ... the first screenshot shows that binary values are being sent, not strings ... hexadecimal numbers are human readable representation of binary values

what problem are you seeing?

There are 2 problems. 1 is how to write out with Serial.write(). 2. Is how to understand what RealTerm is doing that arduino isn't doing. I'll capture that in another question (This question here is very similar to the second problem https://superuser.com/questions/245926/how-does-realterm-send-numbers)

Futhermore, I'm finding that the expected values I'm sending over serial aren't matching the received results. Almost exactly identical to this form https://forum.arduino.cc/t/how-to-send-hexadecimal-value-to-serial-devices/138834/15

The problem was that I wasn't using a RS232 to TTL adapter. Once I added that in between the arduino and the device the correct values were received.

As noticed by jsotola in a comment, your device doesn't seem to be
expecting HEX at all, but rather plain binary. Serial.print() is not
appropriate, as it is designed for sending ASCII text. For binary data,
you should prefer Serial.write(). More specifically, for sending
arbitrary binary data, the proper method is
size_t Print::write(const uint8_t *buffer, size_t size)

Applying this to your example gives:
const size_t packet_length = 6;
uint8_t packet[packet_length] = {0xaa, 0xbb, 0x03, 0x01, 0x03, 0xee};
Serial.write(packet, packet_length);

Thank you! This gets me closer, unfortunately the device still isn't responding. When I spy on the uart cable I see what is being transmitted is "~ (which converted from ascii is 7E 22

@spuder: There is something wrong either with your setup or your serial sniffer. I just tested my code with hd /dev/ttyACM0, and it does send the intended sequence.

I've created a simulator here: https://wokwi.com/projects/337371635280511572
When casting to a char the output is ª»î which matches hex AABB030103EE. So your code does appear to be logically correct, but there is something I'm not understanding in my situation.

@spuder: Your simulation prints “170 187 3 1 3 238” (without the spaces), which does match 0xaa, 0xbb, 0x03, 0x01, 0x03, 0xee.

I now understand ª»î is unicode, 170 187 3 1 3 238 is binary decimal, AABB030103EE is hexadecimal. I was confused because different terminals default to different display formats (even though it is all the same value under the hood).

I setup a loopback debugging cable to see the output. When using RealTerm I get AA BB 03 01 03 EE, but when using the arduino I get  95 91 7E 7F 7E 04 00

Once I used a proper RS232 to TTL adapter between the arduino and the device, the serial values started transmitting properly. Thank you https://www.amazon.com/dp/B07BJJ1T5G?ref=ppx_yo2ov_dt_b_product_details&th=1

if device expects actual numbers, then it does not receive them in hex format or decimal, but in binary. in which case you would need an array of numbers and then go with them using for loop (or purpouse made function.
byte sequence[]={0xAA, 0xBB, 0x03, 0x01, 0x01, 0xEE};
for(byte i=0; i<sizeof(sequence);i++) Serial.write(sequence[i]);

if you have to send it as a HEX, then its most likely a case of hex representation and you can use printf for that
Serial.printf("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", 0xAA, 0xBB, 0x03, 0x01, 0x01, 0xEE);

Another  think is that you should be careful using println when communicating with other devices.
println ads extra character (number) for new line, after the data you wish to send. if you only want to send data you wish to send, then use print instead
Edit:
Thanks for the note from Edgar Bonet, I was warned that printf is still not a standard instruction outside of the ESP core.
Its well worth adding it up by yourself. Look for a guide on arduino playground.

Your Serial.printf() call can be simplified as Serial.print("0xAA 0xBB 0x03 0x01 0x01 0xEE");.

yes, that is correct, but I have wanted to stress the 0x%02X formatting so that it always outputs two digit hex numbers and let the person latter change his variables after format string.

Good point! You may want to add a note, though, warning that Serial.printf() is not a standard Arduino method. It is available on ESP, but not on standard Arduino cores.

To quote you: Good Point!
I have got too used to esp core, that I have assumed that core-Arduino coughed-up with its hobby core in those years.

Alas, it would seem the core Arduino devs do not want the official cores to support printf().

I would suggest you view a tutorial or two on HEX numbers and how they are represented.

@Gil What do you mean? if you see something incorrect state it.  I take Feedback, but be specific so that I and the others can learn from it. I Personaly use HEX numbers in programming more then decimal. Mine communication library has all the instructions in HEX. So if you have some specific improvement of mine approach in mind, state it and I will edit mine answer quoting you in edit, like I did with the Edgar Bonet s  useful point.


text:
How to send an array of unknown size via I2C (from slave to master)?
When I try something like this, everything works.
Slave:
    # define DEFAULT_DATA_SIZE 256

    byte DATA[DEFAULT_DATA_SIZE];

    void requestEvent()
    {
      Wire.write( (byte*) DATA, sizeof(DATA));
    }

    void receiveEvent(int numBytes)
    {
      for (int i = 0; i < numBytes; i++) {
        DATA[i] = Wire.read();
      }
    }

Master:
    # define DEFAULT_DATA_SIZE 5

    void writeData(byte data[], int numBytes) {
      Wire.beginTransmission(I2C_SLAVE_ADDRESS);
      for (int i = 0; i < numBytes; i++)
      {
        Wire.write(data[i]);
      }
      Wire.endTransmission();
    }

    void readData() {
      byte data[DEFAULT_DATA_SIZE];
      Wire.requestFrom( I2C_SLAVE_ADDRESS, DEFAULT_DATA_SIZE );
      if ( Wire.available() == sizeof( data))
      {
        Wire.readBytes( (byte *) data, DEFAULT_DATA_SIZE);
      }
      Serial.print("Byte Array: ");
      for (int i = 0; i < DEFAULT_DATA_SIZE; i++ ) {
        Serial.print(data[i]);
        Serial.print(" ");
      }
      Serial.println();
    }

    byte data[5] = {0x1, 0x2, 0x3, 0x4, 0x5 };

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

      writeData(data, sizeof(data));
      delay(500);
      readData();
    }

    void loop() {

    }

But this only works when the master knows how long the array needs to be.
If I set the value of DEFAULT_DATA_SIZE not to 5, but more, then I get a set of random numbers.
I tried to make the slave pass the length of the array first, and then the array itself. But for some reason it doesn't work and I also get random numbers.
Slave:
    #include <Wire.h>
    # define I2C_SLAVE_ADDRESS 12
    # define DEFAULT_DATA_SIZE 256

    byte DATA[DEFAULT_DATA_SIZE];
    int RECEIVED_NUMBYTES = 0;
    bool isNumBytesSended = false;

    void setup()
    {
      Wire.begin(I2C_SLAVE_ADDRESS);
      delay(1000);
      Wire.onRequest(requestEvent);
      Wire.onReceive(receiveEvent);
    }

    void loop()
    {
    }

    void requestEvent()
    {
      if (!isNumBytesSended) {
        isNumBytesSended = true;
        Wire.write(RECEIVED_NUMBYTES);
      }
      else {
        isNumBytesSended = false;
        Wire.write( (byte*) DATA, sizeof(DATA));
      }
    }

    void receiveEvent(int numBytes)
    {
      RECEIVED_NUMBYTES = numBytes;
      for (int i = 0; i < numBytes; i++) {
        DATA[i] = Wire.read();
      }
    }

Master:
    #include <Wire.h>
    # define I2C_SLAVE_ADDRESS 12
    # define DEFAULT_DATA_SIZE 10

    void writeData(byte data[], int numBytes) {
      Wire.beginTransmission(I2C_SLAVE_ADDRESS);
      for (int i = 0; i < numBytes; i++)
      {
        Wire.write(data[i]);
      }
      Wire.endTransmission();
    }

    void readData() {
      Wire.requestFrom( I2C_SLAVE_ADDRESS, 1 );
      int numBytes = Wire.read();
      Serial.println("numBytes: " + String(numBytes));

      byte data[numBytes];
      if ( Wire.available() == sizeof( data))
      {
        Wire.readBytes( (byte *) data, numBytes);
      }
      Serial.print("Byte Array: ");
      for (int i = 0; i < numBytes; i++ ) {
        Serial.print(data[i]);
        Serial.print(" ");
      }
      Serial.println();
    }

    byte data[5] = {0x1, 0x2, 0x3, 0x4, 0x5 };

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

      writeData(data, sizeof(data));
      delay(100);
      readData();
    }

    void loop() {

    }

Master outputs:

01:20:13.844 -> numBytes: 5
01:20:13.878 -> Byte Array: 11 8 212 8 22
01:21:51.222 -> numBytes: 0
01:21:51.255 -> Byte Array:
01:21:54.323 -> numBytes: 5
01:21:54.323 -> Byte Array: 11 8 212 8 22
01:22:01.682 -> numBytes: 0
01:22:01.717 -> Byte Array:
01:22:04.280 -> numBytes: 5
01:22:04.314 -> Byte Array: 11 8 212 8 22
01:22:06.879 -> numBytes: 0
01:22:06.912 -> Byte Array:
01:22:10.386 -> numBytes: 5
01:22:10.420 -> Byte Array: 11 8 212 8 22

Please tell me the best way to solve this problem. Maybe transfer all values one byte at a time, and put a special delimiter between the beginning of new data?

I get a set of random numbers ... the numbers are not random because they repeat ... the numbers are invalid though

Try making the first byte the length. That will keep you from sending a zero size but the first byte would be 0. Create a function that will send the array byte by byte. Your receiving would also have to know the format.

yes, the idea of sending one byte at a time and specifying the length of the array worked. I'm surprised that I didn't do that sooner :)
SLAVE:
#include <Wire.h>
# define I2C_SLAVE_ADDRESS 12
# define DEFAULT_DATA_SIZE 256

byte DATA[DEFAULT_DATA_SIZE];
int pointer = 0;

void setup()
{
  Wire.begin(I2C_SLAVE_ADDRESS);
  delay(1000);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
}

void loop()
{
}

void requestEvent()
{
  if (pointer > DATA[0]) {
    Wire.write(0);
  }
  else {
    Wire.write(DATA[pointer++]);
  }
}

void receiveEvent(int numBytes)
{
  DATA[0] = numBytes;
  for (int i = 1; i <= numBytes; i++) {
    DATA[i] = Wire.read();
  }
  pointer = 0;
}

MASTER:
#include <Wire.h>
# define I2C_SLAVE_ADDRESS 12

void writeData(byte data[], int numBytes) {
  Wire.beginTransmission(I2C_SLAVE_ADDRESS);
  for (int i = 0; i < numBytes; i++)
  {
    Wire.write(data[i]);
  }
  Wire.endTransmission();
}

void readData() {
  Wire.requestFrom( I2C_SLAVE_ADDRESS, 1 );
  int numBytes = Wire.read();
  Serial.println("numBytes: " + String(numBytes));

  byte data[numBytes];

  for (int i = 0; i < numBytes; i++) {
    Wire.requestFrom( I2C_SLAVE_ADDRESS, 1 );
    data[i] = Wire.read();
  }
  Serial.print("Byte Array: ");
  for (int i = 0; i < numBytes; i++ ) {
    Serial.print(data[i]);
    Serial.print(" ");
  }
  Serial.println();
}

byte data[8] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 };

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

  writeData(data, sizeof(data));
  delay(100);
  readData();
}

void loop() {

}


text:
How to store a struct in a file?
I'm trying to store (read&write( a struct using LittleFS on ESP8266.
Appreciate assistance
struct oper_string
{
  bool state;     /* On or Off */
  uint8_t step;   /* Step, in case of PWM */
  uint8_t reason; /* What triggered the button */
  time_t ontime;  /* Start Clk */
  time_t offtime; /* Off Clk */
};

you can think of a struct as an array (group) of variables which might be of a different sizes and struct helps you take specific portion of this string.
Lets say you have a struct of
struct foo{
   bool first;
   uint8_t Second;
   uint16_t Third;
} structMember;

Then it is stored in a row in exactly same order as they have been defined
---------------------------
| bool | uint8_t | uint16_t|
|1 byte| 1 bytes | 2 bytes |
--------------------------
1B+1B+2B = sizeof(srtuctMember)

File.write()
saves date in a file in block of 1Byte each.
When you send array to the function it actualy receives only  a pointer to its beginning.
That is why many functions take a size as a second argument.
When you send a data into a function in a format its not designed to take you can tell the compiler that the function should trait it as a different type of variable.
Lets say we have function defined as
void sampleFunction(byte var1)
then we can use it by
char x='j';
sampleFunction((byte) x);

which tells compiler to treat 'x' as if it was byte.
when you pass array you are not really passing the actual data, but an information where the data is(same with the struct member), so by putting asterisk after the definition you are telling compiler the format of data it points to.
and when you read it back you will get all the contend back as same data in same order... which struct then divides in a same way
file.write((byte*) &StructMember,sizeof(structMember));

I only wish somebody have explained this to me when I was struggling to understand it dealing with char and utf8 few years ago...

So the idea is that each member in this struc is referenced as a byte / utin8_t pointer? and the result is an arrary of pointers (without any delimiter, space or so) ?

@guyd: StructMember is an instance – not a member – of the struct. The idea is that the struct as a whole is to be handled as an array of bytes. More precisely, the address of the struct is to be treated as the starting address of an array of bytes. That is a pointer to an array (of bytes), not an array of pointers.

@EdgarBonet - Sorry for my english, but a member of the struct is for example offtime which is referenced an address (&). Thank you for clearing this out.

Just as a complement to Tomas' answer (which is perfectly valid), I
would like to point out that consecutive members of a struct may not be
adjacent in memory. Some structs have padding within them, which is
needed to satisfy alignment requirements.
The struct given by Tomas as an example will not have padding, but yours
may. For example, on my 64-bit PC, your struct is stored as follows:

offset
size
member

0
1
state

1
1
step

2
1
reason

3
5
(padding)

8
8
ontime

16
8
offtime

In the table above, “offset” is the position of the member relative to
the start of the struct. The padding after reason is needed in order
to align ontime at an address that is multiple of 8. Your ESP
being a 32-bit machine, it is likely to use only a single byte of
padding.
Padding may be an issue for two reasons:

It can differ between computer architectures. Thus, if you plan to
write the file on the ESP and read it back on your PC (or vice
versa), it is one of the possible sources of incompatibility, the
others being endianness and member sizes.

It is a waste of disk space, although this might not be an issue if
you are only loosing 1 byte out of 20.

If padding can be problematic, the only valid option is to write and
read the struct one member at a time. Conversely, if the file is only
ever going to be accessed by the ESP, and you don't mind loosing a few
percent of the file to padding, then don't worry, follow Tomas' advice,
and read and write the struct as an array of bytes: it is just simpler.

thank you for that point of view (which was a hunch I got when commenting on tomas's answer).
I have 3 other files on that ESP ( can be either ESP32 or ESP8266 ), that paramters are stored.
Other option I was thinking of was save it a string file value0;value1;value2... having a delimiter as a marker.
And lasltly, using ArduinoJSON as key/ value pairs, and again save it similiarly to a parameter file I have on board.
What would you recommend ?

Thanks I was intending to refer to padding, as a part or reasoning for using sizeof rather then specific size number, and wanted to point it out in regards to bool, but somehow it got lost in edit attempting not to write too many points. I accept I am a IDYer, and attempt to write mine answers on a simpler level. And thatnks for improving so far all of mine answers here :-) you deseve the editing rights

@guyd: I almost always favor text formats over binary: they are somewhat harder to parse for a computer, but way more convenient for the humans who are going to debug the stuff. Binary is the choice for when you need space efficiency (either in the file itself or the code that handles it) or I/O performance. That being said: all the options you suggest are valid. Pick the format you are most comfortable with.

@Tomas: Thanks! Sometimes I am a nitpicker. Your answers are helpful and valuable contributions, and improving upon something that is already good feels quite rewarding. ;-)

Thank you both for a complete answer!
Guy

one can write a struct directly into a SPIFS/ FFAT file like this:
 * EXAMPLE READING AND WRITING A C++ STRUCT TO A FILE
 */
#include <FS.h>
#include <SPIFFS.h>

typedef struct {
  char someString[10];
  float someFloat;
} MyStruct;

MyStruct myStruct = { "test test",1.7 };

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  if(!SPIFFS.begin()){
      Serial.println("Card Mount Failed");
      return;
  }

  strncpy( myStruct.someString, "testtesttest", sizeof(myStruct.someString) );
  File myFile = SPIFFS.open("/somefile.txt", FILE_WRITE);
  myFile.write((byte *)&myStruct, sizeof(myStruct));
  myFile.close();
}

void loop() {
  // put your main code here, to run repeatedly:
  File myFile = SPIFFS.open("/somefile.txt", FILE_WRITE);
  myFile.read((byte *)&myStruct, sizeof(myStruct));
  myFile.close();
  Serial.printf( "read: %s, %.2f\n", myStruct.someString, myStruct.someFloat );
  delay(1000);
}

the code above is available on this Github Gist.

Nitpick: if the card fails to mount, setup() should abort() rather than return.

I agree. Is missing a few good practice code verifications for that to work flawlessly. Still is a sound code snippet to use.

@MiguelTomás Guessing it'll work the same using LittleFS ?

to be honest, haven't tried it recently.  however, I see no reason why it will not work...

@MiguelTomás - I'm trying to understand why myFile.read((byte *)&myStruct, sizeof(myStruct)); is used (byte *) ? I would have never guessed that syntax

right... i can recommend some good youtube video tutorials, alternatively coursera.org or udemy


text:
What's the difference between CloudTemperature, CloudTemperatureSensor and Float data types?
I have a SHT30 sensor for Wemos and I am learning to use Arduino IOT Cloud.
I use float data type for my temperature variable but I see two more data types:
CloudTemperature
CloudTemperatureSensor
What are the differences? Shouldn't use float?

From the technical reference for the Arduino Cloud on arduino.cc:

For your convenience, IoT Cloud provides specialized types which are just wrappers around basic types but declare the variable semantics more explicitly. This enables smarter integrations with third-party services (such as Alexa) and better visualization of widgets in dashboards.
You can use them just like a normal variable of the wrapped type, since they support assignment and comparison operators.

These types are actually wrapper classes, which add some functionality to better integrate in cloud services. You can use these just as the normal data types.

You can even look at how they are defined. Let's look at CloudTemperature for example. All the files can be found in the ArduinoIoTCloud repo on github.
The types are defined in the PropertyContainer.h file:
...
#include "types/CloudFloat.h"
...
typedef CloudFloat CloudTemperature;
...

So CloudTemperature is actually just CloudFloat, which is included from the corresponding header file. When we look at the CloudFloat.h file we find:
class CloudFloat : public Property {
  protected:
    float _value,
          _cloud_value;
...

So internally CloudFloat is just a float value with added functionality. And you can use it like any other float, since below that part that I've shown here all the operators (like /, *, +, ...) are overwritten (so the class knows what to do with these operators).
CloudTemperatureSensor is found at CloudTemperatureSensor.h and inherits from CloudFloat so works basically the same way (it only overwrites the assignment operator; the rest is the same as CloudFloat).

Shouldn't use float?

I haven't tried that myself. But from the documentation it sounds like there is no reason to not use the specialized types, since they provide the same functionality and more.


text:
Arduino Serial to USB=>serial data issue
I am using Mega 2560 to receive serial data from another device but the data appears on the serial terminal are strange characters. then i connected my USB to serial cable (HL-340) to the device and tried in serial terminal(Termite), data is landing fine.
Replaced Arduino with another one since I believed there could be a problem, but the problem persisted.
for further investigation i have connected my Arduino (Mega-2560) to my serial(USB->Serial) cable directly to receive data on the terminal but strangely even this is showing the wrong data (Arduino terminal is displaying the wright data but the data appears on the other terminal is wrong) sendind "c" receiving "N"...
what could be the reason for this..its a simple code to print character on the screen.
Thx

You have an rs232 cable not a UART cable.

Google "Arduino MAX232"

You need to be careful. Normal devices that have a "Serial" interface actually have an RS232 interface. While the data transmission scheme is similar with the "Serial" interface on the Uno/Mega (UART on TTL logic), RS232 has totally different voltage levels (up to -15 to +15V), which can kill your Arduino.
To connect an RS232 device to an Arduino you need a level converter (to convert between the RS232 levels and the TTL (Transistor Transistor Logic) level of the Arduino. The chip MAX232 is typically used for this. There are many resources about that on the web and even ready to use modules, which are equipped with a MAX232 and a RS232/Serial plug.


text:
Novice learning Serial.readString()
New to Arduino, getting into String variables and reading them from serial monitor.
Basically what I'm trying to do is have the user input either red, green, yellow. Whichever String they enter the LED comes on.
What is happening seems to be that the if statements are not true and are never entered thus not LEDs come on. I do have a serial.Println(myColor) at the end which displays myColor as the user has inputted into serial monitor. I just don't understand why the if statements are not firing. its really weird.
String msg="What LED do you want to turn on?";
String myColor;
int redPin = 12;
int greenPin = 13;
int yellowPin = 8;

void setup(){
Serial.begin(9600);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
}

void loop(){
    //LED ColorDEmo

    Serial.println(msg);                //print the question to serial monitor
    while(Serial.available() == 0){     //while we wait do nothing till data is available

    }
    myColor = Serial.readString();      // set myColor to serial value

    if (myColor == "red"){              // if the value is red
        Serial.println("In red");
        turnOffLEDS();                  // turn off all LEDS
        digitalWrite(redPin, HIGH);     // turn on red lED
    }

    if (myColor == "green"){            // if the value is green
        Serial.println("In green");
        turnOffLEDS();                  // turn off all LEDS
        digitalWrite(greenPin, HIGH);   // turn on green LED
    }

    if (myColor == "yellow"){           // if the value is yellow
        Serial.println("In yellow");
        turnOffLEDS();                  // turn off all LEDS
        digitalWrite(yellowPin, HIGH);  // turn on yellow LED
    }
    Serial.println(myColor);            // print myColor

}

// turns all LEDS off
void turnOffLEDS(){
    digitalWrite(yellowPin, LOW);
    digitalWrite(greenPin, LOW);
    digitalWrite(redPin, LOW);
}

debug your code by printing data to the serial console ... print the received message and print the length of the message

myColor = Serial.readString();
Serial.println(myColor.length());
Serial.println(myColor)
results
4
red
So it seems it is attaching an additional character tot he end of the String variable. SHould i be using readStringUntil() instead

Just a little side-point: It is a good to get used to using char arrays rather then strings. I know the current way arduino moves is to keep users on lover level, (buing more shields) but once you get to more advanced tasks and have to deal with memory footprint, then habit of using char array makes your life easier latter.

Thanks @Tomas, that's a really good point. String variables are memory hogs from what I've heard from others as well.

Also, what is the program to do if the user enters "RED" instead of "red", "RE" only, "R" only, etc.  That is why single character responses are generally better and less error-prone.

Avoiding String objects (back to the basics) often makes life easier.
Simply check if the answer contains one of the characters 'd' 'g' 'y'
Or (and) simplify your protocol to only send one character.
BTW:You might notice a delay in readString, waiting for a multi-character input to finish, because Serial.available() is true already after the first character of an input, and readString terminates only if it times out

thats a good idea, simplify into single characters.

thank you @jsotola
throught he debugging you mentioned i was able to learn that the '\n' was added to the end of the string. Instead of using
Serial.readString() I used Serial.readStringUntil('\n');
this would check for a delimiter character '\n' then stop. Thus, my myColor variable would be red instead of red'\n'


text:
Stabilization of HX711 and Faster Sampling. Code improvements
Helllo,
I am using load cells in my research project. I have 4 load cells and have connected 4 HX711 modules (one to each load cell) and have connected them to the arduino uno.
I have taken the example code given for 2 load cells and modified it for 4 load cells. My complete code is available here. The original HX711 2 load cell library example code is available here.
I have referred the source code but still have the following questions:
Q1) The following part of the code:
boolean _tare = false; //set this to false if you don't want tare to be performed in the next step
byte loadcell_1_rdy = 0;
byte loadcell_2_rdy = 0;
byte loadcell_3_rdy = 0;
byte loadcell_4_rdy = 0;
while ((loadcell_1_rdy + loadcell_2_rdy + loadcell_3_rdy + loadcell_4_rdy) < 4) { //run startup, stabilization and tare, both modules simultaniously
    if (!loadcell_1_rdy) loadcell_1_rdy = LoadCell_1.startMultiple(stabilizingtime, _tare);
    if (!loadcell_2_rdy) loadcell_2_rdy = LoadCell_2.startMultiple(stabilizingtime, _tare);
    if (!loadcell_3_rdy) loadcell_3_rdy = LoadCell_3.startMultiple(stabilizingtime, _tare);
    if (!loadcell_4_rdy) loadcell_4_rdy = LoadCell_4.startMultiple(stabilizingtime, _tare);
  }

Is this written correctly?
Can this be removed or is this part necessary?
Q2) I wish to increase the sampling rate so I am going to increase the baud rate to 115200 or higher. Does this have any affect on the previous question? Since, the source code seems to have been written for 10SPS.

You don't need 4 ADCs to measure 4 load cells, you need to configure the 4 load cells as Wheatstone bridge and measures it with one HX711 ADC. SparkFun has a good introduction on Getting Started with load cell which explain the details.

Also the higher the sample rate, the noisier the data it become. For a weight scale, accuracy is more important than speed, what is the point of increasing sampling rate. BTW, HX711 sampling rate requires hardware configuration changes. Read Olkal's HX711 library README for more information and why 10SPS is chosen.

@hcheung I am not talking about 4 strain gauges in a wheatstone on a single load cell. I need to measure 4 different forces hence I am using 4 different load cells.

It is better to use a chip from Analog Device AD7799. It has relatively high accuracy and no swimming, compared to the HX711. When connecting 2 load cells of 50 kg on the pavement
the scheme has an accuracy of 10 grams. I use the AD779x library.h and an example program that appears in the file-examples menu in arduino, after installing the library. When hx-711 is connected to the same
the accuracy of my sensors was 30 grams, I measured the accuracy of both ADCs for 10 minutes. I ordered AD7799 on Ali for 2-3$ . You need to take it together with the adapter for the ssop16 c chip
the distance between the terminals of the adapter is 0.65 mm. You also need to take "solder paste with solder", because the conclusions are too small and close. I took the SMD capacitors from the damaged matplate, measuring them
capacity by tester. When the load cell is warmed up with a hairdryer, the data changes greatly. Perhaps you need to put a digital ds18b20 thermal sensor on the thermal sensor on the thermal watch. With even a short - term
when you touch the load cell with your finger, the readings also change greatly due to the sensor warming up from body heat. If you touch through several layers of folded paper, the sensor does not warm up and
the readings do not change. Those who will test load cells by pressing them with their finger should remember that in a few seconds, after touching the load cell with their finger, the heat will reach
the sensor's sensing element along its metal body and the values will float up or down by tens of grams, depending on the connection scheme, sensor type, duration
touching. Press the sensors with any objects, not with your hand directly. L The inductance may or may not be set. It is possible to connect without a reference voltage source
TL431, and directly from the arduino 5v with a filter of 2 capacitors (as shown in the diagram). I first connected without it and the readings were quite normal. We need to try... The power source used
from Hi-link.


text:
Trouble connecting barcode scanner to ESP32 devkit using UART - fails to connect over serial
I'm having trouble connecting a SparkFun 2D Barcode Scanner Breakout (effectively a DE2120) to a 30-pin ESP32 dev kit v1 (marked ESP-WROOM-32) and running the SerialScan sample application for this sensor successfully.
I believe I have the two devices connected as per the instructions:

ESP32 -> DE2120
3V3 -> 3.3v
GND -> GND
RX2 -> RX
TX2 -> TX

In the sample code I have pins configured as follows:
SoftwareSerial softSerial(25,27);

(according to the mapping here these are the TX2/DX2 and the right pin numbers)
But something is not right: the sample code never reports a connection being made. Tracing this back, it looks like isConnected() here is always returning false, which means sendCommand() is either timing out or getting a DE2120_COMMAND_NACK.
I'm stumped. I've tried 2 different scanner units, replaced all the cables, tried swapping pin numbers around, and done a load of trials using HardwareSerial too with no success. The scanner unit itself responds to commands when I connect it to a laptop and talk to it over USB serial.
Any ideas? I am assuming there is something deeply trivial I'm getting wrong (e.g. in the physical connection or in the specifics of serial connections on ESP32). Generally I've found example code from Arduino libraries runs first time, but I am relatively new to Arduino.
Update 7/20: I have tried with pins 16 and 17, and also with RX2->TX and TX -> RX2. I have scanned the setup barcode as per the instructions.

For Serial Communication, you usually connect RX - TX, and TX - RX. 2) For ESP32, the naming convention is based on GPIO pin numbers, So Serial2 (HardwareSerial) is on 16 GPIO16-RX2), and 17 (GPIO17-TX2). 3) ESP32 has 3 hardware serial ports, there is no need for SoftwareSerial.

maybe the scanner module has to be programmed to use the serial port ... it may be programmed by scanning programming barcodes

Thank you both. I have tried the connection pattern you suggested, hcheung (though wouldn't reversing the pin numbers in the source code have the same effect? I tried that too), and have tried with 16 and 17 as the pin numbers. SoftwareSerial is what the example source code uses, in my own program I tried using HardwareSerial too.
jsotola: yes, I had already done that step - updated original question with details.

Answering my own question: this is about the scanner not getting enough power from the ESP32 devkit board, I think.
When I power both the barcode scanner and the ESP32 from separate power supplies (both USB) I can connect from the ESP32 to the scanner and read codes just fine.
However when I power the scanner from the ESP32, following the instructions in the hookup guide, the scanner is unresponsive.