message:
How do you use two piezos at the same time?

I'm trying to replicate a short music clip with two piezos, and I want them to play at the same time. While the right piezo is playing, I want the left one to still be looping. The problem is, I'm not sure how.

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

    //Left hand
    const int leftPin = 10; /Left pin
    const int leftTones[] = {123.4, 103.83, 138.59, 92.50}; //The looping left tones
    const int leftDelays[] = {700, 1300, 900, 900}; //How long those tones last
    const int leftNotes = 4; //How many left notes there are

    //Right hand
    const int rightPin = 2; //Right pin
    const int rightTones[] = {739.99, 587.33, 587.33, 659.25, 698.46, //The looping right tones
    659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 493.88,
    554.37, 587.33, 659.25, 587.33, 554.37, 880.00, 783.99, 739.99,
    587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33,
    659.25, 739.99, 987.77, 987.77, 1108.73, 1174.66, 783.99, 739.99,
    698.46, 1174.66, 1318.51};
    const int rightDelays[] = {700, 1000, 100, 100, 300, 300, 200, //How long those tones last
    300, 300, 200, 700, 700, 250, 150, 200, 400, 300, 300, 400, 200,
    700, 1000, 100, 100, 300, 300, 200, 400, 300, 200, 700, 700, 300,
    200, 400, 300, 200, 400, 300, 200};
    const int rightNotes = 40; //How many right notes there are

    void setup(){
        pinMode(leftPin, OUTPUT);
        pinMode(rightPin, OUTPUT);
        delay(1000);
    }

    void loop(){
      for (int i = 0; i < leftNotes; i++){
        tone(leftPin, leftTones[i]);
        delay(leftDelays[i]);
        noTone(leftPin);
      }
      for (int i = 0; i < rightNotes; i++){
        tone(rightPin, rightTones[i]);
        delay(rightDelays[i]);
        noTone(rightPin);
      }
    }
With this code, the left piezo plays first, and then the right piezo plays. It should be at the same time.

Edited Code:

    long currentMillis = 0;
    long leftPreviousMillis = 0; // previous time for left hand
    long rightPreviousMillis = 0; // previous time for right hand

    const int leftNotes = 4; // The amount of left notes
    const int rightNotes = 40; // The amount of right notes
    int leftIndex = 0; // The specific index for the left piezo
    int rightIndex = 0; // The specific index for the right piezo
    const int leftPin = 10; // The left piezo
    const int rightPin = 2; // The right piezo

    // The specific left pitches (as float)
    const float leftTones[] = {123.4, 103.83, 138.59, 92.50};
    // How long the left pitches last for
    const long leftDelays[] = {700, 1300, 900, 900};

    // The specific right pitches (as float)
    const float rightTones[] = {739.99, 587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 493.88, 554.37, 587.33, 659.25, 587.33, 554.37, 880.00, 783.99, 739.99, 587.33, 587.33, 659.25, 698.46, 659.25, 587.33, 554.37, 587.33, 659.25, 739.99, 987.77, 987.77, 1108.73, 1174.66, 783.99, 739.99, 698.46, 1174.66, 1318.51};
    // How long the right pitches last for
    const long rightDelays[] = {700, 1000, 100, 100, 300, 300, 200, 300, 300, 200, 700, 700, 250, 150, 200, 400, 300, 300, 400, 200, 700, 1000, 100, 100, 300, 300, 200, 400, 300, 200, 700, 700, 300, 200, 400, 300, 200, 400, 300, 200};

    void setup() {
      pinMode(leftPin, OUTPUT);
      pinMode(rightPin, OUTPUT);
      Serial.begin(9600);
      delay(1000);
      tone(rightPin, rightTones[rightIndex]);
      tone(leftPin, leftTones[leftIndex]);
    }

    void loop() {
      currentMillis = millis();
      // Left hand notes
      if (currentMillis - leftPreviousMillis >= leftDelays[leftIndex]) {
        noTone(leftPin); // Turn off the left note
        leftPreviousMillis = currentMillis;
        leftIndex++;
        if (leftIndex == leftNotes) // Reset left hand index
          leftIndex = 0;
        tone(leftPin, leftTones[leftIndex]); // Turn on the new left note
      }

      // Right hand notes
      if (currentMillis - rightPreviousMillis >= rightDelays[rightIndex]) {
        noTone(rightPin); // Turn off the right note
        rightPreviousMillis = currentMillis;
        rightIndex++;
        if (rightIndex == rightNotes) // Reset right hand index
          rightIndex = 0;
        tone(rightPin, rightTones[rightIndex]); // Turn on the new right note
      }
    }
I've done some testing, and I think it's a problem with the tones function. Right now, this code only plays the right hand notes. The problem is this part:

    tone(rightPin, rightTones[rightIndex]);
    tone(leftPin, leftTones[leftIndex]);

When I do this:

    tone(leftPin, leftTones[leftIndex]);
    tone(rightPin, rightTones[rightIndex]);

Only the left hand notes are heard. But, it's not perfect. There's little beeps and buzzes every now and then. This leaves me with the conclusion that if there are two tones at the same time, it only plays the one it reads first. I've tested it with simpler code, and it stands true.

So that begs the question, is it even possible to use two piezos at the same time with one Arduino? I'm testing it with the Arduino simulator tinkercad, so maybe that's the problem? My code works for the left piezo, and the right piezo. But when you put them together, everything messes up.

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

body:
> How do you use two piezos at the same time?

Consider using a [finite state machine][1] type of programming method.

