message:
Trigger event onRelease of button

I am using the [EasyButton library](https://github.com/evert-arias/EasyButton) to detect button presses on an arduino.

I want do execute a function when the user

1. Presses a button
2. Presses and holds a button
3. Releases a button

Detecting when a user presses or holds a button is straight forward

```
#include <Arduino.h>
#include <EasyButton.h>
# define BUTTON_PIN 2;
EasyButton button(BUTTON_PIN);

void onPressedCallback() {
  Serial.println("Button was pressed and released");
}

void onHoldCallback() {
  Serial.println("Button was pressed and held");
}

void setup() {
  button.begin();
  button.onPressed(onPressedCallback);
  button.onPressedFor(buttonHoldDuration, onHoldCallback);
}
```

The easyButton library [has the following events](https://easybtn.earias.me/docs/on-single-press-api)

- onPressed
- onPressedFor
- onSequence

It has the following states

 - isPressed
 - isReleased
 - wasPressed
 - wasReleased
 - pressedFor
 - releasedFor

**How would you trigger an event when a button is 'released'?**

Full Documentation

https://easybtn.earias.me/docs/on-single-press-api

## What I've tried

1. Check the state from inside an event
```
void onHoldCallback() {
  while (button.isPressed() {
     Serial.println("you are still holding the button");
  }
  Serial.println("Button was released");
}
```

This unfortunately creates an infinite loop since the button state is never refreshed (button.begin();)

### Additional Resources

- https://github.com/evert-arias/EasyButton/tree/main/examples
- Source code for the system interupt https://github.com/evert-arias/EasyButton/blob/4e818410252e9518564fc55f8d4a976fac70a9b2/src/EasyButton.cpp#L55-L82

body: Just check the easyButton state in your loop code and run your functions as required. The library already has the events you need, no point rolling your own. It's best just to set a variable or flag in event code so it returns quickly, then deal with the results in the main loop. The easyButton library has done most of that work for you.


sender: user

sender: assistant

body:
The `onPressed()` event [Triggers a callback function when the button has been pressed and released][1].

Here's a test sketch to show what I mean. I've also added a function you could use to detect the moment the button is first pressed.

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

// EasyButton(uint8_t pin,
//            uint32_t debounce_time = 35,
//            bool pullup_enable = true,
//            bool active_low = true)
EasyButton button(2);

void onReleased(){
  Serial.println("Button Releast");
}

void firstPressed(){
  Serial.println("First Pressed");
}

void setup(){

  // Test output to serial monitor.
  Serial.begin(9600);

  // Initialize the button.
  button.begin();

  // Add the callback function to be called
  // when the button is pressed then released.
  // NOTE: This function is only called AFTER
  // the button has been released.
  button.onPressed(onReleased);

}

void loop(){

  // Continuously read the status of the button.
  button.read();

  // Call a function the moment the button is pressed.
  if(button.wasPressed()){
    firstPressed();
  }

}
```

  [1]: https://easybtn.earias.me/docs/on-single-press-api/


message:
Using Visual Studio Code to program an Arduino

I had recently got an Arduino Uno and did quite a few programs on it. Now, I had always used [Visual Studio Code][1] to do my C projects. So, is it possible to use Visual Studio Code to program an Arduino, but without the Arduino plugin available in Visual Studio Code?

This might sound a bit weird, but I wanted to learn how to build those type of plugins from scratch. Are there some resources from where I could learn to do that? I searched through Google, but I couldn't find any answers.

  [1]: http://arduino.cc/en/Main/ArduinoBoardUno

body:
This might not be the answer you are looking for, but maybe it helps you and others. Besides, it's too long to write as a comment.

 1. Use VS Code only as editor

    Make sure that your .ino file is as small as possible, typically, just enough to call a second file (.cpp or .c file). The idea is that you do not need to change the .ino file often as you need to load the .ino file only in your Arduino IDE. All other files (including the .ino) you load in VS Code.

    Than you edit your files in VS Code as asual, but you compile/upload the file with the default Arduino IDE. The Arduino IDE doesn't see files being saved as new, so that's why you need not to change the .ino file often, as you need to synchronize it manually.

 2. MS Visual Studio

    I'm using MS Visual Studio, comparable to VS Code and written stubs or even emulations for certain Arduino classes (like Arduino, but also for other libraries I use on the Arduino, which mimic or at least print something when called).

    This way I can fully compile an Arduino project, and most important, run it so I can check the business logic and some parts of the hardware logic on a normal PC having a decent debugger etc. When working, I can use the first solution to upload it to an Arduino.

    Writing these stubs is quite some work and the simulation can depend on the project (like for a LED strip project I actually visualized the LEDs on a PC).

 3. In both above cases, I use the Arduino IDE only for compiling and uploading, not for editing. It would be also useful to skip using this Arduino IDE completely by using a command line to compile/upload using the CLI version of Arduino (see comment of theBusyBee below. In at least Microsoft Visual Studio but probably Visual Studio Code external commands can be added calling this Arduino IDE for compiling/uploading.

4. PMF's comment below: You can use VisualMicro on top of  Microsoft Visual Studio; this is a paid extension.


body:
If you really looking for an alternate for Arduino IDE. Than I will recommends you to go with platformio. It has great library management.

Just install the platformio extensions on the vs code and you are ready to go.


body:
You can write C++ file with the editor of your choice, include `avr/io.h` to manage Arduino I/O, and then compile with avr-gcc and upload with avrdude. This is what I do because I don't like working with the .ino sketch directory structure that hides away normal C++ code that you would use with any other microcontroller. (See https://arduino.stackexchange.com/questions/40393/what-is-the-relationship-of-an-arduino-ino-file-to-main-cpp, https://arduino.stackexchange.com/questions/32619/why-does-an-ino-file-have-to-be-in-a-folder-of-the-same-name)

Guide: https://create.arduino.cc/projecthub/milanistef/introduction-to-bare-metal-programming-in-arduino-uno-f3e2b4


message:
Problem with displaying true RMS of the main voltage using Arduino Uno and MAX7219

I want to display the true RMS of the main voltage using an Arduino and a MAX7219. At first, I used of circuit #1 (the following circuit) and the [True RMS library](https://github.com/MartinStokroos/TrueRMS). The circuit could successfully return the true RMS and print it on the Serial Monitor of thr Arduino every 0.5 s. The accuracy was acceptable. This circuit was supplied from a PC.

[![Circuit #1][1]][1]

At the next step, I decided to use a MAX7219 (LedControl library) to display the true RMS voltage on a 7-segment display. For this, I used of circuit #2. I don't know what happened. The displayed voltage had variations. In circuit #1, the maximum error was 1 volt (checked by a true-RMS multimeter - for example, the voltage was 210 V and the printed voltage was 209 or 211 V). But in circuit #2, the error was up to 10 V with a fast variation. For example, the voltage was about 210 V (using multimeter) for a minute, but the displayed voltage by the Arduino was 203, then 209, then 217, then 205, then 200, then 215, ....

I also used another true-RMS multimeter to check the first multimeter. The voltage was the same value as the first one showed. The problem was that the voltage remained approximately constant, but the Arduino showed a variable voltage. I checked the supplied voltage from the PC. It doesn't have effective changes.

I also used of circuit #3, but I still had the same problem. It seems that the used of MAX7219 is causing the problem. What is the solution?

[![Circuit #2][2]][2]

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

My code (for bi-color common anode 7-segment - I have 3 digits):

    #include <TrueRMS.h>
    #include <digitalWriteFast.h> // It uses digitalWriteFast only for the purpose of debugging!
                                  // https://code.google.com/archive/p/digitalwritefast/downloads

    #define LPERIOD 1000    // 1000 loop period time in us. In this case 1.0ms
    #define ADC_INPUT 0     // define the used ADC input channel
    #define RMS_WINDOW 40   // rms window of 40 samples, means 2 periods @50Hz
    // #define RMS_WINDOW 50   // rms window of 50 samples, means 3 periods @60Hz

    #define PIN_DEBUG 4

    unsigned long nextLoop;
    int adcVal;
    int cnt = 0;
    float VoltRange = 5.00; // The full scale value is set to 5.00 Volts but can be changed when using an
                            // input scaling circuit in front of the ADC.
    Rms readRms; // create an instance of Rms.

    // Max7219 ===============================================================
    #include "LedControl.h"
    int ClockPin = 5;
    int CsPin = 6;
    int DinPin = 7;
    LedControl lc = LedControl(DinPin, ClockPin, CsPin, 1);
    // 1 as we are only using 1 MAX7219

    void setup() {
      Serial.begin(115200);
      pinMode(PIN_DEBUG, OUTPUT);

      // configure for automatic base-line restoration and continuous scan mode:
      readRms.begin(VoltRange, RMS_WINDOW, ADC_10BIT, BLR_ON, CNT_SCAN);
      //readRms.begin(VoltRange, RMS_WINDOW, ADC_10BIT, BLR_OFF, CNT_SCAN);
      // configure for no baseline restauration and single scan mode:
      //readRms.begin(VoltRange, RMS_WINDOW, ADC_10BIT, BLR_OFF, SGL_SCAN);
        readRms.start(); //start measuring
        nextLoop = micros() + LPERIOD; // Set the loop timer variable for the next loop interval.

      // Max7219
      // the zero refers to the MAX7219 number, it is zero for 1 chip
        lc.shutdown(0, false); // turn off power saving, enables display
        lc.setIntensity(0, 15); // 15 sets brightness (0~15 possible values)
        lc.clearDisplay(0); // clear screen
      }

    // Max7219
    byte board[1][8] = {
      {
        B00000000,
        B00000000,
        B00000000,
        B00000000,
        B00000000,
        B00000000,
        B00000000,
        B00000000
      }
    };

    //  Max7219             Device
    void ClearDisplay(int b, int digit) {
      for (int i=0; i<8; i++) { // It clears all segments of Digit "digit" of Device "n"
        bitClear(board[b][i], 7-digit);
      }
    }

    void Display() {
      for (int i=0; i<9; i++){
         lc.setRow(0, i, board[0][i]);
      }
    }

    //         Device  Digit      Num       Dot
    void SetNum(int b, int digit, int num, int dot) {
    switch(num) {
      case -2: // displays  "-"
        bitClear(board[b][0], 7-digit); // seg-A
        bitClear(board[b][1], 7-digit); // seg-B
        bitClear(board[b][2], 7-digit); // seg-C
        bitClear(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitClear(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case -1: // it clears the display
        bitClear(board[b][0], 7-digit); // seg-A
        bitClear(board[b][1], 7-digit); // seg-B
        bitClear(board[b][2], 7-digit); // seg-C
        bitClear(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitClear(board[b][5], 7-digit); // seg-F
        bitClear(board[b][6], 7-digit); // seg-G
        break;
      case 0:
        bitSet(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitSet(board[b][4], 7-digit); // seg-E
        bitSet(board[b][5], 7-digit); // seg-F
        bitClear(board[b][6], 7-digit); // seg-G
        break;
      case 1:
        bitClear(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitClear(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitClear(board[b][5], 7-digit); // seg-F
        bitClear(board[b][6], 7-digit); // seg-G
        break;
      case 2:
        bitSet(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitClear(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitSet(board[b][4], 7-digit); // seg-E
        bitClear(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case 3:
        bitSet(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitClear(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case 4:
        bitClear(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitClear(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitSet(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case 5:
        bitSet(board[b][0], 7-digit); // seg-A
        bitClear(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitSet(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case 6:
        bitSet(board[b][0], 7-digit); // seg-A
        bitClear(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitSet(board[b][4], 7-digit); // seg-E
        bitSet(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case 7:
        bitSet(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitClear(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitClear(board[b][5], 7-digit); // seg-F
        bitClear(board[b][6], 7-digit); // seg-G
        break;
      case 8:
        bitSet(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitSet(board[b][4], 7-digit); // seg-E
        bitSet(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
      case 9:
        bitSet(board[b][0], 7-digit); // seg-A
        bitSet(board[b][1], 7-digit); // seg-B
        bitSet(board[b][2], 7-digit); // seg-C
        bitSet(board[b][3], 7-digit); // seg-D
        bitClear(board[b][4], 7-digit); // seg-E
        bitSet(board[b][5], 7-digit); // seg-F
        bitSet(board[b][6], 7-digit); // seg-G
        break;
        default:
        break;
      }
      if (dot == 1) {
        bitSet(board[b][7], 7-digit); // seg-dp
      }
    }

    //                          0-1-2-3
    //                  Device  Digit      Num       Dot      Color
    void SetNumWithColor(int b, int digit, int num,  int dot, char color) {
      switch(color) {
        case 'r': // digits 0,1,2,3 are Red
          SetNum(b, digit, num, dot);
          SetNum(b, 4, -1, dot); // clears all Green segments
          SetNum(b, 5, -1, dot); // clears all Green segments
          SetNum(b, 6, -1, dot); // clears all Green segments
          SetNum(b, 7, -1, dot); // clears all Green segments
          break;
        case 'g': // digits 4,5,6,7 are Green
          SetNum(b, digit+4, num, dot);
          SetNum(b, 0, -1, dot); // clears all Red segments
          SetNum(b, 1, -1, dot); // clears all Red segments
          SetNum(b, 2, -1, dot); // clears all Red segments
          SetNum(b, 3, -1, dot); // clears all Red segments
          break;
        case 'o':
          SetNum(b, digit, num, dot); // Turns Red on
          SetNum(b, digit+4, num, dot); // Turns Green on
          break;
        default:
          break;
      }
      Display();
    }

    void loop() {
      adcVal = analogRead(ADC_INPUT); // read the ADC.
      // readRms.update(adcVal); // update
      digitalWriteFast(PIN_DEBUG, HIGH);
      readRms.update(adcVal); // for BLR_ON or for DC(+AC) signals with BLR_OFF
      // readRms.update(adcVal-512); // without automatic baseline restoration (BLR_OFF); substract a fixed DC offset in ADC-units here.
      digitalWriteFast(PIN_DEBUG, LOW);

      cnt++;
      if (cnt >= 1500) { // 500 = publish every 0.5s
        readRms.publish();
        float RMS=readRms.rmsVal;
        float AccRMS=RMS*128;
        int RMSout=AccRMS;
        Serial.print("Vrms=");
        Serial.print(RMSout);
        int a1=RMSout/100;
        int b1=RMSout0;
        int a2=b1/10;
        int a3=b1;
        if (RMSout<200) { // Red
          SetNumWithColor(0, 0, a1,  0, 'r'); // displays a1 at digit 0
          SetNumWithColor(0, 1, a2,  0, 'r'); // displays a2 at digit 1
          SetNumWithColor(0, 2, a3,  0, 'r'); // displays a3 at digit 2
        }else if(RMSout<215){ // Orange
          SetNumWithColor(0, 0, a1,  0, 'o'); // displays a1 at digit 0
          SetNumWithColor(0, 1, a2,  0, 'o'); // displays a2 at digit 1
          SetNumWithColor(0, 2, a3,  0, 'o'); // displays a3 at digit 2
        }else{ // Green
          SetNumWithColor(0, 0, a1,  0, 'g'); // displays 1 at digit 0
          SetNumWithColor(0, 1, a2,  0, 'g'); // displays 2 at digit 1
          SetNumWithColor(0, 2, a3,  0, 'g'); // displays 3 at digit 2
        }
        Serial.print(", Vin=");
        Serial.println(RMS,4);
        // float dc=readRms.dcBias;
        // Serial.println(dc,4);
        cnt=0;
        // readRms.start();  // Restart the acquisition after publishing if the mode is single scan.

      }

      while (nextLoop > micros());  // wait until the end of the loop time interval
      nextLoop += LPERIOD;  // set next loop time to current time + LOOP_PERIOD

    }

    // end of Measure_rms.ino

  [1]: https://i.stack.imgur.com/8ys1m.jpg
  [2]: https://i.stack.imgur.com/VdzUA.jpg
  [3]: https://i.stack.imgur.com/bjgva.jpg

body:
Without seeing your code it's hard to guess completely, but this is my supposition:

* The RMS measurement has to measure rapidly over a short period to capture the peak values of the AC waveform
* You are updating the display while doing the measurement
* The display updates slow down the sampling of the AC waveform giving you incorrect values.

You need to make sure that the sampling of the AC waveform happens fast enough by not doing anything else (much) during the sampling period and only displaying anything on the display when all the sampling for the current data point is done.


message:
How to connect Draw wire encoder to Arduino Uno?

Hello Stack Community,

I am new to Arduino, and I am trying to figure out how to connect a draw wire encoder to Arduino and collect data from it.

I have attached a link of the product that I currently have, which also has datasheet, incase anyone needs more information.

https://www.kuebler.com/en/products/measurement/linear-measuring-systems/product-finder/product-details/A30

I know that the encoder's output is through analog, but I am having trouble with connections as well.

To summarize, how can I connect the encoder to Arduino Uno?

Lastly, I am using the encoder to measure linear distance of linear actuators.

body:
The simplest way is to use the version with potentiometer output:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/tQtif.png)

<!-- End schematic -->

Connect the wiper to an analog input (A0 in the example), and use the analog reference voltage as "supply" voltage.


message:
Why modem driver is loaded and used from my linux machine in order to communicate with Arduino?

Once I plugin an arduino to my linux machine the following response is retrieved (via `dmesg`):

```
[ 7250.906241] perf: interrupt took too long (2504 > 2500), lowering kernel.perf_event_max_sample_rate to 79750
[ 9517.599165] usb 1-3: new full-speed USB device number 5 using xhci_hcd
[ 9517.749504] usb 1-3: New USB device found, idVendor=2341, idProduct=0043, bcdDevice= 0.01
[ 9517.749510] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=220
[ 9517.749513] usb 1-3: Manufacturer: Arduino (www.arduino.cc)
[ 9517.749516] usb 1-3: SerialNumber: 7533131313335170A061
[ 9517.780753] cdc_acm 1-3:1.0: ttyACM0: USB ACM device
[ 9517.781046] usbcore: registered new interface driver cdc_acm
[ 9517.781047] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters

```

The last line from dmesg caught my attention:

```
[ 9517.781047] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
```

Also as far as I remember in order to communicate with arduino my user needs to be into `dialout` group. Does that mean that a modem communication protocol is used in order to communicate from/to arduino in order to communicate via USB?

body:
The answer to that is one of history.

There was a time when the main purpose of the serial port (RS-232/UART) was to "dial out"; i.e. it had a serial connection to a modem, fax machine or a mainframe attached. Whatever it was, the primary function was to provide a data connection to the outer world, possibly incurring charges on a phone line. So, it is the other way round than you guessed: The computer communicated with the modem using a serial protocol named RS-232 or UART.

Therefore, all serial ports have been secured to not allow access, except for the user group "dialout". This has been retained as default, even for emulated and virtual serial ports -- like, for example, serial port over USB.


message:
Is Arduino's USB communication protocol the same as USB modems use?

An Arduino Uno uses for the default USB communication either an FTDI chip in early versions or a microcontroller that emulates/replicates the FTDI chip communication.

Is this type of USB communications the same as the Conexxant CX930xx modems use as well?

What I want to achieve is to emulate the nessesary AT commands using the [ATCommand][1] library to replicate the modem's AT command instruction set. The things that I want to emulate are:

 1. The modem USB communication
 2. The subset of AT commands required for enabling/disabling an incomming call with Caller id
 3. Returning a "fake" incoming call with or without CallerId depending on the provided options from the PC via the AT commands

For the last two I can somehow manage. But I don't know whether the existing FTDI chip/USB microcontroller uses the nessesary protocols that modems use as well. I mean would it be enough if I just replace the hardware and vendor ID or do I need to emulate another type of USB communication as well?

The modem that I want to emulate is the: https://support.lenovo.com/us/en/solutions/pd003647-lenovo-usb-modem-overview

What I want to achieve is to fake an incomming call instead of using the actual modem. The reason why is, because I want to provide my own data towards modem-interfacing desktop application that use CallerId. Instead of using the actual modem I would love to have a fake one where I can emulate various scenarios.

  [1]: https://github.com/yourapiexpert/ATCommands

body:
Commonly USB modems use two layers of communication that are relevant for your issue.

1. A virtual serial communication device, known as CDC/ACM, [Communication Device Class][1], and Abstract Control Model, respectively.

1. Modem control protocol, known as [Hayes command set][2], vulgo "AT command set", on top of this.

Both layers are generally independent of each other. You can use the virtual serial communication for any other purpose. And you can transport the Hayes commands and replies over any other communication stream.

Most Arduino compatible devices reveal themselves as CDC/ACM to a PC, you can check this for example on Windows in the Hardware Manager. Therefore, the underlying transport layer exists for you.

But to answer your concrete question: **No**, the second layer (AT commands) is missing. It is not necessary for the upload process or the serial monitoring.

But you can write a sketch that implements that set of commands you would like use use for your application.

  [1]: https://en.wikipedia.org/wiki/USB_communications_device_class
  [2]: https://en.wikipedia.org/wiki/Hayes_command_set


message:
How do you remove a number of characters from a parsed string?

Using this code - `advertisedDevice.getServiceDataUUID().toString().c_str());` returns the following string -
``0000feaa-0000-1000-8000-00805f9b34fb``

How can I adjust the code to do that it omits the first nine characters leaving only -
``0000-1000-8000-00805f9b34fb``

Thank you.

body:
_Note: Even if this question is about general C++ programming, this might help other Arduino users, too. Better ask at [StackOverflow][1] the next time. ;-)_

The result of your chain of method calls returns a pointer to non-writable `char`s. You can add any offset to this, in the range from 0 to the number of characters.

In your case:

```c++
const char* result = advertisedDevice.getServiceDataUUID().toString().c_str() + 9;
```

  [1]: https://stackoverflow.com/


message:
LM7805 gets very hot with four servo motors

I'm making a robotic arm using three SG90s and one Futaba s3003 servo motors and an ESP32 dev_kit_V4.

The problem is when I am controlling the arm, the voltage regulator gets so hot that I can't touch it. After a minute or so the servos stop rotating and I have to restart the ESP32 to control the servos and the cylce continues.

I tried to connect the ESP32 to a power bank alone but the issue isn't solved. Can you help me?

The schematic for wiring:
 [![enter image description here][1]][1]

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

body:
Depending on load, your servos can draw 250ma of current or more when actuated. This means that your 7805 may need to supply >1 amp of current at 5V.

In order to get 5V from a 12V adapter the 7805 will need to drop 7V (The LM7805 is a linear regulator, essentially a variable resistor). 7V at 1 amp (peak) is 7 watts, which is what your regulator will dissipate during peak current draw.

With effective heat sinking your circuit will work. According to the [datasheet][1], if you are running at room temperature with no heat sink you are limited to ~2.5 watts of dissipation.

If the 7805 chip temperature exceeds 150 degrees C it will go into thermal shutdown, which is probably what you're seeing.

Solutions would be to install an appropriate heat sink on the 7805, use a 7.5 volt power adapter (brings 7805 power dissipation down to ~2.5 watts), use multiple 7805 chips, or power everything with a 5V power adapter.

  [1]: https://www.ti.com/lit/ds/symlink/lm340.pdf


body:
Linear regulators especially the older ones like to go into oscillation at a relative high frequency. This may be load dependent.  The data sheet will recommend the appropriate capacitors to connect to it to prevent that. You would typically use a scope to see this. That oscillation will cause them to get hot rapidly even if they do not have a large load. You can look at the data sheet and determine the temperature rise of the die per watt of power. That you can determine by multiplying the drop across the regulator by the current. You can also apply this to heatsinks and pick one accordingly. There are conditions on this to be sure you have adequate ventilation to get rid of the heat on a air cooled heatsink. Liquid are similar but the numbers are much different.

In your case I would recommend you go to a switch mode regulator, commonly known as a buck or SEPIC regulator. The buck will drop the voltage from a higher voltage. The SEPIC does the same thing but if the input voltage goes below the output setpoint within its range it will boost the voltage keeping it at setpoint. As BobT explained the excess voltage is dropped through the regulator, it sort of acts like a variable resistor. This is dissipated as heat. The current on the input is about the same as the output. A switch mode regulator will operate in the efficiency range of maybe 80% - 95% efficiency, dissipating much less heat. They actually turn on and off very rapidly but the output is filtered so you do not see it.


body: I would recommend you to go with lm2596. That will solve your problem. Its output is adjustable. So set the output voltage first before connecting anything to it.


message:
Can I use this approach so I can sniff both TX and RX signals using a Second arduino?

Based upon this [answer][1] I can hook up 2 arduinos like this:

[![2 arduinos that the second one is used as debug serial port][2]][2]

But AFAIK The main microcontroller uses an RS232 protocol and AtMegau16 (or ATMegau8) converts it into USB one emulating an FTDI chip.

But in my case, I need just the RX port from the second in order to just sniff data. So I looked on how I can pirate the RS232 signal and I found this schematic:

![An rs232 spy cable](https://www.compuphase.com/electronics/rs232-split.png)

Resulting to this monstrocity:

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

But would this allow me the secoind UNO to capture both RX AND TX signals?

  [1]: https://arduino.stackexchange.com/a/90460/43808
  [2]: https://i.stack.imgur.com/ENbwt.png
  [3]: https://i.stack.imgur.com/HVuGG.png

body:
This approach may work in some cases but will not work in all cases.

Assuming the intent is to listen to both the transmit and the receive side of an [RS232][1] type signal.

[An RS232 signal may swing from -12 to +12 Volts][2].  Many logic inputs behave unexpectedly when driven by voltages higher than their supply rail.  A resistor may mitigate this problem.  A [logic level shifter][3] would be better.

The circuit diagram in the question is an example of a [wired OR connection][4].  If either serial transmit line is high the data from the other will be blocked.  As illustrated in this diagram from wikipedia.org.

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

So this circuit diagram will only work reliably for [half duplex communications][6].  If full duplex monitoring is required, two independent receivers / monitors will have to be used.

  [1]: https://en.wikipedia.org/wiki/RS-232
  [2]: https://en.wikipedia.org/wiki/RS-232#Voltage_levels
  [3]: https://en.wikipedia.org/wiki/Level_shifter
  [4]: https://en.wikipedia.org/wiki/Wired_logic_connection#The_wired_OR_connection
  [5]: https://i.stack.imgur.com/ypC58.jpg
  [6]: https://en.wikipedia.org/wiki/Duplex_(telecommunications)


message:
AfMotor Shield Library does not work with template programming

I am able to move motors using AfMotor Shield Library. ( https://github.com/adafruit/Adafruit-Motor-Shield-library )

Like :

    AF_DCMotor insertionMotor(1);
    AF_DCMotor pumpMotor(2);

    void setup()
    {
      insertionMotor.setSpeed(255);
      pumpMotor.setSpeed(255);
      insertionMotor.run(RELEASE);
      pumpMotor.run(RELEASE);
      insertionMotor.run(FORWARD);
      pumpMotor.run(FORWARD);
    }

But if I want to write it like this, only the motor with the template expansion that I called last works.

    enum class direction {
      FRW = 0x01,
      BCKW,
    };

    template<int n, direction type>
    class Motor : public AF_DCMotor {

    public:

      Motor() : AF_DCMotor(n) {
        setSpeed(255);
        run(RELEASE);
        run(type);
      }
    };
    Motor<1, direction::FRW> fanMotor;
    Motor<2, direction::FRW> pumpMotor;

Only the pumpmotor is running. Or if I call the fanMotor after the pumpMotor, it still works.If I remove pumpmotor and leave only fanMotor, the fanMotor also works. Is there something I overlooked?

body:
Your code gives me a compiler error: in

```c++
run(type);
```

the `run()` method expects a `uint8_t`, but it is given a `direction`.
Adding an explicit cast to `uint8_t` makes it compile.

Now, as a general rule, I would advice you to never touch the hardware
in a constructor. The problem is, if you create a global object (like
you are doing here), the constructor gets called before `main()`, thus
before the Arduino core has had a chance to initialize the hardware. If
your constructor touches any hardware register, this may conflict with
the initialization the core is going to perform right at the start of
`main()`.

The usual idiom for doing any hardware initialization is to define in
your object a method called `begin()`, and call it from `setup()`:

```c++
template<int n, direction type>
class Motor : public AF_DCMotor {
public:
  Motor() : AF_DCMotor(n) {}

  void begin() {
    setSpeed(255);
    run(RELEASE);
    run((uint8_t) type);
  }
};
```


message:
What components can be connected to pins 0/1 (RX/TX) without preventing uploading of code?

For a robot project I am using an Arduino Uno, and am running out of pins. The simplest solution would be to use digital pins 0/1. I know this means that I won't be able to use Serial communication (which is fine), but I also know that these pins are also used when uploading code to the board, and connecting components to these pins can interfere with the upload.

Are there certain types of components/interfaces that can be connected to these pins that won't interfere with the upload (without having to disconnect them every time I want to upload)?

In my case, I can choose between either using these pins to drive inputs for an L298N motor driver (TTL inputs), or to read quadrature motor encoder signals. My guess would be that the latter won't work, as these signals may be high and interfere (and I don't know whether applying a voltage to the encoder outputs would cause damage - I have no datasheets for them).

However maybe the TTL inputs of the L298N would be fine? Or do I have no choice but to either have a switch to disconnect the when uploading or find some other way to reduce pin usage (or go for a bigger Arduino)?

body:
This is a general electronic problem, not specific to pins 0/1 of the Arduino.

The basic rule is:

* An input can only accept one signal

But

* One signal can go to many inputs

In other words any INPUT pin can only accept a signal from one place, but an OUTPUT pin can send its signal to many places at once.

The Arduino's serial connection has two signals - one input (RX) and one output (TX).  The input pin (RX) can only get its signal from one place, and when programming that "one place" needs to be the USB to UART converter's TX pin.  So anything connected to that pin that "sends a signal" will confuse everything and communication will fail.

Similarly the USB to UART converter's RX pin can only receive a signal from one place - in this case the Arduino's TX pin - connecting anything to this pin that could output a signal would confuse things and break communication.

So to round that up: you should be fine connecting anything that only *receives* a signal of some form (i.e., anything that is an INPUT, such as an RX pin or some form of control input like your motor controller) to either of those pins, but do not connect anything that can *send* a signal.

There is one caveat though: whatever you connect will receive the serial communication used while programming. That could have unintended consequences, like a motor spinning when you program the board.


message:
Multiply char with float

I have a value for led brightness that is stored as an `unsigned char` (0-255)

```
unsigned char* colors[3];
colors[0] = 255;
colors[1] = 0;
colors[2] = 0;
```

I want to multiply a brightness percentage to that value.

```
float percent = 0.5;
auto red_brightness = colors[0] * percent
```

Since `colors[0]` is of type `char` and `percent` is of type `float`. It gives error `Invalid operands of types 'unsigned char*' and 'float' to binary 'operator*'`

```cpp
unsigned char brightness;
float percent;
unsigned char* colors[3];

void setup() {
  Serial.begin(9600);
  colors[0] = 255;
  colors[1] = 0;
  colors[2] = 0;
}

void loop() {
    brightness = 127;
    float percent = (float)brightness / 255;
    float newRed = (float)colors[0] * percent;

    Serial.println(percent);
    Serial.print("red ");
    Serial.print(newRed);
    Serial.println("");
    delay(1000);
}
```

How can I multiply `colors[0]` (255) by `0.5` to get `127`?

---

## What I've tried

1. Cast `colors[0]` to a float or int

```
    # invalid cast from type 'unsigned char' to type 'float'

    float newRed = (float)colors[0] * percent;
```

2. strtod

Using [this conversion website](https://www.convertdatatypes.com/Convert-char-Array-to-float-in-CPlusPlus.html), I've tried converting like so:

```
    float tempColor = (float)strtod(colors[0],NULL);
    float newRed = tempColor * percent;
```

While this compiles, it always returns `0` (not `127` like I expect)

```cpp
unsigned char brightness;
float percent;
unsigned char* colors[3];

void setup() {
  Serial.begin(9600);
  colors[0] = 255;
}

void loop() {
    brightness = 127;
    float percent = (float)brightness / 255;
    float tempColor = (float)strtod(colors[0],NULL); // <- returns 0.00

    Serial.print("tempColor");
    Serial.println(tempColor);
    delay(1000);
}
```

How can I multiply `255` by `0.5` to get `~127` ?

---

## Solution

Thanks to the pointer by st2000 and [this sparkfun article on datatypes](https://learn.sparkfun.com/tutorials/data-types-in-arduino/defining-data-types)

I avoided floating point and char arrays and converted everything to `byte` and now my code works as expected. Thank you

```
byte brightness;
byte percent;
byte colors[3];

void setup() {
  Serial.begin(9600);
  colors[0] = 255;
}
void loop() {
      percent = 50;
      auto foobar = colors[0] * percent / 100;
      Serial.print("foobar: ");
      Serial.println(foobar);
```

```
11:12:19.833 -> foobar: 127
```

body:
Using "floats" is expensive both in required space and execution time.  Consider avoiding the problem entirely and use [uint8_t or byte][1] for everything.

Then just assume

    percent = 50;

... is 50%.  Then try:

    tempColor =  colors[0] * percent / 100;

... where all variables are of type uint8_t or byte.

  [1]: https://stackoverflow.com/questions/10457210/arduino-uint8-t-variables


body:
You wrote:

> I have an led brightness that is stored as an `unsigned char` (0-255)
>
> ```c++
> unsigned char* colors[3];
> ```

This is not an array of `unsigned char`, this is an array of
**pointers** to `unsigned char`. If you instead write

```c++
unsigned char colors[3];
```

Everything should work as expected.

But then, st2000 has very good advice on how to avoid expensive floating
point operations.


message:
ESP32, ArduinoOTA.h LittleFS.h and data file upload OTA

I'm having a sketch, that works perfectly fine - connects to WiFi, uploading files using `Esp32 LittleFS data Upload` using Arduino IDE (when still connected to my PC), and sketch updates  via OTA (using `ArduinoOTA.h` library).

But when I try to `Esp32 LittleFS data Upload` when MCU is not connected to my PC, I get an error messages:

    espota : /home/guy/snap/arduino/70/.arduino15/packages/esp32/hardware/esp32/1.0.6/tools/espota.py

    [LITTLEFS] data   : /home/guy/Documents/Dropbox/Arduino/sketch_jul26a/data
    [LITTLEFS] start  : 2686976
    [LITTLEFS] size   : 1472
    [LITTLEFS] page   : 256
    [LITTLEFS] block  : 4096
    /sketch_param.json
    /sketch_param_32.json
    /myIOT2_topics.json
    /myIOT_param.json
    /sketch_param_8266.json
    [LITTLEFS] upload : /tmp/arduino_build_103180/sketch_jul26a.littlefs.bin
    [LITTLEFS] IP     : 192.168.2.132

    Sending invitation to 192.168.2.132 ..........
    20:10:59 [ERROR]: No response from the ESP
    LITTLEFS Upload failed!

Just to clarify:

A) sketch OTA works as expected (yes, I changed local USB to the remote one).

B) Tested on 2 different ESP32 MCU's, and failure is the same.

Question:
1) Is it possible to OTA data files using ESP32, `ArduinoOTA.h`, `LittleFS`, ArduinoIDE ? (It works when using ESP8266).

Guy

body:
I can confirm that I've uploaded littlefs data to an ESP32 over OTA using PlatformIO. I haven't tried with ArduinoIDE but it should be possible. Have you tried uploading while monitoring the serial output (i.e. leave it connected to the PC). If you see something in the output, it might be format error coming from the ArduinoIDE upload tool, but I suspect it's just failing to connect.

Is it definitely connecting with the same IP between sketch upload and file upload? When I have these types of problems, it's usually because I've done something in the sketch to disable WiFi or the OTA check. Have you tried uploading the sketch again over OTA?


message:
Arduino alternating between high and low signal without button press

I have connected my LCD with arduino uno. I am controlling contrast with the library and not the potentiometer. I am trying to read input from the button, it is connected to pin 9 of arduino. The resistor in the image is grounded, now arduino is not sensing signal from the button it keeps printing this even though in the timestamp below I have not touched the button. The resistor is 1k ohm.

```
20:03:30.808 -> button not pressed
20:03:31.816 -> button pressed
20:03:32.798 -> button pressed
20:03:33.827 -> button not pressed
20:03:34.821 -> button pressed
20:03:35.849 -> button not pressed
20:03:36.847 -> button not pressed
20:03:37.842 -> button pressed
```

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

```cpp
#include <LiquidCrystal.h>

const int buttonNumPad1 = 9;

int buttonNumPad1State = 0;

int Contrast = 127.5;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  Serial.begin(9600);
  pinMode(buttonNumPad1State, INPUT);
  analogWrite(6, Contrast);
  lcd.begin(16, 2);
}
void loop()
{
  buttonNumPad1State = digitalRead(buttonNumPad1);

  if (buttonNumPad1State == HIGH){
    Serial.println("button pressed");
    lcd.setCursor(0, 1);
    lcd.print("pressed");
  } else {
    Serial.println("button not pressed");
  }

  lcd.setCursor(0, 0);
  lcd.print("Hello");

  delay(1000);

  lcd.clear();
}
```
Top view of my breadboard

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

is it something related to? https://docs.arduino.cc/learn/microcontrollers/digital-pins

> Input pins make extremely small demands on the circuit that they are sampling, equivalent to a series resistor of 100 megohm in front of the pin. This means that it takes very little current to move the input pin from one state to another

  [1]: https://i.stack.imgur.com/4itwa.png
  [2]: https://i.stack.imgur.com/nIV8D.jpg
  [3]: https://i.stack.imgur.com/V5dun.png

body:
Look at this breadboard image:
[![breadboard with lines where the power rails are connected][1]][1]

I have marked the power rail connections with green and red lines. Do you see, that they are not connected in the middle, right there where I've drawn the blue dotted line. Often the power rails of breadboards are not connected internally at that place. If that is the case for your breadboard you would need to bridge that gap with some jumper wires.

If you don't do that, your button and pulldown resistor are not connected to anything but the digital input pin. So there is nothing setting the state of that pin (HIGH or LOW). Its just like you simply connected a wire to the digital input pin. And that's called a **floating pin**. It is not actively pulled in one direction, so any noise, that comes by, might change the state of the input pin.

Make sure your button and pulldown resistor are actually electrically connected to ground. Bridge any gaps in the power rails, that your breadboard might have.

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


message:
Convert Int to HEX, HEX to string and to byte? General converting problem

Since Cpp is not my main language, I struggle to find the best way to convert between types for my needs.
So my starting point is
```cpp
struct can_frame {
    canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
    __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
    __u8    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
```

So first I needed it bo send to Serial as a hex string, so solution I've found and used was
```cpp
String frame = "CAN:";
char dataString[1] = {0};
sprintf(dataString, "X", can1Msg.can_id);
frame += dataString;
for (int i = 0; i < can1Msg.can_dlc; i++) {  // print the data
  char dataString[1] = {0};
  sprintf(dataString, "X", can1Msg.data[i]);
  frame += " " + String(dataString);
}
```

Doesn't seem elegant byt it did the job.

But then I needed to do some checking of ID and specific bytes
So I've saved all String ins `String bytes[8]`
So  now I could something like
```cpp
if (id == "2A0" && bytes[0] == "A0") {
```

And that was almost over, but then I realized that I need to do some checking of Integer number that is saved on 3 bytes.
E.G `byte[2] + byte[3] + byte[4]` which would something like `0020A0` whih will be `8352` as an Int

But converting things around gave all the problems such us `String to const char*` etc.
I wanted to convert `__u8` to byte array so I can do checks and conversions and eventually convert it to string, but I've failed.
Can anyone suggest best approach for this ?

body:
The main problem that you are having is a lack of understanding in what "hex", "byte", etc are.

You are trying to work with four data types (int, hex, string and byte) when in reality there are only two types: String and binary. Everything else is just a representation we as humans use to make easier sense of the binary data.

You have a "source" type (`can1Msg.data`) which is, at one and the same time, binary, integer, hex and byte. The only thing it is not is `String` and you create that manually with your `sprintf` calls.

To compare the third "hex pair" value in your data you simply:

```c++
if (can1Msg.data[2] == 0x42) { ...
```

That is, compare the 8-bit binary value stored in array slice 2 (arrays count from 0 so 2 is the third entry) with the binary value represented by the hex notation 42.  The exact same thing can be done with:

```c++
if (can1Msg.data[2] == 66) { ...
```

66 is the decimal (base 10) equivalent of 0x42.  You can also use binary or octal. These two are also exactly the same:

```c++
if (can1Msg.data[2] == 0102) { ... // octal
if (can1Msg.data[2] == 0b01000010) { ... // binary
```

If you need to examine groups of bytes, such as if you have two bytes that form a 16-bit integer, you simply combine those two bytes into an integer, taking care to obey the correct [endianness](https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/) of the values.  For example if you have a 16 bit integer that is stored as `can1Msg.data[7]` and `can1Msg.data[8]` in *big endian* form, you can use:

```c++
uint16_t val = (can1Msg.data[7] << 8) | can1Msg.data[8];
```

Then simply compare the numeric (binary) integer value at will.  All that line does is take the first 8 bit value and "shift" it 8 bits to the left to make it a 16 bit value with the lower 8 bits set to 0, then overlay the second value over those lower 8 zeroes, to make it a single 16-bit value.


message:
boards.txt - how to create sub-menu (NOT new board!!!)

Arduino 1.8.19

Is it possible to create a sub-menu inside `boards.txt` that would allow having the boards grouped for example by the manufacturer?
If it is possible, please provide an example or at least documentation for the language which is used for boards.txt.

I **don't** want to add a new board.

body:
No, it's not possible.

The board menu ([defined here](https://github.com/arduino/Arduino/blob/43b0818f7fa8073301db1b80ac832b7b7596b828/app/src/processing/app/Base.java#L1427)) is a single flat menu with "scroller" added to it.

To have multiple layers of menu you'd have to rewrite that entire part of the IDE.


message:
displaying double variable problem (Arduino)

so I have a problem with displaying a double variable in OLED & IR remote calculator, like this (using u8g2):
```
displayTextOnRight(String(100000, 0)); //ex. of an void and a number
```
It displays: " "
But when I set to ex. 99999 it displays: "99999"

The same is with
```
displayTextOnRight(String(1000.00, 2));
```
It also displays nothing. (100.00 displays 100.00)

I tried values below zero and it crashes. When I try 6 it's empty whatever I type on my remote.

Please help.

body:
When the first argument to the [String](https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/) constructor is an integer type, it tries to interpret the second argument as a number base and not as a number of decimal places.

So, in `String(100000, 0));`, it kind of thinks you're asking for the number to represented in the `String` in base 0 as opposed to decimal (`DEC`), hexadecimal (`HEX`), binary (`BIN`), etc and base 0 isn't a thing.

With a floating point type first argument like `1000.0` the second argument takes on the meaning of decimal places (seen an `decimalPlaces` in the documentation).

If you want `".00"` after an integer number when it's converted to a String it's probably better to just print it in a second `.print()` call, or to concatenate it to the string. And if you want you can manually type convert integer expressions to floating point type to force selection of the other constructor, e.g. `int a = 10000; whatever.print(String(float(a), 2));`


message:
PSF WiFi module - Is it similar to ESP8266

Some products (as TUYA and SONOFF) are using a PSF wifi module. In this [link][1], PSF-B04 is reffers as ESP8285 design.

does anyone flash a sketch to such chip ? should it be reffered as ESP8285 when selecting chip type in Arduino IDE ?

Guy

  [1]: https://itead.cc/diy-kits-guides/psf-b04-application-guide/

body:
ESP8285 is supported by esp8266 Arduino. You can select it in Tools menu.

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

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


message:
Share interrupt service between class

I would like to share interrupt routine between class. I followed this [tutorial](https://atadiat.com/en/e-arduino-trick-share-interrupt-service-routines-between-libraries-application/).

But I need to call a member function in callback function, I have the issue :
[![enter image description here][1]][1]

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

This is my code :

Timer.h

    static void (*__handleISR)(void);

    class Timer
    {
        public:
            Timer();
            ~Timer();
            static void init();
      static void handleISR(void (*function)(void));
    };

Timer.cpp

    Timer::Timer()
    {
    }

    Timer::~Timer()
    {}

    void Timer::init()
    {
     TCCR2A = 0; //default
     TIMSK2 = 0b00000001; // TOIE2
    }

    ISR (TIMER2_OVF_vect)
    {
     // 256-6=250 --> (250 x 16uS = 4mS)
     // Recharge le timer pour que la prochaine interruption se declenche dans 4mS
     TCNT2 = 6;

        __handleISR();
    }

Device.h

    class Device
    {
     public:
      Device();

     private:
      void isr();
    };

Device.cpp

    Device::Device()
    {
        Timer::init();
        Timer::handleISR(isr);
    }

    void Device::isr()
    {
        // Do my stuff
    }

If I set function isr() static, it works. But I need to call member from Device in isr().

How I can call non static member function ? Or another solution ?

body:
This is not an Arduino specific question but a C++ question, and as such you might get more or better answers on [StackOverflow][1]. Anyway, I'll suggest a possible solution.

A member method always receives a pointer to its object as a hidden first argument that we know as `this`. Only via this argument such a method is able to access member attributes or member methods.

A class method does not have this parameter.

The function type you define is compatible only to functions or class methods.

So you need to provide a pointer (or reference) to the `Device` object.

I reduced your example and replaced the interrupt macro with something a standard C++ compiler accepts, as this is not part of the issue.

Timer.h
```c++
#ifndef TIMER_H
#define TIMER_H

#include "Device.h"

class Timer
{
    public:
        static void setCallback(void (*function)(Device*), Device*);
};

#endif
```

Timer.cpp
```c++
#include "Timer.h"

#define ISR(f) void f()

static void (*_function)(Device*);
static Device* _device;

void Timer::setCallback(void (*function)(Device*), Device* device)
{
    _function = function;
    _device = device;
}

ISR(TIMER2_OVF_vect)
{
    _function(_device);
}
```

Device.h
```c++
#ifndef DEVICE_H
#define DEVICE_H

class Device
{
    public:
        Device();

    private:
        static void isr(Device* device);
        void isr();
};

#endif
```

Device.cpp
```c++
#include "Device.h"
#include "Timer.h"

Device::Device()
{
    Timer::setCallback(isr, this);
}

void Device::isr(Device* device)
{
    device->isr();
}

void Device::isr()
{
    // Do my stuff
}
```

**If** you don't need the `Device` object, you don't need a member method. Then go with a class method, as you already found out.

  [1]: https://stackoverflow.com/


message:
String() vs char for simple flow control

I am newbie in Arduino and writing a program where I want to control the flow by using Serial monitor input (PI controller).
I've read that using String() although easier it is slower than using char. But to use char I would need more lines of code to convert the input into a string for comparison and more knowledge to make the program robust. For the control I will enter small strings like Ramp, Increase, Decrease, Lock, Stop and any other inputs will not be used. Generally, there are not going to be much inputs. The strings are basically going to be put into if-statements leading to functions.

    if(Serial.available()){

    string = Serial.readString()
    or some function to read out all the bytes of the string and return a char containing it;

    if(string="Ramp") {
    do_this();
    }
    else_if(string="Increase"){
    do_that()
    }
    //If nothing matches, continue with code.
    }
Since I need to finish this project soon, I am wondering if it's going to increase the loop time significantly if I use String() or I shouldn't bother learning and using char right now (at a later stage, for sure).

body:
Yes, `String` has a bit more overhead than plain c-strings (aka `char` arrays), though the additional execution time will be way too small for you to notice (especially when you type the commands in by hand).

It will be no problem to use `String` in your sketch, though you should do it right and use `String.reserve()` to allocate enough memory space in the `String` object to hold the longest string, that you have. Also don't just add `String`s together. That way you can avoid memory fragmentation (effectively making swiss cheese out of your RAM) and still use `String`.

Though when you are not in a hurry anymore, learning how to use c-strings will be worthwhile.


body:
Using `Serial.readString()` will make your program _very_ slow. This is
because `readString()` does not know when to stop reading. When the
serial input buffer gets empty, it will wait just in case more
characters may come later. Only when it times out does it return the
string that it could read. The default timeout is one second, so your
program will be unresponsive for a full second after receiving a command
and before acting on it.

You can shorten the timeout using `Serial.setTimeout()`, but this may
make your program harder to test interactively by typing commands on a
terminal emulator.

I recommend you add a terminating character (say, `'\n'`) to each of
your messages, then replace `Serial.readString()` with
`Serial.readStringUntil()`. This method will return immediately when it
finds the terminating character. Note that this character will _not_
appear on the returned string object. `readStringUntil()` also obeys a
timeout, but only when it cannot find the terminating character.

Or you can learn the clean way to [read Serial on the Arduino][1].
Yes, it is a bit harder, but not a horrible thing to do.

[1]: https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27


message:
Char Array in PreProcessor

I need to define an array, that later on will be the name of a class, and will be pointed to.

For example (in a non pre-processor way):

`const char *button_names[4]={"b0","b1","b2","b3"};`

and later on (when it will be define in pre-processor), in a function it will be called as :

`static Button2 button_names[i]`

How can I define it that array to be in pre-processor?

**Edit2:**

    Button2 *Buttons[8] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; // Here I use an optional up to 8 Buttons.

and later on, after I read parameter file: i get the `numSW`

/* Below example is only to check if I can use such technique - I know it is not a good coding. Example here is only for up to 4 Buttons*/

    void init_buttons()
    {
            for (uint8_t i = 0; i < numSW; i++)
            {
                    if (i == 0)
                    {
                            static Button2 bt1;
                            Buttons[i] = &bt1;
                    }
                    else if (i == 1)
                    {
                            static Button2 bt2;
                            Buttons[i] = &bt2;
                    }
                    else if (i == 2)
                    {
                            static Button2 bt3;
                            Buttons[i] = &bt3;
                    }
                    else if (i == 3)
                    {
                            static Button2 bt4;
                            Buttons[i] = &bt4;
                    }

                    Buttons[i]->begin(buttonPins[i]);
                    if (buttonTypes[i] == 0) /* On-Off Switch */
                    {
                            Buttons[i]->setPressedHandler(OnOffSW_ON_handler);
                            Buttons[i]->setReleasedHandler(OnOffSW_OFF_handler);
                    }
                    else if (buttonTypes[i] == 1) /* Momentary press */
                    {
                            Buttons[i]->setPressedHandler(toggle_handle);
                    }
                    Buttons[i]->setID(i);
            }
    }

body:
    void init_buttons()
    {

            for (uint8_t i = 0; i < numSW; i++)
            {
                    Buttons[i] = new Button2;   // <--- **Thnx to Juraj**!!!
                    Buttons[i]->begin(buttonPins[i]);
                    if (buttonTypes[i] == 0) /* On-Off Switch */
                    {
                            Buttons[i]->setPressedHandler(OnOffSW_ON_handler);
                            Buttons[i]->setReleasedHandler(OnOffSW_OFF_handler);
                    }
                    else if (buttonTypes[i] == 1) /* Momentary press */
                    {
                            Buttons[i]->setPressedHandler(toggle_handle);
                    }
                    Buttons[i]->setID(i);
            }
    }


message:
GY-521 output and degrees

I am trying to make an observatory through 2 GY-521 gyroscopes and using the outputs I have to make a motor move, but I have a problem.

When I move one of the two gyroscopes the outputs change, but then as soon as I leave it it returns to the initial value, the data I see via an ESP8266 on an internet site, this is the code:

    #include <Wire.h>
    #include "WiFiEsp.h"
    // Emulate Serial1 on pins 6/7 if not present
    #ifndef HAVE_HWSERIAL1
    #include "SoftwareSerial.h"
    SoftwareSerial Serial1(18, 19); // RX, TX
    #endif

    char ssid[] = "Vodafone-A61356555";            // your network SSID (name)
    char pass[] = "YgtHnkJHNpFAcPfH";        // your network password
    int status = WL_IDLE_STATUS;     // the Wifi radio's status
    int reqCount = 0;                // number of requests received

    WiFiEspServer server(80);

    int MPU = 0x69;
    int MPU1 = 0x69;
    int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
    int16_t AcX1, AcY1, AcZ1, Tmp1, GyX1, GyY1, GyZ1;
    int gyro_state = 2;
    int gyro_state_1 = 3;
    int RED_LED = 8;
    int GREEN_LED = 9;

    void setup(){
      pinMode(gyro_state, OUTPUT);
      pinMode(gyro_state_1, OUTPUT);
      pinMode(RED_LED, OUTPUT);
      pinMode(GREEN_LED, OUTPUT);
      digitalWrite(gyro_state, HIGH);
      digitalWrite(gyro_state_1, HIGH);
      Wire.begin();
      Wire.beginTransmission(MPU);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      Serial.begin(115200);
      // initialize serial for ESP module
      Serial1.begin(9600);
      // initialize ESP module
      WiFi.init(&Serial1);

      // check for the presence of the shield
      if (WiFi.status() == WL_NO_SHIELD) {
        Serial.println("WiFi shield not present");
        // don't continue
        while (true);
      }

      // attempt to connect to WiFi network
      while ( status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);
        // Connect to WPA/WPA2 network
        status = WiFi.begin(ssid, pass);
      }

      Serial.println("You're connected to the network");
      printWifiStatus();

      // start the web server on port 80
      server.begin();
    }

    void loop() {
      // listen for incoming clients
      WiFiEspClient client = server.available();
      if (client) {
        Serial.println("New client");
        // an http request ends with a blank line
        boolean currentLineIsBlank = true;
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            Serial.write(c);
            // if you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so you can send a reply
            if (c == '\n' && currentLineIsBlank) {
              Serial.println("Sending response");

              // send a standard http response header
              // use \r\n instead of many println statements to speedup data send
              client.print(
                "HTTP/1.1 200 OK\r\n"
                //"Content-Type: text/html\r\n"
                "Connection: close\r\n"  // the connection will be closed after completion of the response
                "Refresh: 5\r\n"
                "\r\n");
              client.print("<!DOCTYPE HTML>\r\n");
              client.print("\r\n");
              client.print("
\r\n");
              client.print("Accelerometro Telescopio X: ");
              client.print(AcX);
              client.print("  Accelerometro Cupola X: ");
              client.print(AcX1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("Accelerometro Telescopio Y: ");
              client.print(AcY);
              client.print("  Accelerometro Cupola Y: ");
              client.print(AcY1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("Accelerometro Telescopio Z: ");
              client.print(AcZ);
              client.print("  Accelerometro Cupola Z: ");
              client.print(AcZ1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("Giroscopio Telescopio X: ");
              client.print(GyX);
              client.print("  Giroscopio Cupola X: ");
              client.print(GyX1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("Giroscopio Telescopio Y: ");
              client.print(GyY);
              client.print("  Giroscopio Cupola Y: ");
              client.print(GyY1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("Giroscopio Telescopio Z: ");
              client.print(GyZ);
              client.print("  Giroscopio Cupola Z: ");
              client.print(GyZ1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("Temperatura Telescopio: ");
              client.print(Tmp);
              client.print("  Temperatura Cupola: ");
              client.print(Tmp1);
              client.print("
\r\n");
              client.print("
\r\n");
              client.print("\r\n");
              break;
            }
            if (c == '\n') {
              // you're starting a new line
              currentLineIsBlank = true;
            }
            else if (c != '\r') {
              // you've gotten a character on the current line
              currentLineIsBlank = false;
            }
          }
        }
        // give the web browser time to receive the data
        delay(100);

        // close the connection:
        client.stop();
        Serial.println("Client disconnected");
      }
      digitalWrite(gyro_state, HIGH);
      digitalWrite(gyro_state_1, LOW);

      do {
        Wire.beginTransmission(MPU);
        Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
        Wire.endTransmission(false);
        Wire.requestFrom(MPU, 14, true);       // request a total of 14 registers
        AcX = Wire.read() << 8 | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
        AcY = Wire.read() << 8 | Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
        AcZ = Wire.read() << 8 | Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
        Tmp = Wire.read() << 8 | Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
        GyX = Wire.read() << 8 | Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
        GyY = Wire.read() << 8 | Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
        GyZ = Wire.read() << 8 | Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

        Tmp = Tmp / 340 + 36.53;

        Serial.println("First Gyro");
        Serial.println(GyZ);

        digitalWrite(gyro_state_1, HIGH);
        digitalWrite(gyro_state, LOW);
        delay(1000);

      } while(digitalRead(gyro_state)== HIGH);

      do {
        Wire.beginTransmission(MPU1);
        Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
        Wire.endTransmission(false);
        Wire.requestFrom(MPU1, 14, true);       // request a total of 14 registers
        AcX1 = Wire.read() << 8 | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
        AcY1 = Wire.read() << 8 | Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
        AcZ1 = Wire.read() << 8 | Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
        Tmp1 = Wire.read() << 8 | Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
        GyX1 = Wire.read() << 8 | Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
        GyY1 = Wire.read() << 8 | Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
        GyZ1 = Wire.read() << 8 | Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

        Tmp1 = Tmp1 / 340 + 36.53;

        Serial.println("Second Gyro");
        Serial.println(Gy1);

        digitalWrite(gyro_state, HIGH);
        digitalWrite(gyro_state_1, LOW);
        delay(1000);

      } while(digitalRead(gyro_state_1) == HIGH);

      if (GyY > GyY1) {
        digitalWrite(9, HIGH);
        digitalWrite(8, LOW);
      }
      else if (GyY < GyY1) {
        digitalWrite(8, HIGH);
        digitalWrite(9, LOW);
      }
    }

    void printWifiStatus() {
      // print the SSID of the network you're attached to
      Serial.print("SSID: ");
      Serial.println(WiFi.SSID());

      // print your WiFi shield's IP address
      IPAddress ip = WiFi.localIP();
      Serial.print("IP Address: ");
      Serial.println(ip);

      // print where to go in the browser
      Serial.println();
      Serial.print("To see this page in action, open a browser to http://");
      Serial.println(ip);
      Serial.println();
    }

Output:
```
First Gyro
1503
Second Gyro
3730
First Gyro
1558
Second Gyro
-162
First Gyro
1498
Second Gyro
-164
```

Can anyone explain to me why once I stop moving the gyroscope, the value returns to the initial position? And if it is possible to convert to degrees?

body:
The GY-521 and the MPU6050 are the same functionally, and you need to use one of the several libraries to get what you want.  It appears you are retrieving angular rate values, but what you want is relative heading. The angular rate will return to zero (or whatever the initial value was) once it stops moving, but the heading will (with proper treatment) stay constant.

I have used the MPU6050 in several projects with success, using Jeff Rowberg’s I2CDevLib library, and although getting everything set up is complicated, I recommend it.  [See this post][1] for basic setup.

Also, I note that most of your program has nothing at all to do with the gyroscope.  I recommend you use the smallest and simplest possible program to work out the hardware issues *before* adding the more complex bits.

  [1]: https://www.fpaynter.com/2019/10/basic-arduino-mpu6050-gy-521-test/


message:
Converting 16bit to float

I am trying to communicate with AT30TS75A-MA8M-T with below code, the problem is converting the 16 bit output to float so I can read temp:

Base on [data sheet][1]
[![enter image description here][2]][2]
I suppose to remove first 5 bit in order to read correctly but I am not converting it correctly.

Ex: (0b001001001100000 AND 0 b0111111111100000) = 0b1001001100000
 0b1001001100000 >> 5 = 0b10010011 = 147

        void Atemp::begin()
    {

        Wire.begin();

        // Check if sensor temp sensor is avilable

        // if (mySensor.beginI2C() == false)
        // {
        //     data[9] = 5; // Error Code
        // }
        // Set registor for two decimal
        Wire.beginTransmission(_i2cAddress);
        Wire.write(1);
        Wire.write(0b01100000);
        Wire.endTransmission();
    }

    void Atemp::read()
    {
        Wire.beginTransmission(_i2cAddress);
        Wire.write(0);
        result = Wire.endTransmission();
        // result is 0-4
        if (result != 0)
        {
            data[9] = 5; // Error Code
        }

        result = Wire.requestFrom(_i2cAddress, (uint8_t)2);
        if (result != 2)
        {
            data[9] = 5; // Error Code
        }
        else
        {
            uint8_t part1 = Wire.read();
            uint8_t part2 = Wire.read();

            data[7] = part1;
             data[8] = part2;
            int16_t rawval = (part1 << 8 | part2) ;
            // rawval >>= 6;
            float temp = rawval / 256.0f;
            floatconv(temp);
        }
    }

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8839-DTS-AT30TS75A-Datasheet.pdf
  [2]: https://i.stack.imgur.com/bGVzS.png

body:
You need to do two things:

1. Right-shift the data to align it to the right of the variable, and
2. Multiply it by the value of one bit.

When right shifting be sure to do it in a *signed* data type so that C will *sign extend* the value and retain any negativeness to the value.

So taking the 12-bit examples from the datasheet you right shift 4 bits, so

```
SDDDDDDDDDDD0000
```
becomes
```
SSSSSDDDDDDDDDDD
```
(where S is the sign bit and D is a valid data bit, and 0 is padding)

Then simply multiply the value by 0.0625 to get the actual temperature.

In code that might look like:

```c++
int16_t rawval = part1 << 8 | part2;
rawval >>= 4; // Do this in the int16_t to preserve the sign
float temperature = rawval * 0.0625;
```

For different resolutions right shift by different amounts and multiply by the appropriate single-bit value for that resolution (hint: 11 bit is double the value of 12 bit, 10 bit is double the value of 11 bit, etc).


body:
Just a complement to Majenko's answer. The temperature register is set
in such a way that you can interpret it in the same way irrespective of
the selected resolution:

```c++
int16_t rawval = part1 << 8 | part2;
float temperature = rawval * (1/256.0);
```


message:
ESP32- Sporadic slow receive of MQTT messages

**Problem description:** Every ~20+ published messages (using terminal), MCU receives that message in a very noticeable delay (mostly ~10 sec, few time it got up to 1 min). Upon receive (printed in Serial monitor), MCU is working as expected.

**Hardware:** ESP32 DEVKIT MCU, `PubSubClient.h` for MQTT and `WiFi.h` for WiFi.

**Important remark:** Code is same for ESP8266 and ESP32.This behavior happens **only** on ESP32.

**Question:** Does ESP32 has a know issue regarding receiving MQTT messages? is there a workaround? or perhaps- bug in code?

What did I do to try isolating the problem:

1) Tried on 3 different ESP32s (2 DEVkit MCU, and 1 with relays on board) - same behavior - it is not an specific MCU hardware problem.

2) Used another PC to publish MQTT messages (via terminal. MAC and Linux, and a 3rd party MQTT App)- no change. It has nothing to do with publishing platform.

3) To rule out it may be a MQTT broker's fault (Local RPI3 connected using LAN cable)- Subscribing to that topic in order to see if the delay repeats . MQTT server receive pubs on time. Broker responds on time (while waiting to see when publish is received in Serial monitor).

4) adding a flashing LED every 200ms in `loop()`, to verify that MCU is not get stuck in a process. `loop()` is looping as expected (see in code below).

5) Spitting heap free memory to Serial monitor, in order to see if there is some memory issue, degradation. Nothing suspicious.

6) Code simplification- used code segments from ESP32 wifi and MQTT pubsub's example, while disabling every functionality of original code(with and without). Delay still happens sporadically.

**OUTPUT1**- sending "0" and "1" almost simultaneously,  almost 15 sec delay

    13:31:21.516 -> Message arrived [myHome/test] 0 <--- right after this, "1" was sent
    13:31:22.510 -> 278616 <---- free heap size (send every 1000 ms. non-blocking)
    13:31:23.570 -> 278616
    13:31:24.630 -> 278616
    13:31:25.657 -> 278616
    13:31:26.718 -> 278616
    13:31:27.778 -> 278616
    13:31:28.805 -> 278616
    13:31:29.866 -> 278616
    13:31:30.926 -> 278616
    13:31:31.954 -> 278616
    13:31:33.014 -> 278616
    13:31:34.075 -> 278616
    13:31:35.102 -> 278616
    13:31:35.964 -> Message arrived [myHome/test] 1 <--- received 15 sec later

**OUTPUT-2:** Code

    #include <WiFi.h>
    #include <PubSubClient.h>

    WiFiClient espClient;
    PubSubClient client(espClient);

    const char *mqtt_server = "192.168.2.100";

    void setup_wifi()
    {

            delay(10);
            // We start by connecting to a WiFi network
            Serial.println();
            Serial.print("Connecting to ");
            // Serial.println(ssid);

            WiFi.mode(WIFI_STA);
            WiFi.begin("iot", "GdS");

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

            Serial.println("");
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
    }

    void callback(char *topic, byte *payload, unsigned int length)
    {
            Serial.print("Message arrived [");
            Serial.print(topic);
            Serial.print("] ");
            for (int i = 0; i < length; i++)
            {
                    Serial.print((char)payload[i]);
            }
            Serial.println();

            // Switch on the LED if an 1 was received as first character
    }

    void reconnect()
    {
            // Loop until we're reconnected
            while (!client.connected())
            {
                    Serial.print("Attempting MQTT connection...");
                    // Create a random client ID
                    String clientId = "ESP8266Client-";
                    clientId += String(random(0xffff), HEX);
                    // Attempt to connect
                    if (client.connect(clientId.c_str()),"guy","kupelu9e")
                    {
                            Serial.println("connected");
                            // Once connected, publish an announcement...
                            client.publish("myHome/log", "hello world");
                            // ... and resubscribe
                            client.subscribe("myHome/test");
                    }
                    else
                    {
                            Serial.print("failed, rc=");
                            Serial.print(client.state());
                            Serial.println(" try again in 5 seconds");
                            // Wait 5 seconds before retrying
                            delay(5000);
                    }
            }
    }

    void setup()
    {
            Serial.begin(115200);
            setup_wifi();
            client.setServer(mqtt_server, 1883);
            client.setCallback(callback);
            reconnect();
    }
    void loop()
    {
            loop_buttons();
            if (!client.connected())
            {
                    reconnect();
            }
            client.loop();
            static unsigned long lastentry = 0;
            static unsigned long lastentry2 = 0;
            if (millis() - lastentry > 200)
            {
                    pinMode(2, OUTPUT);
                    digitalWrite(2, !digitalRead(2));
                    lastentry = millis();
            }
            delay(50);
            if (millis() - lastentry2 > 1000)
            {
                    Serial.println(ESP.getFreeHeap());
                    lastentry2 = millis();
            }
    }

body:
In case somebody finds this when faced with the same issue:
I had a similar problem on a Pico W. Turned out that the Serial.println()s in the MQTT callback clobbered the MQTT+WiFi stack. Something did not multitask nicely. Not accessing the Arduino Serial port in the MQTT callback fixed it.


message:
No GPS data Neo 6M DFRduino Nano

I checked several answers for same question but none of them help.

I also changed the nano board and GPS module but without luck. I ran it outdoor.

[This post question][1] had same issue except my date **does not display the correct date and time**.

My connection:
```
vcc->5V
rxd->d4
txd->d3
gnd->gnd
```
FullExample program from TinyGPS++, I get following types of entries

```
Sats HDOP  Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
           (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
----------------------------------------------------------------------------------------------------------------------------------------
0    100.0  ********** *********** **** 00/00/2000 00:00:00 152  ****** ****** ***** ***   ******** ****** ***   324   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 230  ****** ****** ***** ***   ******** ****** ***   486   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 308  ****** ****** ***** ***   ******** ****** ***   648   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 384  ****** ****** ***** ***   ******** ****** ***   810   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 463  ****** ****** ***** ***   ******** ****** ***   972   0         0
0    100.0  ********** *********** **** 00/00/2000 00:00:00 541  ****** ****** ***** ***   ******** ****** ***   1134  0         0
```

  [1]: https://arduino.stackexchange.com/questions/25901/not-getting-data-from-gps

NMEA read from serial

```
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,01,05,,,20*7F
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30

$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,1,1,01,14,,,29*76
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
```

**UPDATE:**

I change the antenna. At some time I got this. From the GPGSV sentence I know that there are about 15 16 satellites in view but the FullExample only show 0.

```
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,15,04,,,31,07,,,33,09,,,34,11,,,30*74
$GPGSV,4,2,15,12,,,33,13,,,30,14,,,33,15,,,27*7D
$GPGSV,4,3,15,16,,,33,19,,,34,20,,,30,21,,,33*70
$GPGSV,4,4,15,22,,,32,23,,,33,33,,,35*7B
$GPGLL,,,,,,V,N*64

$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,16,04,,,32,07,,,33,08,,,31,09,,,33*7A
$GPGSV,4,2,16,11,,,29,12,,,33,13,,,30,14,,,34*73
$GPGSV,4,3,16,15,,,32,16,,,33,19,,,33,20,,,31*73
$GPGSV,4,4,16,21,,,33,22,,,33,23,,,34,33,,,35*7D
$GPGLL,,,,,,V,N*64
```
My idea now is to supply external power for the DFRduino Nano

Any idea how I can continue. Should I changed to other type of gps module?

body: The ceramic antenna is the issue. I changed to the external 1.5GHz one. It got fix under 5 seconds


message:
Can you coax another I²C connection out of an Arduino Nano Every?

I'm looking to network a bunch of devices (boards in a Eurorack case) over I²C, but I don't want to compromise the address space available to each individual device for its own needs. The obvious solution here is to give each device its own I²C bus which it controls, and then connect them together over another.

Two independent I²C connections would be needed on a microcontroller in this setup, and if I understand the datasheet correctly, the MCU on the Arduino Nano Every [can act as host on one bus and client on another][datasheet] using the Dual Mode setup of the Two-Wire Interface (see Chapter 25 of the linked datasheet), but the board only exposes two sets of I²C-capable pins and [they are wired together in the schematic][schematic].

What steps would I need to take to coax another I²C connection out of an Arduino Nano Every?

[datasheet]: https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega4808-09-DataSheet-DS40002173C.pdf
[schematic]: https://docs.arduino.cc/static/1d097e7f46445e1d9a88348af88dcb4f/schematics.pdf

body:
Welcome!

Theoretically you can connect 127 devices to the I2C bus. I suggest you do a little reading on the I2C bus before you start your design. Hopefully all of these I2C devices are on the same board but since you want to network them I have a feeling you are making a very painful mistake. I2C was never intended to be used for networking.

For a bunch of devices I would seriously look at CAN, two wires to connect them is all that is needed even for well over 250 meters or 800 feet with the baud rate of 250 kbit/s. I usually also run a ground. This will be much faster than the I2C. CAN is a simplex communication mode that turns around very fast. Each node can send and receive under software control. It does its own arbitration no need to worry about it the controllers do it for you.


message:
Can I run Arduino code on a 6502?

I've been doing projects with the arduino boards for a long time and accordingly also with the libs from adafruit etc. But that was too boring for me and I wanted to get more into the matter, so I used youtube and acquired knowledge about the microcontrollers eeproms etc. itself . But now my question is whether I, if I have the necessary interface adapters, etc., can compile the libs from adafruit, etc. and flash the hex file directly onto an eeprom and then use it with e.g. connect and use a 6502. but I need the corresponding settings in the IDE so that the code can be executed correctly, right? and what is the best way to do this? and general tips would also be nice thanks in advance

body:
No, you can't.

You would fail at the first hurdle: you would need to find a 6502 C++ compiler, and AFAICT there is no such thing.

Without a C++ compiler for the 6502 you would never be able to compile C++ code for the 6502.

The closest you would come is to program in pure C for the 6502, which means you won't be able to use 99% of the Arduino libraries (not counting the fact that many use architecture-specific register access) since they are written in C++ not in C.


message:
Input on the Nano RP2040 does not float

I am using the Nano RP2040 with MicroPython and run the following code:

```
import machine
import time

p0 = machine.Pin(0, machine.Pin.IN)
while True:
    print(p0.value())
    time.sleep(0.3)
```

The Nano has built-in pull-up and pull-down resistors. If I do not specify ```machine.Pin.PULL_xx```, then these built-in resistors are not activated. If they are not activated, then shouldn't the signal received be floating, i.e., shouldn't the environment interfere with the input signal and make the code above print random series of 0s and 1s on the REPL? What actually happens is the REPL prints all 0s.

I read of how input pins are interpreted as high-impedance output and while I suspect this may be the cause, I do not not understand what that means.

body:
That you'll get noise on a floating input observable in the read value isn't something you can rely on. The AVR like the ATMega328P seems to readily couple house/mains frequency noise onto inputs. However, I went to demonstrate this sort of thing for someone with a NodeMCU(ESP8266) board and found it was much harder to influence.

As I understand it the RP2040 has configurable Schmitt trigger inputs with a minimum hysteresis of 0.1 * IOVDD, 330 mV minimum, I think. And that these are on by default.  So your noise has to be bouncing across this threshold to affect the read value, which it may easily not be doing. If you turn off the Schmitt trigger feature, you *may* see more noise. I don't know how to disable them in MicroPython. The PicoSDK has a function called `gpio_set_input_hysteresis_enabled` that should do it.

You can also try running something like an old vacuum cleaner next to it to throw lots of noise into the environment.

For my own curiosity I may try playing with this on an RPI Pico, though perhaps not in MicroPython (we'll see) and if I do I'll show what I found.


message:
Using Millis instead of delay to reboot relay

I want to reboot relay (turn off , waiting 4 seconds and turn ON)
it works perfectly if I use delay(4000), but code is blocked while delay (4 seconds) and I cant start relay 2.
How can I use Millis instead of delay to reboot relay 1 and start relay 2 same time?

    #include <SPI.h>
    #include <Ethernet.h>
    #include <Wire.h>
    #include <EthernetUdp.h> //Load the Udp Library

    //Ethernet
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Assign mac address
    IPAddress ip(192, 168, 1, 178); //Assign the IP Adress
    unsigned int localPort = 80; // Assign a port to talk over
    char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //dimensian a char array to hold our data packet
    String datReq; //String for our data
    int packetSize; //Size of the packet
    EthernetUDP Udp; // Create a UDP Object                            //server port
    String readString;

    bool relayState = false;
    //define relay pins
    int relay_1 = 22;
    int relay_2 = 24;

    void setup() {
      Serial.begin(9600);
      Ethernet.begin(mac, ip);
      Udp.begin(localPort); //Initialize Udp
      delay(2000);

      //Initial state of the relay
      pinMode(relay_1, OUTPUT); digitalWrite(relay_1, LOW); //relay 1 is On
      pinMode(relay_2, OUTPUT); digitalWrite(relay_2, HIGH);//relay 2 is Off

    }

    void loop() {

      packetSize = Udp.parsePacket(); //Reads the packet size
      if (packetSize > 0) { //if packetSize is >0, that means someone has sent a request
        Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
        String datReq(packetBuffer); //Convert char array packetBuffer into a string called datReq
        //Serial.println(datReq);

        if (datReq == "relay1reboot") { //reboot relay
          digitalWrite(relay_1, HIGH);//relay off
          delay(4000);
          digitalWrite(relay_1, LOW);//relay on

          Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
          Udp.print("relay 1 reboot");
          Udp.endPacket(); //End the packet

        }
        if (datReq == "relay2on") {
          digitalWrite(relay_2, LOW);//relay 2 on
          Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
          Udp.print("relay 2 on");
          Udp.endPacket(); //End the packet
        }
        if (datReq == "relay1on") {
          digitalWrite(relay_1, LOW);//relay 2 on
          Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
          Udp.print("relay 1 on");
          Udp.endPacket(); //End the packet
        }
        // Use the snapshot to set track time until next event
        //previousMillis = currentMillis;
      }
    }

    //}
    memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE); //clear out the packetBuffer array

    }

body:
A general approach to remove a `delay()` is to replace it by some code
that:

* takes note that some action (whatever follows the `delay()`) will have
  to be performed in the future

* takes note of the current time.

Then, somewhere else in `loop()`, you check whether that “some action”
has to be done right now and, if this is the case, does it.

In this particular case, I would add a global boolean variable named
`relay1isRebooting`. When it is true, that means that the relay has been
turned off and will have to be turned on in the near future.

```c++
bool relay1isRebooting = false;
unsigned long relay1rebootStarted;

void loop() {
  packetSize = Udp.parsePacket();
  if (packetSize > 0) { //we have received a packet
    // ...
    if (datReq == "relay1reboot") {
      digitalWrite(relay_1, HIGH); //relay off
      relay1isRebooting = true;
      relay1rebootStarted = millis();
    }
    // ...
  }

  // Switch back the relay 1 on if needed.
  if (relay1isRebooting && millis() - relay1rebootStarted >= 4000) {
      digitalWrite(relay_1, LOW); //relay on
      relay1isRebooting = false;
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.print("relay 1 reboot");
      Udp.endPacket();
  }
}
```

Please note that the test for whether the relay 1 should be turned back
on is performed outside the `if (packetSize > 0)` block. Also note that
`relay1rebootStarted` has a valid value only when `relay1isRebooting` is
`true`.


message:
Is it possible to remove the bootloader while flashing using the bootloader?

The question is meant as in, can I lock myself out of the Arduino using the bootloader, if I flash a hex file that doesn't contain the bootloader?

Or does the bootloader automatically add the flashed file after itself, so that it's never overwritten?

The device in question is an Arduino Pro Micro (ATMega32u4). Asking, because I don't have an ISP available right now, and I have to flash pre-compiled hex files.

body:
If you don't play around ISP programming and have not already been playing around with ISP programming, your bootloader is fine and will remain fine no matter what you try to upload. The bootloader has its own protected section, so it's not necessary to tack it onto your sketch code on every upload. The Pro Micro bootloader can't be updated via itself anyway.

Worst case what you try to upload your precompiled binaries and they simply don't work.

You *can* upload code that fails to respond to the 1200 baud touch request that is used to reset the board into the bootloader, which may make you think you've screwed up the board, but you haven't. The Pro Micro version of Caterina bootloader supports a double-tap reset for an 8-second upload window no matter what you've put (or tried putting) on the chip.

Practically speaking, the existing bootloader is immutable and will always work for you until ISP becomes involved at some point.


message:
List of supported boards in Arduino IDE 2.0

Where can I find the list of supported boards in Arduino IDE 2.0 without installing the IDE? Googling it was not fruitful. Specifically, I'm looking for ESP32-S3 support.

body:
The 2.X IDE [makes use][1] of [arduino-cli](https://github.com/arduino/arduino-cli):

> The backend operations such as compilation and uploading are offloaded
> to an arduino-cli instance running in daemon mode.

which has roughly the same internals as [arduino-builder](https://github.com/arduino/arduino-builder)

> The arduino-builder is now just a wrapper of arduino-cli

which is what the 1.X IDE uses to launch the build process. Roughly speaking, they support the same boards.

About the only difference I've noticed is that the 2.X IDE does not *yet* support `disableRTS` and `disableRTS` board properties, so some ESP32 board that require these settings will not (yet) work in with the 2.X IDE's serial monitor. The ESP32-CAM-MB together with ESP32CAM is one combination where the Serial Monitor won't work. You can still upload with it though.

So, the IDE should compile and upload for your ESP32-S3 just fine. If you want to know whether or not the Serial Monitor will work, it's down to looking at the specific board schematic to see whether or not the EN/RESET and GPIO0 signals are connected to the serial transceiver using only diodes. The official boards don't do this. So if you have one of the Expressif devkits (or a clone) the 2.0 IDE Serial Monitor will work fine with it.

  [1]: https://github.com/arduino/arduino-ide


body:
> Where can I find the list of supported boards in Arduino IDE 2.0
> Specifically, I'm looking for ESP32-S3 support.

Without knowing what you want to do, the short answer is: check this JSON's `"boards"` properties: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json.

The Arduino IDE is just a user interface on top of the `arduino-cli`. It provides a way to change the [`board_manager#additional_urls`](https://arduino.github.io/arduino-cli/latest/configuration/) property of the CLI configuration. Once a new 3rd party platform URL is specified in the IDE, the CLI will see the available boards of the [platform](https://arduino.github.io/arduino-cli/latest/platform-specification/). You'll need to install the platform to verify and upload your sketches. After installing the platform, the [`"boards.txt"`](https://arduino.github.io/arduino-cli/latest/platform-specification/#boardstxt) will be available on your filesystem for the CLI. For this example, this is https://github.com/espressif/arduino-esp32/blob/master/boards.txt.


message:
Looking for a very simple board

I’ve worked with esp8266/esp32 boards in the past and they were great. But now I have a very simple project where both of these are way too powerful.

I want to read one analog input over USB per COM. That’s it. No wifi, no Bluetooth, no 32 bit or any of these _fancy things_.
It should be programmable without any hardware other than a computer though. It doesn’t need to be Arduino. All it has to do is to read the input and respond to serial communication.

But I’m absolutely overwhelmed by all these microcontrollers. Most of them are feature packed.

So I’m asking for a way to find a proper controller/board on my own. Feel free to recommend one though.

body:
Since you seem to have some experience, seemingly these are valid options:

1. Obtain the smallest Arduino you can get. For example, a DigiSpark  original or clone, or a DFRobot Beetle. Use the Arduino IDE to program it.

1. Obtain the smallest AVR board you can get. For example, with an ATmega32u4. Download ASF, the Atmel Software Framework, learn how to use it. It provides a lot of sources for ADC and USB.


body:
Since you require USB, nano/micro are your way forward.
being mass produced anything smaller would actually turnout to be more expensive.

If you for those reading this message latter: If you do not need USB then you have a pro-miny (needs USB->ttl for programing)

If you are going really minimalist you can go with MSP430 chips (arduino programming available via PlatformIO).
Atmega32u4 can although run on its own without crystal, but I find Crystal free (using builtin crystal) run of MSP430 much better with timing.
Problem with MSP430 is that TI software development dedepartment is stuck in middle ages. (I am not sure if they even employ a full-time programmer) and if you are programming on arm, you might Have a problem compiling it from arm platform.


message:
avr_boot change LED pin

I would like to know how can I change LED pin for [avr_boot][1] bootloader.

I can see there is option in variants folder but in the manual it mention "if using USE_LED adapt LED-pins in asmfunc.S" which is not clear. I am using pin PC3 how do I write it.

  [1]: https://github.com/zevero/avr_boot

body:
Near the top of asmfunc.S, you have [these lines][code]:

```lisp
; LED Pins
#define DDR_SS _SFR_IO_ADDR(DDRD), 5 // SS pin (PIN, PORT)
#define PORT_SS _SFR_IO_ADDR(PORTD), 5

#define DDR_PW _SFR_IO_ADDR(DDRD), 6 // Power pin (PIN, PORT)
#define PORT_PW _SFR_IO_ADDR(PORTD), 6
```

These define the “write” or “slave select” LED pin as PD5 (registers
DDRD and PORTD, bit 5), and the “power” LED as PD6 (registers DDRD
and PORTD, bit  6).

These are the lines you have to change if using different pins. For
example, pin PC3 is: registers DDRC and PORTC, bit 3.

[code]: https://github.com/zevero/avr_boot/blob/v1.3.0/asmfunc.S#L9-L14