text:
Can I flash hoodloader2 or HEX files on Arduino Simulators?
I want to make a HID Keyboard out of Arduino UNO, in UNO board the script runs perfectly fine, but the UNO board requires me to flash it every-time I want to put in a new script in it, so can I do the same on an Arduino Simulator? can I Flash Hoodloader2 on Arduino simulators by shorting the ICSP pins on UNO Board on a Simulator? if yes, please suggest the name of the application/ website.

which simulator?  ... why don't you just test it instead of asking?

Only Arduino boards with ATmega16u2 as USB adapter can use Hoodloader. So not even all Uno clones can use it.
I doubt the simulator is so precise that it would simulate the second MCU on Uno to allow flashing it over its ICSP heeader (ICSP2). I guess it doesn't even support flashing the main MCU over ICSP.
If the simulator supports Arduino Lenonardo, then you can maybe use the HID library. Leonardo has ATmega32u4 which has native USB support.


text:
Can I improve EEPROM lifetime by not changing bits?
In my current project I need to store the current elapsed time in hours to retrieve it in case of power loss. Since I am using a Arduino Nano I would ideally like to use the built in EEPROM without additional hardware.
The written values and their order will always be:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0 -> ....
If I write that on EEPROM per 0->0 full cycle the last bit will change 7 times and the other bits are pretty much idle. That's why I thought of distributing the changes more evenly by using instead the sequence
0 -> 1 -> 3 -> 7 -> 15 -> 31 -> 63 -> 0 -> ....
This would change every bit only once during a full 0->0 cycle. Does this improve EEPROM life expectancy or is the life expectancy linked to updating full bytes rather than individual bits?
edit: Since the question was closed for being off-topic, I altered the introduction a little bit. I am sorry if some of the comments are no longer fully valid. Since I don't fully understand why the question was closed (especially since there is EEPROM-tag), I would be grateful for a tip where on stackexchange the question would be best suited.

Good question! You may consider adding zeros instead of ones (255 → 254 → 252 → 248 → 240 → 224 → 192 → 255), as for an EEPROM, a pure “write” operation only turns ones into zeros. On AVR, you could also try to use the “write only” mode of the EEPROM (see the datasheet) instead of the “Erase and Write in one operation” mode, which is the one used by the Arduino EEPROM library.

Thank you for your comment. If I understand it correctly if i go from 00000001 to 00000011 what will actually happen is 00000001->11111111->00000011. So in order for my strategy to even have the hope to make sense I need to work with zeros instead of ones?

That's my understanding, but I am far from being an expert in EPPROM. I am eager to see the answers you get. ;-)

The more practical solution is to store data to EEPROM only when you really need it - when power goes out.

If this is a contrived question (i.e. home work) then you just have to look for clever answer like you and Edgar have found.  BTW a 1MB EEPROM, if you flip 1 bit of 8 every second for every byte, should last you over 90 days. If this is real life don't forget about the bigger (practical) picture. As gbg points out. I had a friend at ---- years ago working on a chip.  You write to RAM and before the power completely gave out the chip would dump the RAM into EEPROM. Problem solved (if that chip exists).

Thanks for the additional comments. The question is from a real project so all solutions are on the table. Personally I would prefer a solution without additional hardware. If it is really possible to break down the aging to the flipping of individual bits the chip should last for 50+ years, which is more than sufficient. However to me it is not fully clear as of yet if flipping of individual bits is really a thing altogether and especially with respect to aging.

Guessing, it is the number of changes that makes the difference. A real story, we accidentally wrote the time to EEPROM and only discovered it when boards started to fail in the field ... all at nearly the same time.  Naturally, we had to recall and repair the boards. So, if you really have a zero tolerance, I would suggest you add a way of checking if the EEPROM continues to work as expected.  Perhaps w/something more clever than majority vote where you repeat the above describe approach 3 times over cutting the EEPROM life by 1/3 but gaining a way to verify it is still working.

This is a trick we use for the EEPROM emulation of the chipKIT core for PIC32. However in that situation since it's emulating EEPROM with flash memory you have to manually perform a sector erase, so writing a byte over the top of an existing byte only if the difference between the two bytes is some bits being cleared (erased is 0xFF) work well.

Because EEPROMS are (always) written byte-wise, I pretty much doubt this will change anything in the life expectancy.

On your next design consider using FRAM, it is non volatile and supports almost unlimited (10 - 14th) read write cycles. The library I use or EEPROM supports the update function where it reads the memory first and does not write to it if it is to remain unchanged.

It is possible to write to ATmega EEPROM address without clearing its previous value. The write mode is set with the EEPMx bits in the EECR register.
The avr-libc eeprom.h write functions only use the erase and write mode and the Arduino EEPROM library only uses avr-libc eeprom.h write function.
I modified the EEPROM_write example function from the datasheet to write without erase.
#include <EEPROM.h>

void setup() {

  Serial.begin(115200);

  int address = 0;

  EEPROM.write(address, 0b11111111);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111110);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11111101);
  Serial.println(EEPROM.read(address), BIN);

  EEPROM_write_no_erase(address, 0b11101111);
  Serial.println(EEPROM.read(address), BIN);

}

void loop() {

}

void EEPROM_write_no_erase(unsigned int uiAddress, unsigned char ucData) {
  /* Wait for completion of previous write */
  while (EECR & (1 << EEPE))
    ;
  /* Set up address and Data Registers */
  EEAR = uiAddress;
  EEDR = ucData;
  /* Write only */
  EECR |= (1 << EEPM1);
  EECR &= ~(1 << EEPM0);
  /* Write logical one to EEMPE */
  EECR |= (1 << EEMPE);
  /* Start eeprom write by setting EEPE */
  EECR |= (1 << EEPE);
}

the output is as expected:
11111111
11111110
11111100
11101100

I don't know if use of this feature improves the lifetime of the ATmega EEPROM.

It would be safer to set EEMPE and EEPE with interrupts disabled, as recommended by the datasheet.

@EdgarBonet this code is from the datasheet. I guess it expects the function to be called with interrupts disabled if a conflict is possible

source: Stack Exchange

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

sort: votes


text:
I2S pins don't output audio in ESP8266
I am trying to use the ESP8266 to output some audio, but I'm having trouble making it work. I downloaded the library ESP8266Audio and am testing one of the examples they have in the repo, namely streaming MP3 from HTTP, (link). There is nothing however outputted from the I2S pins, D1 and D2, but only from RX pin. I have a dual amplifier, so I need the analog signals, not the digital. So I want to ask if there is something extra I need to add in the program, or if I'm using the wrong pins. Any help is appreciated :)

I2S is a digital protocol that controls a CODEC chip which you need in between your ESP8266 and the amplifier.

Shouldn't there be a built-in I2S module in the ESP8266? I'm using the Nodemcu model, according to the docs, there is one accessible through pins D1 and D2. I'm quite new to microcontrollers so pardon me.

I'm not familiar with the internals of the ESP8266. I know there is one in the ESP32, but it's awful because of noise from the WiFi. If there is one in the ESP8266 it will be as bad.

There might be a built-in I2S module, but an I2S module does not output an analog signal. The ESPs have no DAC, so you definitely need additional hardware in form of a I2C-DAC/codec IC. There's no software solution.

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


text:
Attach the Arduino ISR function to the class member
I intended to use a timer interrupt for limited instances of a class in my ESP32 Arduino project. My first code conception was as follows:
portEXIT_CRITICAL_ISR(&lock0);
  }

hw_timer_t * timer[3] = NULL;

class myClass
{
private:
  irqCallback timmerCB;
  volatile uint8_t pri_var1, pri_var2;
  static uint8_t class_instance_number=0;
public:
  volatile uint8_t pub_var1, pub_var2;
  myClass(/* args */);
  ~myClass();
};

myClass::myClass(/* args */)
{
  timmerCB=timerCBArray[class_instance_number];
  timer[class_instance_number] = timerBegin(0, 80, true);
  timerAttachInterrupt(timer[class_instance_number], &timmerCB, true);
  class_instance_number++;
}

However, I have this problem: how can I change the variable inside the interrupt regarding to each class instance?

I know this is a late answer but I think it is possible to get past the problem with this if you use std::bind
Below is a full example but if that is too long to read,  here is a minimal example.
class ISRClass {
public:
  ISRClass(int pin) : pin_(pin) {}

  void setup() {
    attachInterrupt(digitalPinToInterrupt(pin_),
                    std::bind(&ISRClass::sensePinIsr, this), CHANGE);
  }

private:
  int pin_;
  ulong change_count_;

  void IRAM_ATTR sensePinIsr() {
    // do something fast and simple
    change_count_++;
  }
};

The function returned by std::bind takes no arguments, not even this.
Full example follows.
Here is an example.  This class uses interrupts to simply set the state of a member variable when the pin has changed state.  It then only reads the pin when needed.  You still have to query the member variable in the loop, but that is about 10x faster than reading the pin.
#include "FunctionalInterrupt.h"
#include <Arduino.h>
#include <functional>
#include <optional>
#include <map>

using CallBack = std::function<void(int)>;

class PinMonitor {
public:
  PinMonitor(int pin) : pin_(pin) {}
  void setup() {
    pin_state_ = digitalRead(pin_);
    attachInterrupt(digitalPinToInterrupt(pin_),
                    std::bind(&PinMonitor::sensePinIsr, this), CHANGE);
  }

  std::optional<int> CheckForNewPinState(int debounce) {
    if (!change_count_) {
      return std::nullopt;
    }
    if (!is_debouncing_) {
      is_debouncing_ = true;
      debouce_started_at_ = millis();
      return std::nullopt;
    }
    auto time = millis();
    if (time < debouce_started_at_) {
      debouce_started_at_ = time; // handle timer rollover
    }
    if (time < debouce_started_at_ + debounce) {
      return std::nullopt;
    }
    is_debouncing_ = false;
    change_count_ = 0;
    auto new_pin_state = digitalRead(pin_);
    if (new_pin_state != pin_state_) {
      pin_state_ = new_pin_state;
      for ( auto [_, callback] : callbacks_) {
        callback(pin_state_);
      }
      return pin_state_;
    }
    return std::nullopt;
  }

  int DoIfPinStateChanges(const CallBack callback) {
    next_callback_key++;
    callbacks_[next_callback_key] = callback;
    return next_callback_key;
  }

