body:
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);
      }

title: Error in reading wind speed from esp32

Answers: 0


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

title: Does anyone have code that successfully calculates velocity from an accelerometer

Answers: 1

body:
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][1] 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][2].

> 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][3].

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.

[![enter image description here][4]][4]

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

[![enter image description here][5]][5]

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.

  [1]: https://en.wikipedia.org/wiki/Kinematics
  [2]: https://www.st.com/resource/en/application_note/cd00269797-using-lsm303dlh-for-a-tilt-compensated-electronic-compass-stmicroelectronics.pdf
  [3]: https://en.wikipedia.org/wiki/Gimbal_lock
  [4]: https://i.stack.imgur.com/ieA7e.jpg
  [5]: https://i.stack.imgur.com/UQX1N.jpg


body:
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 );
}
```

title: Undefined reference to function in custom library

Answers: 2

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

```c
// 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
```c
// 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 );
}
```

body:
To complement Bob's answer it is good practice to add header guards for detecting C++ specifically:

```c++
#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.


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

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

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

title: Ways to detect if a ball has reached the wall?

Answers: 1

body:
> The ball will hit the wall with a small impact...

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

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

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][2].

  [1]: https://i.stack.imgur.com/dx8Gl.png
  [2]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button


body:
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!

title: Guru meditation error load prohibited, esp32s. While using Fastled

Answers: 1

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

```c++
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...

```c++
int rod[10];
arrayBuilder(rownum, myhex, false, rod);
```


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

```c++
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
[![enter image description here][1]][1]

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

title: Problems in running two solenoid together at the same time

Answers: 1

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


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

title: ESP32 WROOM32E w/ Arduino IDE 2axis joystick - how do I get a good reading?

Answers: 0


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

title: Different meanings of pid and vid in boards.txt

Answers: 1

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


body:
[This guide ][1]  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?

  [1]: https://create.arduino.cc/projecthub/SURYATEJA/use-a-buzzer-module-piezo-speaker-using-arduino-uno-89df45

title: Do passive buzzers require a PWM pin?

Answers: 1

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


body:
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)00, 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;
    }

title: Milliseconds using square wave RTC

Answers: 1

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


body:
## Problem description
When XIAO microcontroller is connected to the sensor signal output pin, keep printing unexpected values.

Sketch
[![enter image description here][1]][1]
[![enter image description here][2]][2]
I haven't sensor circuit diagram, you can machine translate and read the page<https://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

![Vendor-supplied sample code](https://aws1.discourse-cdn.com/arduino/original/4X/e/9/9/e9939564973468d73ca65706dff0df430504bc72.gif)

### Normal output:

[![enter image description here][3]][3]

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:

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

![](https://tupian.li/images/2022/04/04/new1.gif)
![](https://i.stack.imgur.com/Lk9oY.png)

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

3. 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)
[![enter image description here][4]][4]

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

![gif](upload://9HX2jdkzyDmOlOL7EKuT28SLOsQ.gif)

5. 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)
![22-04-04-23-35-46.gif](https://tupian.li/images/2022/04/04/22-04-04-23-35-46.gif)
![](https://iili.io/MRCnSa.gif)
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](https://gist.github.com/allrobot/c70abc599ca8eb7fbc246ed67515449a)

Sensor parameters: [{ED0056}Sensor](https://www.yuque.com/cs/products/rwe87o)

Microcontrollers XIAO general description: [Getting Started with Seeeduino XIAO - Seeed Wiki](https://wiki.seeedstudio.com/Seeeduino-XIAO/)

Microcontrollers XIAO instruction manual: <https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/ATSAMD21G18A-MU-Datasheet.pdf>
[![enter image description here][5]][5]

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

  [1]: https://i.stack.imgur.com/63bmP.jpg
  [2]: https://i.stack.imgur.com/QUrPg.png
  [3]: https://i.stack.imgur.com/zELX3.png
  [4]: https://i.stack.imgur.com/EwulX.png
  [5]: https://i.stack.imgur.com/myihn.png

title: How do I solve the sensor’s abysmal abnormal output?

Answers: 2

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

[![Pinout of the Xiao Microcontroller board][1]][1]

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.

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

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

[![!\[image|667x500\](upload://6MZQ5bHsZdZKAhBULisPfXrMJu9.png)][1]][1]

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


body:
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, "d-d-d d:d:d", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);

    #elif CASE == 2
      sprintf(clk2, "d-d-d d:d:d", 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:
    }

title: `time.h` vs `TimeLib.h` on AVR boards

Answers: 1

body:
You are assuming the avr-libc "epoch" is the same as the UNIX "epoch". It isn't. According to [the manual](https://www.nongnu.org/avr-libc/user-manual/group__avr__time.html#gaa9336f97d394e8e02d97b9ff4fb0aca2):

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


body:
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 '-'

title: Can no longer select a port in Arduino IDE on Linux?

Answers: 0


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

title: RF24 Network. More than one payload

Answers: 0


body:
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:
1) `void newMSG(char *msg)` simulates the splitting part of a long `msg` input.
2) `void printStrcut_content(RFmsg &_payload)` prints struct's content.
3) 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

title: Doest a local struct variable get destroyed?

Answers: 1

body:
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"};


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

title: What is the difference between SCLK and CLK pins?

Answers: 2

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

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


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

title: Emulate Joystick

Answers: 2

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

body:
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][1] 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][2] 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.

  [1]: https://create.arduino.cc/projecthub/muhammad-aqib/arduino-pwm-tutorial-ae9d71
  [2]: https://www.instructables.com/Arduino-RC-Circuit-PWM-to-analog-DC/


body:
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][1]'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-

  [1]: https://arduino.stackexchange.com/users/4143/majenko

title: Circular buffer implementation and Serial.print()

Answers: 2

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

```c++
circular_buffer *cb;
```

becomes
```c++
circular_buffer cb;
```

And then

```c++
cb_init(cb);
```

becomes:

```c++
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()`.

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

```c++
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:

