message:
Doest a local struct variable get destroyed?

For a RF project I need to split payload for a max predefined chunk size.
For that I created a `RFmsg` struct.

The unexplained part I need help in is why when I create a **local** instance  of `RFmsg`, its contents are remain in tact after function is recalled? is it a struct "thing"? or something else I'm missing ?

To solve that I know that wiping struct content after initiating will solve that, but I'm want to be sure.

for that I share a minimal code that:
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

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


sender: user

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

Please do forgive me if anything in this question does not make sense, I am very new to PCB and Arduino.

I am following a tutorial through where the person doing it is making a small data computer (for a balloon or drone, I don't know) on Eagle By Autodesk. I am on a part of the tutorial where an SD & MMC card reader is being used. The instuctor is using a library he has made himself, whilst I am using the default Adafruit library. On his library for the SD card reader, he has a CLK pin, however on the default Adafruit library there is the SCLK pin.

Is there a difference between SCLK pins and CLK pins? And am I ok just to use the CLK pin?

Thank you very much :)

sender: assistant

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


message:
Emulate Joystick

I am trying to automate a existing system that uses Joystick as its input to move the Motors in x&y directions. I actually want to emulate arduino to exactly do what the joystick is doing by just emulating the joystick through arduino. Joystick has 4 wires
1- 5Volt
2- Ground
3- x-axis
4- Y-axis

Actually i want arduino to map in such a way that it's only two digital pins are used to connect with joystick cable 3 & 4 and process inputs exactly in such a way that system thinks that as it is the input from the joystick. I just don't want to mess with the electronics of the existing system. That's why just trying to hack into joystick.

UPDATE: i have checked the Joystick for simple voltage and Resistance Measurements.
It seems like it is 1KOhm Pot.

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/


message:
Circular buffer implementation and Serial.print()

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

    #include <stdio.h>

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

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

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

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

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

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

The `for` loop which I commented out is the problematic one - or at least what I believe. My problem can be very much related to my poor C-language skills. I thought that `cb->buffer_arr = {0,0,0,0,0};` code piece in the initialization function should have worked (thinking very much Python-ic way) but it didn't.

So, if anyone can see the issue and help me fixing it, I'd be very much appreciated.
Thanks in advance.