  void RemoveCallback(int key) {
    callbacks_.erase(key);
  }

private:
  int pin_;
  int pin_state_;
  ulong change_count_;
  CallBack callback_ = [](auto a) {};
  std::map<int, CallBack> callbacks_;
  bool is_debouncing_{};
  ulong debouce_started_at_{};
  int next_callback_key{};

  void IRAM_ATTR sensePinIsr() { change_count_++; }
};

Then in main you could use this like below.
NetworkConnection networkConnection;
OTAHandler otaHandler;
Logger &logger = Logger::getInstance();

PinMonitor pinMonitor1(16);
PinMonitor pinMonitor2(17);

int call_count{};
int removable_callback{};

void setup() {
  networkConnection.connect();
  logger.startWebSocket();
  otaHandler.setup();
  pinMode(16, INPUT_PULLDOWN);
  pinMode(17, INPUT_PULLDOWN);
  auto chip_id = ESP.getEfuseMac();

  pinMonitor1.setup();
  pinMonitor1.DoIfPinStateChanges([chip_id](auto a) {
    logger.infoln("chip %12llx, reports pin1 new state of %d detected", chip_id, a);
  });
  removable_callback = pinMonitor1.DoIfPinStateChanges([chip_id](auto a) {
    logger.infoln("second call back was called on pin1, new state of %d detected", a);
    call_count++;
  });
  pinMonitor2.setup();
  pinMonitor2.DoIfPinStateChanges([chip_id](auto a) {
    logger.infoln("chip %12llx, reports pin2 new state of %d detected", chip_id, a);
  });

}

void loop() {
  otaHandler.loop();
  logger.checkWebSocket();

  std::optional<int> new_pin_state1;
  std::optional<int> new_pin_state2;

  new_pin_state1 = pinMonitor1.CheckForNewPinState(100);
  if (new_pin_state1) {logger.infoln("new pin1 state is %d", *new_pin_state1);}

  new_pin_state2 = pinMonitor2.CheckForNewPinState(100);
  if (new_pin_state2) {logger.infoln("new pin2 state is %d", *new_pin_state2);}

  if (call_count > 5) {pinMonitor1.RemoveCallback(removable_callback);}

}

Interrupt Service Routine (ISR) outside a class
Let's consider a simple use of interrupts:
volatile bool switchChanged;

void switchPressed ()
  {
  switchChanged = true;
  }  // end of switchPressed