```c++
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:

```c++
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");
}
```


body:
A question I have long had regards an interaction between `#define` statements and a library header include. I've seen several Arduino libraries use this rather convenient configuration system where you can write a `#define` statement, then include the `#include header` instruction and the library will change its behavior.

Does anyone know why this does or does not work? My understanding of how `#include` works is that it copies the file into its place in the new file and that C/C++ code with headers should thus form something of a tree shape. It would thus make sense that any lines of code present before I `#include` a library would have to be seen by the library when the preprocessor does its thing and copies the `#include`-d file.

But I've previously been told it doesn't actually work this way (despite actual examples, but by that point I had misplaced the libraries that did it). However, I've finally tracked down an example of someone doing this, and I'd like to know how this behavior works. Is it a feature of Arduino in specific or something?

Here's a library that does it: https://github.com/madpilot/mDNSResolver

title: Odd behavior of defines - is this Arduino specific and how does it work?

Answers: 2

body:
The mDNSResolver library README has
> You can change a few settings by defining some constants before including the mDNSResolver header file *[in the sketch]*

*I added "in the sketch", because it is where **you** include mDNSResolver header file.*

This will not work because mDNSResolver.cpp, which uses the values of the defines, is compiled without any knowledge of the ino file content.

*A deeper explanation would be too long and out of scope for Arduino SE.*

body:
In the first few lines of the library .h file you linked, it tests a symbol it has not defined, ESP32 (`#if defined(ESP32)`) and alters the compilation according to the definedness of that symbol.

Since the compiler input will be one long file with all the #include files already "spliced" inline, <strike>you (or a previously included .h file) have the option to pre-define that variable</strike> to alter the compilation as this library writer provided.

Update:

@RDragonflydr: I believe you are correct, that the ESP32 symbol is defined by the compiler (or more likely, the makefile) for the target processor. And to clarify my statement that "the compiler input will be one long file", I'm referring to the compilation of each module of your project, not to the entire project at once. Each library will each be compiled, separately, and each of your modules will be compiled separately, and in *each of those cases*, the compiler input will consist of the module code with all of the #included files "spliced" into place, the #defined symbols and macros substituted, and comments stripped out.