# EDIT #
After [Majenko][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

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


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

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

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


message:
Inconsistent behavior of include statements?

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?

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.


message:
Arduino shield stacking issue

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.

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.


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

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!

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


message:
Integer division

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

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


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

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?

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.


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

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.

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.


message:
Using Analog Pins for Power

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

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.


message:
Playing a sound file with Arduino Uno Wifi

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.

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.


message:
Can't get Adafruit MusicMaker and Ethernet to work at the same time

Working on an IoT project.
Environment:
- Adafruit Feather M4 Express
- Adafruit MusicMaker FeatherWing (amplified, this is a VS1053 at heart)
- Silicognition PoE FeatherWing (electrically compatible with the Adafruit Ethernet FeatherWing)
- PlatformIO with Visual Studio Code on a Mac (all libraries are up-to-date)

The Problem:
I can get either the Ethernet to work or the MusicMaker to work, but not both at the same time.
There are no errors during initialization, they just don't work.

Specifically, the MusicMaker's `sineTest()` method doesn't generate any sound if Ethernet has been initialized. Likewise, the Ethernet client's `connect()` method is unable to connect if the MusicMaker is initialized. Both methods work fine if the other device hasn't been initialized.

Feather Pins:
```
Purpose                    Pin
-------------------------- ---
VS1053 Chip select           6
VS1053 Data/command select  10
VS1053 Data request          9
SD Card Chip select          5
Ethernet Chip select        14
```
Note that I'm not currently using the SD card and haven't called its `begin()` method.
Note also that the Ethernet chip select is on a non-standard pin because the default conflicts with the VS1053 data/command select.

Also, the PoE FeatherWing has an EEPROM on it with a unique MAC address and reading this works fine.

One other note: I thought that I had this combination working in an earlier prototype a few months ago, but that may have been with the Feather 32U4.

TIA.

The prototype code:
```
#include <Arduino.h>
#include <Adafruit_VS1053.h>
#include <Ethernet.h>
#include <IPAddress.h>
#include <SPI.h>
#include <Wire.h>

//
// Pins for the Ethernet and MusicMaker FeatherWings.
// NOTE: These definitions assume a Feather M4 Express with a PoE FeatherWing
//       modified to have its chip select on pin 14 because the default conflicts
//       with the MusicMaker's DCS pin.
//
#define VS1053_CS       6     // VS1053 chip select pin (output)
#define VS1053_DCS     10     // VS1053 Data/command select pin (output)
#define SD_CARD_CS      5     // Card chip select pin
#define VS1053_DREQ     9     // VS1053 Data request, ideally an Interrupt pin
#define ETHERNET_CS    14     // Ethernet chip select pin. Note that this is custom because the default conflicts with VS1053_DCS.

//
// PoE FeatherWing.
//
#define MAC_EEPROM_I2C_ADDRESS      0x50  // I2C address of the 24AA02E48 EEPROM chip that contains our MAC address (on the PoE FeatherWing).
#define MAC_EEPROM_REGISTER         0xFA  // Register within the 24AA02E48 that contains the first byte of our MAC address.

#define HANG      while( true ){ delay( 10 ); }
IPAddress         host = { 172, 24, 110, 1 };
uint16_t          port = 8000;
const char*       path = "/sounds/DingDong.mp3";
Adafruit_VS1053   player{ Adafruit_VS1053( -1, VS1053_CS, VS1053_DCS, VS1053_DREQ ) };
EthernetClient    client;
uint8_t           mp3Buf[VS1053_DATABUFFERLEN];
uint32_t          contentLength;
byte              macAddress[6]{};

uint32_t          beginRequest();
void              readMacAddress( byte* );

void setup()
{
  Serial.begin( 115200 );
  while( !Serial ){ delay( 10 ); }
  Serial.println( "MusicMaker/Ethernet Prototype" );

  Wire.begin();

  Ethernet.init( ETHERNET_CS );
  readMacAddress( macAddress );
  if( !Ethernet.begin( macAddress ))
  {
    Serial.printf( "Unable to initialize the network; hardware status is %d\n",
                   Ethernet.hardwareStatus());
    HANG;
  }

  Serial.print( "Mac address: " );
  for( int ii = 0; ii < 6; ii++ )
  {
    if( macAddress[ii] < 16 ) { Serial.print( '0' ); }
    Serial.print( macAddress[ii], HEX );
    if( ii < 5 ) { Serial.print( ':' ); }
  }
  Serial.println();
  Serial.print( "DNS IP:      " ); Serial.println( Ethernet.dnsServerIP());
  Serial.print( "Local IP:    " ); Serial.println( Ethernet.localIP());
  Serial.print( "Gateway IP:  " ); Serial.println( Ethernet.gatewayIP());
  Serial.print( "Subnet mask: " ); Serial.println( Ethernet.subnetMask());

  if( !player.begin())
  {
    Serial.println( "Unable to initialize the MusicMaker" );
    HANG;
  }
  Serial.println( "Initialized the MusicMaker" );
  player.setVolume( 40, 40 );
  player.sineTest( 0x44, 1000 ); // 1KHz tone for one second.

  contentLength = beginRequest();
  Serial.printf( "HTTP content length: %d\n", contentLength );
}

void loop()
{
  if( player.readyForData())
  {
    if( client.available() > 0 )
    {
      uint8_t bytesRead = client.read( mp3Buf, VS1053_DATABUFFERLEN );
      if( bytesRead > 0 )
      {
        player.playData( mp3Buf, bytesRead );
        contentLength -= bytesRead;
        if( contentLength <= 0 )
        {
          Serial.println( "That should be all of our sound" );
        }
      }
    }
  }
}

uint32_t beginRequest()
{
  if( !client.connect( host, port ))
  {
    Serial.print( "Unable to connect to " );
    Serial.print( host ); Serial.print( ':' ); Serial.println( port );
    HANG;
  }

  Serial.print( "GET " ); Serial.print( path ); Serial.print( " HTTP/1.1\r\n" );
  Serial.print( "Host: " ); Serial.print( host ); Serial.print( "\r\n" );
  Serial.print( "Connection: close\r\n\r\n" );

  client.print( "GET " ); client.print( path ); client.print( " HTTP/1.1\r\n" );
  client.print( "Host: " ); client.print( host ); client.print( "\r\n" );
  client.print( "Connection: close\r\n\r\n" );

  char http[] = "HTTP/";
  client.find( http );                  // Skip over the HTTP/ part of the header.
  client.parseFloat( SKIP_WHITESPACE ); // Skip over the HTTP version number.

  int httpStatus = client.parseInt( SKIP_WHITESPACE );
  if( httpStatus < 200 || httpStatus > 299 )
  {
    Serial.printf( "GET request failed; HTTP status is %d\n", httpStatus );
    client.stop();
    HANG;
  }

  char lengthHeader[] = "Content-Length:";
  client.find( lengthHeader );
  int contentLength = client.parseInt();

    char endOfHeaders[] = "\r\n\r\n";
  if( !client.find( endOfHeaders ))
  {
    Serial.println( "Invalid HTTP response (missing trailing line endings)" );
    client.stop();
    HANG;
  }
  return contentLength;
}

void readMacAddress( byte* addr )
{
  Wire.beginTransmission( MAC_EEPROM_I2C_ADDRESS );
  Wire.write( MAC_EEPROM_REGISTER );
  int failed = Wire.endTransmission();
  if( failed )
  {
    Serial.printf( "Unable to retrieve MAC address; endTransmission returned %d\n", failed );
    HANG;
  }

  byte* b = addr;
  int bytesRead = Wire.requestFrom( MAC_EEPROM_I2C_ADDRESS, 6 );
  if( bytesRead < 6 )
  {
    Serial.printf( "Unable to retrieve MAC address; fewer than six bytes\n" );
    HANG;
  }

  while( Wire.available())
  {
    *b++ = Wire.read();
  }
}
```

body:
Turned out to be a hardware problem.

The PoE FeatherWing's default CS pin conflicts with the MusicMaker's DCS pin. The PoE CS pin can be changed by cutting a trace on the back of the board and bodging a wire from a pad to whatever pin you want to use instead. I had done that.

Turns out though, that I hadn't cut it completely. This was causing the Ethernet library to pull the MusicMaker DCS low every time it pulled the Ethernet CS low.

I finally figured it out when I hooked up a logic analyzer to all of the CS pins and the SPI pins. It was very clear that MusicMaker DCS was going low with Ethernet CS.

Yay Logic Analyzer.


message:
String Comparison

I am trying to compare two string but each time i am getting awkward results. When i use Equals() function i always get the wrong answer and never satisfy the IF statement. When i use compareTo() function i always get the right answer (which is btw not correct) but it always just satisfy the IF statement.

```c++
String input;
String Answer = "cat";

void setup()
{
  Serial.begin(19200);
}

void loop()
{
  while (Serial.available() == 0)
  {
    Serial.readStringUntil('\n');
    if (input.equals(Answer))
    {
      Serial.println(input + ", Correct");
    }
    else
    {
      Serial.println(input + ", wrong");
    }
  }
}
```

Above is the code i am using to learn the string Comparison.

body:
You have defined a variable named `input`, but you never assign a value
to it. It should thus always have its initial value, which is an empty
string.

Here:

```c++
Serial.readStringUntil('\n');
```

you probably meant

```c++
input = Serial.readStringUntil('\n');
```


message:
Why use multiple filters output thousands value, use one or two filter can output normal value?

## Problem

If the loop runs only one simulated pin and uses a filter, it will output normally (analog 1600~2200, filter 0~500), but creating an array to store multiple filtered simulated pin values will cause problems, and the output will be abnormal (10000~80000).

![2022-04-15--15-00-07_fps=8_scale=720_max_colors=128|690x298](https://aws1.discourse-cdn.com/arduino/original/4X/6/9/5/6950edfbf1acdc9eed2746e95fa0e06828356b4f.gif)

If analog read six sensors, and their value is 1600~2200.

It used the code below.

```C
#include "EMGFilters.h"
#define SERIAL_TX_BUFFER_SIZE 4096 //修改串口接收缓冲区大小为2048
const int SensorInputPin[] = {A0, A1, A2, A3, A4, A5};
EMGFilters myFilter[6];
SAMPLE_FREQUENCY sampleRate = SAMPLE_FREQ_500HZ;
NOTCH_FREQUENCY humFreq = NOTCH_FREQ_50HZ;

void setup()
{

    for (int i = 0; i < 6; i++)
    {
        myFilter[i].init(sampleRate, humFreq, true, true, true);
    }
    Serial.begin(115200);
    Serial1.begin(250000);
    analogReadResolution(12);
}
void loop()
{
    long time = millis();
    int x[6] = {0,0,0,0,0,0};
    int analog[6] = {0,0,0,0,0,0};

    for (int index = 0; index < 6; index++)
    {
        //x[index] = myFilter[index].update(analogRead(SensorInputPin[index]));
        analog[index] = analogRead(SensorInputPin[index]);
    }
    while ((millis() - time) < 2)
    {
        delayMicroseconds(100);
    }
    Serial.printf("filter:%d %d %d %d %d %d analog:%d %d %d %d %d %d\n", x[0], x[1], x[2], x[3], x[4], x[5],analog[0],analog[1],analog[2],analog[3],analog[4],analog[5]);
    Serial1.printf("<%d,%d,%d,%d,%d,%d>", x[0], x[1], x[2], x[3], x[4], x[5]);
}
```

Change `index<6` to `index<2`, and uncomment `\\x[index] = myFilter[index].update(analogRead(SensorInputPin[index]));`

It will be a normal output using two inputs and filters.

![2022-04-15--15-15-26_fps=8_scale=720_max_colors=128|690x341](https://aws1.discourse-cdn.com/arduino/original/4X/5/e/9/5e9e39c25020a7816c04deb0cc7cdabc3f2de437.gif)

But changing `index=0;index<2` to `index=0;index<6` will be abnormal output.
![2022-04-15--15-29-32_fps=8_scale=720_max_colors=28|690x323](https://aws1.discourse-cdn.com/arduino/original/4X/e/b/c/ebc212b30692150bc1cfb0c29c4d9733a6195105.gif)

If changing to `index=3;index<4` or `index=2;index<3`...etc, it will be normal output:
![2022-04-15--15-15-43_fps=8_scale=720_max_colors=128|690x459](https://aws1.discourse-cdn.com/arduino/original/4X/0/5/8/05885f12cbba1c227d4f4349a169a8979a2f8caa.gif)

Sketch:
![image|470x500](https://aws1.discourse-cdn.com/arduino/optimized/4X/b/f/b/bfb266cf4e5eb7357b6804bb7bb3a9fbd7f75694_2_705x750.png)
![image|667x500](https://aws1.discourse-cdn.com/arduino/original/4X/5/5/3/553b46bb94559258b980463677a5bdee60e6a63d.png)
![](https://aws1.discourse-cdn.com/arduino/optimized/4X/1/b/c/1bccfe458e8f9843f7c8312806ff5909fd09b390_2_517x351.jpeg)
![](https://aws1.discourse-cdn.com/arduino/optimized/4X/d/1/4/d140c573d60e65c1333760ca63b1a9155da322bd_2_601x750.jpeg)
![](https://aws1.discourse-cdn.com/arduino/optimized/4X/6/e/c/6ec16040627057412528f8ec8bf60ee7da128bf1_2_273x373.jpeg)

XIAO MCU schematic in the HTML: https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/Seeeduino-XIAO-v1.0-SCH-191112.pdf

I don't have a sensor schematic.

Filter code: https://github.com/oymotion/EMGFilters/blob/master/EMGFilters.cpp

I hope each simulation output to look like the first Gif(normal output), what should I do to achieve this?

  [1]: https://i.stack.imgur.com/uzcRR.gif

body:
This is a bug in the filter library you are using. [It has already been
reported][bug] (by you, maybe?).

As Majenko and chrisl suggested in comments, the crux of the problem is
that you need one filter per input channel. Using multiple instances of
`EMGFilters` seems like the obvious solution. Alas, the library keeps
the filter state in global variables, which essentially means your six
filter objects all reference the same actual filter.

[bug]: https://github.com/oymotion/EMGFilters/issues/3


message:
How to prevent replacing of the value for a key in Preferences?

```
#include <Preferences.h>

Preferences preferences;

const char* roomname_long = "String 1";
const char* roomname_short = "String2";
const char* roomname_long_test = "String 3";
String roomname;

void setup() {
  Serial.begin(115200);
  preferences.begin("app",false);

  preferences.begin("credentials", false);
  preferences.putString("roomname_long", roomname_long);
  preferences.putString("roomname_short", roomname_short);
  preferences.putString("roomname_long", roomname_long_test);

  roomname = preferences.getString("roomname_long", "");

  Serial.println(roomname_long);
  Serial.println(roomname_short);
  Serial.println(roomname);

  preferences.end();
}

void loop() {

}
```

I try to save some data on my esp32 it works actually but if I try to save another variable with the same key it writes over the String before how can I interrupt that?

on the Serial Monitor I got this:

```
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1324
ho 0 tail 12 room 4
load:0x40078000,len:13508
load:0x40080400,len:3604
entry 0x400805f0
String 1
String 2
String 3
```

I want that if I put another variable in "roomname_long" key it must not be overwritten.

So it should be stay on String 1

body:
You can use `isKey` to test if the preferences key is already set.

```
preferences.putString("roomname_long", roomname_long);
preferences.putString("roomname_short", roomname_short);
if (!preferences.isKey("roomname_long")) {
  preferences.putString("roomname_long", roomname_long_test);
}
```


message:
Do I need to use resisters and ICes for specific sensors.What if I dont use it,Will it impact my arduino board some how like making it useless &faulty

So I was reading about `Simple AutomaticLight Controller using LDR.` or with the help of LDRSenso. But I have `LM393 Photoresistor (LDR) Sensor` I like to know are they same thing or somewhat different. So the way they work is detecting

`light intensity and It is associated with both analog output pin and digital output pin labelled as AO and DO respectively on the board.When there is light, the resistance of LDR will become low according to the intensity of light. The greater the intensity of light, the lower the resistance of LDR.`

And before that I was reading about `Analog Piezoelectricity Ceramic Piezo Vibration Sensor For Arduino`

So LDR sensor needs some kind of resister. And Analog Piezoelectricity Ceramic Vibration sensor needs some IC.

Can Anyone be specific to these specific resister and IC for each sensor types. I have them both as module for arduino Uno. I like to code in gcc avr. Thats how I am restricted. And will use C code to control but Can any please be briefly explain this type of resister for LDR sensor and Piezoelectric vibration sensor IC. Just few words to help me relate to some explanation and easily get poped in my mind when ever I hear about these two modules again. So Just some brief on this specific types of resister and IC related to these two modules why they needed how to code, and control through code

These are pictures of two sensors as Chrisl asked

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

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/K25Nd.jpg
  [2]: https://i.stack.imgur.com/tXirc.jpg

https://www.daraz.pk/products/i140816069-s1300868385.html?urlFlag=true&mp=1

https://www.daraz.pk/products/i162290793-s1329534669.html?urlFlag=true&mp=1

body:
Both images, that you included, show breakout boards. They are circuit boards (PCB - Printed Circuit Board), which contain all the components, that are needed to connect the corresponding part (in your case a piezo and an Light Dependent Resistor (LDR)). They are called this way, because they are "breaking out" simple output pins from the sensor circuitry for directly connecting them to the Arduino. So instead of having to build the circuit with the pure components you have a simple board, which gives you standard pin headers for connecting to the your Arduino. They are also often called "modules".

That means, that you don't need any additional circuitry or ICs to connect these boards to the Arduino. For the piezo sensor the image even shows the wiring diagram. You can see there, that you don't need any additional parts besides the breakout board, piezo and the Arduino itself. The same applies for the LDR breakout board.

**Connections:**

For the piezo sensor you have an analog output. Thus you need to connect that to an analog input on the Arduino (A0 to A7) and read the signal with `analogRead()`.

For the LDR breakout board I cannot be sure without a link to the product page, but it seems, that it has a digital output (DO). You can connect it to a digital input of the Arduino. It will switch between HIGH and LOW at a certain threshold brightness, which you can control by using a small screwdriver to rotate the little potentiometer on the board (the blue box with the hole in the middle).


message:
Can't figure out why what I'm trying to do isn't working. Trying to light up a RGB with buttons with AnalogWrite

DISCLAIMER : I have just started Arduino, like 2 days ago, I've been following some tutorials on YouTube, and I tried to do this myself, but I can't figure out why it isn't working, can't find what I'm doing wrong.

THE SETUP (I've already tested it with some other code that proved me that the setup is working, each buttons and each pin of the RGB LED, I know for sure that this is the code not working)

[![SIDE PICTURE][1]][1]
[![ABOVE PICTURE][2]][2]

I am trying to light up the led to RED thanks to second button (from LEFT), Green with third, Blue, with fourth, and the first one to put the LED off . I am aswell trying to make a perfect visual transition between each colors going from 255 to 0 decimal..

Here is my code :

```
#define BLUE 10
#define GREEN 11
#define RED 5

int buttonBlueOn = 9;
int buttonGreenOn = 8;
int buttonRedOn = 3;
int buttonRgbLedOff = 2;

void setup() {
  // put your setup code here, to run once:
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(buttonRedOn, INPUT_PULLUP);
  pinMode(buttonGreenOn, INPUT_PULLUP);
  pinMode(buttonBlueOn, INPUT_PULLUP);
  pinMode(buttonRgbLedOff, INPUT_PULLUP);

}

int redValue;
int greenValue;
int blueValue;

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

  // -------------------------------- RED ------------------------------ //

#define delayTime 20

  if (digitalRead(buttonRedOn) == LOW)
  {
    digitalWrite(RED, HIGH);
    redValue = 255;
  }

  if (digitalRead(buttonRedOn) == LOW and GREEN == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out green brings red full
    {
      redValue += 1;
      greenValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  if (digitalRead(buttonRedOn) == LOW and BLUE == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out blue brings red full
    {
      redValue += 1;
      blueValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(BLUE, blueValue);
      delay(delayTime);
    }
  }

  // -------------------------------- GREEN ------------------------------ //

  if (digitalRead(buttonGreenOn) == LOW)
  {
    digitalWrite(GREEN , HIGH);
    greenValue = 255;
  }

  if (digitalRead(buttonGreenOn) == LOW and RED == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out red brings green full
    {
      greenValue += 1;
      redValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  if (digitalRead(buttonGreenOn) == LOW and BLUE == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out blue brings green full
    {
      greenValue += 1;
      blueValue -= 1;
      analogWrite(BLUE, blueValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  // -------------------------------- BLUE ------------------------------ //

  if (digitalRead(buttonBlueOn) == LOW)
  {
    digitalWrite(BLUE, HIGH);
    blueValue = 255;
  }

  if (digitalRead(buttonBlueOn) == LOW and RED == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out red brings blue full
    {
      blueValue += 1;
      redValue -= 1;
      analogWrite(RED, redValue);
      analogWrite(BLUE, blueValue);
      delay(delayTime);
    }
  }

  if (digitalRead(buttonBlueOn) == LOW and GREEN == HIGH)
  {
    for (int i = 0; i < 255; i += 1) // fades out green brings blue full
    {
      blueValue += 1;
      greenValue -= 1;
      analogWrite(BLUE, blueValue);
      analogWrite(GREEN, greenValue);
      delay(delayTime);
    }
  }

  // -------------------------------- OFF ------------------------------ //

  if (digitalRead (buttonRgbLedOff) == LOW)
  {
    digitalWrite(GREEN, LOW);
    digitalWrite(RED, LOW);
    digitalWrite(BLUE, LOW);
  }

}

 ```

WHAT IT DOES : Nothing at all, nothing lights up, nothing happens, I'm a bit confused

I am so new to this, sorry if I'm doing something wrong on this forum

  [1]: https://i.stack.imgur.com/sSSQ8.jpg
  [2]: https://i.stack.imgur.com/zfT1A.jpg

body:
Your program makes things too complex. You should rethink your whole strategy.

My preferred method is to have a "target" colour and a "current" colour. When you press a button you simply change what your target colour is. And then every iteration through `loop()` (either slowed down with a short `delay()` or triggered with `millis()`) you compare the target and current colours, and if they differ then move the current colour a step closer to the target colour.

That way you remove all the logic of "if this is pressed but not this then fade between these two colours", instead it's just "if this is pressed then I want to go to this colour" and the changing of the colour is completely independent.

I [wrote a blog post](https://majenko.co.uk/blog/our-blog-1/flexible-led-fading-14) on the topic some time ago that you might find helpful.


message:
Changing I2C Address on Garmin LidarLite, resets on reboot

I am trying to change the I2C address of multiple Garmin LidarLite-V3. I am able to change them one at a time using the LidarLite C++ library using the setI2Caddr function, and can see the updated I2C address using i2cdetect. The problem is that when the LidarLite loses power and turns back on, the address is reset to the default 0x62. This means when I have multiple LidarLite connected in parallel, they all default to the same I2C address and I am unable to individually change the addresses using the setI2Caddr function. How can I change the I2C address so that it persists through a power cycle, or alternatively change the addresses when multiple LidarLite are connected in parallel?

body:
The [manual][1] of the Garmin Lidar Lite tells you about this. From page 5 under "Configurable I2C Address":

> This can be used to run multiple devices on a single bus, by enabling one,
changing its address, then enabling the next device and repeating the
process.
>
>The I2C address will be restored to default after a power cycle

So you cannot change the fact, that the I2C addresses will be reset to the default value on power cycle. But on startup you can give each sensor its own address. For that you need to wire the Power Enable pins to digital pins on the Arduino. When the digital pin is HIGH, the sensor is deactivated. So you start with all the Power Enable pins on HIGH. Then you set the first Power Enable pin to LOW, set the sensors I2C address via the corresponding I2C command and then proceed to the next sensor. When finished every sensor has its corresponding address and you don't get any collisions on the bus, since you always have only one sensor with the default address enabled at any time.

  [1]: https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf


message:
Which Arduino board would be sufficient for the following simulink project?

I'm trying to run a Fuzzy Logic MPPT Algorithm in Arduino UNO, [here's the Simulink File][1]

However when I try to upload the code, I get the following error

[![enter image description here][2]][2]

Is this project possible with UNO, if yes, what shall I do? Else which Arduino board would be suitable for this project?

  [1]: https://drive.google.com/drive/folders/1b2aHGw1rrPcKOgMciU1zWIJqr5E1oU8Y?usp=sharing
  [2]: https://i.stack.imgur.com/WDVDp.png

body:
We cannot answer about your Simulink program (since this site is only about Arduino). But currently you are using 3 times the RAM an Uno has. You can try to optimize your Simulink program, though I doubt that you will be able to reduce the needed memory that much.

So you should switch to a board with significantly more RAM. There are many to choose from, with different RAM, flash, peripherals, pin numbers. Write down all your requirements and then look for a fitting board


message:
Why is the server.on() function from "ESPAsyncWebServer.h" executed in the setup() side and not on the loop() side?

I'm implementing an example in which 2 ESP32's communicate each other using the HTTP Protocol. One acts as Server the other as Client. In the examples provided, I am curious about the declaration on the server, as its implementation is declared in the setup() function (I am using the standard Arduino IDE), which is supposed to have code that executes only once, rather than the loop() function (at least in this example), which is supposed to refresh the call every cycle, yet it remains empty:

```/* Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-client-server-wi-fi/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// Set your access point network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";

/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

String readTemp() {
  return String(bme.readTemperature());
  //return String(1.8 * bme.readTemperature() + 32);
}

String readHumi() {
  return String(bme.readHumidity());
}

String readPres() {
  return String(bme.readPressure() / 100.0F);
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  Serial.println();

  // Setting the ESP as an access point
  Serial.print("Setting AP (Access Point)…");
  // Remove the password parameter, if you want the AP (Access Point) to be open
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readHumi().c_str());
  });
  server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readPres().c_str());
  });

  bool status;

  // default settings
  // (you can also pass in a Wire library object like &Wire2)
  status = bme.begin(0x76);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // Start server
  server.begin();
}

void loop(){

}
```
You can see the "server.on(....)" declarations in the setup() side of the code, and the empty loop() function in the end.
```
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
```
So, my assumption is that the server is already running in the background when executing server.begin() and does not need to be explicitly called, but it still confuses me because there is no explicit declaration on the loop() such as server.loop() or something similar.
Can you explain how this works and why it is not necessary to explicitly declare the function on the loop()?

Thanks
-EZ

body:
`Server.on()` sets a *callback function*. That registers a function to be executed when a certain event happens at a later date. In this case it's when a certain URL is requested with a `GET` method.

Any time a request is made to the web server a list of "on" registered events is examined for one that matches the request, then the associated function (in this case a *lambda function*) is executed.

And all that is done *asynchronously* (hence the name) in the background in another thread so you don't need to explicitly do anything.


body:
The construct with a lambda function
```
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readTemp().c_str());
  });
```
is same as

```
server.on("/temperature", HTTP_GET, onGetTemperature);
```
where `onGetTemperature` is a function defined before `void setup()`
```
void onGetTemperature(AsyncWebServerRequest *request) {
  request->send_P(200, "text/plain", readTemp().c_str());
}
```
Would you in this case ask why it is "executed in the setup()?"


body:
Yes, `server.on()` is a callback function, but that's not the entirety of the story.

You don't see anything related to the server in `loop()` either, because somewhere in the backend of all that code, probably in `server.begin()`, the server attaches a callback or ISR of its own to the networking stack of the ESP. Now, when the ESP gets a message across the network of the right type, the networking stack redirects the message into the server's internal callback, at which point the server checks the page that was viewed and executes the appropriate `server.on`-specified function that you put in `setup()`.

I haven't yet had the chance to look into exactly how the server's callback is attached to the networking stack, but that's how it operates asynchronously. Either it's originally activated by a Wi-Fi hardware ISR (allowing it to temporarily pause your code's execution to run the server) or it's run by a small scheduler-like section of code that is executed outside of `loop()` (meaning that between iterations of `loop()`, it might be handling the server. It's probably this case since this is when some parts of the networking stack are handled anyway).

One minor note: this operation has a potential side effect of causing memory use or CPU use by the server when you might have *intended* to allocate either to your own application code, so if you start seeing odd timing errors or memory corruption on a *really* large application, you may want to look into this as a potential cause.


message:
Arduino Code is slow when running two task

[![This is the code][1]][1]

- I want pin 11 to give a square wave of once 3 sec

- and want pin 12 to act as a switch to glow pin 13 Built in led..

 - connected pin 12 to GND with 10k resistor

If i fed the switch code alone it is fast(the led turn on instantly), but when i fed this code (the on in picture) it has a 1 sec lag to turn on the led. why?

And also if i connect pin 11 to 12 i assume the builtin led should turn on and off according to the wave form coming out of  but the led is always low.

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

body:
Basically, the code comprises Two Parts

 1. Square Wave with 3-sec delay on and 3-sec delay off
 2. if the pin 12, is high pin 13 will be high and if 12 is low 13 is also low(a simple on/off switch)

---------

The second block of code executes only after the first Block of code is done executing.

That's why when I connected the pin 11 to 12 the led wasn't shining because when the WAVE code(that first block of code which gives a square wave) was running, the second block of code was quiet hence the 12th pin was still not become a switch yet.

And the delay I told was due to this, actually, the delay is 6 sec.
Because after the switch code completes its run, it will take a whole six seconds for the Arduino to come back to switch code in the loop because the wave signal of 3 sec on and 3 sec off should run.

if you want to run two tasks at the same time you need to learn the topics of millis() and protothreading.

----------

You can ask me why I was this dumb to ask a question like this, because the only programming language I have ever snorted is python and in there I learned python is an interpreter and it executes line by line, Since Arduino ide code is built around c++ which is the compiler.

I thought the code won't run line by line instead the code will be compiled but now only I understood that even though the file is compiled there is no chance every code can be run at the same time as the actual meaning of the compiler.


message:
How to know the data type of constant in arduino IDE?

For example constant of ```MSBFIRST```, It used to as input in ```SPI.setBitOrder(MSBFIRST)```. But sadly i don't know the type data of ```MSBFIRST```. This is applied to like ```SPI_MODE0``` and other.

body:
From SPI.h:

    #ifndef LSBFIRST
    #define LSBFIRST 0
    #endif
    #ifndef MSBFIRST
    #define MSBFIRST 1
    #endif

As you can see, there is no type. The compiler merely substitutes literally "1" for "MSBFIRST". So your code would read, after pre-processing:

     SPI.setBitOrder(1)

To know exactly what type "1" is (I'm not sure why you need to know) then you would look up "C++ integer promotion". In other words, how are literal integers handled by the C++ compiler.

---

From a comment:

> In which case it's better to look at the desired type of the destination function not the type of the macro or const.

Quite right. If you look further into the SPI.h file you see this:

      // This function is deprecated.  New applications should use
      // beginTransaction() to configure SPI settings.
      inline static void setBitOrder(uint8_t bitOrder) {

So, ignoring what type MSBFIRST is, you can see that the function expects uint8_t.


message:
How arduino PORTB pins are addressed if I want to access them with pointer?

So Let say I want to access Digital Pin 13. Thats port B pin. Is there an memory address associated with this pin 13 of Arduino Uno r3?

How Port B pins are addressed with corresponding pin numbers like What is the address of digital pin 13?

Currently I am assuming its pin address is `0x05` so my pointer looks like this

     uint8_t *adr=0x00+0x05;

Now If I do

      *adr |= 0x20;

then should I expect that I am writing to some pin so I like to know which data sheet I should refer for pin addresses of port B?

Currently my code is not working because no matter which pin I connect my LED to it blinks. What if I dont want to use any library and just write to address and I need PORT B pin address how to refer to different pins?

Now assume I have a code that uses avr gcc

    #include <avr/iom328p.h>//avr/io.h
    #include    <util/delay.h>
    #include <avr/sfr_defs.h>

    #define     BLINK_DELAY_MS  18000

    int main (void)
    {
        DDRB |= _BV(DDB5);

        while(1)
        {
            PORTB |= _BV(PORTB5);
            _delay_ms(BLINK_DELAY_MS);

            PORTB &= ~_BV(PORTB5);
            _delay_ms(BLINK_DELAY_MS);
        }

        return 0;
    }

What is the values correspond to `DDRB` and `_BV(DDB5);` and `PORTB` and `_BV(PORTB5);`? I like to do it with pointers so I need addresses of PORT B all pins I know the macros but I like the actual addresses . there should be a some datasheet for this what  its called. Does arduino has it that gives memory mapped addresses?

The above code is simply for blinking LED light

body:
The address of `PORTB` can be found in the [ATmega328P datasheet][328p],
section “I/O-Ports”, subsection “Register Description”. It is repeated
near the end of the section “Register Summary”, where it is documented
as:

    0x05 (0x25)

Admittedly, this is confusing: there are two addresses! There is a
footnote that gives some hint on the reason:

> When using the I/O specific commands IN and OUT, the I/O addresses
> 0x00 - 0x3F must be used. When addressing I/O Registers as data space
> using LD and ST instructions, 0x20 must be added to these addresses.

To clarify, this register is mapped in two different address spaces:

- It has I/O address `0x05`. The I/O address space is a small (6 bits)
  address space dedicated to I/O registers. It is actually too small to
  host all the I/O registers. It can be accessed with the `in` and `out`
  instructions. Addresses lower than 32 can also be bit-addressed with
  the instructions `sbi`, `cbi`, `sbis` and `sbic`.

- It has data address `0x25`. This is a much larger address space that
  gives access to all the I/O registers and to the RAM. It is used with
  the `ld`/`st` family of instructions.

Since the C and C++ languages are not aware of the I/O address space, a
regular data pointer is assumed to always point to the data address
space. Thus, if you want to create a pointer to this register, you may
write:

```c++
volatile uint8_t *adr = 0x25;  // PORTB
```

Note the `volatile` qualifier. This is required to prevent the compiler
being too “smart” and optimizing out some of your writes under the
assumption that this is just RAM.

Then you may turn the LED on with:

```c++
*adr |= 1 << 5;  // set PORTB5
```

Withe the proper optimization options, the compiler may be able to
optimize this into `sbi 0x05, 0x05`, if it can prove that the address
stored in the pointer doesn't change.

> I need addresses of PORT B all pins I know the macros but I like the
> actual addresses.

I would recommend this:

```c++
volatile uint8_t *adr = &PORTB;
```

This avoids having [magic numbers][] in your code, and makes the
programmer's intent clear.

One last comment. When compiling your code I got:

```text
include/avr/iom328p.h: [...]
error "Include <avr/io.h> instead of this file."
```

Just include `<avr/io.h>`: this header takes care of including both the
correct `<avr/iomXXX.h>` and `<avr/sfr_defs.h>`.

[328p]: https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf
[magic numbers]: https://en.wikipedia.org/wiki/Magic_number_(programming)


message:
Working with two analog sensors, ATmega16

I want to work with two analog sensors connected to [ATmega16][1]. The first one is the temperature sensor (LM35), connected to PA0. The LED should be ON when the temperature goes high. The second one is the photo-resistor and it's connected to PA1. I want to turn the LED ON when the lighting is low.
I was looking for a solution all over the internet, but couldn't find something similar to my situation. They all just say one thing- you can't read two analog sensors at the same time.

I have this code that works just for one sensor:

```c++
#define F_CPU 1600000UL
#include <avr/io.h>

void ADC_Init() {
    DDRA = 0x0;
    ADCSRA = 0x87;
    ADMUX = 0x40;
}

uint16_t ADC_Read(uint8_t channel) {
    ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC)) ;
    return ADC;
}

int main(void) {
    ADC_Init();
    DDRB = 0xFF;
    while (1) {
        uint8_t value;
        value = ADC_Read(0);
        if (value > 70) {
            PORTB |= (1<<0);
        } else {
            PORTB &= ~(1<<0);
        }
    }
}
```

Can you somehow help me to modify this code, give me advice on how can I do it, or some example?

  [1]: http://ww1.microchip.com/downloads/en/devicedoc/doc2466.pdf

body:
I just skimmed over the ATmega16 datasheet, so perhaps take this answer with a grain of salt.

It is technically true that you cannot read two ADC channels at the same time because there is only one ADC and you must multiplex the various channel inputs to that one ADC. You can, most likely, change the ADC source at runtime to switch between the different channels.

Take a look at the ADMUX register description in the [datasheet][1]

Right now, you set the mux once during the init() function and then never change it. In your new code, you will have to change the value in the register at runtime (in addition to any other configuration/housekeeping that is required) which should happen in your main loop()

High level description:

    int main()
    {
        system_init();

        while (1)
        {
            set ADMUX to read from PA0
            read ADC

            set ADMUX to read from PA1
            read ADC

            do stuff
        }

    }

  [1]: http://ww1.microchip.com/downloads/en/devicedoc/doc2466.pdf


message:
Arduino Wire library and Type Cast help

I'm having troubles understanding this line of code that I see with every Arduino EEPROM tutorial.
```
int saveLocation = 4095;
Wire.write((int)(saveLocation >> 8));
```
*Question 1:* Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

According to the wire library documentation, you can use `wire` to send the following:

```
Wire.write(value) // value to send as a single byte
Wire.write(String) // a string to send as a series of bytes
Wire.write(data, length) // an array of data to send as bytes, the number of bytes to transmit.
```

So my variable, `int saveLocation = 4095` is not a string or array, so it must be a considered as a 'value', which means it's being sent as 1 byte.

*Question 2:* If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

*Question 3:* If `saveLocation` is already an integer, why would cast it to `int`?

*Question 4:* Since `int` is two bytes, does `wire.write` only send out the lower byte?

Thanks in advance for the help.

body:
> Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

Yes. What's in the brackets is evaluated then the result cast to int.

> Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

You wouldn't.

> Question 3: If saveLocation is already an integer, why would cast it to int?

You wouldn't

> Question 4: Since int is two bytes, does wire.write only send out the lower byte?

Yes, just the lowest 8 bits.

The cast to an integer is completely redundant here. It's not performing anything other than making the code harder to understand. You can remove it and it won't make any difference.

In fact the presence of the int cast triggers an overloaded function:

    inline size_t write(int n) { return write((uint8_t)n); }

So it just re-casts it to an unsigned 8-bit integer (byte) anyway.


body:
You are right about being confused. This casting doesn't make any sense.

> Question 1: Do the parenthesis indicate that the bitshift happens BEFORE the type cast? What's the order of operations?

Yes, the bitshift happens before the casting because of the parentheses.

> Question 2: If it's being sent as 1 byte, why would I cast it to an integer of 2 bytes?

You wouldn't. It is cast to `uint8_t` (aka `byte`) anyway by the parameter type.

> Question 3: If saveLocation is already an integer, why would cast it to int?

Doesn't make sense to me either. You don't need to. Though it also doesn't hurt here (same goes for question 2)

> Question 4: Since int is two bytes, does wire.write only send out the lower byte?

Yes, only the lower byte. The function parameter is of type `uint8_t`, which is exactly one byte. Thats the reason for the bit shifting. By shifting the value right by 8 you effectively shift the high byte to the low byte position.


message:
ESP32: why does malloc can only alloc 126888 bytes with 402540 bytes heap?

I need a buffer of the size `153600 bytes` in my ESP32 project, but I could not create a static buffer in code nor can I `malloc` the buffer.

The ESP32 itself reports:
```
  ESP.getHeapSize()  // = 402540
  ESP.getFreeHeap()  // = 376980
  ESP.getPsramSize() // = 0
  ESP.getFreePsram() // = 0
```

`malloc(153600)` returns `NULL`; I wrote a little loop which decrements by one and retries to malloc. The first time it works is `malloc(126888)` so this seems to be the maximum buffer I can get.

*(I tried it with different boards; one from eBay and one from a genuine distributor - no differences.)*

Clearly the heap size is big enough. So I'm thinking that the RAM is possibly split into different chunks and no one is big enough for my buffer?

Is there any documentation which explains this behavior?

body:
Yes, the ESP32 memory is arranged in a number of different chunks. Those chunks are all aggregated by the memory manager to appear as a single heap, but they're actually separate.

As the [ESP-IDF documentation mentions](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/mem_alloc.html):

> At startup, all ESP-IDF apps log a summary of all heap addresses (and sizes) at level Info:
>
>     I (252) heap_init: Initializing. RAM available for dynamic allocation:
>     I (259) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
>     I (265) heap_init: At 3FFB2EC8 len 0002D138 (180 KiB): DRAM
>     I (272) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
>     I (278) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
>     I (284) heap_init: At 4008944C len 00016BB4 (90 KiB): IRAM

And of course you have some heap fragmentation from other threads allocating and deallocating memory, so the biggest contiguous block of memory you can allocate will be smaller than the biggest region.

To further illustrate I found this handy memory map on the Arduino forums:

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

There you can clearly see the SRAM is split into different chunks. The main reason for this is to better allow concurrent access by the two cores in the dual-core variants of the chip.

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


message:
Having trouble reading multiple thermistors w/ Arduino 2560

I'm trying to get my code to read multiple thermistors and I can't quite seem to get it correct using my arduino 2560. The first issue is it's not reading more than the first thermistor. The next issue is the for loop that displays the current temperature always reads "TURN OFF" when its below the 60C range.

Here is my code:

```lang-cpp
/* Here we have a few constants that make editing the code easier. I will go
  through them one by one.

  A reading from the ADC might give one value at one sample and then a little
  different the next time around. To eliminate noisy readings, we can sample
  the ADC pin a few times and then average the samples to get something more
  solid. This constant is utilized in the readThermistor function.
  */
const int    SAMPLE_NUMBER      = 10;

/* In order to use the Beta equation, we must know our other resistor
  within our resistor divider. If you are using something with large tolerance,
  like at 5% or even 1%, measure it and place your result here in ohms. */
const double BALANCE_RESISTOR0   = 10060.0; //
const double BALANCE_RESISTOR1   = 10000.0;
const double BALANCE_RESISTOR2   = 10000.0;
const double BALANCE_RESISTOR3   = 10000.0;
const double BALANCE_RESISTOR4   = 10000.0;
const double BALANCE_RESISTOR5   = 10000.0;
const double BALANCE_RESISTOR6   = 10000.0;
const double BALANCE_RESISTOR7   = 10000.0;
const double BALANCE_RESISTOR8   = 10000.0;
const double BALANCE_RESISTOR9   = 10000.0;

// This helps calculate the thermistor's resistance (check article for details).
const double MAX_ADC            = 1023.0;

/* This is thermistor dependent and it should be in the datasheet, or refer to the
  article for how to calculate it using the Beta equation.
  I had to do this, but I would try to get a thermistor with a known
  beta if you want to avoid empirical calculations. */
const double BETA               = 3977.0;

/* This is also needed for the conversion equation as "typical" room temperature
  is needed as an input. */
const double ROOM_TEMP          = 295.950;   // room temperature in Kelvin

/* Thermistors will have a typical resistance at room temperature so write this
  down here. Again, needed for conversion equations. */
const double RESISTOR_ROOM_TEMP = 10980.0;

//===============================================================================
//  Variables
//===============================================================================
// Here is where we will save the current temperature
double currentTemperature = 0;

//===============================================================================
//  Pin Declarations
//===============================================================================
//Inputs:
int thermistorPin0 = 0;  // Where the ADC samples the resistor divider's output
int thermistorPin1 = 1;
int thermistorPin2 = 2;
int thermistorPin3 = 3;
int thermistorPin4 = 4;
int thermistorPin5 = 5;
int thermistorPin6 = 6;
int thermistorPin7 = 7;
int thermistorPin8 = 8;

//Outputs:

//===============================================================================
//  Initialization
//===============================================================================

void setup()
{
 // Set the port speed for serial window messages
 Serial.begin(9600);
}

//===============================================================================
//  Main
//===============================================================================

//===============================================================================
//  Functions
//===============================================================================
/////////////////////////////
////// readThermistor ///////
/////////////////////////////

double readThermistor()
{
 // variables that live in this function
 double rThermistor0 = 0; // Holds thermistor resistance value
 double rThermistor1 = 0;
 double rThermistor2 = 0;
 double rThermistor3 = 0;
 double rThermistor4 = 0;
 double rThermistor5 = 0;
 double rThermistor6 = 0;
 double rThermistor7 = 0;
 double rThermistor8 = 0;

 double tKelvin0     = 0;            // Holds calculated temperature
 double tKelvin1     = 0;
 double tKelvin2     = 0;
 double tKelvin3     = 0;
 double tKelvin4     = 0;
 double tKelvin5     = 0;
 double tKelvin6     = 0;
 double tKelvin7     = 0;
 double tKelvin8     = 0;

 double tCelsius0    = 0;            // Hold temperature in celsius
 double tCelsius1    = 0;
 double tCelsius2    = 0;
 double tCelsius3    = 0;
 double tCelsius4    = 0;
 double tCelsius5    = 0;
 double tCelsius6    = 0;
 double tCelsius7    = 0;
 double tCelsius8    = 0;

 double adcAverage0  = 0;            // Holds the average voltage measurement
 double adcAverage1  = 0;
 double adcAverage2  = 0;
 double adcAverage3  = 0;
 double adcAverage4  = 0;
 double adcAverage5  = 0;
 double adcAverage6  = 0;
 double adcAverage7  = 0;
 double adcAverage8  = 0;

 int    adcSamples0[SAMPLE_NUMBER];  // Array to hold each voltage measurement
 int    adcSamples1[SAMPLE_NUMBER];
 int    adcSamples2[SAMPLE_NUMBER];
 int    adcSamples3[SAMPLE_NUMBER];
 int    adcSamples4[SAMPLE_NUMBER];
 int    adcSamples5[SAMPLE_NUMBER];
 int    adcSamples6[SAMPLE_NUMBER];
 int    adcSamples7[SAMPLE_NUMBER];
 int    adcSamples8[SAMPLE_NUMBER];

 /* Calculate thermistor's average resistance:
    As mentioned in the top of the code, we will sample the ADC pin a few times
    to get a bunch of samples. A slight delay is added to properly have the
    analogRead function sample properly */

 for (int i = 0; i < SAMPLE_NUMBER; i++)
 {
   adcSamples0[i] = analogRead(thermistorPin0);  // read from pin and store
   adcSamples1[i] = analogRead(thermistorPin1);
   adcSamples2[i] = analogRead(thermistorPin2);
   adcSamples3[i] = analogRead(thermistorPin3);
   adcSamples4[i] = analogRead(thermistorPin4);
   adcSamples5[i] = analogRead(thermistorPin5);
   adcSamples6[i] = analogRead(thermistorPin6);
   adcSamples7[i] = analogRead(thermistorPin7);
   adcSamples8[i] = analogRead(thermistorPin8);

   delay(10);        // wait 10 milliseconds
 }

 /* Then, we will simply average all of those samples up for a "stiffer"
    measurement. */
 for (int i = 0; i < SAMPLE_NUMBER; i++)
 {
   adcAverage0 += adcSamples0[i];      // add all samples up . . .
   adcAverage1 += adcSamples1[i];
   adcAverage2 += adcSamples2[i];
   adcAverage3 += adcSamples3[i];
   adcAverage4 += adcSamples4[i];
   adcAverage5 += adcSamples5[i];
   adcAverage6 += adcSamples6[i];
   adcAverage7 += adcSamples7[i];
   adcAverage8 += adcSamples8[i];

 }
 adcAverage0 /= SAMPLE_NUMBER;        // . . . average it w/ divide
 adcAverage1 /= SAMPLE_NUMBER;
 adcAverage2 /= SAMPLE_NUMBER;
 adcAverage3 /= SAMPLE_NUMBER;
 adcAverage4 /= SAMPLE_NUMBER;
 adcAverage5 /= SAMPLE_NUMBER;
 adcAverage6 /= SAMPLE_NUMBER;
 adcAverage7 /= SAMPLE_NUMBER;
 adcAverage8 /= SAMPLE_NUMBER;

 /* Here we calculate the thermistor’s resistance using the equation
    discussed in the article. */
 rThermistor0 = BALANCE_RESISTOR0 * ( (MAX_ADC / adcAverage0) - 1);
 rThermistor1 = BALANCE_RESISTOR1 * ( (MAX_ADC / adcAverage1) - 1);
 rThermistor2 = BALANCE_RESISTOR2 * ( (MAX_ADC / adcAverage2) - 1);
 rThermistor3 = BALANCE_RESISTOR3 * ( (MAX_ADC / adcAverage3) - 1);
 rThermistor4 = BALANCE_RESISTOR4 * ( (MAX_ADC / adcAverage4) - 1);
 rThermistor5 = BALANCE_RESISTOR5 * ( (MAX_ADC / adcAverage5) - 1);
 rThermistor6 = BALANCE_RESISTOR6 * ( (MAX_ADC / adcAverage6) - 1);
 rThermistor7 = BALANCE_RESISTOR7 * ( (MAX_ADC / adcAverage7) - 1);
 rThermistor8 = BALANCE_RESISTOR8 * ( (MAX_ADC / adcAverage8) - 1);

 /* Here is where the Beta equation is used, but it is different
    from what the article describes. Don't worry! It has been rearranged
    algebraically to give a "better" looking formula. I encourage you
    to try to manipulate the equation from the article yourself to get
    better at algebra. And if not, just use what is shown here and take it
    for granted or input the formula directly from the article, exactly
    as it is shown. Either way will work! */
 tKelvin0 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor0 / RESISTOR_ROOM_TEMP)));

 tKelvin1 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor1 / RESISTOR_ROOM_TEMP)));

 tKelvin2 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor2 / RESISTOR_ROOM_TEMP)));

 tKelvin3 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor3 / RESISTOR_ROOM_TEMP)));

 tKelvin4 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor4 / RESISTOR_ROOM_TEMP)));

 tKelvin5 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor5 / RESISTOR_ROOM_TEMP)));

 tKelvin6 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor6 / RESISTOR_ROOM_TEMP)));

 tKelvin7 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor7 / RESISTOR_ROOM_TEMP)));

 tKelvin8 = (BETA * ROOM_TEMP) /
           (BETA + (ROOM_TEMP * log(rThermistor8 / RESISTOR_ROOM_TEMP)));

 /* I will use the units of Celsius to indicate temperature. I did this
    just so I can see the typical room temperature, which is 25 degrees
    Celsius, when I first try the program out. I prefer Fahrenheit, but
    I leave it up to you to either change this function, or create
    another function which converts between the two units. */
 tCelsius0 = tKelvin0 - 273.15;  // convert kelvin to celsius
 tCelsius1 = tKelvin1 - 273.15;
 tCelsius2 = tKelvin2 - 273.15;
 tCelsius3 = tKelvin3 - 273.15;
 tCelsius4 = tKelvin4 - 273.15;
 tCelsius5 = tKelvin5 - 273.15;
 tCelsius6 = tKelvin6 - 273.15;
 tCelsius7 = tKelvin7 - 273.15;
 tCelsius8 = tKelvin8 - 273.15;

 return tCelsius0; // Return the temperature in
 return tCelsius1;
 return tCelsius2;
 return tCelsius3;
 return tCelsius4;
 return tCelsius5;
 return tCelsius6;
 return tCelsius7;
 return tCelsius8;

}

void loop()
{
 /* The main loop is pretty simple, it prints what the temperature is in the
    serial window. The heart of the program is within the readThermistor
    function. */
 currentTemperature = readThermistor();
 delay(3000);

 /* Here is how you can act upon a temperature that is too hot,
 too cold or just right. */
 if (currentTemperature > 0.0 && currentTemperature < 60.0)
 {
   Serial.print("It is ");
   Serial.print(currentTemperature);

 }
 else (currentTemperature >= 60.0);

 {
   Serial.print("It is ");
   Serial.print(currentTemperature);
   Serial.println("C. SHUT OFF!");
 }
}
```
I'm no expert in coding, so if you have any suggestions that could help, I would very much appreciate it.

body:
Welcome to Stack Exchange!

The problem causing the first issue is your multiple `return` statements in the `readThermistor` function. `return` exits the function, so when the code runs `return tCelsius0` it will exit the function and not run any of the later return statements.

Try storing your temperatures in an array and then returning that array. However, you also only read one of the values in the `main()` function anyway.

The problem causing the second issue is you have an `if` and an `else`. To properly check for your second condition `currentTemperature >= 60.0`, you need to have an `else if` instead.