As has been discovered, using calls to the [delay()][2] function (where the processor does nothing) blocks any other feature of the sketch (user's program). In a finite state machine programming pattern, there are no calls to the delay() function.  Instead the sketch's loop() function is allowed to execute as fast as possible. The trick is to control what code is executed in the loop() function based on a state machine.  And, in this case, use time to change between different states.

In an Arduino platform (the hardware and software you never or seldom see that makes up an Arduino) a counter is always tracking elapsed time.  Use the [millis() function][3] to retrieve the current value in milliseconds (1000 milliseconds = 1 second) each time through the loop() function. Consider using a 2 state state machine. In the 1st state get the current counter value, add to it the delay in milliseconds of the next note, start the note playing and finally change the variable tracking states to the 2nd state. The next time through the loop() function, while in the 2nd state, check if the response from calling millis() again is larger then the value saved while in the 1st state.  If it is, stop playing the note and change the variable tracking states to the 1st state.

Once working, create a second similar state machine to play the counter melody.

However, as [delta-g](https://arduino.stackexchange.com/users/33871/delta-g) has pointed out, the library picked out by the O.P. apparently can not play more than one note at a time.  But,[ve7jro](https://arduino.stackexchange.com/users/37523/ve7jro) has pointed out that [this Arduino tunes library](https://github.com/nathanRamaNoodles/Noodle-Synth) may be able to satisfy the requirement of playing 2 notes at the same time as stated in the O.P.'s question.

Creating a state machine in a invaluable programming lesson.  However, [this Arduino state machine library][4] is available should the programmer wish to take advantage of it.

  [1]: https://en.wikipedia.org/wiki/Finite-state_machine
  [2]: https://www.arduino.cc/reference/en/language/functions/time/delay/
  [3]: https://www.arduino.cc/reference/en/language/functions/time/millis/
  [4]: https://www.arduino.cc/reference/en/libraries/statemachine/


sender: user

sender: assistant

body:
It's always good to look at the documentation when you have a question about how a piece of code works.  In this case I looked at the page for the tone function which can be found here.  https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/

And the second sentence on that page says it all:

> Only one tone can be generated at a time. If a tone is already playing
> on a different pin, the call to tone() will have no effect. If the
> tone is playing on the same pin, the call will set its frequency.


message:
is #ifdef __SD_H__ considered a bad practice?

Say I'm working on a library^**1** to which I want to add support for `SD.h`^**2** but knowing for a fact that many microcotrollers don't support `SD.h` *(therefore they result in compilation errors [eg. Attiny85])* I don't want to just `#include <SD.h>` *(or even `#ifndef __SD_H__` then `#include <SD.h>`)* in `Mylibrary.h` and make it totally unusable for some microcontrollers. So I was wondering, is it considered ok to just add the functionality like...
```c++
// Mylibrary.h

#ifdef __SD_H__
    // Save functionality for those including `SD.h` to their `sketch.ino`
    void Mylibrary::save(String filename){
        SD.open(filename, FILE_WRITE)
        // ...
    }
#endif
```
...without ever including the `SD.h` in `Mylibrary.h` and hence force the user whenever he\she wants to use some SD functionallity, to just include `SD.h` in his\her `sketch.ino`?  **+***(it sound exhausting to do something like [this](https://github.com/GiorgosXou/NeuralNetworks/blob/31bb95e4cefcaefb28f6b031a634ded6c7274a7d/src/NeuralNetwork.h#L52-L55) for every MCU, as an alternative way)*

[**1**] *(in my case [this library](https://github.com/GiorgosXou/NeuralNetworks))*
[**2**] *(in my case  something related to [this](https://github.com/GiorgosXou/NeuralNetworks/issues/18#issuecomment-1792298022))*

**PS.** The reason I'm asking is because I don't remember seeing it anywhere being used that way and I'm slightly confused as to if this is the right or wrong thing to do so

body:
I don't think this will work, however you could try it and see. Just set the board type to something that doesn't support SD.h.

My problem would be that your library is a separate compilation unit (ie. file) that would be compiled against the things *you* put as header files.

If your library user uses SD.h in the main .ino file, then your library (which is compiled separately) would not know about that. In other words, it wouldn't know whether or not to *implement* the Mylibrary::save function.

I think a fairly simple solution would be to put a define in the include file for your library, eg.

    #define USE_FILE_SAVING false

Then check that in your code. You don't need a whole list of MCUs, just inform the user that if they want file saving implemented to change that one line.

---

For more information see [How the IDE organizes things](https://arduino.stackexchange.com/a/13182/10794)


body:
Yes, it is in general a bad practice to use include guard define to detect if the header file is included. It will work only in a header file in a compilation unit which includes the detected header file.

In Arduino all ino files of the sketch are one compilation unit. But every C or C++ file is a separate compilations unit. They would not 'see' the include guard from an include in the ino file(s).

If you want to use the include guard define, don't relay on it exclusively. Use your own define and set it if you detect the include guard. This way user can set it if theirs SD library has a different name for the include guard.

```
#ifdef __SD_H__
#define XY_USE_SD_LIB
#endif

#ifdef XY_USE_SD_LIB
    // Save functionality for those including `SD.h` to their `sketch.ino`
    void Mylibrary::save(String filename){
        SD.open(filename, FILE_WRITE)
        // ...
    }
#endif
```
I use this in my popular ArduinoOTA library [here](https://github.com/JAndrassy/ArduinoOTA/blob/5f838871e213474e7dabf70f2ddfc5ecb6cb971a/src/ArduinoOTA.h#L121).

There is other way to detect includes and it works across compilation units, but it doesn't work on all Arduino platforms. It is the `__has_include` 'directive'. I use it [here](https://github.com/JAndrassy/TelnetStream/blob/6005d8d917ee64a80417bae5b4b964cf7a6b3726/src/NetTypes.h#L42).


message:
Compilation error: 'Serial' does not name a type

```c++
#include <IRremote.h>

IRrecv IR (11);

Serial.begin(9600);

void setup() {
  // put your setup code here, to run once:
  IR.enableIRIn();
}

void loop() {
  // put your main code here, to run repeatedly:
  if (IR.decode()){
    Serial.println(IR.decodedIRData.decodedRawData, HEX);
    delay(1500);
    IR.resume();
  }
}
```

body: In C & C++, executable statements must be within a function. Your third statement, `Serial.begin(9600);` is (or should be) executable but since it is outside any function, the compiler tried to interpret it as a declaration - thus, the error.


message:
Just one more pin!

I have an Arduino project to control a motor's speed at 3 levels, indicated by 3 LEDs, so level 1 is speed 1 and LED 1, and so on for levels 2/3.

Also, I added a low-battery voltage indicator to monitor the battery level.

I am going to use an ATtiny45, which has 8 pins(Vcc, GND, 1 analog pin, 5 digital pins). The project needs 6 digital pins and 1 analog pin, so only one more pin is needed.

I do not want to use an expander or I2C, as they will make the project more complex, and it is only one pin!

I can use a larger microcontroller but it would be the last choice.

Here is my project's diagram and code:

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

    //********************************************^************************************************
    //  https://forum.arduino.cc/t/control-motor-speed-with-npn-and-push-button-no-driver/1184925
    //
    //
    //
    //  Version    YY/MM/DD    Comments
    //  =======    ========    ====================================================================
    //  1.00       20/23/02    Running code
    //  1.10       20/23/03    Added motor and LEDs OFF if switch pressed for >= 3 sec.
    //
    //
    //

    #define PRESSED            HIGH
    #define RELEASED           LOW

    #define ENABLED            true
    #define DISABLED           false

    #define LEDon              HIGH
    #define LEDoff             LOW

    #define MOTORoff           0

    #define lipo               A0

    float lipoV = 0;

    //GPIOs
    const byte Button        = 2;
    const byte ledpin        = 3;
    const byte ledpin1       = 4;
    const byte ledpin2       = 5;
    const byte Motor         = 9;
    const byte heartbeatLED  = 13;
    const byte Red           = 6;

    //Variables
    byte lastButton          = RELEASED;
    byte currSwitch;

    int Speed_Level;

    bool bCheckingSwitch     = DISABLED;

    //timing stuff
    unsigned long heartbeatTime;
    unsigned long switchesTime;
    unsigned long threeSecondTime;

    //                                      s e t u p ( )
    //********************************************^************************************************
    void setup()
    {
      pinMode(Button, INPUT);
      pinMode(lipo, INPUT);

      pinMode(ledpin, OUTPUT);
      pinMode(ledpin1, OUTPUT);
      pinMode(ledpin2, OUTPUT);
      pinMode(Motor, OUTPUT);
      pinMode(heartbeatLED, OUTPUT);
      pinMode(Red, OUTPUT);

    } //END of   setup()

    //                                       l o o p ( )
    //********************************************^************************************************
    void loop()
    {

      //************************************************              T I M E R  heartbeatLED

      //is it time to toggle the heartbeat LED ?
      if (millis() - heartbeatTime >= 500ul)
      {

        //restart this TIMER
        heartbeatTime = millis();

        //toggle the heartbeat LED
        if (digitalRead(heartbeatLED) == HIGH) digitalWrite(heartbeatLED, LOW);
        else digitalWrite(heartbeatLED, HIGH);
      }

      //************************************************              T I M E R  check switches
      //is it time to check our switches ?
      if (millis() - switchesTime >= 50ul)
      {
        //restart this TIMER
        switchesTime = millis();

        checkSwitches();
      }

      //************************************************              T I M E R  three seconds
      //if enabled, is it time to turn things OFF ?
      if (bCheckingSwitch == ENABLED && millis() - threeSecondTime >= 2000ul)
      {
        //we are finished with this TIMER
        bCheckingSwitch = DISABLED;

        //restart the sequence
        Speed_Level = -1;

        analogWrite(Motor, MOTORoff);
        digitalWrite(ledpin, LEDoff);
        digitalWrite(ledpin1, LEDoff);
        digitalWrite(ledpin2, LEDoff);
        digitalWrite(Red, LEDoff);
      }

    } //END of   loop()

    //                               c h e c k S w i t c h e s ( )
    //********************************************^************************************************
    void checkSwitches()
    {
      byte state;

      //************************************************              Button
      state = digitalRead(Button);

      //has there been a state change in the switch ?
      if (lastButton != state)
      {
        //update to the new state
        lastButton = state;

        //*******************************
        if (state == PRESSED)
        {
          //enable the TIMER
          bCheckingSwitch = ENABLED;

          //start the TIMER
          threeSecondTime = millis();
        }

        //*******************
        //the switch was released
        else
        {
          //disable the TIMER
          bCheckingSwitch = DISABLED;

          Speed_Level++;
          lipoV = analogRead(lipo);

          //battery checker
          if(lipoV < 680){
            digitalWrite(Red,LEDon);
          }

           else
           {
            digitalWrite(Red,LEDoff);

           }

          //don't go over 3
          if (Speed_Level >= 4)
          {
            Speed_Level = 0;
          }

          //*******************
          if (Speed_Level == 1)
          {
            analogWrite(Motor, 50);
            digitalWrite(ledpin, LEDon);
            digitalWrite(ledpin1, LEDoff);
            digitalWrite(ledpin2, LEDoff);
          }

          //*******************
          else if (Speed_Level == 2)
          {
            analogWrite(Motor, 75);
            digitalWrite(ledpin, LEDoff);
            digitalWrite(ledpin1, LEDon);
            digitalWrite(ledpin2, LEDoff);
          }

          //*******************
          else if (Speed_Level == 3)
          {
            analogWrite(Motor, 100);
            digitalWrite(ledpin, LEDoff);
            digitalWrite(ledpin1, LEDoff);
            digitalWrite(ledpin2, LEDon);
          }

          //*******************
          else
          {
            analogWrite(Motor, MOTORoff);
            digitalWrite(ledpin, LEDoff);
            digitalWrite(ledpin1, LEDoff);
            digitalWrite(ledpin2, LEDoff);
            digitalWrite(Red,LEDoff);
          }

      }

    }
    }//END of   checkSwitches()

    //********************************************^************************************************

Can I use tA0 as input and output at the same time like this?

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

Or can I reduce the LED pins, meaning use 1 pins for 2 LEDs?

  [1]: https://i.stack.imgur.com/tb4KJ.png
  [2]: https://i.stack.imgur.com/KnlLG.png

body:
You may try [charlieplexing][] your LEDs. Using only 3 digital pins
you can drive up to 6 LEDs. A web search for “charlieplexing
Arduino” should get you started.

[charlieplexing]: https://en.wikipedia.org/wiki/Charlieplexing


body:
As a (slightly hacky and binary :) ) suggestion, you could use just two LEDs and free up a pin with the following...

Level 1 - LED 1 on, LED 2 off

Level 2 - LED 1 off, LED 2 on

Level 3 - LED 1 on, LED 2 on

This is a really simple change to your current set up and code

Alternatively (as suggested by @dandavis) use a set of 3 neopixels and drive from just 1 pin


message:
Using Adafruit RTClib without fragmenting the heap

I'm getting ready to add DS1307 support to my Arduino app, and was *horrified* when I looked at the sourcecode for the RTC_DS1307 class in Adafruit's RTClib library...

~~~
DateTime RTC_DS1307::now() {
  uint8_t buffer[7];
  buffer[0] = 0;
  i2c_dev->write_then_read(buffer, 1, buffer, 7);

  return DateTime(bcd2bin(buffer[6]) + 2000U, bcd2bin(buffer[5]),
                  bcd2bin(buffer[4]), bcd2bin(buffer[2]), bcd2bin(buffer[1]),
                  bcd2bin(buffer[0] & 0x7F));
}
~~~

... and realized that it appears to be instantiating a new throw-away DateTime object on the heap every time you call now()... which AFAIK, is the **ultimate** Arduino C++ taboo.

I was about to tear into the class and rewrite it to reuse a singleton DateTime object that gets created once and reused forever... but then I remembered about return value optimization.

**Is** this actually a scenario where RVO will automagically kick in to save the day and prevent a heap-allocation (by pre-allocating space for the DateTime object on the caller's stack prior to calling `now()`), or is this library indeed doing something as taboo as I think it is?

body:
I think you are confusing the stack and the heap. For something to appear in the heap you would expect to see the words `new` or `malloc` which I don't see.

What is happening here is that a DateTime object is being created (in the stack frame of the current function) by `RTC_DS1307::now` which is being (presumably) copied into a variable of that type in the caller's stack frame when the function returns.

No memory is being wasted here.

---

> it appears to *literally* be instantiating a new throw-away DateTime object on the heap

What gives you that idea? The heap is not involved without you using `new` or `malloc`.

---

The heap is a block of memory used for dynamic memory allocation by using `malloc` or `new`, generally speaking. Typically it will be allocated past the place in RAM where variables are allocated (ie. after all the variables) and grow upwards, whereas the stack will be allocated at the end of available memory and grow downwards. Thus they don't clash until they collide, either by using too much stack (eg. by recursive function calls) or by allocating too much of the heap (by repeatedly calling `malloc` and without calling `free`).

When you use the heap, by using `malloc` you will get a *pointer* which you can then use, and pass around. That memory which you have reserved is yours until you free it, by literally calling `free`. In C++ something very similar is done by using `new` and `delete`.

If you don't call `malloc` or use `new` then you aren't using the heap, end of story.


body:
I wrote a minimal sketch that calls `RTC_DS1307::now()`, disassembled
it, and here is what I saw:

 * The caller allocates 6 bytes on the stack for holding the return
   value.

 * It writes the address of this stack location in the register pair
   r25:r24, as per the AVR calling convention,1 then calls
   `RTC_DS1307::now()`.

 * As the callee computes the fields of the resulting `DateTime` (by
   means of inlined calls to `bcd2bin()`), it writes them directly into
   the caller's stack frame, with no intermediate copy in RAM.

This looks to me like return value optimization.

**However**, in order to witness this behavior, I had to call
`RTC_DS1307::now()` _twice_. If the method is called from a single place
within the sketch, the compiler inlines it, and there isn't even a
function call to begin with.

Then, of course, the heap is never touched.

1 You would expect the `this` pointer to be passed as the
first argument, in r25:r24. It would seem it has been optimized out,
which makes sense given that there is only one `RTC_DS1307` object in
the whole sketch.


message:
Please help me with my project of water pump relay switching too fast

I have some problems with my project.

I'm using a water level sensor with two outputs, a 5V fan and a water pump. Here's the wiring [![project][1]][1].

What I want to do with this project is:
1. When the water reaches 2 cm, then the water pump is on while the fan is off.
2. When the water is less than 2 cm, then the water pump is off and fan is on.

The problem is, when the water is below the threshold, the sensor reading is quite unstable, thus making the relay switching too fast ([see the video][2]).

How to eliminate this problem?

```c
#include <Wire.h>
#include <Blynk.h>
#include <LiquidCrystal_I2C.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//Initialize the LCD display
LiquidCrystal_I2C lcd(0x27, 16, 2);
char auth[] = "xxx";//Enter your Auth token
char ssid[] = "xxx";//Enter your WIFI name
char pass[] = "xxx";//Enter your WIFI password
BlynkTimer timer;

#define pinSensor A0
#define PIN_RELAY_1  D3
#define PIN_RELAY_2  D4
const int startThreshold = 2; // pumping shall start at startThreshold [cm] and above
const int stopThreshold  = 1; // pumping shall start at stopThreshold  [cm] and below

int sensorValue = 0; // sensor reading integer
float tinggiAir = 0; // height of water
float sensorVoltage = 0; // voltage sensor
int nilaiMax = 686; // max value of sensor after fully drowning it in water
float panjangSensor = 4.0 ; // sensor's height in cm

enum StatusType {CHECKLEVEL, LEVELHIGH, PUMPING};
StatusType status = LEVELHIGH;   // Let's start with LEVELHIGH to check level and set the display correctly

void setup() {
  Serial.begin(115200);
  lcd.begin();
  Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
  lcd.backlight();
  pinMode(PIN_RELAY_1, OUTPUT);
  pinMode(PIN_RELAY_2, OUTPUT);
  digitalWrite(PIN_RELAY_1, LOW);
  digitalWrite(PIN_RELAY_2, LOW);
  lcd.setCursor(0, 0);
  lcd.print("Water level");
  lcd.setCursor(4, 1);
  lcd.print("Monitoring");
  delay(1000);
  lcd.clear();
  timer.setInterval(100L, wLevel);
}
void wLevel() {
   sensorValue = analogRead(pinSensor);
  tinggiAir = sensorValue*panjangSensor/nilaiMax;
  sensorVoltage = sensorValue*5.0/686;
}

void loop() {
      Blynk.run();
     timer.run();
     handleStatus();
}

void handleStatus() {
  switch (status) {
    case CHECKLEVEL:
      // Wait for level above threshold
      if (tinggiAir >= startThreshold) { // if wlevel more than startThreshold [cm], then
        status = LEVELHIGH;
        Serial.println("LEVELHIGH");
      }
      break;
    case LEVELHIGH:
      levelIsHigh();
      break;
    case PUMPING:
      if (tinggiAir < stopThreshold) { // if wlevel less than stopThreshold [cm] (use hysteresis!) then
        levelIsLowAgain();
        status = CHECKLEVEL;
        Serial.println("CHECKLEVEL");
      }
      break;
  }
  displayValues();
}

void displayValues() {
  static int oldSensorValue = -1; // variable untuk menampung nilai baca dari sensor dalam bentuk integer
  float oldTinggiAir = -1; // variabel untuk menampung ketinggian air
  float oldSensorVoltage = -1; // untuk menampung nilai ketinggian air

  if (oldSensorValue != sensorValue ||
      oldTinggiAir   != tinggiAir   ||
      oldSensorVoltage != sensorVoltage) {
    Serial.print("Sensor Value = ");
    Serial.println(sensorValue);
    Serial.print("Sensor Voltage = ");
    Serial.println(sensorVoltage);
    Serial.print("Tinggi Air = ");
    Serial.println(tinggiAir);
    Serial.println();
    // Display ke LCD
    lcd.setCursor(0, 0);
    lcd.print("WLevel:");
    lcd.print(tinggiAir);
    lcd.setCursor(12, 0);
    lcd.print("cm");
    oldSensorValue = sensorValue;
    oldTinggiAir   = tinggiAir;
    oldSensorVoltage = sensorVoltage;
    Blynk.virtualWrite(V0, tinggiAir);
  }
}
void levelIsHigh() {
  digitalWrite(PIN_RELAY_1, HIGH);
  digitalWrite(PIN_RELAY_2, LOW);
  lcd.setCursor(0, 1);
  lcd.print("F:OFF P:ON");
  Blynk.logEvent("wlevel", "wLevel more than 2cm");
  status = PUMPING;
  Serial.println("PUMPING");
}

void levelIsLowAgain() {
  digitalWrite(PIN_RELAY_1, LOW);
  digitalWrite(PIN_RELAY_2, HIGH);
  lcd.setCursor(0, 1);
  lcd.print("F:ON P:OFF");
  status = CHECKLEVEL;
  Serial.println("CHECKLEVEL");
}
```

  [1]: https://i.stack.imgur.com/U65Xi.jpg
  [2]: https://drive.google.com/file/d/1ZnZDB_p5DCyQzRFeX6tikA9K75JRICJK/view?usp=sharing

body:
The problem lies in the specification itself. According to your rules,
what should the pump do if the water level is _exactly_ 2 cm?
Granted, there is no such thing as an _exact_ physical measurement. But
you have to realize that _every_ measurement system is noisy. Noise is a
fact of life you have to cope with when playing with hardware. You may
try to make it smaller (by filtering), but it will always be there. Now
the question is: what should the pump do if the difference between the
water level and the required 2 cm is less than the noise amplitude?

The standard solution, as suggested by KIIV, is to implement some
[hysteresis][]. You define _two_ thresholds: one for turning the pump on
and another, lower threshold for turning it off. When the readings are
in between these two thresholds, you live the pump alone, in whatever
state it was before.

In pseudo-code:

```c
const float low_threshold = 1.9;
const float high_threshold = 2.1;

void loop() {
    float water_level = get_level_reading();
    if (water_level < low_threshold)
        turn_pump_off();
    if (water_level > high_threshold)
        turn_pump_on();
}
```

If the difference between these thresholds is larger than the noise
amplitude, noise will not disturb your system.

[hysteresis]: https://en.wikipedia.org/wiki/Hysteresis


message:
Use TCC1 timer to generate PWM on personnal board built with SAMD21E18A

I'm trying to generate a PWM signal from `TCC1`. I have a personnal board built with `SAMD21E18A`. I want to use pin 27 `PA30`, in my `variant.cpp` I have this line:

```c
{ PORTA, 30, PIO_PWM, PIN_ATTR_DIGITAL|PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, TCC1_CH0, EXTERNAL_INT_10 }, // SWCLK
```

I understand I can use `TCC1_CH0` on this pin with `PIO_TIMER`. Here is what I've tried at the end of my setup:

```c
  pinPeripheral(27, PIO_TIMER);
  pinMode(27, OUTPUT);

  ....

  Tcc* TC = (Tcc*)GetTC(TCC1_CH0);
  TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
  TC->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1;
  TC->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
  TC->PER.reg = 255;
  TC->CC[0].reg = 128;
  TC->CTRLA.reg |= TCC_CTRLA_ENABLE;
```

But it's not working: I have nothing on my pin.

Edit: I've also tried this in my setup:

```c
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(TCC1_GCLK_ID) |
                     GCLK_CLKCTRL_GEN_GCLK0 |
                     GCLK_CLKCTRL_CLKEN;
  while (GCLK->STATUS.bit.SYNCBUSY);

  Tcc* TC = (Tcc*) TCC1;
  TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE;

  TC->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;

  TC->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV1 |
                   TCC_CTRLA_RUNSTDBY;

  PORT->Group[PORTA].PINCFG[30].bit.PMUXEN = 1;
  PORT->Group[PORTA].PMUX[15].reg = PORT_PMUX_PMUXE_E;

  TC->CC[0].reg = 1000;
  TC->CC[1].reg = 4000;

  // Activer le timer
  TC->CTRLA.reg |= TCC_CTRLA_ENABLE;
  while (TC->SYNCBUSY.bit.ENABLE);
```

I have something on my oscilloscope, but the signal seems not to be good, HIGH signal is very very quick and low signal very long.

body:
For example, settings for ATSAMR21G18A (it is similar to you MCU), PA08 PWM:

Pin init:

    // GPIO PA08 PWM (DO)
    PORT->Group[0].PINCFG[8].reg = PORT_PINCFG_PMUXEN;
    PORT->Group[0].PMUX[8/2].bit.PMUXE = PORT_PMUX_PMUXE_E_Val; // TCC0/WO[0]

Timer init:

    void timer0_init()
    {
     GCLK->CLKCTRL.reg =   GCLK_CLKCTRL_ID_TCC0_TCC1 // Gen Clk Sel ID TCC0_TCC1
        | GCLK_CLKCTRL_GEN_GCLK0 // Generic clock generator 0
        | GCLK_CLKCTRL_CLKEN;  // Clock Enable

     PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1;  // Divide by 1
     PM->APBCMASK.reg |= PM_APBCMASK_TCC0;   // TCC0 APB Clock Enable

     TCC0->WAVE.reg = TCC_WAVEB_WAVEGENB_NPWM;

     TCC0->PER.reg = 80; //TCC0/WO[0] PWM 100kHz DT=50%
     TCC0->CC->reg = 40;

     TCC0->CTRLA.reg = TCC_CTRLA_CPTEN0 | TCC_CTRLA_ENABLE; // Enable
    }


message:
How to compile without adding the bootloader?

I'm using a standalone atmega328p with a 16MHz crystal.

I'm programming it via `avrdude` on a raspberry pi, using the SPI and RESET pins.

When I compile my program, this is what I see at the end of the output:

    ----------------
    Device: atmega328p

    Program:    4152 bytes (12.7% Full)
    (.text + .data + .bootloader)

    Data:        253 bytes (12.4% Full)
    (.data + .bss + .noinit)

As far as I understand, the bootloader is used to program the chip via UART, which I do not need(?). I'm assuming that the bootloader is still being compiled because of the output above containing `.bootloader` in the program part.

My program is compiled using the arduino SDK, with the following `Makefile`

    ARDUINO_DIR = /usr/share/arduino
    BOARD_TAG = uno

    include /usr/share/arduino/Arduino.mk

I went through `Arduino.mk` and found this on line `1626`:

    ifndef AVRDUDE_ISP_BURN_BOOTLOADER
        ifneq ($(strip $(BOOTLOADER_FILE)),)
            AVRDUDE_ISP_BURN_BOOTLOADER += -U flash:w:$(BOOTLOADER_PARENT)/$(BOOTLOADER_PATH)/$(BOOTLOADER_FILE):i
        endif
    endif

Which supposedly provides an option to turn off adding the bootloader but I couldn't figure out how to use it, so I just commented the line out:

    ifndef AVRDUDE_ISP_BURN_BOOTLOADER
        ifneq ($(strip $(BOOTLOADER_FILE)),)
            # AVRDUDE_ISP_BURN_BOOTLOADER += -U flash:w:$(BOOTLOADER_PARENT)/$(BOOTLOADER_PATH)/$(BOOTLOADER_FILE):i
        endif
    endif

But still, after compiling i see the `.bootloader` part and the program size remains the same.

Is it possible to tell it to skip adding the bootloader?

And yes, this is completely unnecessary for my application, I just want it, I want it bad.

body:
Seeing .bootloader section in size output doesn't mean it's really present. It just means the sum of all three is 4152 bytes.

You can check the hex file if it contains large block of data at the bootloader address space. The main program starts at the lower adresses and then there should be big gap and at the end bigger chunk of data with adresses in bootloader section (but only if you really have a bootloader).

But unless you program also BOOTRST fuse, it won't start in bootloader anyway.

Usage of `AVRDUDE_ISP_BURN_BOOTLOADER` is normal environment variable (can be also set inside of Makefile) and as it's tested for not being present so you can just check if it's not being set somewhere in Makefile


body:
I found [this question](https://stackoverflow.com/questions/46346816/understanding-flash-composition-of-arduino-bootloader) which shows that the bootloader's address space is `7800` to `7FF0`. I also confirmed that by taking a look at `atmega328p`'s bootloader hex file stored in `/usr/share/arduino/hardware/arduino/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex` and indeed the first line is this:

    :107800000C94343C0C94513C0C94513C0C94513CE1

*[Hex file format explained here.](https://en.wikipedia.org/wiki/Intel_HEX)*

So I then went back to my compiled hex file and checked whether there's anything at this address and there wasn't.

So apparently my program does not contain the bootloader.

I'm adding this as a separate answer with all the details because it took me some time to figure it out after reading [KIIV](https://arduino.stackexchange.com/users/23841/kiiv)'s answer, credit goes to him.


body:
I strongly doubt the compiler adds the bootloader. What that message is probably trying to tell you is that the bootloader is being included in its assumed address space.

There are various bootloaders, Optiboot is only 512 bytes. If you are programming directly (not via a bootloader) then the bootloader isn't required, of course.

If you program via SPI and set the BOOTRST flag appropriately then the processor will boot directly into your code which will save a small amount of time as the bootloader waits to see if there is any serial input for reprogramming. Plus, you get another 512 bytes for your code.

In your case, it hardly matters as the reported 4152 bytes is way short of 32 KB.


message:
Why my pushbutton always reads LOW?

This is the code I used in  my project

```
void setup() {
  Serial.begin(9600);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(5,INPUT);
}
void loop() {
  Serial.println(digitalRead(5));
  if(digitalRead(5)==HIGH){
    blink(12,100);
    blink(11,100);
    blink(10,100);
    blink(9,100);
    blink(8,100);
    blink(7,100);
    blink(6,100);
    Serial.println("blink done");
  }

}
void blink(int a,int b)
{
  digitalWrite(a,HIGH);
  delay(b);
  digitalWrite(a,LOW);
  delay(b);
}
```
[![Image of Tinkercad of my work][1]][1]

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

>Project link
https://www.tinkercad.com/things/55vY18FFxDR-blinking-led-wave/editel?sharecode=xQAM80Uu6sJ-hBnLLd04KasomJ2eNNzWLgKZMARe4ig

body:
When you press the button, you short the bottom blue (GND) and the bottom red (+5V) lines. That will in the least serious case cause your Arduino to reset, but could also damage the button, burn a wire or a capacitor, or brick your Arduino. There's some protection on the board to prevent serious damage or even injury to someone, but still you should **absolutely avoid** shorting +5V to GND.

The fix is actually quite simple: Replace the short blue wire with a large resistor, something like 10k. Then the Button will still read low when it's not pressed, but read high when it's pressed. That's called a "pull-down" resistor.


message:
Best Solution to Parallel UART reads with Arduino Due

I have 4 Arduino boards pushing data over UART to 4 serial ports on the Arduino Due at `115200` baud rate.

Data format - `<Short URL>,<Number of the Node>`

Eg: `px.ht/d/mCxG,1"`

Arduino Due has 4 hardware serial ports and one native USB port. I want to interface all the 4 UART nodes to each hardware serial of the Due and then push this data onto the `SerialUSB` port which is native USB at baud rate of `2000000`.

**What did I try?**

 1. Sequential read of all Serial ports - Obviously poor performance
 2. Used Serial Events - For some reason never able to get the callback triggered.
 3. Used some FreeRTOS library and there are a lot of data misses.

When using RTOS, the data from multiple nodes is getting mixed up and printed incorrectly. I'm looking for some efficient way to read parallel data from all UARTs without data overlap and stream data and given the MCU on Arduino Due is very powerful I don't think that's what is bottlenecking the performance.

body:
> It seems the arduino's wrappers for serial API's are very slow

They aren't. There are some functions that depend on timeouts: these can
indeed be very slow. However, if you read the ports in a _non blocking_
fashion, everything should be fast. Non blocking basically means never
waiting, and never trying to read more bytes than what is currently
`available()`. For example:

```c++
const int buffer_size = 64;  // tune to taste

char buffer1[buffer_size];
int size1 = 0;
// same for buffer2, size2, etc.

void loop() {
    while (Serial1.available()) {
        char c = Serial1.read();
        if (size1 < buffer_size - 1)
            buffer1[size1++] = c;  // buffer the incoming character
        if (c == '\n') {  // found end-of-message
            buffer1[size1] = '\0';  // terminate the string
            Serial.print(buffer1);  // send through USB
            size1 = 0;  // get ready for next message
        }
    }
    // then the same for Serial2, ...
}
```

If you know a bit about object oriented programming, you can easily
rewrite this in a more elegant way, with no repeated code.


message:
Make two LEDs fade in and out with with different PWM values

I have two UV leds, one Vf 3.3V @ 150 mA and the second one Vf 5V @ 150 mA. I need a circuit to make them fade in and out alternatively, *i.e.*, as one goes dimmer the other goes brighter and vice versa. I tried an Arduino PWM transistor approach with the Attiny85 board and the code below and it works, but I need the *ledPin2* led to work with at a lower *maxbrightness*. How can I modify the code so that I can set the *maxbrightness* for *ledPin2* to be around 25, while the *maxbrightness* for *ledPin1* remains 255 and yet both take the same time to fade in and out?

```
int ledPin1 = 0;
int ledPin2 = 4;
int minbrightness = 0;
int maxbrightness = 255;
int fadeAmount = 1;
int tim=4;

void setup()  {
   pinMode(ledPin1, OUTPUT);
   pinMode(ledPin2, OUTPUT);
}

void loop()  {
  analogWrite(ledPin1, minbrightness);
  analogWrite(ledPin2, maxbrightness);
  minbrightness = minbrightness + fadeAmount;
  maxbrightness = maxbrightness - fadeAmount;
  if (minbrightness == 0 || minbrightness == 255 ){
    fadeAmount = -fadeAmount ;
  }
  delay(tim);
}

```

body:
I don't think you have much choice than to come up with a sort of a counter and instead of having a single variable for the brightness of all the LEDs, you'll have to maintain a separate brightness variable for each channel which will have its own unique dimming profile. You'll then have to empirically determine how many counts it'll take for you to decrease/increase the PWM duty cycle on each separate channel (since perceived brightness isn't linear).

Something like this? The brightness of 32 and a modulo 8 was chosen to be a factor of 256, so it's more or less synced.

```
int ledPin1 = 0;
int ledPin2 = 4;
int brightnessLP1 = 0;  //begin with the LED off
int brightnessLP2 = 32; //begin with the LED on
int fadeAmount = 1;
int tim=4;

void setup()  {
   pinMode(ledPin1, OUTPUT);
   pinMode(ledPin2, OUTPUT);
}

void loop()  {
  //counter value accommodates the modulo below
  for(int brightnessCounter = 1; brightnessCounter < 257; brightnessCounter++) {

     analogWrite(ledPin1, brightnessLP1);
     analogWrite(ledPin2, brightnessLP2);
     brightnessLP1 = brightnessLP1 + fadeAmount;
     if(brightnessCounter  % 8) {
       brightnessLP2 = brightnessLP2 - fadeAmount;
     }
     delay(tim);
  }
  fadeAmount = -fadeAmount;
}
```

I'm sure you could make it cleaner or link the brightness values to the counter, but I'll leave that to you.


message:
Why isn't pin 6 on my Adafruit Feather RP2040 being sent high when I ask it to?

I have an Adafruit Feather RP2040 ([pinouts](https://learn.adafruit.com/adafruit-feather-rp2040-pico/pinouts)) connected via pin 6 to a [relay](https://www.adafruit.com/product/2895). The code (below) triggers the relay when a separate color sensor returns "enough" red values.

The color sensor works (confirmed by the serial print statements); the on-board LED (connected internally to pin 13) lights up when it should; but I don't get any voltage on pin 6 when I should. I'm testing the voltage with a standard multimeter. If I move my connecting wire from pin 6 to pin 13, I get voltage (and the relay activates). Why doesn't pin 6 get voltage? What else can I do to diagnose the issue?

Software versions:
* Arduino.CC IDE v2.2.1 (latest)
* Arduino IDE Board manager: added https://github.com/earlephilhower/arduino-pico, version 3.6.0 (latest)
* Adafruit APDS9960 Library from https://github.com/adafruit/Adafruit_APDS9960, version 1.2.3, released Jan 30 of this year. According to https://github.com/adafruit/Adafruit_APDS9960/tags there is a version 1.2.4 released on May 12th, but since this is just the light sensor code, which is behaving correctly, I don't believe the issue lies here.

Code:
```cpp
// copied & modified from the source at:
// https://github.com/adafruit/Adafruit_APDS9960/blob/master/examples/color_sensor/color_sensor.ino

#include "Adafruit_APDS9960.h"
Adafruit_APDS9960 apds;

// the pin on the feather that we're using to talk to the relay
#define PIN_TO_RELAY 6

#define BUCKET_FULL_RED 50

void setup() {
  // enable Serial communication
  Serial.begin(115200);

  // try to start the color sensor
  if(!apds.begin()) {
    Serial.println("failed to initialize device! Please check your wiring.");
  }
  else {
    // Assume success
    // Serial.println("Device initialized!");

    // we want color readings
    apds.enableColor(true);
  }

  // define the relay pin as an OUTPUT pin
  pinMode(PIN_TO_RELAY, OUTPUT);
  // start with the relay "open" AKA not running the pump
  digitalWrite(PIN_TO_RELAY, LOW);

  // use the built-in LED as an external signal for "pumping"
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // create some variables to store the color data in; unused, except for 'red'
  uint16_t red, green, blue, clear;

  // for checking the relay pin state
  int relay_pin_state = 0;

  // for extra printing
  int debug = 1;

  // wait for color data to be ready
  while (!apds.colorDataReady()) {
    delay(5);
  }
  // get fresh data; we only care about the red, but we have to read them all
  apds.getColorData(&red, &green, &blue, &clear);

  if (debug) {
    Serial.print("current red value is:"); Serial.println(red);
  }

  if (debug > 2) {
    relay_pin_state = digitalRead(PIN_TO_RELAY);
    if (relay_pin_state == HIGH) {
      Serial.println("steadystate: Relay pin is HIGH / enabled");
    } else {
      Serial.println("steadystate: Relay pin is LOW / disabled");
    }
  }

  if (red > BUCKET_FULL_RED) {
    if (debug) {
      Serial.println("start the pump (for 5 sec)");
    }

    // light up the built-in LED
    digitalWrite(LED_BUILTIN, HIGH);
    // "close" the relay to turn on the pump
    digitalWrite(PIN_TO_RELAY, HIGH);

    if (debug > 2) {
      relay_pin_state = digitalRead(PIN_TO_RELAY);
      if (relay_pin_state == HIGH) {
        Serial.println("pumping: Relay pin is HIGH / enabled");
      } else {
        Serial.println("pumping: Relay pin is LOW / disabled");
      }
    }

    // wait for a while for the pump to do its work
    // 5 sec in ms; TODO: eventually circa 4 min
    delay(5 * 1000);

    if (debug) {
      Serial.println("stop the pump");
    }

    // turn off the built-in LED
    digitalWrite(LED_BUILTIN, LOW);
    // "open" the relay to turn off the pump
    digitalWrite(PIN_TO_RELAY, LOW);
  }
  // no need to cycle quickly; wait 1 sec in ms
  delay(1 * 1000);
}
```

I just looked more closely at the pinouts page again, and was surprised to see the hole labeled "6" on the front is labeled "GP08" on the back, which corresponds to "GPIO8" in https://learn.adafruit.com/assets/107203. I wonder if I'm sending the "D4" pin HIGH ("GPIO6") instead of the one I'm expecting.

body:
The pin labeled as GP06 on the bottom side of the PCB is labeled as D4 on the top side of the PCB. It is pin 4.

from https://learn.adafruit.com/adafruit-feather-rp2040-pico/pinouts

> D4/GP06 - Digital I/O pin 4. It is also SPI0 SCK, I2C1 SDA and PWM3 A.


body:
Turns out I misled you with my ignorance. I took for granted that the thing labeled "6" on the front was in fact Pin 6, but it's not:

[![feather with pin "6" circled][1]][1]

Indeed, if I turn it over, that's "GP08":

[![reverse face of feather with the same location labeled "GP08"][2]][2]

... and so my code needs to use pin 8, not pin 6.

User [timemage](https://arduino.stackexchange.com/users/70020/timemage) pointed out similar confusion on a recent post: https://arduino.stackexchange.com/questions/94659/d1-mini-esp8266-no-sound-on-speaker where the silk-screened label on the front of the board did not match the actual pin number. They additionally point out a file that I would have never stumbled upon, but demonstrates this mapping: https://github.com/adafruit/circuitpython/blob/16c8c9a739cfe0db2c712696eb340de2d7944d41/ports/raspberrypi/boards/adafruit_feather_rp2040/pins.c#L24, namely:

~~~
    { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) },
    { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) },
    { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO7) },
    { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO8) },  /* right here */
    { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) },
    { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) },
~~~

The description of [the pinout](https://learn.adafruit.com/adafruit-feather-rp2040-pico/pinouts) still contains some misleading information, in my opinion:

> D6/GP08 - Digital I/O pin 6. It is also SPI1 MISO, UART1 TX, I2C0 SDA and PWM4 A.

Here, it seems to me that this spot is still being called "pin 6".

  [1]: https://i.stack.imgur.com/hLxZ2.jpg
  [2]: https://i.stack.imgur.com/zi9kS.jpg


message:
How to find out all #define used by arduino-cli in compile?

How to find out all `#define` used by `arduino-cli` in compile?

I had seen something some time ago, but I cannot find it again. I think that it was some option somewhere, and the result was that the compile did not end normally, but some generated file contained lots of useful and lots of obscure defined names.

I would like to find everything that's defined in my program, which I want to write, compile, and then run on different Arduinos, but it sometimes need different Serial to be used, different pin assignments, different internal buffer sizes and so on.

And I would like to organize the differences better, than just put all and everything to one big `#ifdef` - `#endif` for each extra platform.

Something like:

* if it does not have `Serial` but `Serial1`, `#define Serial Serial1`
* if it has 2kB RAM or less, set MY_BUF_SIZE to 10; if it has less than 3kB use 30, else use 100.
* but if it is `Micro Pro`, use this pin assignment, else if it is `Nano Every` use that, else issue error/warning for user, that pins need to be assigned.

And many others...

body:
I am not familiar with arduino-cli. If you can manage to find the `g++`
command line it uses for compiling your sketch, then you can get the
list you are looking for by using a modified version of that command:

* add the options `-E -dM`
* find the option `-o output_file` and change the name of the output
  file to something more appropriate.

---
**Edit**: Following a suggestion by @gilhad, you can build the required
command line by piping the output of arduino-cli through `sed`:

```shell
arduino-cli compile | \
    sed -n '/g++.*\.ino\.cpp\.o/{s/-MMD//;s/-o .*/-E -dM -o defines.dump/;p}'
```


message:
Reading serial data from Arduino in Python continually

Using a stepper motor and a range finder (TFLuna), I am trying to build a "Lidar" (like a Radar, but with light). Here is the algorithm:
- Turn motor one step, calculate angle, measure distance to whatever it hits, giving polar coordinates;
- Calculate Cartesian coordinates and send to Python;
- Collect a few hundred measurements and show the scatter plot.

This works, but only if I restart the sketch and the Python routine at the same time. After I collected all the data for one plot, I cannot restart the Python script to collect another round of data - it shows that there is no data in waiting. Also, the Arduino script never hangs due to the buffer getting full (as Python has stopped reading).

How can I make it so that the Arduino and the motor do their thing (swinging back and forth 180º, looking at stuff), and I am able to collect an amount of data in Python intermittently -- whenever I choose to restart the script one more time?

Here is the code. First, Arduino. "count" is the number of steps by which the motor has rotated; tflI2C is the range-finder object.

```cpp
#include <Stepper.h>
#include <Arduino.h>
#include <Wire.h>        // Instantiate the Wire library
#include <TFLI2C.h>      // TFLuna-I2C Library v.0.1.1
#include <math.h>

TFLI2C tflI2C;
int16_t  tfDist;    // distance in centimeters
int16_t  tfAddr = TFL_DEF_ADR;  // Use this default I2C address

const int stepsPerRevolution = 2048;  // change this to fit the number of steps per revolution

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
int stepCount = 0;         // number of steps the motor has taken

void serialFlush(){
  while(Serial.available() > 0) {
    char t = Serial.read();
  }
}

void setup() {
  // initialize the serial port:
  Serial.begin(115200);
  Wire.begin();           // Initalize Wire library
  myStepper.setSpeed(10);
  //myStepper.step(stepsPerRevolution/2);
  //delay(1000);
  //myStepper.step(-stepsPerRevolution/2);
}

void coordinates(int count){
  struct Polar {
    float angle;
    int16_t distance;
  } pPoint;
  struct Cartesian {
    float xCoord;
    float yCoord;
  } cPoint;

  float angle = count*(2.0*PI)/stepsPerRevolution;
  byte flag = 0;
  //Serial.flush();
  while (Serial.availableForWrite() < sizeof(struct Cartesian)){}
  if(tflI2C.getData(tfDist, tfAddr)){
    pPoint.angle = angle + PI/2.0;
    pPoint.distance = tfDist;
    cPoint.xCoord = pPoint.distance * cos(pPoint.angle);
    cPoint.yCoord = pPoint.distance * sin(pPoint.angle);
    if (pPoint.distance <= 50 ){
      Serial.write((char*)&cPoint, sizeof(struct Cartesian));
    }
  }
  return;
}

void loop() {
  // step one step:
  for (int k=0; k<stepsPerRevolution/4; k++){
    myStepper.step(1);
    coordinates(stepCount);
    stepCount += 1;
    delay(10);
  }
  for (int k=0; k<stepsPerRevolution/2; k++){
    myStepper.step(-1);
    coordinates(stepCount);
    stepCount -= 1;
    delay(10);
  }
  for (int k=0; k<stepsPerRevolution/4; k++){
    myStepper.step(1);
    coordinates(stepCount);
    stepCount += 1;
    delay(10);
  }
  delay(5000);
}
```

and here is Python:

```python
ardu = serial.Serial('/dev/cu.usbserial-1460', baudrate=115200, timeout=.1)
radarImage = []
structSize = struct.calcsize("ff")
ardu.reset_input_buffer()

i = 0;
while True:
    if ardu.in_waiting >= structSize:
        arduRead = ardu.read(structSize)
        point = list(struct.unpack("ff",arduRead))
        if i <= 10:
            print(point)
        radarImage.append(point)
        i += 1
    else:
        pass
    if i > 2000:
        break
ardu.close()
```

Here is a sample from a "first round" data collection. Yes, my desk is messy...

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

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

body:
> I am puzzled why the Arduino code isn't simply stopping at "Serial.availableForWrite()" when I stop reading data on the Python side -- it keeps on running.

This depends on the Arduino board used - specifically on if it has native USB support. Boards without native USB support (like Uno or Nano) use a second chip, which receives UART (Serial) data from the main chip and interfaces that to USB. The main chip cannot know about the state of the USB chip, so it will send regardless of a program listening.

Boards with native USB support somewhat depend on the OS/driver/program to collect the data from the USB endpoints. If your program doesn't collect that data, but also doesn't close the connection, then the data will pile up in the buffer and `availableForWrite()` should return 0 when the buffer is full (blocking further writing to Serial). But if your program closes the connection correctly (as it should on exiting), then the Serial data doesn't even get send, but discarded. See [Majenkos answer to this question][1], which is relevant here.

So generally: No, the Arduino won't stop sending data, only because you don't listen. Building a simple command system to tell the Arduino to start/stop sending data is a common way to handle this situation. Or you could implement a protocol, which lets the python script correctly detect start and end of each data packet.

  [1]: https://arduino.stackexchange.com/questions/72189/what-happens-to-serial-output-when-no-one-is-listening


message:
Need help with parsing NWS JSON weather alerts causing reset on ESP8266

I'm trying to parse the JSON string from the National Weather Service Alerts and am encountering a problem where the code can't parse the value and the device auto-resets.  I've used this code before on a different API to get the current weather conditions, and that works fine - I'm not sure what I'm doing wrong and would greatly appreciate any advice or help.  Thanks!

Here is the error:
<pre>
21:13:07.521 -> wdt reset
21:13:07.521 -> load 0x4010f000, len 3424, room 16
21:13:07.521 -> tail 0
21:13:07.521 -> chksum 0x2e
21:13:07.521 -> load 0x3fff20b8, len 40, room 8
21:13:07.521 -> tail 0
21:13:07.521 -> chksum 0x2b
21:13:07.521 -> csum 0x2b
21:13:07.521 -> v00045d00
21:13:07.521 -> ~ld
21:13:07.555 -> ����n�r��n|�l�l`b��|r�l�n��n�l`��r�l�l��
</pre>

And here's my code:
```
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>

const char* ssid     = "mySSID";                      // SSID of local network
const char* password = "myPassword";                 // Password on network

WiFiClient client;
char weatherServerName[] = "api.weather.gov";
String result;

//For testing change this zone to any zone from the NWS that's currently experiencing a weather alert
//Find an active alert area by going to https://api.weather.gov/alerts/active and looking for the code in the "affectedZones"
String zone = "LEZ144";

bool hasAlert = false;

void setup() {
  Serial.begin(115200);
  Serial.println("=====================================================================================================");
  Serial.println("Connecting");

  WiFi.begin(ssid, password);

            while (WiFi.status() != WL_CONNECTED)
            {
            delay(500);
            Serial.print(".");
            }

  Serial.println("Connected");
  delay(1000);
}

void loop() {
  Serial.println(":D");
  getWeatherAlerts();
  delay(100000);
}

void getWeatherAlerts()
{
  String server = weatherServerName;

  if (client.connect(server, 443))
       {
          client.println("GET /alerts/active?zone=" + zone);
          client.println("User-Agent: ArduinoWiFi/1.1");
          client.println("Connection: close");
          client.println();
          }
  else {
         Serial.println("connection failed");        //error message if no client connect
         Serial.println();
       }

                                       //waits for data
  while (client.connected() || client.available())
       {                                             //connected or data available
         char c = client.read();                     //gets byte from ethernet buffer
         result = result+c;
       }

  client.stop();                                      //stop client
  result.replace('[', ' ');
  result.replace(']', ' ');
  Serial.println(result);
  char jsonArray [result.length()+1];
  result.toCharArray(jsonArray,sizeof(jsonArray));
  jsonArray[result.length() + 1] = '\0';
  StaticJsonDocument<8196> root;
  DeserializationError error = deserializeJson(root, jsonArray);

  if (error)
    {
      Serial.println("parseObject() failed");
    }

  String features = root["features"];

  Serial.println(features);

  if(features.length() == 0)
  {
    Serial.println(features);
    hasAlert = false;
  }
  else
  {
    String severity = root["features"]["severity"];
    Serial.println(severity);
    if(severity == "Moderate" || severity == "Severe")
    {
      hasAlert = true;
    }
    else
    {
      hasAlert = false;
    }
  }

  Serial.println(hasAlert);
}
```

body:
By default, the size of the stack is [limited to 4KB](https://github.com/esp8266/Arduino/blob/3.1.2/cores/esp8266/cont.h#L27) on ESP8266, so you cannot store an 8KB document there.

To fix this issue, replace the [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/) with a [`DynamicJsonDocument`](https://arduinojson.org/v6/api/dynamicjsondocument/) to move the buffer to the heap.

See also: [Why does my device crash or reboot?](https://arduinojson.org/v6/issues/crash-or-reboot/)


body:
There is a good clue in the first line of your reported error:

    21:13:07.521 -> wdt reset

The ESP-8266 Watchdog Timer (WDT) will reset the device if it has not been correctly 'fed' for a period of time (the watchdog timeout).

As @Juraj noted, the ESP-8266 Arduino libraries 'helpfully' add WDT feeds at various points, suggesting the timeout is because your code is either crashing (overflowing into invalid program code) or is timing out (valid code, but stuck in a loop).

The backtrace information printed on the reset can be used to find where the WDT happened specifically in your code, so you can find the issue (which could be the one @Benoit Blanchon noted). I have found [this exception decoder][1] to be very useful to translate the code to the functions in your code.

Also worth noting that the 'garbled characters' after the WDT reset backtrace information is the bootloader startup message, which is fixed at 74880 baud, you can change baud rate of your serial terminal to see those (and 'garble' the other messages).

(Info about watchdog timers and feeding below isn't directly relevant in this case, as @Juraj noted, but is left in for context)

[This is an example document from TI introducing watchdog timers][2]. For the ESP8266, you might find [this techtutorialsx document][3] more useful. In summary, you need to either turn off the watchdog, or issue periodic

    ESP.wdtFeed();

commands. Turning off the watchdog is an appealingly easy option, but it disables a really useful tool to help you to make your project/product handle unexpected conditions/bugs more gracefully, so I'd encourage you to learn how to use it and then *feed* it as above.

(As @Benoit Blanchon noted, there are other issues on the implementation, which should be addressed, and perhaps deserve a separate post in code review. However I wanted to explain the reason for the reset you asked about, which isn't specifically JSON-related, and will continue to occur unless you take action as above)

  [1]: https://github.com/me-no-dev/EspExceptionDecoder
  [2]: https://e2e.ti.com/blogs_/b/powerhouse/posts/what-is-a-watchdog-timer-and-why-is-it-important
  [3]: https://techtutorialsx.com/2017/01/21/esp8266-watchdog-functions/


message:
ESP32 + Stepper Motor 17HS3401S + A4988 driver. Stepper cannot move in Clockwise direction

```
/*
 *   Basic example code for controlling a stepper with the AccelStepper library
 *
 *   by Dejan, https://howtomechatronics.com
 */

#include <AccelStepper.h>

const int DIR = 12;
const int STEP = 14;

#define motorInterfaceType 1
// Define the stepper motor and the pins that is connected to0
AccelStepper motor(motorInterfaceType, STEP, DIR); // (Type of driver: with 2 pins, STEP, DIR)

void setup() {
  // Set maximum speed value for the stepper
  motor.setMaxSpeed(1000); // Set maximum speed value for the stepper
  motor.setAcceleration(500); // Set acceleration value for the stepper
  motor.setCurrentPosition(0); // Set the current position to 0 steps
  Serial.begin(115200);
  //pinMode(32,OUTPUT);
}

void loop() {
  Serial.println("Moving to 800");
  motor.moveTo(800); // Set desired move: 800 steps (in quater-step resolution that's one rotation)
  motor.runToPosition(); // Moves the motor to target position w/ acceleration/ deceleration and it blocks until is in position
     // Move back to position 0, using run() which is non-blocking - both motors will move at the same time
  motor.moveTo(0);
  Serial.println("Moving to 0");
  while (motor.currentPosition() != 0) {
    motor.run();  // Move or step the motor implementing accelerations and decelerations to achieve the target position. Non-blocking function
    //
    //
  }
}
```
I tried using this code to check if my motor can move in a clockwise and anti-clockwise direction as stated by the tutorial. However it only manages to turn into anti-clockwise direction. I tried connecting the four motor pins to the driver as the order, the if the black wire is connected to the pin 2B of the driver, the motor will move anti-clockwise. Else if the black wire is connected to the pin 1B of the driver, the motor will move clockwise. I also have tried changing `motor.moveTo(800)` to `motor.moveTo(100)` and `motor.moveTo(0)` to `motor.moveTo(-100)` yet it still outputs the same thing. What is wrong with my code that may cause the motor to only move in one direction?

body:
I'm fortunate enough to know the cause. It's because of my fault in Wiring pins. At first, the orders on my driver pins (2B-2A-1B-1A) were black, green, blue, and red. Luckily, I came across this picture and changed the orders as in the pic. 2B-Black, 2A-Green, 1B-Red, 1A-Blue. It now can move towards both directions (clock-wise and anti-clockwise) [![enter image description here][1]][1]

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


message:
Arduino Uno, does a lower Aref voltage work well for measuring current? without increasing ADC integral non-linearity

I want to measure current using a Arduino Uno and use a very low resistance of 0.1Ohm or lower for the shunt resistor to measure the current(to reduce power waste and heat generation),
as a result resolution wouldn't be good at lower currents, while I do not need a very good resolution better resolution makes it more dependable and more easy to use and more universal.
and it is very unlikely that I would run close to that many amps through it, as for that it would need 10A of current to reach 1V.

**my idea to solve this was** to set the Aref to a lower voltage of 1.1V by setting it to the internal Aref this would mean it could measure up to 11A of current but also has 5 times as much resolution.

but I noticed people online seemed to never do this, and instead just use higher restance of 1Ohm or such or directly use a external higher resolution ADC(and still only use a small part of it) or some dedicated amp measuring hadware. so I started to wonder **does the internal ADC in the arduino behave worse when set to 1.1V aref instead of the default 5V aref despite the datasheet saying it can go down to 1V aref?**

setting the Aref inside of the arduino to the internal Aref of 1.1V and using a 0.1 Ohm resistor would give +-10mA resolution(up to 11A), if I where to use a 1 Ohm resistor like most others do it would even give 1ma resolution(up to 1.1A).

is there something I am missing? which is the reason why other people do not change the Aref for this?
**does lowering the Aref to 1.1V cause a reduction in the lineairity of the ADC curve(so that at some places the steps are a bigger difference than at some other places) compared to when it is kept to the default 5V Aref?**

or as a shorter more TLDR question:
-----------------------------------

**does anyone have graphs or data available about the linearity of the arduino ADC with the ADC Aref at different voltages?**
mostly to compare the linearity at a Aref of 1.1V and 5V.

**definitions**
---------------

ADC Linearity in this context refers to integral non-linearity

**extra**
---------

I already looked into those 4 sources:

 - https://arduino.stackexchange.com/questions/28663/can-i-supply-the-aref-pin-with-an-analog-pin-from-the-same-board
 - https://support.arduino.cc/hc/en-us/articles/360018922239-About-the-AREF-pin
 - https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/
 - https://electronics.stackexchange.com/questions/45664/voltage-limitations-on-aref-for-arduino
 - https://content.arduino.cc/assets/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf?#G1202563

they all seem to confirm exactly what I was thinking with my solution.
but none of them seem to give any info about how actually the Analog to Digital converter works on different Aref voltages, so for example if using a lower Aref might for example make the steps per volt less of a straight line and instead more of a curve or such where steps might all have different voltage difference differences?
the datasheet I found only gave a fixed offset value but not how or if it was affected by the used Aref voltage, and neither any form or graph or such of the typical integral non-linearity.
only one value that it has a integral non-linearity of 0.5LSB

## things people mentioned ##

 - apaerently the arduino ADC indeed has some non linearity, but no actual values are given and neither if it also depends on the Aref voltage, people mention/reffer that the arduino ADC should be most efficient at the middle value of the ADC https://arduino.stackexchange.com/a/69390/70020
 - to reduce energy wasting and maintain higher resolutions people recommend adding in a differential amplifier which would allow using even lower shunt resistors and still a good resolution. in theory this should do the same as changing the Aref, but then allowing even more sensitivity since the Aref can only go down to 1v so 5 times amplificaton

body:
If you used the 3.3 volt pin as external AREF a 1.5Ω resistor would drop 3V @ 2 Amps, 3V would produce an ADC value of 930 or 2.15mA per ADC count.
If you use the 1.1V internal AREF, a 0.5Ω resistor would drop 1V @ 2A, ADC values would be the same.


message:
The Arduino copy of example code for tone() function produces a compile error: 'tone' is not declared in this scope. How can I fix this?

It's 32-bit ARM core processor is SAM3X8E ARM Cortex-M3 CPU.

Error:

```
sketch_nov16b\sketch_nov16b.ino: In function 'void setup()': sketch_nov16b:49:43: error: 'tone' was not declared in this scope tone(8, melody[thisNote], noteDuration);
^ sketch_nov16b:61:13: error: 'noTone' was not declared in this scope noTone(8);
^ exit status 1 'tone' was not declared in this scope
```

Code:

```lang-cpp
/*

  Melody

  Plays a melody

  circuit:

  - 8 ohm speaker on digital pin 8

  created 21 Jan 2010

  modified 30 Aug 2011

  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/Tone

*/

#include "pitches.h"

// notes in the melody:
int melody[] = {

  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {

  4, 8, 8, 4, 4, 4, 4, 4
};

void setup() {

  // iterate over the notes of the melody:

  for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second divided by the note type.

    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.

    int noteDuration = 1000 / noteDurations[thisNote];

    tone(8, melody[thisNote], noteDuration);

    // to distinguish the notes, set a minimum time between them.

    // the note's duration + 30% seems to work well:

    int pauseBetweenNotes = noteDuration * 1.30;

    delay(pauseBetweenNotes);

    // stop the tone playing:

    noTone(8);

  }
}

void loop() {

  // no need to repeat the melody.
}
```

body:
In short, they just never implemented `tone()` in the Due/SAM core.
So you're not going to get the normal `tone()` function working.

* The tone.h [header is empty](https://github.com/arduino/ArduinoCore-sam/blob/790ff2c852bf159787a9966bddee4d9f55352d15/cores/arduino/Tone.h).
They probably should done any number of things that would produced a somewhat clearer warning about this.

* The counterpart .cpp file has been renamed to .cpp.disabled so that the no attempt is made to compile it and is [full of AVR-based code](https://github.com/arduino/ArduinoCore-sam/blob/790ff2c852bf159787a9966bddee4d9f55352d15/cores/arduino/Tone.cpp.disabled) that they'd copied into the project for reference with the intention of replacing it but never did.

There a [github issue](https://github.com/arduino/ArduinoCore-sam/issues/24) tracking this. But it hasn't been updated since 2020. That issue [references the Arduino forum](https://forum.arduino.cc/t/arduino-due-and-tone/133302) for apparently working alternative code for producing tones. So maybe try their code.

I don't see any popular alternative packaged as an Arduino library for producing simple tones. However, the chip has a DAC and there is an [Audio Library](https://github.com/arduino-libraries/Audio/tree/master). It's a bit overkill for producing basic tones, but you could modify [the example](https://github.com/arduino-libraries/Audio/blob/master/examples/SimpleAudioPlayer/SimpleAudioPlayer.ino) there to fill the buffer with a tone's waveform rather than loading it from an sdcard file.


message:
PubSubClient constructor parameter type mismatch

I am just learning an Arduino so this is totally educational purpose call.

I want to instantiate `PubSubClient` client with `WiFiClient` parameter.

```

#include <WiFiClient.h>
#include <PubSubClient.h>

WiFiClient *wifi = NULL;
PubSubClient client(wifi);

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}
```
compilation gives me back:
```
Compilation error: no matching function for call to /home/tepo/Arduino/libraries/PubSubClient/src/PubSubClient.h:116:4: note:   candidate expects 0 arguments, 1 provided
/home/tepo/Arduino/libraries/PubSubClient/src/PubSubClient.h:88:7: note: candidate: 'PubSubClient::PubSubClient(const PubSubClient&)'
 class PubSubClient : public Print {
       ^~~~~~~~~~~~
/home/tepo/Arduino/libraries/PubSubClient/src/PubSubClient.h:88:7: note:   no known conversion for argument 1 from 'WiFiClient*' to 'const PubSubClient&'

exit status 1

Compilation error: no matching function for call to 'PubSubClient::PubSubClient(WiFiClient*&)'
```
and listing all the other constructors.

type chain seems to hold:
`class WiFiClient : public ESPLwIPClient` -> `class ESPLwIPClient : public Client` -> `class Client: public Stream`

`PubSubClient` ctor:
```
 PubSubClient(Client& client);
```

so why is it not accepting a WifiClient as a parameter?

body:
The issue you're encountering with the PubSubClient constructor in Arduino is related to how you're passing the WiFiClient object. You're currently using a pointer (WiFiClient *wifi), but the PubSubClient constructor expects a reference to a Client object, not a pointer.

The WiFiClient class inherits from the Client, so it can be used with PubSubClient. However, you need to pass an instance of WiFiClient, not a pointer to an instance.

Here's how you can correct your code:

    #include <WiFiClient.h>
    #include <PubSubClient.h>

    WiFiClient wifi;
    PubSubClient client(wifi);

    void setup() {
      // put your setup code here, to run once:
    }

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

In this corrected version, wifi is an instance of WiFiClient, not a pointer. When you pass wifi to the PubSubClient constructor, it correctly matches the expected Client& client parameter type.

In C++ a pointer (WiFiClient *) is a variable that holds the memory address of an object.
A reference (WiFiClient &) is an alias for an object.
The PubSubClient constructor expects a reference because it needs to interact with the Client object throughout its lifecycle, and references are generally safer and more straightforward to use in this context than pointers.


message:
Use attiny85 reset pin as analog pin

I want to use the reset pin of the attiny85 as an analog pin to read the battery voltage, to be used as low level battery indicator.

So there is a lipo battery that will always be connected to this pin.

I need a high-voltage programmer to do so but I read that the reset pin can be simply an analog pin if the voltage to it is above 2.5v . Is it true?

If so, I can program it with Arduino SPI normally as the battery will never go below 2.5v.

Edit

Thanks @timemage for your answer, it really has good info.

But I can verify that if you give 5v to the Vcc of the attiny and connect a lipo (above 2.5v) to the reset pin, it will work as an analog pin.

I used a potentiometer and yes it is working, you can see more info about this as well in [this post][1].

The real info starts from Post#10.

It is really a complex situation here as what I did was using the reset pin as reset and as an analog pin at the same time. It is not recommended but it works!

Please if you can review the post in the Arduino forums and rewrite your thoughts here it will be useful for more people to get useful info.

  [1]: https://forum.arduino.cc/t/use-attiny85-reset-pin-as-input-switch/1189555/30

body:
The following was in answer to the question in [its original form](https://arduino.stackexchange.com/revisions/94863/1).

This is kind of more on an electronics question. But it may be of some interest people here, mostly because of Digispark clones that still have their reset functionality.

It's easier to answer these in a different order.

> I read that pin reset can be simply analog pin of the voltage to it is above 2.5v Is it true?
> If so, i can program it with arduino spi normally as the battery will never go below 2.5v

**Practically speaking the answer is best summarized as "no".**

It took me a while to realize what you were talking about, mostly because of
this 2.5V number, which I still don't completely understand. Originally I thought you talking about the internal 2.56V reference.  The way I'm interpreting this is **"As long as I don't actually cause a reset, is it true that I can use the ADC0 channel that is on the ATtiny85 RESET pin."**

Practically, I think no. But, this idea is amusing and also more than a little disturbing.  It seemed that the answer could be a qualified yes only because it seemed ATMEL would need to have done extra work to make this not possible, even if trying to do it is a bit nuts. Naturally, I had to try it.

In testing I found that yes, the RESET pin still seems to function as an ADC channel.  I was able to hook the division point of 2/3rds (ish) voltage divider to the reset and got a reading of 0xAD (as an 8-bit measurement) which is indeed about 2/3rds of 0xFF. At least this is the case with my particular chip under whatever operating conditions.

According to the datasheet the V_RST (nRESET pin voltage threshold)
is specified at 3V to be between 0.2 VCC and 0.9 VCC.  It doesn't seem like you would have good reason to think the chip is certain to stay out of reset below 0.9 VCC which at 5V is 4.5V. I did not experiment with mine to find out where the threshold happened to be except that 1/3 VCC did trigger a reset.

So, I don't know where your 2.5V comes from except to say it's a number near the middle of the possible V_RST range for an AVR at 5V. Even if you find this is where the threshold is for your chip, it isn't specified to be exactly there. The fact that I got a reading at 2/3rds instead of a reset does not seem specified to happen that way according to the datasheet.

Another thing about this is when the pin is used as RESET has its internal pullup is enabled, which is listed between 30K and 60K.  So whatever you connect to your reset pin (your battery) is connected to the AVR VCC through a pullup.

Anyway, it's interesting but is ultimately probably a bad idea.

> So there is a lipo battery will be always connected to this pin

If you want to play with this using-RESET-pin-for-ADC-channel thing anyway,
**definitely don't have your battery connected to reset when you program**, at least not without reasonable series resistance.  Otherwise when your programmer goes to reset your ATtiny85 **it will short your battery to GND through the programmer**.

> I want to use reset pin of attiny85 as analog pin to read the battery voltage to be used as low level battery indicator

**Voltage isn't a great indication of the state of charge** of batteries generally. Under some conditions you can get a rough idea with it. The flatter the discharge voltage curve is the less useful voltage is as an indication of charge state. Lithium chemistries are sort of prized for producing fairly flat discharge curves at a voltage level high enough to do useful work. Typically a "coulomb counting" method is used instead. Basically you sample current over time and integrate (sum) this, not reading instantaneous (or short term averaged) battery voltage. And that has its own intricacies with not drifting from true value. Getting a reasonable sense of lipo's state of charge is enough of a pain to do well that **there exist metering chips specifically designed to do this**.  I don't have good recommendations for them, but MAX17043 and MAX17048 are among the first part numbers for this sort of chip found on modules from suppliers of Arduino-related stuff.

> I want to use reset pin of attiny85 as analog

For most Arduino users it's really best to leave the reset pin alone. **The ATtiny84 is not much larger than an ATtiny85 and gives you an few extra pins** and is otherwise very similar. The ATtiny84 also supported by [attinycore](https://github.com/SpenceKonde/ATTinyCore). If you are hard set on using the ATtiny85 **make sure you've exhausted all your options for using your other pins**. There are ways to connect multiple switches to a single `analogRead()` capable pin. There are ways to put LEDs and switches on the same pin if you don't mind the light coming on when you push button, etc.

> I need high voltage programmer to do so but

Right, so back onto using non-RESET functionality of the RESET pin the normal way.

Sort of. **You don't need high voltage serial programming mode to program your code that use the reset pin onto the chip and then to disable the reset pin and use it via `digitalRead()`/`digitalWrite()`/`analogRead()`/etc.**. But **you do need high voltage mode to program again after that,** either by programming code via high voltage mode or programming (unprogramming really) the `RSTDISBL` fuse to re-enable RESET functionality that ISP/SPI mode requires. In other words: if you're treating the parts as one-time-programmable then you need only an ISP programmer. But, during development you're probably not going to want to just toss out piles of otherwise perfectly good chips.

If you're determined to use the ADC channel that's on the reset pin, programming RSTDISBL fuse is the thing you want to do. Then you get useful range out of the ADC channel and the ability to disable the pullup, and maybe even fewer random resets.

And yeah, you need a high-voltage mode programmer to recover from that, and you need to be either able to remove the chip from the board or design the board to handle HVSP signals coming to it; in particular to handle 12V that will be applied to reset.  Which is also something that should not make its way to your lipo.


message:
Arduino Nano Every USB Connection not working

I have two original (designed and assembled in Italy) Arduino Nano Every Boards from a German Web Shop. They came sealed in original packaging. When I try to connect them to my PC, they don't power up.

What I've tried so far:

  * 6 different USB cables
  * 1 Desktop PC with Arch Linux as well as Windows 10, all USB Ports available (front headers, back side motherboard)
  * 1 Laptop PC with Arch Linux
  * 1 Google Pixel 4 XL using a USB-B to -C adapter

No combination of the USB cables with any of the aforementioned USB Ports / Machines / Operating Systems allow the Arduino Nano Every Boards to boot up (no LEDs flashing).

I tried powering the boards using a 9V battery block on the V_in and GND pins, which works. I also tried powering the boards using a 9V battery block and then connecting the USB, but the aforementioned machines / operating systems do not recognize a new device connected via USB, despite the boards being powered (LEDs flashing).

I also triple-checked the physical connection of the USB cables on both ends to be sure they are inserted properly. I can use the aforementioned USB cables, USB ports, machines, and operating systems to charge other devices or transfer data with other devices (like, e.g., smartphones, e-book readers, USB flash memory sticks, external hard drives, ...).

What should I try next to get the Arduino Nano Every working?

Please let me know which extra information I should provide. Thanks!

Note: As far as I can see, using `lsusb` on Linux should always list connected USB devices, regardless of the groups my user's in. Nevertheless, I also loaded the `cdc_acm` module and added `SUBSYSTEMS=="usb-serial", TAG+="uaccess"` to a udev rule located at `/etc/udev/rules.d/01-ttyusb.rules`, and reloaded the udev rules, to no avail.

body:
These types of questions often requires considerable trouble shooting until the cause is found.  In order to make this useful to as many people as possible, let us compile a list of actions. *(Add a comment if any have additional actions to try and I'll add them to the list.)*

 - "...powering the boards using a 9V battery block on the V_in and GND pins..."

Confirm the 9V supply is connected to VIN. An internal voltage regulator will then provide the necessary 5V and 3V3 to the rest of the Nano-Every. Consider if 9V was accidentally connected to either the 5V or 3V3 pins, parts of the Nano-Every my be damaged.

 - "using lsusb on Linux should always list connected USB devices"

Yes, it should. If "lsusb" is typed before and after plugging in the Nano Every there should be an additional USB device listed.  If there is no change, there may be something physically wrong (bad cable or incorrect cable (i.e. charging only), bad Nano or burnt out part).

Also, "lsusb" normally does not require root privileges. But consider trying "sudo lsubs" to confirm all USB devices are seen.

Here is an example output of "lsusb" run when an Nano-Every was connected to a Ubuntu computer:

    $ lsusb
    ...
    Bus 001 Device 004: ID 2341:0058 Arduino SA Arduino Nano Every

 - "I also loaded the cdc_acm module ..."

Inspecting a Ubuntu system that can successfully program a Nano-Every, I see no package with the words cdc_acm in it installed.

*(I'm going to have to look into the above. While Ubuntu's package manager does manage cdc-acm.ko, cdc-acm.ko exists.)*

 - "...and added SUBSYSTEMS=="usb-serial", TAG+="uaccess" to a udev rule located at /etc/udev/rules.d/01-ttyusb.rules"

Be aware that adding a udev rule with a low value such as "01*" is likely to be obscured by any udev rule with a higher number should a match be found. Most developers add udev rules which start with a high number such as "99*" to mitigate this problem.

This said, it is unlikely a modification to udev rules is necessary. Most if not all Linux distributions will handle a [USB/CDC][1] type of peripheral adequately with out modifications. Plugging in a Nano-Every into the above mentioned Ubuntu computer generates a new device at /dev/ttyACM0.

 - "I tried powering the boards using a 9V battery"

Avoid using [PP3 type 9 Volt batteries][2]. They can be problematic when their lower current capacity has been reached.  At which point their output voltage may drop. Leading to unexpected results. If such a battery is necessary, pay close attention to current needs adding up all the expected maximum currents. In brief, lower powered processor on Arduino boards built using an [LDO (Low DropOut regulator)][3] have the best chance of working as expected. Other Arduino boards may not work as well and high current components such as a motor, solenoid or relay will likely not work.

  [1]: https://en.wikipedia.org/wiki/USB_communications_device_class
  [2]: https://en.wikipedia.org/wiki/Nine-volt_battery
  [3]: https://en.wikipedia.org/wiki/Low-dropout_regulator


body:
It's some regression in linux core and 1200baud touch doesn't work properly (it seems it's used switching between updi mode and serial link).

I started using script mentioned in https://github.com/arduino/ArduinoCore-megaavr/issues/124 and i was able to upload it in most cases (but better than mostly failing) when I execute it few seconds before the upload.

For example curiosity nano board with Atmega4809 works perfectly as it's emulating debugger+serial+mass storage (but needs correct VID/PID in udev rules or connecting storage)

Mentioned script:

<!-- language: python -->

    #!/usr/bin/python3
    #   Run this script to reset the Arduino Nano Every
    #   eg. sudo python3 mcu_reset.py
    #
    # Note: You must install pyserial first; i.e. sudo pip3 pyserial

    import serial
    import os, sys
    # total arguments
    n = len(sys.argv)
    if n >= 2:
        port = sys.argv[1]
    else:
        port = '/dev/ttyACM0'

    print("Port: {}".format(port))

    #re-enable hupcl temporarily (necessary for arduino reset using serial port)
    os.system('sudo /bin/stty -F {} hupcl'.format(port))

    try:
        #perform Arduino Nano Every reset "handshake"
        ser = serial.Serial()
        ser.baudrate = 1200
        ser.port = port
        ser.open()
        ser.close()

    except serial.SerialException:
        print("Error: serial.SerialException")
        exit()


message:
Is there a maximum length of an array in ROM?

Consider the following code:

```cpp
    #include <Arduino.h>

    unsigned char testimage [] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ... many more rows ...
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

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

        Serial.println("start");

        for (int i = 0; i < 10; i++) {
            Serial.println((int)(testimage[i]));
        }

        Serial.println("stop");

    }
    void loop()
    {}
```
I found out that then the array gets a certain size, there is nothing being sent to the serial monitor. It looks like the entire program freezes. I do not even see the `start` message appear.

I haven't tried to find the exact size, but it is somewhere between 4500 and 8000. (When sized around 4500, it works, when around 8000 it doesn't).

When I do not address the array though, I do see the `start` and `stop` messages appear.

I am using an Arduino ATMega2560.

body:
In this case the RAM size is the limit. And you'd need some space for stack/heap,..

If you use non-const array, it'll be copied from flash to RAM at the startup

On the mega2560 even using const it still be copied into the RAM as each FLASH/RAM/EEPROM has different address space

Only way would be using [PROGMEM](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/) and it can't be used directly (again different address spaces for flash/ram)

You can guess the mega2560 has 8KB RAM and you should keep some RAM for runtime. If there isn't enough of space, the stack and heap will be smashing each other and it would behave completely unpredictably (overwritten return addresses, runaway code and so on)


body:
It isn't clear whether you meant to put your array in ROM as your question implies, but the code you presented assigns it to RAM. That would surely restrict to your array to less than the 8K of of RAM minus whatever is needed by (globals + your libraries' statics + your code's statics + the stack).

Update:

> I assumed the data section of the code would end up in ROM.

In fact, an image of the *initialized data* section does become part of the ROM image. The initial values need to be saved somewhere so RAM can be initialized each time the program is(re-)started but it is not accessed from ROM during run-time. (Note we're not talking about PROGMEM data here, which *is* kept in ROM and accessed from there even at run-time.)


message:
PubSubClient hanging on ESP32C3

I may have done some things incorrectly here, but this I what I have for publishing image that I read from serial camera to the MQTT broker:

```
void capturePicture() {
  if (!cam.takePicture())
    client.publish("info", "Failed to snap!");
  else
    client.publish("info", "Picture taken!");

  char length[21];
  uint32_t jpglen = cam.frameLength();

  sprintf(length, "buffer length: %d", jpglen);
  client.publish("info", length);

  byte wCount = 0;  // For counting # of writes
  client.publish("info", "transfer about to begin");
  client.beginPublish("picture", jpglen, false);
  client.publish("info", "after beginPublish");

  while (jpglen > 0) {
    uint8_t* buffer;
    uint8_t bytesToRead = min((uint32_t)16, jpglen);  // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);

    client.write(buffer, bytesToRead);

    jpglen -= bytesToRead;
  }

  client.endPublish();
  client.publish("info", "transfer should have ended;");
}
```

I know the board is working, I am connected to the broker and I can receive messages.
In the `loop` I am reading few sensors and pushing the string into the topic
```
void loop() {
  delay(1000);

  if (count == 5) capturePicture();

  if (!client.connected()) {
    reconnect();
  }

  int multi = analogRead(A2);
  int odor = analogRead(A1);
  int voc = analogRead(A0);

  char name[21];
  sprintf(name, "%d;%d;%d", multi, odor, voc);

  bool pubScss = client.publish("measurement", name);

  count++;
  client.loop();
}
```
and all that works fine.

what happens when `capturePicture()` gets executed is this:

```
Picture taken!
buffer length: 49048
transfer about to begin
```
--that's what I see on the topic's subscriber side, then it freezes for about 10secs and then it continues with sending messages from the `loop`.

So it seems like it never gets past `client.beginPublish("picture", jpglen, false);` call.
I'm setting PubSubClient's buffer size to `client.setBufferSize(10235);`

What can be happening here? Something I can further test??

Thanks for advices!

body:
The short form of the below is something like: **"After calling `.beginPublish()`, call `.endPublish()` before making a call to either `.publish()` or `.beginPublish()`.**

---

We don't have your actual code. And that makes things difficult.
However, this is **a** source of problems in what you have shown:

```c++
  client.beginPublish("picture", jpglen, false);
  client.publish("info", "after beginPublish");
  ...
  client.endPublish();
```

It kind of looks like you may intended the second publish to help you debug the initial problem. But again, we don't have your code. I don't know if this (or something just like it) is in your original. In any case, it's not doing you any good as a debug aid.

---

The `.beginPublish()`/[`.write()`-type stuff]/`.endPublish()` constructs a message in the MQTT protocol as you make these calls.
**By inserting `.publish()` call between them you are corrupting the communication.** In short, you're embedding an MQTT message part way inside of another MQTT message.

Something a bit like saying
```
HowHello. are you today?
```

instead of

```
Hello. How are you today?
```

This is confusing something, probably the server. Perhaps also the library itself and any client that receives whatever the server ends up passing along.

---

I tested with a few variations on this code:

```c++
//#define CAUSE_TROUBLE

void one_shot_message() {
  client.publish(MQTT_TOPIC, "[hi]");
}

void do_test() {
  static const char part1[] = "<Hello";
  static const char part2[] = " World>";
  static const char both_parts_length = // just being very explicit
      (sizeof part1 - 1) // part1 sans null terminator
    + (sizeof part2 - 1);// part2 sans null terminator
                       // the .publish accepting strings doesn't null terminate, so we aren't.

#ifndef CAUSE_TROUBLE
  one_shot_message(); // okay before beginPublish or after endPublish
#endif

  client.beginPublish(MQTT_TOPIC, both_parts_length, false);
#ifdef CAUSE_TROUBLE
  one_shot_message(); // not okay between beginPublish/endPublish
#endif
  client.print(part1);
  // tested with one_shot_message() called here (not-okay location) as well
  client.print(part2);
  client.endPublish();
}
```

What happens in the case of `#define CAUSE_TROUBLE` (at the least with server I'm using and the client I've written on a PC) is that a single corrupt-looking message comes through and then the ESP32 client reconnects to the server. Probably the server is closing the connection. It does this on a cycle of about 6 seconds. The corrupt message has the correct topic, which makes *some* sense because the topic is written as part of the `.beginPublish()` before there's an opportunity to corrupt the message. This may not be exactly what you're seeing, but I don't have good cause to think I should be seeing exactly what you're seeing; not the same exact code, client, server. It is similar anyway.

---

So, you can have `client.publish("info", "before beginPublish");`
or a `client.publish("info", "after endPublish");` at those locations, but not between the begin and end calls. If you wanted to try doing something like that, you probably could probably do so by creating a second `PubSubClient` so that you could fire off these smaller messages in a separate protocol stream while in the middle of constructing/sending a larger message on the main stream.  However the messages may not arrive in order, either because the of how the library works or because of timing in the network. So if you want to do that you may also want to send a counter value with each message so you can reconstruct the timeline in the sending code.

An aside regarding `sprintf` vs `snprintf`:

```
  char name[21];
  snprintf(name, sizeof name, "%d;%d;%d", multi, odor, voc);
```

`sprintf()` is something that exists to support very old code or very old compilers.  There's otherwise no use case involving `sprintf()` that would not be better using `snprintf()`


message:
Feather M0 doesn't show up as a COM or Serial port

I am trying to upload a simple blink program on my Adafruit Feather M0 Radio with LoRa Radio Module to ensure that it connects to my PC. So far, I have:

 - Gone through 4 data cables
 - Tested for connection on 3 different devices (laptop on Windows 11, desktop on Windows 10, and computer running CentOS respectively)
 - Followed the direction for using the board with the IDE [here][1] and [here][2]

But the Port submenu is greyed out and when it isn't, it just doesn't have the port that recognizes my Feather. When going into Device Manager, I can't see it in the list of devices even when I refresh.

  [1]: https://learn.adafruit.com/adafruit-feather-m0-radio-with-lora-radio-module/setup
  [2]: https://learn.adafruit.com/adafruit-feather-m0-radio-with-lora-radio-module/using-with-arduino-ide

body: Turns out the bootloader/USB firmware wasn't loaded in, which is why the double-tap reset wasn't working. I looked into the option of using another board as a programmer to get the bootloader in my Feather, but it proved to be more of a hassle than I thought so I'm just going to get a replacement. Hope this helps someone out in the future.