The library code (the .cpp) is not #included so it does not become part of the translation unit. Only the library header file is included. That is common - and necessary - to all environments, and one of the functions of the C or C++ preprocessor. This happens for each module - separately - in a multi-module compilation. The library files will have been


body:
This question deals with fonts. Well, actually, singular include files with constants that form bitmap fonts or images for LCD or OLED displays, such as this one: https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/src/OLEDDisplayFonts.h. A strangely hard to research (but common) problem occurs when anyone attempts to include one of these font files in multiple files in an application.

Even with an include-guard present, reuse of this .h file will cause strange linker errors about redefinition of a variable. It turns out that any variable actually declared in a .h file will cause it to be created multiple times in the program, and then when the different files depending on the font.h file are linked, the variables collide. An example of it would be here: https://stackoverflow.com/a/4936294/11381501, or in my very own question some time ago here: https://arduino.stackexchange.com/questions/73095/how-to-create-large-progmem-arrays-and-not-annoy-the-linker

The issue is, I've seen some libraries that avoid this error (such as https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/src/OLEDDisplay.h#L64) despite having variables declared in .h files. I've even included this OLEDDisplay.h file (indirectly via the main library file for my screen) in multiple of my own .h files in one project and it hasn't caused linker errors. What causes *this* globally-scoped variable in a .h file to not produce linker errors when my own code usually does?

title: Inconsistent behavior of include statements?

Answers: 1

body:
The esp8266-oled-ssd1306 has it wrong, but with examples of the library it is saved by optimization. Other files where the font gets included don't use it so it is optimized away. Otherwise it would be duplicated.

OLEDDisplayFonts.h is included in OLEDDisplay.h which is included in OLEDDisplay.cpp and in SSD1306Wire.h which is included in the sketch. This creates two instances of the variables defined in OLEDDisplayFonts.h. But the instance in OLEDDisplay.cpp is optimized away, because that file doesn't use fonts. So for the linker there is only one instance of the variable.

relevant part from .map file for the SSD1306UiDemo.ino example
```
 .irom.text.OLEDDisplayFonts.h.857.11
                0x000000004023b7fd     0x25ab ./SSD1306UiDemo.ino.cpp.o
 .irom.text.OLEDDisplayFonts.h.434.10
                0x000000004023dda8     0x13b9 ./SSD1306UiDemo.ino.cpp.o
 .irom.text.OLEDDisplayFonts.h.10.9
                0x000000004023f161      0xaab ./SSD1306UiDemo.ino.cpp.o
 .irom.text.OLEDDisplayFonts.h.10.9
                0x000000004023fc0c      0xaab ./libraries/esp8266-oled-ssd1306/src/OLEDDisplay.cpp.o
 .irom.text.OLEDDisplayFonts.h.10.9
                0x00000000402406c7      0xaab ./libraries/esp8266-oled-ssd1306/src/OLEDDisplayUi.cpp.o
```

The right way is to put variables in a cpp or c file and if they should be visible from other file, then use `extern` keyword in that file (usually over an included .h file) to declare that the variable exists.