void setup ()
  {
  pinMode (2, INPUT_PULLUP);
  attachInterrupt (0, switchPressed, CHANGE);
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

That compiles fine.

ISR inside a class as a class function (method)
Now let's imagine we want to put the interrupt handling into a class for our convenience.
class myClass
  {
  volatile bool switchChanged;

  public:

  void begin ()
    {
    pinMode (2, INPUT_PULLUP);
    attachInterrupt (0, switchPressed, CHANGE);   // <--- line 10
    }  // end of myClass::begin

  void switchPressed ()
    {
    switchChanged = true;
    }  // end of myClass::switchPressed

  };  // end of class myClass

myClass foo;  // make an instance of myClass

void setup ()
  {
  foo.begin ();
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

That does not compile:
ISR_in_class_test.ino: In member function ‘void myClass::begin()’:
ISR_in_class_test:10: error: argument of type ‘void (myClass::)()’ does not match ‘void (*)()’

What is going on here?
ISRs have to be static functions, taking no arguments. However (non-static) class functions have an implied this-> pointer which points to the particular instance of the class.
For example, if we have two instances:
myClass foo;
myClass bar;

If we call foo.begin() then this-> points to "foo", and if we call bar.begin then this-> points to "bar".
However an ISR, when fired by the processor, cannot know whether this-> is "foo" or "bar" or something else. Thus the compiler cannot compile that line.

ISR inside a class as a static class function
We can try to work around this by making the class function static. Doing that means that the function is not tied to any particular instance, and thus the attachInterrupt line will compile.
class myClass
  {
  volatile bool switchChanged;   // <--- line 3

  public:

  void begin ()
    {
    pinMode (2, INPUT_PULLUP);
    attachInterrupt (0, switchPressed, CHANGE);
    }  // end of myClass::begin

  static void switchPressed ()
    {
    switchChanged = true;   // <--- line 15
    }  // end of myClass::switchPressed

  };  // end of class myClass

myClass foo;  // make an instance of myClass

void setup ()
  {
  foo.begin ();
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

However now we have a different problem:
ISR_in_class_test.ino: In static member function ‘static void myClass::switchPressed()’:
ISR_in_class_test:3: error: invalid use of member ‘myClass::switchChanged’ in static member function
ISR_in_class_test:15: error: from this location

A non-static class variable cannot be called from a static class function. Why? Because the compiler doesn't know which variable you want. Is it foo.switchChanged or bar.switchChanged?

ISR inside a class as a static class function with static variables
To make the static function work, it can only access static variables. So we can make switchChanged static. Plus we need to define an instance of this static variable.
class myClass
  {
  static volatile bool switchChanged;  // declare

  public:

  void begin ()
    {
    pinMode (2, INPUT_PULLUP);
    attachInterrupt (0, switchPressed, CHANGE);
    }  // end of myClass::begin

  static void switchPressed ()
    {
    switchChanged = true;
    }  // end of myClass::switchPressed

  };  // end of class myClass

volatile bool myClass::switchChanged;  // define

myClass foo;  // make an instance of myClass

void setup ()
  {
  foo.begin ();
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

Now the class compiles. However we have thrown away most of the advantages of having a class in the first place, as we are forced to use a static function, and that static function can only access static variables.

Glue routines
To work around this problem we can write short "glue" routines. These are functions that interface between an ISR and an instance of a class.
class myClass
  {
  volatile bool switchChanged;

  static myClass * instances [2];

  static void switchPressedExt0 ()
    {
    if (myClass::instances [0] != NULL)
      myClass::instances [0]->switchPressed ();
    }  // end of myClass::switchPressedExt0

  static void switchPressedExt1 ()
    {
    if (myClass::instances [1] != NULL)
      myClass::instances [1]->switchPressed ();
    }  // end of myClass::switchPressedExt1

  public:

  void begin (const byte whichPin)
    {
    pinMode (whichPin, INPUT_PULLUP);
    switch (whichPin)
      {
      case 2:
        attachInterrupt (0, switchPressedExt0, CHANGE);
        instances [0] = this;
        break;

      case 3:
        attachInterrupt (1, switchPressedExt1, CHANGE);
        instances [1] = this;
        break;

      } // end of switch
    }  // end of myClass::begin

  void switchPressed ()
    {
    switchChanged = true;
    }

  };  // end of class myClass

myClass * myClass::instances [2] = { NULL, NULL };

// instances of our class
myClass foo;
myClass bar;

void setup ()
  {
  foo.begin (2);   // pin D2
  bar.begin (3);   // pin D3
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

This is a bit fiddly, however what it is doing is remembering in an array which instance of the class is associated with which interrupt. The "glue" routines switchPressedExt0 and switchPressedExt1 call the appropriate instance of the switchPressed function by using the remembered class pointer.
Now the non-static function switchPressed can access non-static class variables.

This answer was reproduced from my forum, but I can't post link-only answers here.

The Glue routines make myclass only work for specific scenarios. Can you use myclass as a base class and then use inheritance to create new class definitions for each scenario?

I tried it and realized inheritance does not work since we inherit the static variable. Creating two classes with identical code and different names works...but that's duplicated code which is also not a clean solution.

@PhilippWerminghausen You only have a fixed amount of hardware. It is hard to make a general class (which you might instantiate hundreds of times) but which have to share a single timer or interrupt. Compromises have to be made.


text:
Error in reading wind speed from esp32
I need your assistance with a problem I am facing. I built a weather station. esp32 board was used in this project. I used a hall sensor with a magnet in the wind speed measuring part (ANEMOMETER). Previously the method I used was when 20 counts of magnet counted by the hall sensor, it will count the time for 20 counts and output the average wind speed. Code worked fine with the esp32 board. But for better accuracy, I changed the method. Now the method is within 20 seconds how many counts of the magnet were detected will be output as an average wind speed. Since then the wind speed reading couldn't be seen on the serial monitor. ( I have the wind speed part of the code built for the Arduino Uno & it works fine with both methods). The Arduino sketch is below. The only change I did in 2 methods are
if (revolutions>=20) { was changed to if ((millis ()-timeold)==30000) {
    //Define all libraries in here....

#include<FirebaseESP32.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include "DHT.h"

#define FIREBASE_HOST "https://digital-weather-station-default-rtdb.firebaseio.com/"
#define FIREBASE_AUTH "jbqMg4BPxhCTTicMJAXXvV3LiuFW85PZVb8e8GZY"

const char *ssid = "SVITIN-70A0";
const char *password = "10237684";
String D;

#define DHTPIN 4
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define Offset 0;

// Connect pin 1 (on the left) of the sensor to GROUND
// Connect pin 2 of the sensor to +3.3V
// Connect pin 3 (on the right) of the sensor to whatever your DHTPIN is

DHT dht(DHTPIN, DHTTYPE);

FirebaseData firebaseData;

//Variables For Humidity & Temperature
float h=0;  //Define Humidity value Default Value = 0
float t=0;  //Define Temp value in celcius Default Value = 0

//Variables For Wind Speed
volatile byte revolutions;
float rpmilli;
float Speed;
unsigned long timeold=0;

//Variables For Wind Direction
int VaneValue;// raw analog value from wind vane
int Direction;// translated 0 - 360 direction
int CalDirection;// converted value with offset applied
int LastValue;

//Defined new void funtion for get temp and hum...
void Temp(){
   // Wait a two seconds between measurements.
  delay(2000); // Reading temperature or humidity takes about 250 milliseconds!
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));

  if (Firebase.pushFloat(firebaseData, "/Weather Results/Temperature",t))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }

  if (Firebase.pushFloat(firebaseData, "/Weather Results/Humidity",h))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
 }
 else
 {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }
  }

void WSpeed(){
    // if (revolutions>=20) {
   if ((millis ()-timeold)==30000) {
    //Update RPM every 30 seconds, increase this for better RPM resolution,
    //decrease for faster update

    // calculate the revolutions per milli(second)
    rpmilli = ((float)revolutions)/(millis()-timeold);

    timeold = millis();
    revolutions = 0;

    // WHEELCIRC = 2 * PI * radius (in meters)
    // speed = rpmilli * WHEELCIRC * "milliseconds per hour" / "meters per kilometer"

    // simplify the equation to reduce the number of floating point operations
    // speed = rpmilli * WHEELCIRC * 3600000 / 1000
    // speed = rpmilli * WHEELCIRC * 3600

    Speed = rpmilli * 0.7665 * 3600;

    Serial.print("RPM:");
    Serial.print(rpmilli * 60000);
    Serial.print(" Speed:");
    Serial.print(Speed);
    Serial.println(" kmph");

  if (Firebase.pushFloat(firebaseData, "/Weather Results/Speed",Speed))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }
  }
}

  void rpm_fun()
{
  revolutions++;
}

void WDirection(){
VaneValue = analogRead(34);
Direction = map(VaneValue, 0, 4095, 0, 360);
CalDirection = Direction + Offset;

// Only update serial monitor if change greater than 5 degrees.
if(abs(CalDirection - LastValue) > 1){
Serial.print(VaneValue); Serial.print("\t\t");
Serial.print(CalDirection); Serial.print("\t\t");
getHeading(CalDirection);
LastValue = CalDirection;
}
  }

// Converts compass direction to heading
void getHeading(int Direction) {
if(Direction < 35){
Serial.println("N");
 D="N";
}

else if (Direction < 100){
 Serial.println("NE");
 D = "NE" ;
}

else if (Direction < 170){
  Serial.println("E");
  D = "E" ;
  }

else if (Direction < 200 ){
  Serial.println("SE");
  D = "SE" ;
  }

else if (Direction < 210){
  Serial.println("S");
  D = "S" ;
  }

else if (Direction < 245){
  Serial.println("SW");
  D = "SW" ;
  }

else if (Direction < 259){
  Serial.println("W");
  D = "W" ;
  }

else if (Direction < 268){
  Serial.println("NW");
  D = "NW" ;
  }

else
Serial.println();

if (Firebase.pushString(firebaseData, "/Weather Results/Wind Direction",D))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println(F("DHTxx test!"));
  dht.begin();                                                               //DHT and TEMP sensor starting.....
  attachInterrupt(digitalPinToInterrupt(27), rpm_fun, RISING);                // Attaching Interrupt funtion for wind speed....
  revolutions = 0;
  rpmilli = 0;
  timeold = 0;
  LastValue = 1;
  Serial.println("Vane Value\tDirection\tHeading");

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

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

  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.reconnectWiFi(true);
}

void loop() {
  Temp();
  delay(2000);
  WSpeed();
 delay(2000);
  WDirection();
 delay(2000);
  }

the problem is probably the == ... think about it


text:
Does anyone have code that successfully calculates velocity from an accelerometer
I'm trying to calculate the speed of a rocket for my project. I've been given the task of calculating this with an adxl3xxx accelerometer sensor. I'm not sure how to go about this as an accelerometer takes gravity acceleration into account. Can someone provide some form of code to help me understand. I've heard some theory like caliculatong yaw, pitch and roll then using trig to factor out gravity. Not sure how that works. I've also heard about quartenions not sure what they are. If someone could help me out that would be great thx

https://arduino.stackexchange.com/search?q=velocity+accelerometer

Calculating velocity from acceleration is not easy.  Simply put, velocity is derived by calculating the integral of acceleration with respect to time.  In practice, however, this leads to accumulated errors which generally render the process impractical for any but the shortest amount of time.
For further reading, this Wikipedia Kinematics page does a good job at relating acceleration, velocity and position using math.

… calculating yaw, pitch and roll then using trig to factor out
gravity …

Essentially, this is the first of two steps in coding up a tilt compass (the type you find in your cell phone).  You need the yaw, pitch and roll information before you can make sense of the magnetometer data.  Consider reading the first half of a tilt compass description to understand how to calculate yaw, pitch and roll.  Like this one.

I've also heard about quartenions not sure what they are.

Quaternion are an alternative to using trigonometry to derive (in this case) yaw, pitch and roll.  There are two advantages (in this case).  First, Quaternions are easier for a computer to calculate. Second, Quaternion yaw, pitch and roll calculations do not go to infinity for certain situations.  In the real world using physical gyroscopes this is commonly known as Gimbal lock.
Added later...

How would i go about using trig?

Trigonometry is not necessary if it is physically arranged such that all acceleration to gain the velocity of interest occurs only in 1 of the X, Y or Z directions of the accelerometer.  Then all that is need is to integrate the accelerometer readings in that direction with respect to time.
If this happens to be in the same direction as earth's gravity, simply subtract 9.8m/s2 out.
If you can't physically arrange it, then you need to read all 3 (X, Y & Z) accelerometer values. From this data pitch and roll can be calculated.  The trigonometry equations for this is on page 21 of the  "tilt compass description" link above.

That said we notice on that same page an equation to calculate the magnitude of acceleration.

So it may be possible that we can calculate the velocity due to the magnitude of the overall acceleration by sampling the accelerometer X,Y & Z sensors over time.  And avoid trigonometry entirely.
However there is a problem.  We have not accounted for gravity.  Again, if we assume gravity is in the same direction as travel we can subtract it it out.  But if travel is, say, 45 degrees off from the gravity vector, we would only want to subtract cos(45) * 9.8m/s2.  Consider only knowing the overall acceleration magnitude does not supply enough information to determine the angle between the acceleration due to gravity and acceleration due to a change of velocity from zero to an unknown velocity with respect to earth.
At this point decisions need to be made regarding how to account for gravity.  9.8m/s2 may be trivial when compared to the vehicle's acceleration and therefor can be ignored.  Or it may be so critical that extreme measures like tracking where the sun is in the sky become a feasible way to find the actual pitch and roll of the vehicle.

OMGoodness, did I really say "gumball lock"?

How would i go about using trig?

I can not answer that in the space of a comment.  So I will add it to the end of the above answer.

Also, this video may help.  But pay attention to what he says at this point in that video.


text:
Undefined reference to function in custom library
Hello I am making a private Arduino library but am having trouble understanding how it is linked. Why does this h file work, but when I move the definition of board_led to a matching c file, it throws an error at compilation: In function loop: undefined reference to board_led(bool).
I am using the following board manager to compile in the Arduino IDE:
https://raw.githubusercontent.com/maximintegratedmicros/arduino-collateral/master/package_maxim_index.json
I am using the following board target: MAXIM ARM 32bit boards > MAX32630FTHR
#pragma once

#include "Arduino.h"
#include <stdbool.h>
#include <gpio.h>

extern const gpio_cfg_t s_board_led;

extern void board_led(bool on) {
     GPIO_OutPut( &s_board_led, on ? 0 : ~0 );
}

I suspect you're compiling from C++ code, and including that header.
When C++ links to C code, the C++ code needs to see extern "C" on the declaration, or surrounding the declaration (via extern "C" { /* function declarations */ })
If you are compiling C++ code against the C code (and linking them together), try making sure extern "C" is used, for example like this:
// arduino_lib.h
#pragma once

#include "Arduino.h"
#include <stdbool.h>
#include <gpio.h>

extern const gpio_cfg_t s_board_led;

extern "C" void board_led(bool on);

While nothing changes in the .c file
// arduino_lib.c
#include "arduino_lib.h"

const gpio_cfg_t s_board_led = /* some value */;

void board_leb(bool on) {
     GPIO_OutPut( &s_board_led, on ? 0 : ~0 );
}

To complement Bob's answer it is good practice to add header guards for detecting C++ specifically:
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

// your function definitions here

#ifdef __cplusplus
}
#endif // __cplusplus

That way the extern "C" is only applied if the header file is included into a c++ file but not if it's included into a c file.


text:
Ways to detect if a ball has reached the wall?
I'm building a kind of pin ball machine, and I need to detect when the ball has hit the wall with the sensor attached.
The ball will hit the wall with a small impact, not large enough to push a button probably. What sensor would be the best to use in this case?
I thought about ultrasonic but I'm not a fan of the constant chirping. Can a light sensor be used here? Eg if there's 10% light left, we assume the ball has reached the wall.

You could use a light barrier (using a small laser diode), which is aligned along the wall. The ball will get into the light ray and will disrupt the light barriers signal. Or you could attach a vibration/sound sensor to the wall to detect the impact.

If you want to write an answer, please write only one solution in one answer. If you have more ways to solve this, please write multiple answers so we can vote for the solutions separately.

The ball will hit the wall with a small impact...

Consider using the well proven pinball bumper design omitting the hammer feature:

In many pinball machines a "rubber ring" is stretched in front of one or more "leaf switches".  When the ball hits the "rubber ring" one or more of the "leaf switches" closes (or opens depending on if the "leaf switch" is N.O. or N.C.).  There are many example for connecting switches to an Arduino.


text:
Guru meditation error load prohibited, esp32s. While using Fastled
I am encountering a Guru meditation error, Load prohibited on my current sketch for the esp32s.
Here is the code:
#include <FastLED.h>

#define NUM_LEDS 120
#define LED_PIN 3
CRGB leds[NUM_LEDS];

int H1[12][10] = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
  {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
  {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
  {30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
  {40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
  {50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
  {60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
  {70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
  {90, 91, 92, 93, 94, 95, 96, 97, 98, 99},
  {100, 101, 102, 103, 104, 105, 106, 107, 108, 109},
  {110, 111, 112, 113, 114, 115, 116, 117, 118, 119}

};

int connections[7][6] = { // dont forget to change 7 to the number of hubs
  {2,3,4,5,6,7},
  {1,7,3,0,0,0},
  {1,2,4,0,0,0},
  {1,3,5,0,0,0},
  {1,4,6,0,0,0},
  {1,5,7,0,0,0},
  {1,2,6,0,0,0}
};

int const life = 3;
int numHubs = 7;

void setup() {
}

void loop() {
  path_taker(path_picker(numHubs, connections), H1);
  delay(500);
}

int* path_picker(int numHubs,int connections[7][6]){ // dont forget to change 7 to the number of hubs!
  int hub = random(1,numHubs)-1;
  int i = 1;
  int path[life];
  int a = 0;
  path[0] = hub;

  while (i <= life){
    a = connections[hub][random(0,6)];
    if (a != 0){
      path[i] = a;
      hub = a;

      i = i+1;
    }

  }
  return path;
}

void path_taker(int path[life], int H1[12][10]){
    int ini = 0;
    int fin = 0;
    int rod[10];
    for (int i = 0; i < sizeof(path) - 1; i++){
      ini = path[i];
      fin = path[i+1];
      switch (ini){
        case 1:
        switch (fin){
          case 2:
          lightup(arrayBuilder(0, H1, false));
          break;

          case 3:
          lightup(arrayBuilder(4, H1, false));
          break;

          case 4:
          lightup(arrayBuilder(3, H1, true));
          break;

          case 5:
          lightup(arrayBuilder(5, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(8, H1, true));
          break;

          case 7:
          lightup(arrayBuilder(9, H1, false));
          break;
        }
        break;

        case 2:
        switch (fin){
          case 1:
          lightup(arrayBuilder(0, H1, true));
          break;

          case 3:
          lightup(arrayBuilder(1, H1, false));
          break;

          case 7:
          lightup(arrayBuilder(11, H1, true));
          break;
        }
        break;

        case 3:
        switch (fin){
          case 1:
          lightup(arrayBuilder(4, H1, true));
          break;

          case 2:
          lightup(arrayBuilder(1, H1, true));
          break;

          case 4:
          lightup(arrayBuilder(2, H1, false));
          break;
        }
        break;

        case 4:
        switch (fin){
          case 1:
          lightup(arrayBuilder(3, H1, false));
          break;

          case 3:
          lightup(arrayBuilder(2, H1, true));
          break;

          case 5:
          lightup(arrayBuilder(6, H1, true));
          break;
        }
        break;

        case 5:
        switch (fin){
          case 1:
          lightup(arrayBuilder(5, H1, true));
          break;

          case 4:
          lightup(arrayBuilder(6, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(7, H1, false));
          break;
        }
        break;

        case 6:
        switch (fin){
          case 1:
          lightup(arrayBuilder(8, H1, false));
          break;

          case 5:
          lightup(arrayBuilder(7, H1, true));
          break;

          case 7:
          lightup(arrayBuilder(10, H1, true));
          break;
        }
        break;

        case 7:
        switch (fin){
          case 1:
          lightup(arrayBuilder(9, H1, true));
          break;

          case 2:
          lightup(arrayBuilder(11, H1, false));
          break;

          case 6:
          lightup(arrayBuilder(10, H1, false));
          break;
        }
        break;
      }
    }
  }

int* arrayBuilder(int row, int hexigon[12][10], bool reverse){
  int rod[10];
  if (reverse){
    for (int i=9; i>=0;i--){
      rod[i] = hexigon[row][i];
    }
  }else{
    for (int i=0; i<10;i++){
      rod[i] = hexigon[row][i];
    }
  }
  return rod;
}

void lightup(int rod[10]){
  int i = 0;
  while (i<10){
    EVERY_N_MILLISECONDS(50){
      leds[rod[i]] = leds[i] = CHSV(255, 255, 255);
      fadeToBlackBy( leds, NUM_LEDS, 10);
    }
  }

  FastLED.show();
}

Here is the decoded exception from Exception Decoder:
 EXCVADDR: 0x00000000 Decoding stack results 0x400d0cc7:
path_taker(int*, int (*) [10]) at C:\Users\****\Documents\Arduino\Wall_Art_MKI/Wall_Art_MKI.ino line 75

0x400d0d3e: loop() at C:\Users\****\Documents\Arduino\Wall_Art_MKI/Wall_Art_MKI.ino line 44

0x400d1315: loopTask(void*) at C:\Users\*****\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.6\cores\esp32\main.cpp line 23

0x40085d81: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

I posted this on Reddit, and a user suggested that the error was occuring on line 201. The issue being that I am attempting to return a pointer to a local variable within the function, arrayBuilder.
I have been doing research on the topic, but I still can't figure out how to resolve the error.
I would greatly appreciate any advice!

Instead of trying to return a pointer to a local variable (which is always doomed to fail, since you end up with a pointer to rubbish) you should create your array outside the function and pass a pointer to it as a parameter, then fill that array through the pointer:
void arrayBuilder(int row, int hexigon[12][10], bool reverse, int *rod){
  if (reverse){
    for (int i=9; i>=0;i--){
      rod[i] = hexigon[row][i];
    }
  }else{
    for (int i=0; i<10;i++){
      rod[i] = hexigon[row][i];
    }
  }
}

Then...
int rod[10];
arrayBuilder(rownum, myhex, false, rod);


text:
Problems in running two solenoid together at the same time
I am trying to activate two solenoids (12V/350mA, connected to a 12V/1A adaptor) at the same time using the TIP120 NPN-transistor and 1kohm resistor using the UNO board. Using a simple program,
void loop()
{
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(5000);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(2000);
}

if I am using a big LED on the pin of the board, I am able to easily blink them but the solenoid is not working?
for powering the Arduino board, I am either using USB or a 12V/1A adaptor, and both result in the same output.
the schematic of the simple connections can be found here   https://www.arrow.com/en/research-and-events/articles/arduino-solenoid-project-control-solenoid-with-arduino-board
can someone please suggest what can I do to start two solenoids at the same time?
I have tried increasing the voltage and current as well from an externally powered source as well. but it did not actuated two valves together

Could you please add a schematic to your question?

previous question about the same project https://arduino.stackexchange.com/questions/89073/controlling-multiple-solenoid-with-relay-and-arduino-and-the-process-stops-after

@Juraj yes, but the question is different. and the circuit is also different, instead of relay, I am using transistor which solved previous problem

@EdgarBonet the circuit is so simple that I don't add it here instead I have given the link. only transistor and resistor

The TIP120 is a poor choice for this application. It's a "Darlington" transistor which means it will turn your 12V into just 10.4V. You'd be better with a simple BJT or even better still a MOSFET.

@Majenko thanks for your answer, but if TIP120 is a problem then probably even 1 valve should not be working.  On the contrary, valves are working perfectly fine when used one at a time. The only problem is they are not working together. Do you really think BJT/MOSFET will solve the problem?

@RajagopalanP I didn't say it was the problem, only that it was a poor choice.

The transistor is a current device and it has a gain. There are several ways that transistor could be hooked up most of them wrong for your application. You do not post a schematic, is it possibly you do not know how to create one. Pictures do not give resistor vales and circuit configuration. There should be no trade secrets on your circuit that  I know about.

@Gil, thanks for your response. I have updated the circuit diagram in the question section. please let me know your thoughts.

@Majenko, Yes yes I get your point. I even used an external source where I increased the voltage up to 24V/1A and 15V/1.5 A but the valve did not actuate. so it seems Voltage drop might not the be the bigger problem, can you suggest something to solve this problem

It will not work as you have it pictured. The ground of the 12V must be connected to the ground of the Arduino. You can put both resistors on the same pin of the Arduino, the one that is working (probably pin 13). Staying with what you have coded would be better. Since each of the solenoids require 1A each your power supply must supply at least 2 amps.
In your code setup() you need to define each pin you will use as an output, (int ledPin = 4; int ledPin = 5;) There are other ways but that follows the example.   then use the pinmode to declare them as an output, pinMode(led1, OUTPUT);  for each pin you want to drive the transistor. Then your code will work. Look at this link for an example: https://www.arduino.cc/en/Reference.digitalWrite.
I used pins 4 and 5, no reason other then 13 blinks with the on board led when it is booting. It is pre defined as an output in the Arduino start code (you normally do not have access to that), that is why it worked.
If you elect to use a MOSFET TheSource becomes the emitter, The Drain becomes the collector and the gate becomes the gate. You would need to pick an avalanche rated one that can


text:
ESP32 WROOM32E w/ Arduino IDE 2axis joystick - how do I get a good reading?
How do I get the full range of motion from an analog joystick and the ESP32 WROOM32E using the arduino IDE with esp-idf installed?
Using a 2 axis analog joystick, the 5v/3.3v pin, ground pin and the following code I do not get the correct results printed out. I do get the correct range of values to print but when the Jstick is at 50% or greater it's distance away from center it will print out 50 or -50 when it should be closer to 25. I cannot use the full range of motion, I tried it with the 5v pin and did not have better results, I tried a second identical board, I swapped out my playstation style analog jsticks. Why does it do this? Is this a code probelem?
int       test  = 0;
const int pinVar  = 33;

int  read_jstick(int rxy)
{ int JXY = analogRead(rxy);  //int JXYr = map(JXY,0,4095,-50,51);
  return JXY;
}
void  print_jstick(int pjs)
{ Serial.print("Joystick-X:  "); Serial.println(pjs);
}
void setup()
{ Serial.begin(115200); pinMode(pinVar,OUTPUT);
}
void loop()
{ test = read_jstick(pinVar);
  print_jstick(test);
}

Adding:
looking at the profile the joystick motion is like this: L   _\ | / _   R
When the joystick is like this: | print val is: ~2500 at 5v and ~1800 at 3v
When the joystick is like this: _ on the L side the print val is 0
When the joystick is like this: _ on the R side the print val is 4095
Cool, but...
When the joystick is like this: \ at about 50% the range of motion, the value reads 0. It should be closer to 1200.
When the joystick is like this: between \ and | (0 and 50% range of motion) the print values will vary within the range of 0 and the middle value
I would like to be able to read the full range of motion on the joystick and receive a values incrementally over the entirety of that distance, how do I accomplish this? Example: I would like to move in let's say 10 incremental 'steps' with the joystick physically and the printout should be 1 through 10 and that would cover the movement from stationary to full extent of motion.
I have multiple of the same dev board, multiple of the same joystick, I have swapped cables and wires and I don't see how this could be a hardware problem so let's focus on coding unless it's perfect and should work exactly how I want it to because then that means for sure it's hardware and I just wasted a bunch of money buy multiple of everything and it's all broken. Sorry that I am frustrated here.
Update: I believe that a standard analog joystick module cannot be used with the ESP32 properly because the ESP32 cannot read the resistance of the joystick beyond 1.1v which means that it stops reading values in the middle of its range. You cannot get a scaling range of return from the joystick so it's basically a bad analog version of a digital left right up down inputter.
Prove me wrong please. If there is a way to read an analog pin higher than 1.1v or some other way so I could use the joystick for it's full range of motion on an ESP32 please let me know. All I can do is get a scaling range from stationary to a short move in 1 direction and when the stick is pushed passed 50% that direction it's all maxed out read value wise when it should be related to the position along length of travel.

start debugging by printing the value of axisVar

it makes a difference if you define variables as signed or unsigned

thanks, I have it print the value now and that's how I can tell that half way through the joysticks motion it hits the max 50/-50. I will try them as signed/unsigned variables.

I am saying to write the simplest code ... the map function is not simplest code ... print what is actually being read from the joystick without modifying the value

Did that, it sits at around  a val of 1800 with range between 0 and 4095 when I move the joystick. The problem here is that the values of 0 and 4095 are in the middle of the sticks motion from stationary to one extent, eg at half of it's range of motion it maxes at the high or low value. I can only use half of the joysticks range of motion on each axis.

it is probably caused by using a signed integer ... I don't have an ESP32 right now to test your code ... btw  you did not write the simplest code ... don't be calling functions for reading a joystick and for printing the value ... it could be the functions that are messing up the values

That sounds to me like your joystick is the problem. If you have a multimeter you can verify it directly by measuring the voltage at the slider pin. If it doesn't change in the last half of the full side motion, then the joystick itself only supports a smaller range of motion.

@chrisl - The Joystick works with my arduino correctly, I can receive readings along the full motion of the joystick and I have tried multiple joysticks and the full range of motion is not available on the ESP32 for some reason, I also don't know how to do what you said with the multimeter. Powered by either 5v or 3v the print has the same issue, it stops half way through the sticks motion at the max or min value instead of being half way through the range of values. I also tried this on multiple dev boards, the same type of board. Is this and ADC software issue that can be coded to solve?

@jsotola - I don't understand your simple code thing because I will need functions down the line to handle the joystick values and I don't understand how what I wrote wasn't simple. So then Signed v unsigned seems to have no effect whatsoever that I noticed. If you don't know how to use the ESP32 then you might not be helping and could be leading me down the wrong rabbit hole. If this is a print issue then no one could use a joystick and pass its values, I think it's something internal to with the ADC that needs to be modified but I don't know what or how. Thanks for your time.

yes, you will need functions, but how do you know if the function call somehow changes the reading? ... at this point, you do not know what value is actually returned by the analogRead(rxy) function ... that is why I suggested that you simply get the value and print it inside loop()

@jsotola
"const int pinVar  = 33;
void setup(){ Serial.begin(115200); pinMode(pinVar,INPUT); }
void loop(){ int J = analogRead(pinVar);  Serial.println(J); }"
That gave me the same results... when the joystick is at 50% it's range (~25% the total range from max - to max + along the same axis) it prints out the max value and will do that for any position above it. I don't think you understand the problem. There is some ADC (analog to digital conversion) coding that neither of us know how to do.

you may be right that I do not understand the problem ... try an unsigned integer unsigned int J = analogRead(pinVar);

@jsotola I have already said that I tried that and that it did not change anything, I did the whole gamut of combos signed v unsigned and it was a waste of time. I'm almost 100% certain that the ESP32 cannot use a standard analog  joystick correctly because it can only read up to 1.1v so no once you pass that 1.1v range on the stick it maxes out and that is at a point less than 50% the distance of travel in 1 direction on the axis.

Same issue here. Did you get any answer?


text:
Different meanings of pid and vid in boards.txt
Let's see the leonardo section in boards.txt:
leonardo.name=Arduino Leonardo
leonardo.vid.0=0x2341
leonardo.pid.0=0x0036
leonardo.vid.1=0x2341
leonardo.pid.1=0x8036
leonardo.vid.2=0x2A03
leonardo.pid.2=0x0036
leonardo.vid.3=0x2A03
leonardo.pid.3=0x8036

leonardo.upload.tool=avrdude
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.maximum_data_size=2560
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
leonardo.upload.use_1200bps_touch=true
leonardo.upload.wait_for_upload_port=true

leonardo.bootloader.tool=avrdude
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F

leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341
leonardo.build.pid=0x8036
leonardo.build.usb_product="Arduino Leonardo"
leonardo.build.board=AVR_LEONARDO
leonardo.build.core=arduino
leonardo.build.variant=leonardo
leonardo.build.extra_flags={build.usb_flags}

What are the meanings of the leonardo.vid|pid.* and of the leonardo.build.vid|pid?
Perhaps the first are for the USB serial device at runtime and the second for the bootloader?

The build ones are used when compiling the Arduino core. The others are used to identify the board when it resets into the bootloader so it can find the right com port to upload to

Ok, but the problem is the run-time pid/vid are 2341:8036. If the first set is used to identify the bootloader should not contain these values, otherwise it's impossible to detect it!

@Mark The runtime ones can be whatever you like. The IDE opens the (manually) selected COM port at 1200 baud which resets the board into the bootloader. Then it waits for a new device to appear that matches one of the bootloader VID/PID pairs (any one will do) at which point it records the COM Port and passes that to avrdude to upload the program.

It's exactly what I'm doing right now. But because even the default run-time VID/PID pairs for Leonardo are in that set, I cannot be sure if it's the bootloader or not! Example: if the reset does not work, I assume there is a bootloader while it's still the application serial channel.

@Mark If the reboot didn't work then there won't be a new device.


text:
Do passive buzzers require a PWM pin?
This guide   Shows how to wire a passive buzzer to be used with tone(). I notice they have it wired to D9, which is a PWM pin. But is it required to use a PWM capable digital output pin to play tones from a passive buzzer?

No, it doesn't need to be a PWM pin. tone() uses a timer and an interrupt to generate the audio signal and can work with any IO pin.


text:
Milliseconds using square wave RTC
i am trying to make a code that prints the time hh:mm:ss:ms using RTC,i have made it using millis() but it  is not accurate +/-2 milliseconds
ho can i make it using sq wave and intterupt
here is the code that i have used
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;      // This is the DS1307 hardware RTC
RTC_Millis SoftRTC;   // This is the millis()-based software RTC
long startMS;  // This will hold the start time in milliseconds

void setup ()
{
    Wire.begin();
    RTC.begin();                       // Connect to the DS1307
    SoftRTC.begin(RTC.now());  // Initialize SoftRTC to the current time
    startMS = millis();  // get the current millisecond count
}

void loop()
{
    DateTime now = SoftRTC.now();
    long nowMS = millis();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.print(':');
    Serial.print((nowMS - startMS)%1000, DEC);  // print milliseconds
    Serial.println();

i tried to put this code that is based on ISR but with no luck
volatile time_t isrUTC;         // ISR's copy of current time in UTC
volatile time_t millisecondsFromISR;         // ISR's copy of current time millisecond offset

void incrementTime()
{
    millisecondsFromISR = millis();  //do first to get most accuracy
    ++isrUTC;
}

int getMilliseconds() {
    // need to make an atomic copy:
    nointerrupts();
    unsigned long t = millisecondsFromISR;
    interrupts();

    return millis() - t;
}

what is not accurate +/-2 milliseconds? ... the prints the time hh:mm:ss:ms takes time to execute

so if i make it with external clock will it make a diff?

You cannot get better than ±2 ms with millis(). If you need more accuracy, use micros().

same code
or what do u suggest?

All you have to do is record the number of milliseconds at the moment the square wave toggles on its 1 second cycle. Then your milliseconds is the difference between that and the current.
In short: update startMS when triggered by the RTC's output.

do u have a helping code?

@AmrAhmed no, but you already have code to set startms in your program, and there are plenty of interrupt examples on the web.

yes i have checked these codes for interrupt with no luck  to make a running code

@AmrAhmed Then maybe you should try again, and then show us what you tried, and we may be able to help you with it.

volatile time_t isrUTC;         // ISR's copy of current time in UTC
volatile time_t millisecondsFromISR;         // ISR's copy of current time millisecond offset
...
void incrementTime()
{
millisecondsFromISR = millis();  //do first to get most accuracy
++isrUTC;
}
...
int getMilliseconds() {
// need to make an atomic copy:
nointerrupts();
unsigned long t = millisecondsFromISR;
interrupts();
return millis() - t;

}
this one of the codes that i tried to work on with no luck

@AmrAhmed Comments are not for code.

i have added the code in my question

And what didn't work with it? How is that code snippet integrated with the rest of your code?

i could not make it working

Without seeing how that snippet is integrated with the rest of your code, or how the RTC module is wired up, we cannot help/.

unfortunately this what i got when i tried to integrate both


text:
How do I solve the sensor’s abysmal abnormal output?
Problem description
When XIAO microcontroller is connected to the sensor signal output pin, keep printing unexpected values.
Sketch

I haven't sensor circuit diagram, you can machine translate and read the pagehttps://www.yuque.com/cs/products/rwe87o
Detailed description:
The sensor has been outputting a raw value of about 4000. That is to say, the transformation of the function outputs is around  1600000~400000. Not the 0 to 30 values I expected to output.(I tried to use other development board ESP32 to read the sensor value using ADC and its own power supply pin, and still output the original value of 4000(output 1600000~400000), as shown in the figure below.)
Abnormal output

Normal output:

This is the output I expect, but I can't reproduce the normal output (last month was very occasionally normal output, I don't know why it can't normal output now and the environment has not changed...Analog circuits are too much like witchcraft...)
I try to do:

Measured with a digital multimeter to ESP32 and XIAO, the power supply pin(to measure voltage between 3.3V and GND pin) is about 3.1V~3.3V(maybe my positive and negative probes are not accurate).

Check XIAO's ADC using ADC pin to GND pin for any problems with Analog pins read GND and VCC respectively, with 12bit resolution and output of 100 and 4000 + respectively.XIAO is fine.

The Sensor connects the TTL to USB power supply pin, but the output is still abnormal.(I used PWM pin by esp32 or xiao MCU to output analog 3.3V, results  same to abnormal output)

If the sensor signal output is connected to MCU, the high value of 4000 is output(The original value).  Seems to be the power problem, someone tell me how to minimize the power ripple effect and make the 3.3V stable output provided by the battery?
But when I unplug the sensor, the MCU outputs random values, and I don't want the sensor output to be affected by other factors.

DMM Checks the sensor output and GND pin separately, using only the DMM, sensor, 3.3V battery module, and breadboard：
(This is one 3P Dupont line and the colors are random.I didn't have a wiring error. If the wiring is wrong neither the MCU nor the sensor will work properly, let alone output signals)

The quality of my DMM is poor, I will measure it when my FLUKE17B+ arrives.

Use MCU to read the value, sure enough, the output value is not affected by the power on or off, because the output value is more than 100000(raw value is 4000,12 bit).
other
Asked the store, customer service said this is not normal, the sensor should output the value of 0~500, if the sensor monitors the current output of 200~400, not monitoring the general output of 0~30 range.
Equipment information
XIAO EMG sampled code: EMG.ino · GitHub
Sensor parameters: {ED0056}Sensor
Microcontrollers XIAO general description: Getting Started with Seeeduino XIAO - Seeed Wiki
Microcontrollers XIAO instruction manual: https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/ATSAMD21G18A-MU-Datasheet.pdf

How do I solve XIAO’s the sensor’s abnormal output?

Please add a schematic to your question. It's not at all clear how all the components are interconnected. Have you connected all of the grounds properly?

In your wiring diagram (fritzing) Vcc and ground of the sensor on the right are connected to the upper power rail. Though there is no other connection to that rail. Where does the power and groumd connection come from for the sensor?

Ten days ago, I connected the power supply pin of the USB to TTL module, and it could output normal signals. However, the 3.3V usB-to-TTL pin is only one.

My six sensors need six 3.3V pins, the battery module supplies power to the sensor, but the oscilloscope outputs the original value of the sensor above 4000.

on Leonardo you power it from 3.3 V pin? The analog pins of Leonardo read values from 0 to 5 V and the xiao analog input reads from 0 to 3.3 V

@Juraj The sensor manual indicates that the output analog range is 0 to 3.0V, which is within xiao's range of reception.

could it be that xiao registers only support msb side alignment while arduino defaults to lsb alignment?  could try to check arduino (or any other working setup's readings) vs xiao under same conditions to get to the bottom of it.  or better yet analogRead a pot.

@Abel I used analogread function readings provided by Arduino hardware library without experience in low-level debugging. If the resolution is set to 16bit, the output will be 1000-60000. I tested the analog pins on another development board(ESP32) with the same results. I am now contacting the sensor manufacturer to try to solve this problem. The manufacturer claims that the technicians use the power supply pins provided by the development board,  there is no such problem as mine.

First thing I notice in your photo is that you have your 3.3V and GND wires around the wrong way on the Xiao microcontroller board. This will indeed give you wrong results.
Please see the image below for the pinout.

Your Fritzing circuit diagram has the correct wiring for 3.3V and GND.
Please do a couple of tests to verify your setup once the wiring has been corrected. First, remove the sensor and use a potentiometer to provide an analog input into A0. Verify that the potentiometer gives you the correct response that you expect and cross check it with an oscilloscope or digital multi-meter (DMM).
Secondly, power up only the sensor and test the output of the sensor with an oscilloscope or DMM. This should how up as the clean analog signal that you expect.
If these two tests pass, then when you connect up the sensor to the Xiao microcontroller board it should work as expected.

Hello, not in the wrong direction.  It's just the color of the lines that misleads you. I was misled by its color, the reverse connection short-circuit MCU. (I'll re-upload the picture for you to see.) Yesterday I have tested XIAO with the potentiometer and everything is normal. I think there may be something wrong with the sensor itself. Multimeter to measure voltage between sensor's GND and sensor output is 0.15~0.20V.  Sensor states a reference voltage of 1.5 and then a range of 0 - 3 volts, which made me wonder if it will work correctly with analogRead();

Great to hear that it was wired correctly and that you had just wired it up with red for GND and black for 3.3V. However this is bound to cause confusion which could lead to mistakes. Please perform the tests in the bottom half of the answer to determine if the fault lies with the sensor or the microcontroller.

This is a 3P integrated line, the seller random gift of different colors of the line. There seems to be Abnormal output with the sensor as soon as it is connected any MCU. I am contacting the manufacturer to solve it.Besides, I didn't have a wiring error. If the wiring is wrong neither the MCU nor the sensor will work properly, let alone output signals(These tests were tested yesterday. Unfortunately, it cannot output the desired clean signal)

I don't have an oscilloscope, and the DMM I have is of poor quality. I have placed an order of FLUKE 17B+ online, and I will use it to check the output of the sensor in a few days.

You seem pretty sure it is the sensor, so perform the sensor test, where you only power the sensor and measure the output with a DMM. Even a poor quality DMM will give you enough information to tell if the sensor is fauty or not.

Now it solved. I was so stupid, because I didn't connect the MCU to the sensor power, so the MCU couldn't measure the sensor value with the reference power.


text:
`time.h` vs `TimeLib.h` on AVR boards
Why do I get wrong result when using time.h library when using AVR boards, such Nano/Uno/Pro Micro (while when using TimeLib.h).
OUTPUT (for given Epoch ):
TimeLib: 2022-04-02 16:11:20
time.h: 0152-03-01 16:11:20
CODE:
#define CASE 1

#if CASE == 1
#include <time.h>
#elif CASE == 2
#include <TimeLib.h>
#endif

time_t bootTime = 1648915880;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\nStart!");
  delay(1000);

  char clk2[40];

#if CASE == 1
  struct tm *tm = localtime(&bootTime);
  sprintf(clk2, "%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);

#elif CASE == 2
  sprintf(clk2, "%04d-%02d-%02d %02d:%02d:%02d", year(bootTime), month(bootTime), day(bootTime), hour(bootTime), minute(bootTime), second(bootTime));
#endif
  Serial.println(clk2);
}

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

localtime() requires a timezone to be set. No idea how you set that. Use gmtime() instead to get the UTC (GMT) time which has no timezone.

well for that, I guessed it'll take TZ=0, or any default, no-TZ value.

Never guess anything. The problem with these functions is they grew up on UNIX (or Linux) where the OS provides things like the selected timezone. How avr-libc handles these things I have no clue.

in time.h tm struct the year starts in 1900 and the moths are 0 to 11.

@Juraj, yes- that I know, but year 153 while we are 2022, strikes a bit odd. Also subtracting few seconds bootTime, yielded a non rational change in result.

You are assuming the avr-libc "epoch" is the same as the UNIX "epoch". It isn't. According to the manual:

Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.

So you need to subtract the UNIX_OFFSET from your time value before passing it to any avr-libc functions.
Also you should initialize the time system with set_zone() and similar functions.


text:
Can no longer select a port in Arduino IDE on Linux?
I am trying to upload to my Elegoo Mega 2560. I previously had it set up properly with the board installed and selected and the port automatically detected.
Now when I go to Tools and hover my mouse over Port nothing happens. I don't get an additional menu showing the port that is detected.
At the bottom of the IDE it says:
Arduino Mega or Mega 2560, ATmega2560 (Mega2560) on /dev/ttyACM0

But when I attempt to upload i get this error:
avrdude: ser_open(): can't open device "/dev/ttyACM0": No such file or directory
ioctl("TIOCMGET"): Inappropriate ioctl for device
ioctl("TIOCMGET"): Inappropriate ioctl for device
avrdude: ser_send(): write error: Bad file descriptor
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: Bad file descriptor
avrdude: stk500_send(): failed to send command to serial port

When I run the following command:
ls /dev | grep ttyACM0

I get no output and error code 1, which indicates that this port doesn't exist. The board is plugged in and some leds are lit up so it is receiving power. I tried reinstalling the drivers via board manager and deleting the files in the arduino15 directory and reinstalling the drivers. I've tried uninstalling and installing arduino ide all together but I still get the same error.
Why does it think it is at /dev/ttyACM0 but then at the same time it can't access it on this port?
This isn't working on my arch linux machine. Plugging the same board into a windows 10 machine and uploading the same code works just fine.
After reinstalling Arduino IDE on Arch Linux it no longer shows the board at ttyACM0 instead just showing a '-'

The output from dmesg might be helpful.

the IDE remembers the last selected port even if the port is no longer available. don't get distracted by that and do the common port-not-available trouble shooting. try different USB cable, USB connector, computer...


text:
RF24 Network. More than one payload
I am using Nrf24Lo1 to communicate a payload of button commands resulting in leds being lit on second. This is working OK.
My aim is to have one as Tx and more than one as RX, I can find several that work in the opposite direction, but none can be adapted. Is it possible to have more than one payload (say "payload2" sent to its own pipe address (Rx)?
//Payload_TX
#include "SPI.h"
#include "RF24.h"
#include "nRF24L01.h"
#define CE_PIN 7
#define CSN_PIN 8
#define INTERVAL_MS_TRANSMISSION 250
RF24 radio(CE_PIN, CSN_PIN);
#define WHICH_NODE 1     // must be a number from 1 - 6 identifying the PTX node

const uint64_t wAddress[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL};
const uint64_t PTXpipe = wAddress[0];
const int ip1 = 3;
const int ip2 = 6;
const int ip3 = 15;
const int ip4 = 16;
const int ip5 = 17;
const int ip6 = 18;

//NRF24L01 buffer limit is 32 bytes (max struct size)
struct payload {
  byte button1;
  byte button2;
  byte button3;
  byte button4;
  byte button5;
  byte button6;
};
payload payload;

//struct payload2 {
// byte data1;
//char data2;
//};
//payload2 payload2;

void setup()
{
  Serial.begin(115200);
  pinMode(ip1, INPUT_PULLUP);
  pinMode(ip2, INPUT_PULLUP);
  pinMode(ip3, INPUT_PULLUP);
  pinMode(ip4, INPUT_PULLUP);
  pinMode(ip5, INPUT_PULLUP);
  pinMode(ip6, INPUT_PULLUP);

  radio.begin();
  //Append ACK packet from the receiving radio back to the transmitting radio
  radio.setAutoAck(false); //(true|false)
  //Set the transmission datarate
  radio.setDataRate(RF24_250KBPS); //(RF24_250KBPS|RF24_1MBPS|RF24_2MBPS)
  //Greater level = more consumption = longer distance
  radio.setPALevel(RF24_PA_MIN); //(RF24_PA_MIN|RF24_PA_LOW|RF24_PA_HIGH|RF24_PA_MAX)
  radio.setChannel(108);
  //Default value is the maximum 32 bytes
  radio.setPayloadSize(sizeof(payload));
  //radio.setPayloadSize(sizeof(payload2));
  //Act as transmitter
  radio.openWritingPipe(PTXpipe);
  radio.stopListening();
}
void loop()
{
  radio.openWritingPipe(PTXpipe);
  payload.button1 = digitalRead(ip1);
  payload.button2 = digitalRead(ip2);
  payload.button3 = digitalRead(ip3);
  payload.button4 = digitalRead(ip4);
  payload.button5 = digitalRead(ip5);
  payload.button6 = digitalRead(ip6);
  radio.write(&payload, sizeof(payload));
  Serial.print("Data1:");
  Serial.println(payload.button1);
  Serial.print("Data2:");
  Serial.println(payload.button2);
  Serial.println("Sent");
  delay(INTERVAL_MS_TRANSMISSION);
}`

 // payload Rx
 #include "SPI.h"
#include "RF24.h"
#include "nRF24L01.h"
#define led1 3
#define led2 4
#define led3 5
#define CE_PIN 7
#define CSN_PIN 8
#define INTERVAL_MS_SIGNAL_LOST 1000
#define INTERVAL_MS_SIGNAL_RETRY 250
RF24 radio(CE_PIN, CSN_PIN);
//const byte address[6] = "00001";
const uint64_t rAddress[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL };
//NRF24L01 buffer limit is 32 bytes (max struct size)
struct payload {
  byte button1;
  byte button2;
  byte button3;
  byte button4;
  byte button5;
  byte button6;
};
payload payload;
unsigned long lastSignalMillis = 0;

void setup()
{
  Serial.begin(115200);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  radio.begin();
  //Append ACK packet from the receiving radio back to the transmitting radio
  radio.setAutoAck(false); //(true|false)
  //Set the transmission datarate
  radio.setDataRate(RF24_250KBPS); //(RF24_250KBPS|RF24_1MBPS|RF24_2MBPS)
  //Greater level = more consumption = longer distance
  radio.setPALevel(RF24_PA_MIN); //(RF24_PA_MIN|RF24_PA_LOW|RF24_PA_HIGH|RF24_PA_MAX)
  radio.setChannel(108);
  //Default value is the maximum 32 bytes1
  radio.setPayloadSize(sizeof(payload));
  //Act as receiver
  radio.openReadingPipe(0,rAddress[0]);
  radio.startListening();
}
void loop()
{
  unsigned long currentMillis = millis();
  if (radio.available() > 0) {
    radio.read(&payload, sizeof(payload));
    Serial.println("Received");
    Serial.print("Button1:");
    Serial.println(payload.button1);
    Serial.print("Button2:");
    Serial.println(payload.button2);
    if (payload.button1 == 0) {
      digitalWrite(led1, HIGH);
    } else {
      digitalWrite(led1, LOW);
    }
    if (payload.button2 == 0) {
      digitalWrite(led2, HIGH);
    } else {
      digitalWrite(led2, LOW);
    }
    if (payload.button3 == 0) {
      digitalWrite(led3, HIGH);
    } else {
      digitalWrite(led3, LOW);
    }
    lastSignalMillis = currentMillis;
  }
  if (currentMillis - lastSignalMillis > INTERVAL_MS_SIGNAL_LOST) {
    lostConnection();
  }

}
void lostConnection()
{
  Serial.println("We have lost connection, preventing unwanted behavior");
  delay(INTERVAL_MS_SIGNAL_RETRY);
}

I am rather old any any help gratefully received.  Thanks for reading.

Just change the address you send to with radio.openWritingPipe(...)...?


text:
Doest a local struct variable get destroyed?
For a RF project I need to split payload for a max predefined chunk size.
For that I created a RFmsg struct.
The unexplained part I need help in is why when I create a local instance  of RFmsg, its contents are remain in tact after function is recalled? is it a struct "thing"? or something else I'm missing ?
To solve that I know that wiping struct content after initiating will solve that, but I'm want to be sure.
for that I share a minimal code that:

void newMSG(char *msg) simulates the splitting part of a long msg input.
void printStrcut_content(RFmsg &_payload) prints struct's content.
output show that only after boot, its content are gibberish, but after that, it shows the content of last struct update.

CODE:
#include <Arduino.h>
#define MSG_LEN 10
#define DEVNAME_LEN 8

char *devName = "TEST";

struct RFmsg
{
    int msg_num;
    int tot_msgs;
    int tot_len;
    char payload[MSG_LEN];
    char dev_name[DEVNAME_LEN];
};

void newMSG(char *msg)
{
    RFmsg _payload;
    printStrcut_content(_payload);

    _payload.tot_len = strlen(msg);
    strcpy(_payload.dev_name, devName);
    _payload.tot_msgs = (int)(_payload.tot_len / MSG_LEN);

    if (_payload.tot_len % MSG_LEN > 0)
    {
        _payload.tot_msgs++;
    }

    for (uint8_t i = 0; i < _payload.tot_msgs; i++)
    {
        strcpy(_payload.payload, "");
        for (uint8_t n = 0; n < MSG_LEN; n++)
        {
            _payload.payload[n] = (char)msg[n + i * MSG_LEN];
        }
        _payload.payload[MSG_LEN] = '\0';

        Serial.print("chunk #");
        Serial.print(i);
        Serial.print(": ");
        Serial.println(_payload.payload);
    }
}
void printStrcut_content(RFmsg &_payload)
{
    Serial.print("LEN: ");
    Serial.println(_payload.tot_len);
    Serial.print("PAyLOAD: ");
    Serial.println(_payload.payload);
    Serial.print("name: ");
    Serial.println(_payload.dev_name);
    Serial.print("tot_msgs: ");
    Serial.println(_payload.tot_msgs);
}

void setup()
{
    Serial.begin(115200);
    while (!Serial)
        ;
    Serial.println("\nStart");
}
void loop()
{
    newMSG("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    delay(5000);
}

OUTPUT:
Start
LEN: 36
PAyLOAD: UVWXYZ
name:
tot_msgs: 4
chunk #0: 1234567890
chunk #1: ABCDEFGHIJ
chunk #2: KLMNOPQRST
chunk #3: UVWXYZ
LEN: 36
PAyLOAD: UVWXYZ
name:
tot_msgs: 4
chunk #0: 1234567890
chunk #1: ABCDEFGHIJ
chunk #2: KLMNOPQRST
chunk #3: UVWXYZ
LEN: 36
PAyLOAD: UVWXYZ
name:
tot_msgs: 4
chunk #0: 1234567890
chunk #1: ABCDEFGHIJ
chunk #2: KLMNOPQRST
chunk #3: UVWXYZ

I also would guess that the struct just always lands on the same memory space, thus retaining the value. Though you cannot count on that. You don't have any control over that.

@Juraj since it is a tiny part of much larger code, I was shocked to see this behavior repeats, at it was intentionally kept some how. what do you recommend ?

Just initialize the struct variable with known values at the start of your function. You just did see that behavior because you didn't do that. You should always initialize variables in functions. Only global variables get initialized implicitly.

As described in the comments: Your local struct variable probably always is placed in the same space in memory and this part of the memory isn't overwritten by your program. When declaring local variables they are not implicitly initialized (written with a value). If you don't initialize the variable yourself, its value will be whatever data is currently in that memory space.
The compiler optimizes your code and also decides on where to place variables on the stack. In this case it is always placed at the same memory space, but you cannot count on that. It is undefined behavior and any change to your program can also change that fact. And you don't have any control over that.
This is the reason, why you should always initialize local variables before reading them.

what do you recommend ?

Just initialize the members of that struct variable before using them. Set all members to a value. You can even do that in one step together with declaring it:
RFmsg _payload = {1, 2, 3, "payload", "devname"};

Just to clarify, undefined behaviour does not necessarily mean there will be zeroes there or any specific thing at all. And under certain circumstances what is there might be the same thing that was there the previous time the function was called. If you decide to not bother initialising variables because "it seemed to work last time" you will eventually find that a change to your code will come back to bite you.


text:
What is the difference between SCLK and CLK pins?
Please do forgive me if anything in this question does not make sense, I am very new to PCB and Arduino.
I am following a tutorial through where the person doing it is making a small data computer (for a balloon or drone, I don't know) on Eagle By Autodesk. I am on a part of the tutorial where an SD & MMC card reader is being used. The instuctor is using a library he has made himself, whilst I am using the default Adafruit library. On his library for the SD card reader, he has a CLK pin, however on the default Adafruit library there is the SCLK pin.
Is there a difference between SCLK pins and CLK pins? And am I ok just to use the CLK pin?
Thank you very much :)

Which Arduino board are you using?

@sempaiscuba The Teensy 3.2 (it's not technically an Arduino).

Ah.  Just that you tagged your question as arduino-uno, which doesn't have either an SCLK or a CLK pin.

@sempaiscuba yeah sorry, my bad

"CLK" stands for "CLocK". "S" stands for "Serial". So "SCLK" is "Serial CLocK". You also get "SCL" (often used for I2C) and "SCK" meaning the same thing.
An SD card has multiple modes of communication: serial, or 4-bit parallel (called SDIO). A clock is a clock whether it is used for serial or parallel communication. What you call it doesn't really matter, at best it just gives a hint about what kind of communication it is used for.
It's like some people use MOSI/MISO and some use SDO/SDI, or DO/DI. There's no standard. It's just data moving one way, data moving the other, and some form of clock to keep it all together.

Well they both are clock pin, but on an arduino uno the sclk pin may refer to the spi clock pin while the clk may refer to the i2c clock pin. I2C and SPI are two communication protocols. So if you know which one you're using take action with the corresponding pins.
I Think the best would be for you to share the tutorial you are following and the place in the code you dont underst

Though with I2C the clock pin is commonly called SCL. So again another version of these similar abbreviations.


text:
Emulate Joystick
I am trying to automate a existing system that uses Joystick as its input to move the Motors in x&y directions. I actually want to emulate arduino to exactly do what the joystick is doing by just emulating the joystick through arduino. Joystick has 4 wires
1- 5Volt
2- Ground
3- x-axis
4- Y-axis
Actually i want arduino to map in such a way that it's only two digital pins are used to connect with joystick cable 3 & 4 and process inputs exactly in such a way that system thinks that as it is the input from the joystick. I just don't want to mess with the electronics of the existing system. That's why just trying to hack into joystick.
UPDATE: i have checked the Joystick for simple voltage and Resistance Measurements.
It seems like it is 1KOhm Pot.

what is your question? ... it is unclear what you are trying to do

what does this mean? ... emulating the joystick through arduino

I actually emulate arduino ... it is possible that you are using the wrong word emulate

For reading a joystick you need 2 analog inputs. You cannot get the same info from 2 digital input pins. Not possible. Is that what you wanted to ask?

I am trying to say that, i want arduino to act as the joystick and output exactly same signals as the joystick does. Actually i am trying to automate a system which takes input from the joystick and subsequently rotates the motors in that direction.

Then you need to provide the link to the joystick that you want to emulate. Is the joystick just the potentiometers for the axes or is there some additional electronics?

Actually i am trying to automate a system which takes input from the joystick and subsequently rotates the motors in that direction ... is that somehow relevant to the question?

i want arduino to act as the joystick and output exactly same signals as the joystick does ... why didn't you say this at the begining?

Maybe "DS3502 I2C Digital 10K Potentiometer" will work. I am interested to hear if it really works as a joystick pot replacement because I have never used it.

Thank you, i am already going to use digital Pot. As per my knowledge, does digital Pot also Acts as a DAC. correct me of i am wrong please.

But i will be using two channel digital pot that is MAX5392

Based on your wiring information, this looks like an analog joystick. You specified using two digital output pins to emulate the joystick to the target device.
The way to do this is to use PWM and a simple resistor-capacitor filter to convert the digital output to an analog 0-5v signal.
Here is some information about PWM:

Arduino and PWM The Arduino IDE has a built in function
“analogWrite()” which can be used to generate a PWM signal. The
frequency of this generated signal for most pins will be about 490Hz
and we can give the value from 0-255 using this function.
analogWrite(0) means a signal of 0% duty cycle.
analogWrite(127) means a signal of 50% duty cycle.
analogWrite(255) means a signal of 100% duty cycle.
On Arduino Uno, the PWM pins are 3, 5, 6, 9, 10 and 11. The frequency
of PWM signal on pins 5 and 6 will be about 980Hz and on other pins
will be 490Hz. The PWM pins are labeled with ~ sign.

Here is a tutorial on converting the PWM signal to an analog voltage level:

The RC filter is a simple circuit element used to convert a pulsed
signal to a flatter signal. The key concept is that the capacitor
shunts the varying voltage to ground, producing a DC voltage.

Thank you for such comprehensive reply. Will look into it.

Any help Guys, please? I am Still stuck at the same point that how can i emulate Arduino as a joystick.


text:
Circular buffer implementation and Serial.print()
I am trying to implement the simplest circular buffer in Arduino. I think I am able to implement it because my push and pop functions do not return any errors. However, when I want to print the data in the buffer using Serial.print(), the code goes into an infinite loop. Here is my code:
#include <stdio.h>

typedef struct circular_buffer
{
    int buffer_arr[5];
    int head;
    int tail;
} circular_buffer;

void setup()
{
  Serial.begin(9600);
  Serial.println("Circular buffer started");
}

void loop()
{
  circular_buffer *cb;
  cb_init(cb);
  if(Serial.available()){
    char instruction = Serial.read();
    Serial.println(instruction);
    if(instruction == 'a'){
      if(Serial.available()){
        char instruction = Serial.read();
        Serial.println("here");
      }
      char key = Serial.read();
      cb_push_front(cb, key);
      Serial.print(String(key));
      Serial.println("    is entered");
    }
    else if(instruction == 'd'){
      cb_pop_back(cb);
      Serial.println("last item removed");
    }
//    for(int i=0; i<5; i++){
//      Serial.print(cb->buffer_arr[i]);
//
//    }
    Serial.println("-");
  }
}

void cb_init(circular_buffer *cb)
{
    // cb->buffer_arr = {0,0,0,0,0};
    for(int i=0; i<5; i++){
      cb->buffer_arr[i] = 'c';
//      Serial.print(sizeof(*cb));
    }
//      Serial.print(cb->buffer_arr[0]);
    cb->head = 0;
    cb->tail = 0;
}

void cb_push_front(circular_buffer *cb, char item)
{
    cb->head++;
    cb->buffer_arr[cb->head] = item;
}

void cb_pop_back(circular_buffer *cb)
{
    cb->tail++;
    cb->buffer_arr[cb->tail] = 0;
}

The for loop which I commented out is the problematic one - or at least what I believe. My problem can be very much related to my poor C-language skills. I thought that cb->buffer_arr = {0,0,0,0,0}; code piece in the initialization function should have worked (thinking very much Python-ic way) but it didn't.
So, if anyone can see the issue and help me fixing it, I'd be very much appreciated.
Thanks in advance.
EDIT
After Majenko's answer I have updated the code like that. I still have issues how to print though. I am not sure whether I am printing the address of the circular buffer as ASCII in this way. I tried to pass the cb to a print function in two ways. None seems to work, though...
#include <stdio.h>

typedef struct circular_buffer
{
    int buffer_arr[5];
    int head;
    int tail;
} circular_buffer;

circular_buffer cb;

void setup()
{
  Serial.begin(9600);
  cb_init(cb);
  Serial.println("Circular buffer started");
}

void loop()
{
  if(Serial.available()){
    char instruction = Serial.read();
    Serial.println(instruction);
    if(instruction == 'a'){
      Serial.print("a pressed");
      cb_push_front(cb, instruction);
    }
    else if(instruction == 'd'){
      Serial.print("d pressed");
    }
    else{
      Serial.print("UNKNOWN");
    }
    Serial.println("-");
  }
}

void cb_init(circular_buffer &cb)
{
    for(int i=0; i<5; i++){
      cb.buffer_arr[i] = 'c';
    }
    Serial.println("here init");
    cb_print1(&cb);
    cb_print2(cb);
    cb.head = 0;
    cb.tail = 0;
}

void cb_push_front(circular_buffer &cb, char item)
{
    cb.head++;
    cb.buffer_arr[cb.head] = item;

    cb_print1(&cb);
    cb_print2(cb);
}

void cb_pop_back(circular_buffer &cb)
{
    cb.tail++;
    cb.buffer_arr[cb.tail] = 0;
}

void cb_print1(circular_buffer *cb)
{
  Serial.println("here print1");
  for(int i=0; i<5; i++){
    Serial.print(cb->buffer_arr[i]);

  }
}

void cb_print2(circular_buffer cb)
{
  Serial.println("here print2");
  for(int i=0; i<5; i++){
    Serial.print(cb.buffer_arr[i]);

  }
}

And the returned output is like that:
here init
here print1
9999999999here print2
9999999999Circular buffer started
a
a pressedhere print1
9997999999here print2
9997999999-
a
a pressedhere print1
9997979999here print2
9997979999-

Thats not really a circular buffer. The indexes need to wrap around at the limit of the buffer (5). Otherwise you will write outside of the buffer with messages long enough.

You might find this useful: https://github.com/MajenkoLibraries/CircularBuffer

Thank you very much for the help. I sure have issues with how I pass the addresses and point to the variables. You are correct about limiting the buffer size but in this particular application, there is no way to fill the buffer - unless I code wrong :) That's why I wanted to keep as simple as possible.

You create a variable that can point to a circular buffer (*cb) but at no point do you actually point it at a circular buffer.
Either you need to create a new circular buffer or don't create a pointer, but create a statically allocated circular buffer. The latter is the preferred method.
Simply remove the * from your cb declaration, which makes a standard struct variable, then take the address of that (with &) to pass as a pointer to your other functions. Or change the other functions to pass by reference.
For example:
circular_buffer *cb;

becomes
circular_buffer cb;

And then
cb_init(cb);

becomes:
cb_init(&cb);

As do all the other functions that you pass the cb variable to.
Also every time you pass through loop() you will be wiping and making a new circular_buffer variable. Instead cb should really be global and the cb_init() call should be in setup().

Thank you for the answer. I have updated the code according to your answer. However, it seems that I still have issues with printing. Sorry to bother with those beginner questions.

There are multiple issues with this code. Majenko already showed the
main one, I will add a few more here.
First, about the circular buffer implementation. As has been stated in a
comment, for the buffer to be considered circular, the indices should
wrap around. I would add a small nitpick: it is customary, in C++, to
start filling an array from index 0. Thus you should post-increment
(rather than pre-increment) the indices:
void cb_push_front(circular_buffer *cb, char item)
{
    cb->buffer_arr[cb->head] = item;
    cb->head++;                            // post-increment
    if(cb->head == circular_buffer_size)   // with wrap-around
      cb->head = 0;
}

There is still an issue though: the buffer can overflow. You should only
add an item if there is room to do so. And you should only remove an
item if the buffer is not empty. You know that the buffer is empty when
tail=head, but how do you know when it is full? If you completely fill
the buffer and the indices wrap around as they should, you end up with
head=tail, and you cannot tell the difference between a full buffer and
an empty buffer. There are two ways around this:

You can keep an extra variable in the struct that helps you tell the
difference. This could be a count of the elements in the buffer, or a
boolean that tells you when the buffer is empty, or a boolean that
tells you when it is full.

You can refrain from completely filling the array and consider that
the buffer is full when it has been filled to its full capacity, where
the “capacity” is defined as the size of the array minus one. Then the
buffer is full when
(head + 1) = tail [modulo array length].

Here is an implementation of the second strategy:
void cb_push_front(circular_buffer *cb, char item)
{
    int next_head = cb->head + 1;          // increment
    if(next_head >= circular_buffer_size)  // with wrap around
      next_head = 0;
    if(next_head == cb->tail){
      Serial.println("buffer overflow");
      return;
    }
    cb->buffer_arr[cb->head] = item;
    cb->head = next_head;
}

int cb_pop_back(circular_buffer *cb)
{
    if(cb->tail == cb->head) {
      Serial.println("buffer underflow");
      return -1;
    }
    char item = cb->buffer_arr[cb->tail];
    cb->tail++;
    if(cb->tail >= circular_buffer_size)
      cb->tail = 0;
    return item;
}

Note that there is no point in cb_pop_back() overwriting the buffer.
On the other hand, it is often very useful for this function to return
the item that has just been popped.
Now, a few random comments:

Rather than hard-coding the array size (5) in multiple places,
define a constant at the beginning of the program
(circular_buffer_size in my examples) and use it everywhere. This
makes it clearer what the number means, and makes it easier to change
the size if you ever need to.

Since you are storing characters, use an array of char.

Your code for handling Serial does not cope well with the situation
where there is a small delay between the 'a' instruction and the
character to be added. If you can afford blocking code, the simplest
solution is to block until the user provides the character:

if(instruction == 'a'){
  while(!Serial.available())
    ;  // wait for the key to be entered
  char key = Serial.read();
  cb_push_front(&cb, key);
  Serial.print(key);
  Serial.println(" is entered");
}

Very important points, thank you! I've been struggling with passing the cb properly to the functions so I didn't put much effort on -optimization- so to say. I still have some issues in printing. I've updated the question. But I will implement these points after it. Thank you so much.

Re “I will implement these points after it”: that's not a good idea. Fix these issues right now, then you program will work as expected. Or, if it doesn't, then it will be much easier to understand what is going wrong.