body:
hey y'all first post here so my apologies if I'm a bit of a NEWB, I'm currently trying to control a set of individually addressable 3-pin led strips I got from the  type S formula drift LED kit model number LM532654-1. Ive used FastLEDS for a few projects now but this one is stumping me. I may have the wrong type maybe or there could be a special line of code I need to enter to talk to the chip-sets. Any help would be greatly appreciated. Also thank you all so much here on the forum, its saved my tail on so many occasions.
[![The code Ive been playing with to figure it out. its not clean but it might give an idea what ive been working][1]][1]
[![This is the spec of the LED strips ive been working with, the SMD5050 front and back glow.][2]][2]

  [1]: https://i.stack.imgur.com/74XKk.png
  [2]: https://i.stack.imgur.com/Ht2DD.png

    //#include <WS2812Serial.h>
    //#define USE_WS2812SERIAL
    #define FASTLED_INTERNAL
    #include <FastLED.h>
    #include <FastLED_NeoPixel.h>
    FASTLED_USING_NAMESPACE

    #define DATA_PIN1           2
    #define DATA_PIN2           3

    #define COLOR_ORDER         GRB
    //#define LED_TYPE            WS2812SERIAL
    #define LED_TYPE            SM16703
    #define NUM_LEDS_1 50
    int i=NULL;

    CRGB leds_1[NUM_LEDS_1];
    FastLED_NeoPixel_Variant strip(leds_1, NUM_LEDS_1);

    void setup(){
      //pinMode(DATA_PIN1,OUTPUT);
      Serial.begin(9600);
      FastLED.addLeds<LED_TYPE,DATA_PIN1,COLOR_ORDER>(leds_1, NUM_LEDS_1)
            .setCorrection( TypicalLEDStrip );
            FastLED.addLeds<LED_TYPE,DATA_PIN2,COLOR_ORDER>(leds_1, NUM_LEDS_1)
            .setCorrection( TypicalLEDStrip );

    }

    void loop(){

      strip.begin(FastLED.addLeds<LED_TYPE, DATA_PIN1, GRB>(leds_1, NUM_LEDS_1));

      for(i=0; i<NUM_LEDS_1; i++){
        leds_1[i] = CRGB :: Green;
        FastLED.show();
        }

        for(i=0; i<NUM_LEDS_1; i++){
        leds_1[i] = CRGB :: Green;
        FastLED.show();
        }

title: Type S Automotive underglow LEDS not responding to program in FastLEDS library

Answers: 0


body:
I'm having issues stacking shields on my Arduino Mega 2560. I would like to add to the mega a ethernet shield (https://store.arduino.cc/products/arduino-ethernet-shield-2) and on top of that the dragino lora shield v1.4 (https://wiki.dragino.com/index.php?title=Lora_Shield). When I connect only the dragino lora shield to the mega I do get the lora to initialize but the moment I add the ethernet shield to the mega and the dragino lora shield to the ethernet shield the lora initialization fails. Is this stacking possible and if so any advice on how to get all to work together?

Thanks in advance.

title: Arduino shield stacking issue

Answers: 1

body:
Both those boards use pin 10 for chip select by default. You will need to change that.

Probably the simplest one to change is the LoRa board. If you look at the WiKi page you link to it lists a set of resistors and jumpers which can be altered to modify the connectivity of the board.  By default R9 is populated which connects to pin 10. If you move that to the R10 position next to it you will instead be connecting to D5 for the chip select pin. Moving surface mount resistors can be tricky though so you may want to practice working on a scrap board first.

And of course when you have changed the chip select pin you will also have to change your code to use that new chip select pin instead.


body:
So I have been stuck with this for quite some days now and am really unable to put my finger on what's wrong here. Any help would be great. Try not to list down the disadvantages of SoftwareSerial, I know about them. Is this issue happening cause of it?

**What I am trying to achieve?** Two Arduino (Nanos) are connected to each other and are trying to communicate with each other via SoftwareSerial UART (multiple Arduinos are connected to multiple Arduinos but for the sake of keeping the code minimalistic, assume one-to-one communication).

**Code for Arduino 1**:
```
#include <SoftwareSerial.h>

String val = "4";

SoftwareSerial a(6, 7); // rx, tx
SoftwareSerial b(8, 9); // rx, tx
SoftwareSerial c(10, 11); // rx, tx
SoftwareSerial d(12, 13); // rx, tx

String a_s, b_s, c_s, d_s;

void setup() {
  a.begin(9600);
  b.begin(9600);
  c.begin(9600);
  d.begin(9600);
  Serial.begin(9600);
  a_s = "";
  b_s = "";
  c_s = "";
  d_s = "";
}

void loop() {
  delay(100);

  d.print(val);

  if(d_s == "") {
    if(d_s == "" && d.available()) {
      char rd = d.read();
      Serial.print("ddddddddddd ");
      Serial.println(rd);
      d_s = rd;
    }
  }
}
```

**Code for Arduino 2:**

```
#include <SoftwareSerial.h>

String val = "5";

SoftwareSerial a(6, 7); // rx, tx
SoftwareSerial b(8, 9); // rx, tx
SoftwareSerial c(10, 11); // rx, tx
SoftwareSerial d(12, 13); // rx, tx

String a_s, b_s, c_s, d_s;

void setup() {
  a.begin(9600);
  b.begin(9600);
  c.begin(9600);
  d.begin(9600);
  Serial.begin(9600);
  a_s = "";
  b_s = "";
  c_s = "";
  d_s = "";
}

void loop() {
  delay(100);

  b.print(val);

  if(b_s == "") {
    if(b.available()) {
      char rd = b.read();
      Serial.print("bbbbbbbbbbbb ");
      Serial.println(rd);
      b_s = rd;
    }
  }
}
```

**Actual and Expected output for Arduino 1:**
`ddddddddddd 5`

**Actual output for Arduino 2: (no output!!)**
```
```

**Expected output for Arduino 2:**
`bbbbbbbbbbbb 4`

While debugging, I realized if I comment out c.begin(9600) and d.begin(9600) from the code for Arduino 2, the actual output is the same as the expected output.
```
//   c.begin(9600);
//   d.begin(9600);
```

Ohh and yes, the connections are as follows:

| **ard1** | **ard2** |
| ---- | ---- |
| GND  | GND  |
| D12  | D9   |
| D13  | D8   |

Both the Arduinos are connected (and hence powered) via individual cables to the same laptop.
Is there something I am missing out on? I know SotfwareSerial has its downsides but is this something SoftwareSerial is causing? If yes, why is the actual output of Arduino 1 is same as the expected output? Shouldn't it have the same effect on both the Arduinos?

TIA!

title: Weird SoftwareSerial behaviour with Arduino nano when multiple SoftwareSerial objects are configured

Answers: 1

body:
Is one of the downsides of SoftwareSerial that you know about the fact that *only one SoftwareSerial can be set to receive data at a time*?

You have to select one *and only one* instance to receive data using the `.listen()` method.

If you want to be able to receive from multiple devices at once you will have to use either hardware UARTs or a single SoftwareSerial and a "bus" infrastructure (RS485 or similar).


body: I want to divide two integers and get how often one of them fits into the other completely, so there will always be an integer as an output. In python you do this kind of operation with `//`.

title: Integer division

Answers: 1

body:
In C++, the integer division operator is `/`, and the floating point
division is also `/`. The compiler chooses according to the types of the
operands:

- if either or both operands are floating points numbers, you get a
  floating point division

- if both operands are of some integer type, you get an integer
  division.

Thus:

- `5.0/2.0`, `5.0/2`, `5/2.0` all have the same value, namely `2.5`

- `5/2` is `2`.


body:
I need to do some math with vars from an attitude sensor (acclerometers and gyroscopes) on an esp8266. int32_t math with those vars does not have enough range and the float math operations are abyssmally slow.

I'm hoping to use a fixed-point format with 24 bits on the left of the decimal point and 8 bits on the right side.  So a number would be stored in a int32_t as 0xffffff.ff.  A typical operation would be a multiply like ((i64) x * y) >> 24).

So 64-bit math is needed. Would this be significantly slower than a float multiply?

title: On an esp8266 what is faster, 64-bit math or float math?

Answers: 2

body:
Calculating the relative performance of 64 bit integer versus floating point multiplication is a little more difficult than it would appear.

It's easy to time a loop that does thousands of calculations, but unless you do something with the result the compiler will happily optimize them away. It's tempting to multiply constants, but the compiler will also happily optimize that away.

To keep the code as simple as possible and not introduce anything into the loop that would take more time, you need to disable or bypass the compiler's optimizations. An easy way to do that is to use the `volatile` modifier on the variables. `volatile` tells the compiler that it can't assume the variable hasn't changed, so the compiler will disable optimizations like caching the variable in a register or noticing that the same calculation is being done over and over again and just doing it once.

Using this technique, with a couple of tests to verify that the compiler would perform optimizations that interfere with timing, I get these results:
```
non-volatile uint32_t microseconds 1
constants uint32_t microseconds 5
uint16_t microseconds 162513
uint32_t microseconds 137513
uint64_t microseconds 1287533
int16_t microseconds 337513
int32_t microseconds 300023
int64_t microseconds 1287513
float  microseconds 912529
```

64 bit unsigned or signed multiplication takes about 1.4x the time as floating point multiplication.

The first test verified that non-volatile variables are optimized out. The second test verified that multiplying constants is also optimized out.

Turning off Wifi also helps keep test results consistent.
```
#include <Arduino.h>

#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif

#define TIMES_TO_LOOP 1000000

volatile uint16_t ux16, uy16, uresult16;
volatile uint32_t ux32, uy32, uresult32;
volatile uint64_t ux64, uy64, uresult64;

volatile int16_t x16, y16, result16;
volatile int32_t x32, y32, result32;
volatile int64_t x64, y64, result64;

volatile float xf, yf, resultf;

uint32_t x32n, y32n, result32n;

uint16_t seed16() {
  return random(0, 0xffff);
}

uint32_t seed32() {
  return random(0, 0xffffffff);
}

uint64_t seed64() {
  return seed32();
}

float seedfloat() {
  float x, y;

  x = seed32();
  y = seed32();

  return x / y;
}

void setup() {
  uint32_t i;
  uint64_t micros_start, micros_end;

  Serial.begin(115200);
  Serial.println("hello world");

  WiFi.mode( WIFI_OFF );

  delay(1000);

  x32n = seed32();
  y32n = seed32();

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    result32n = x32n * y32n;
  micros_end = micros();

  Serial.print("non-volatile uint32_t microseconds ");
  Serial.println(micros_end - micros_start);

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    result32n = 540000 * 15;
  micros_end = micros();

  Serial.print("constants uint32_t microseconds ");
  Serial.println(micros_end - micros_start);

  ux16 = seed16();
  uy16 = seed16();
  x16 = ux16;
  y16 = uy16;

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    uresult16 = ux16 * uy16;
  micros_end = micros();

  Serial.print("uint16_t microseconds ");
  Serial.println(micros_end - micros_start);

  ux32 = seed32();
  uy32 = seed32();
  x32 = ux32;
  y32 = uy32;

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    uresult32 = ux32 * uy32;
  micros_end = micros();

  Serial.print("uint32_t microseconds ");
  Serial.println(micros_end - micros_start);

  ux64 = seed64();
  uy64 = seed64();
  x64 = ux64;
  y64 = uy64;

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    uresult64 = ux64 * uy64;
  micros_end = micros();

  Serial.print("uint64_t microseconds ");
  Serial.println(micros_end - micros_start);

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    result16 = x16 * y16;
  micros_end = micros();

  Serial.print("int16_t microseconds ");
  Serial.println(micros_end - micros_start);

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    result32 = x32 * y32;
  micros_end = micros();

  Serial.print("int32_t microseconds ");
  Serial.println(micros_end - micros_start);

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    result64 = x64 * y64;
  micros_end = micros();

  Serial.print("int64_t microseconds ");
  Serial.println(micros_end - micros_start);

  xf = seedfloat();
  yf = seedfloat();

  micros_start = micros();
  for(i = 0; i < TIMES_TO_LOOP; i++)
    resultf = xf * yf;
  micros_end = micros();

  Serial.print("float  microseconds ");
  Serial.println(micros_end - micros_start);
}

void loop() {
}
```

body:
OK, I took the trouble to code fixed-point routines and test them.  Here is the code ...

// fixed-point routines for 20 bit integer / 12-bit fraction
// format 0xfffff.fff, max value is +-524288.9998

#define FP_I 20     // integer bits,  e.g. 0xfffff.0
#define FP_F 12     // fraction bits, e.g. 0x0.fff
#define fpMul(_x,_y) ( (i32)( ((i64) _x * _y) >> FP_F) )
#define fpDiv(_x,_y) ( (i32)(  (((i64) _x) <<   32)      \
                             / (((i64) _y) >> FP_I) ) )
#define decToFp(_dec) ((i32) (_dec * 4096))   // e.g. decToFp(-1.2)
#define fpToI32(_fp)  ((i32) (_fp  / 4096))

I did a 1000 loops and used the loop counter as the operation argument.  So each loop was one operation plus one floating-point increment.  I did this for fixed-point multiply, floating-point multiply, fixed-point divide, and floating-point divide.

The results were shocking.  The fixed-point multiply took almost exactly the same time as the floating-point. The fixed-point divide took 60% longer than the floating-point.  I went over my code and tried everything I could think of.  I built it in debug and release mode.  I tried 80MHz and 160MHz.  I found floating-point speeds on the web and my floating-point tests closely matched those.

I am at a loss as to how the 64-bit math could be slower than the floating-point.  Both are implemented in software.  I'm sure the floating-point is highly optimized with some tricks and coded in machine language.  But my fixed-point code is just shifts and 64-bit multiply/divides.  I don't think there are any tricks that could be used for it.

At least this makes the decision easy. I guess I'll use floating-point as sparingly as possible and cross my fingers that I can get my app to work fast enough.

I hope this is helpful to some passing-by googlers.  I couldn't find anything when I googled it.


body:
This is my first time programming an Arduino. I have a small brushed DC motor that I want to control using a 5V relay, which in turn is connected and controlled by the Arduino.

What I would like to do is this: Command the relay to turn ON for a specified amount of time, after pressing a momentary push button, then turn OFF once the specified amount of time has passed.

Once that's done, I would like it to reset itself, so to speak, so if I press the push button again it does the same thing.

My current script is:

    const int relay = 8; //motor relay
    const int button = 9; //momentary trigger switch

    int status = true;

    void setup() {
      // put your setup code here, to run once:
      pinMode(8,OUTPUT);
      pinMode(9, INPUT_PULLUP);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if (digitalRead(button) == true) {
        status = !status;
        digitalWrite(relay, status);
      } while (digitalRead(button) == true);
      delay(500);
    }

What it currently does is: if I push the push button once, it will command the relay ON until I press the button again, which then turns the relay OFF until further input.

I know that I should use the millis() function for the timer functionality, but for the life of me I haven't been able to figure out how to make it work thus far.

Any suggestions?

title: Turn on a relay for a specified amount of time after the press of a momentary switch

Answers: 0


body:
I have connected 64 led strips and 8 shift registers (connected to 64 sensors) to 5V and ground of arduino. Voltage received at led strip is 3.1V and at registers is 3.2V. I plan to add an led display as well a small buzzer to it. Can I connect it to the same 5V? What should I make sure in this in terms of voltage supply so that there is no less supply as well loss of power? What if I add a 9V battery instead?

Note: I am just a beginner in this topic.

title: 64 led strips and 8 shift registers (connected to 64 sensors) connected to 5V and ground of arduino

Answers: 1

body:
I guess you are currently powering all this through a USB port on your PC. You are lucky if you haven't fried anything on the Arduino. When the 5V pin goes down to 3.1V this means that either you have fried the power electronics or you are currently totally stressing the power supply out. Power supplies, which are overloaded often drop the voltage significantly, or just fail outright.

All the LEDs, shift registers and sensors draw current. With this much LED strips you can easily get into the territory of many amps of current needed for driving them (depending on the number of LEDs and the current draw of each LED). A PC USB port will only provide 500mA by default. An Arduino can handle a current output from the 5V pin of about 1A, including the current, that the Arduino itself needs. So lets say 800mA. When you provide power through the barrel jack this also depends on the voltage of your power supply. The linear voltage regulator dissipates the voltage difference to 5V as heat, so supplying a higher voltage means more heat, means it can handle less current.

**What to do now:**
- You need to power your LED strips, shift registers and sensors directly from your power supply. The current for them should not go through the Arduino. If you use a power supply with a higher voltage than 5V, you need to buy a voltage regulator for 5V that is capable of providing the total needed current (+ at least 20% headroom to be safe and reduce heat). Go for a switching "buck" converter type, not for a linear converter. They are way more efficient and provide less heat. There are ready-to-use modules available on the typical sides (for example the one named like the biggest river). Often they have a small potentiometer on them, which you can spin with a small screwdriver to set the wanted output voltage (here 5V).
- Make sure, that the used power source is actually capable of providing the total needed current. For this you first need to calculate how much current the project will draw. For example: Standard addressable LED strips with WS2812 will draw 60mA per LED when on full brightness white. Multiply with the number of LEDs to get the total current for them. GO through all components of your project and write down the current draw (look at the datasheet for such info). Add it all up. Then get a power source (and if needed voltage regulator) that can handle at least 20% more than that.

> What if I add a 9V battery instead?

As written above you will need an external voltage regulator for your project. Also: If you mean the standard 9V block batteries, then just forget it. They are not meant for high power applications and can only provide very low current. You should look in the direction of LiIon or LiPo batteries. When you use them please also buy a fitting charger module (since these are rather particular about how they want to be charged).

But before choosing a battery you first need to know how much current your project draws. Then you need to set a time range how long the project should run on the battery without charging. Then you can choose a battery based on that.


body:
I'd like to power something needing 5V DC using the Arduino Uno analog pins. Specifically, I'm following the "Fun Plug-in Hack for Arduino UNO" section of [this Adafruit tutorial][1]. It states:

> "If you set analog pin A3 to an OUTPUT and HIGH and A2 to an OUTPUT
> and LOW you can power the RTC directly from the pins!"

It doesn't seem to work, so I try this with a multimeter hooked up to A2 & A3:

    void setup() {
      pinMode(A2, OUTPUT);
      pinMode(A3, OUTPUT);
      analogWrite(A2, LOW);
      analogWrite(A3, HIGH);
    }

    void loop() {}

I only measure ~0.8V, trying 2 boards including a brand-new unboxed one. This is the same whether the board is powered via USB or via 9V battery in the barrel jack.

But I *can* measure ~5V from those pins if I set the "ground" pin as INPUT_PULLUP (using the built-in pull-up resistor) instead of OUTPUT:

    void setup() {
      pinMode(A2, INPUT_PULLUP);
      pinMode(A3, OUTPUT);
      analogWrite(A3, HIGH);
    }

    void loop() {}

I don't believe Adafruit is wrong, since conceptually it makes more sense to set both pins to OUTPUT, with one being HIGH and the other being LOW. So what am I doing wrong?

  [1]: https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/wiring-it-up

title: Using Analog Pins for Power

Answers: 1

body:
The analog pins are only analog *inputs* but *digital* outputs (and inputs too). You use `digitalWrite()` to control a pin's HIGH or LOW state.

`ànalogWrite()` is for use with the PWM pins (I hate the name the chose for that function it's so wrong on so many levels).

Also this powering trick only works for things that need very small currents (< about 20mA) since that is the maximum an IO pin can deliver.

----

Incidentally, you *can* use `analogWrite()` on a non-PWM pin, but it's either fully on (analog value >= 127) or fully off (analog value < 127). The macros HIGH and LOW are 1 and 0 respectively, so that equates to "fully off" and "fully off" on a plain non-PWM pin.


body:
I have an Arduino Uno Wifi (Rev2) and I want to play a sound file. I found two libraries so far but neither of them work. The TMRpcm library (https://www.arduino.cc/reference/en/libraries/tmrpcm/) only works on the base Arduino Uno and anther library called AudioZero (https://www.arduino.cc/reference/en/libraries/audiozero/) does not seem to be compatible with Arduino Uno Wifi.
Is there any other library that I could use to play a sound file. I have an SD card attached and a library that can read in a .wav file but no library to actually output the sounds on a basic speaker.

I need to use the Arduino Uno Wifi for what I am trying to achieve since communicating with the internet is crucial.
Using a base Uno with a wifi attachment did not prove to be promising since the attachment acted as it's own board and need to be flashed.

title: Playing a sound file with Arduino Uno Wifi

Answers: 1

body: No sounds library seems to exist that is compatible with the architecture of the Arduino Uno Wifi specifically. Other micro-controllers need to be looked into.