body:
I want to create a custom keyboard mapping in the [official arduino keyboard library](https://www.arduino.cc/reference/en/language/functions/usb/keyboard/)

Why do the key definitions add 136 to each number?

[See Keyboard_es_ES.h on github](https://github.com/arduino-libraries/Keyboard/blob/master/src/Keyboard_es_ES.h#L37-L42
)

```
#define KEY_MASCULINE_ORDINAL    (136+0x35)
#define KEY_INVERTED_EXCLAMATION (136+0x2e)
#define KEY_GRAVE                (136+0x2f)
#define KEY_N_TILDE              (136+0x33)
#define KEY_ACUTE                (136+0x34)
#define KEY_C_CEDILLA            (136+0x31)
```

Looking at the [ascii table](https://www.asciitable.com/), I see nothing special about value 136

title: Why does keyboard.h add 136 to each key?

Answers: 1

body:
It could be argued that this is an implementation detail of the library,
that does not need to be documented. ;-) Anyway, here is the reason...

The keyboard library uses a custom encoding scheme for representing
_both_ characters and keys. The public methods `press()`, `release()`,
`write()`, `print()` and `println()` interpret the user-provided data
according to this scheme. With this encoding, the interpretation of a
byte depends on which of these three ranges it belongs to:

* Bytes in the range [0, 127] are understood to be ASCII
  characters. This is what enables you to write things like
  `Keyboard.println("Hello!");`. The library uses a keyboard layout
  array to map those characters to key scan codes¹, possibly modified by
  Shift or AltGr. You provide a pointer to this array as an argument to
  `begin()`.

* Bytes in the range [128, 135] are interpreted as modifier keys,
  such as `KEY_LEFT_CTRL`, `KEY_RIGHT_SHIFT`, etc. Note that these keys
  do not have proper scan codes, as their state is transmitted to the
  host as a bit map (one byte for the eight keys) rather than as codes
  added to a list.

* Bytes in the range [136, 255] are interpreted as raw scan codes
  in the range [0, 119], shifted by 136. This is what lets you
  actuate arbitrary keys such as `KEY_PRINT_SCREEN` or `KEY_LEFT_ARROW`.
  All scan codes of a standard full-size PC keyboard (ANSI 104 or
  ISO 105) lie in the range [4, 101]: you can access all of
  them, and even some more like `KEY_F24`.

Regarding the file Keyboard\_es\_ES.h: the codes in there are for keys
that match ASCII characters in the US layout but not in the Spanish
layout. The purpose is to ensure that every key of a ISO 105
keyboard can be actuated using either an ASCII character (like
`Keyboard.press('a');`) or a `KEY_*` macro.

¹ The USB standard calls them “usage codes”, but the old term “scan
codes” seems more prevalent.


body:
I'm an art student and absolute beginner to electronics/code  -  my broader goal is to learn how to control individual LEDs when there are many of them (like 64 or more even, so am learning about shift registers, multiplexing etc. also).

I have been working with a [4x4 matrix example][1] by Jon Fox. I have breadboarded it as below and checked it multiple times.

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

For the most part it's successful; the code runs and I get the LED animations in his code. I am also able to anticipate which parts of the code refer to which LEDs when I test by commenting out parts of the code - for example `r1c1()` refers to the top row, right-most LED.

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

However, the top row, second from the left LED does not turn on.

I have tested the individual LEDs before starting, tested the connections of the wires in case they don't make good connection in the breadboard, and tried adding 330 Ω resistors to the rows (instead of the orange connection wire in the image), and tried with 1 kΩ resistors instead of 220 Ω. The reason I tried those values was that I have been successful when I've used another set up I have, image below.

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

The blue and the white LEDs draw similar voltage so as far as I understand this wouldn't affect anything. The code runs great on this also.

I understand I could still be making some human error, especially as I've been going crazy with this. However, because I really want to understand the factors involved in controlling LEDs, I'd love to know if at all there are other variables at play.

For one, I was looking into 'floating inputs' hence tried adding the other set of resistors, and tried colour LEDs (more bulbs were either off or dim) as well as 3 mm white LEDs (same result as 5mm). The most difficult thing in this process is wondering what I don't know, so if anyone can direct me towards things I should consider for my purpose, or help me solve my current problem, I'd be really grateful.

  [1]: https://github.com/FoxJon/Arduino4x4LEDMatrix
  [2]: https://i.stack.imgur.com/Did77.png
  [3]: https://i.stack.imgur.com/8PqpU.jpg
  [4]: https://i.stack.imgur.com/ZoUkU.jpg

title: One LED in 4x4 matrix does not turn on

Answers: 1

body:
It is very difficult to be certain.  You state that the second from the left LED in to top row is not turning on as expected.  In the bread-board diagram this LED is plugged into holes D7 and D8.  However, in the image it appears this LED is plugged into holes D8 and E8.

The exact letter/number may not matter if you are not following your bread-board diagram precisely.  However all pins in a row (i.e. A8, B8, C8, ... , E8) are shorted together.  So plugging in an LED into holes D8 and E8 would prevent it from lighting up.

Also, you have added resistors to your matrix which are not in the bread-board diagram.  The column resistors appear correct but the row resistors are questionable.  In practice, if you are going to light only 1 LED in a column at a time, then you might get by with only column resistors.  For such a configuration (only column resistors) you may see the LEDs dim if you light more than 1 per column.  If you do want to light more then one LED per column, the trick is to let the software switch LEDs on and off such that there is only one lit per column at a time. But fast enough so that a human eye can not see it.  So a bit faster than 100ms.


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

title: Trigger event onRelease of button

Answers: 3

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.

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/

body:
Origionally I started with the EasyButton library, but when I wasn't able to get it working I switched to the `madleech/Button@^1.0.0` library and got the following working.

Note that this depends on polling which could definitly be improved.

While this deviates from the original question, I feel it is worth sharing for anyone else who wants a working but (less than ideal) solution.

```
#include <Arduino.h>

#include <Button.h>

Button button1(2);

unsigned long buttonCheckMillis;

void setup()
{
  buttonCheckMillis = millis();
  button1.begin();
}

void loop()
{
  if (button1.toggled()) {
    // User pressed the button
    if (button1.read() == Button::PRESSED) {
      Serial.println("Button Pressed");
    }
    // User released the button
    else {
      Serial.println("Button Released");
    }
  }
  // Poll every 100 milliseconds to see if user is still holding button
  if (millis() - buttonCheckMillis > 100) {
    buttonCheckMillis = millis();
    if (button1.read() == Button::PRESSED) {
      Serial.println("Button Held");
    }
  }

}
```


body:
In Summary. If the argument is true, I want to create a function that prints the necessary stuff into the serial. However, if its false serial is uninitialised and does not print anything, it only executes the code.
The code below does not work, but it's an example code to show what I mean.
```
bool status;
void setDebug(bool x){
 if (x){
  Serial.begin(115200);
  status = true;
 }
else {
 status = false;}
}
void setup(){
 setDebug(true);
}
void loop(){
Serial.println("Hello World");
}
```
I have found a few solutions that might be beneficial
1.  If Statement - This overall code works; however, I am looking for a better and more efficient way to do this
```
void loop(){
 if (status){
  Serial.println("Hello World");
 }
}
```
2. Preprocessor directive - I have seen many libraries use #ifdef DEBUG, which works. However, I want to be able to  change it through a function, and the preprocessor directives won't allow me to do that
```
void loop(){
 #ifdef DEBUG
  Serial.println("Hello World");
 #endif
}
```
How else can I achieve this?

title: How initialise and uninitialise serial based on the user's input?

Answers: 0


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

title: Using Visual Studio Code to program an Arduino

Answers: 3

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


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

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

Answers: 1

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.


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

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

Answers: 1

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.


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

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

Answers: 1

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.


body:
I have two ESP32s. One is acting as webserver and the other is acting as a client that will send a GET request to the server ESP32. Both of the ESP32s are connected to the same WiFi AP.

For sending the request I need to know the server address, but I don't want to enter it into the code manually.

Is there any way with which I can figure out the IP address of the server ESP32 using the other ESP32?

title: Communication between two ESP32s using WiFi

Answers: 0


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

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

Answers: 1

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


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

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

Answers: 1

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/


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

title: LM7805 gets very hot with four servo motors

Answers: 3

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.


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

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

Answers: 1

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)


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

title: AfMotor Shield Library does not work with template programming

Answers: 1

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


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

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

Answers: 1

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.


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

title: Multiply char with float

Answers: 2

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.


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

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

Answers: 1

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?


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

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

Answers: 1

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


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

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

Answers: 1

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.


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

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

Answers: 1

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.


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

title: displaying double variable problem (Arduino)

Answers: 1

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


body:
I would like to connect ESP8266 with Azure IoT Hub Device via X509 certificate. Currently, I can connect using the symmetric key connection to my device, but I have devices that I want to authenticate with X509 certificate.

I found a [solution][1], but is for Arduino Nano 33 IoT, which is probably using another chip and it has encryption slot.

I am trying to do this using the Azure IoT SDK C library, but without much success. Here is a code that is using Mqtt and WiFiClientSecure plus BearSSL in order to connect via certificate. Unfortunately, the only solution that I found was to generate ECCX09 certificate with a chip that have encryption and to just use the thumbprint. Here is my try to use the certificate:

```
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT

// C99 libraries
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <cstdlib>

// Libraries for MQTT client, WiFi connection and SAS-token generation.
#include <ESP8266WiFi.h>
#include <ArduinoBearSSL.h>
#include <ArduinoMqttClient.h>

// Additional sample headers
#include "secrets.h"

// Utility macros and defines
#define LED_PIN 2

// Translate iot_configs.h defines into variables used by the sample
static const char* ssid = SECRET_WIFI_SSID;
static const char* password = SECRET_WIFI_PASS;
static const char* host = SECRET_BROKER;
static const String device_id = SECRET_DEVICE_ID;

// Memory allocated for the sample's variables and structures.
static WiFiClientSecure wifi_client;
static BearSSLClient ssl_client(wifi_client);
static MqttClient mqtt_client(ssl_client);

// Auxiliary functions
static void connectToWiFi()
{
  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to WIFI SSID ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

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

/*
 * Establishses connection with the MQTT Broker (IoT Hub)
 * Some errors you may receive:
 * -- (-.2) Either a connectivity error or an error in the url of the broker
 * -- (-.5) Check credentials - has the SAS Token expired? Do you have the right connection string copied into arduino_secrets?
 */
void connectToMQTT() {
  Serial.print("Attempting to MQTT broker: ");
  Serial.print(host);
  Serial.println(" ");

  while (!mqtt_client.connect(host, 8883)) {
  // failed, retry
    Serial.print(".");
    Serial.println(mqtt_client.connectError());
    delay(5000);
  }
  Serial.println();

  Serial.println("You're connected to the MQTT broker");
  Serial.println();

  // subscribe to a topic
  mqtt_client.subscribe("devices/" + device_id + "/messages/devicebound/#");
}

unsigned long getTime() {
  // get the current time from the WiFi module
  // return WiFi.getTime();
  return time(NULL);
}

static void establishConnection()
{
  // Set the username to "<broker>/<device id>/?api-version=2018-06-30"
  String username;

  // Set the client id used for MQTT as the device id
  mqtt_client.setId(device_id);

  username += host;
  username += "/";
  username += device_id;
  username += "/api-version=2018-06-30";
  mqtt_client.setUsernamePassword(username, "");

  if(WiFi.status() != WL_CONNECTED) {
    connectToWiFi();
  }

  if (!mqtt_client.connected()) {
    // MQTT client is disconnected, connect
    connectToMQTT();
  }
}

// Arduino setup and loop main functions.

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  Serial.begin(9600);

  // Set the X.509 certificate
  // ssl_client.setEccCert(CLIENT_CERT);
  ssl_client.setEccSlot(0, CLIENT_CERT);

  // Set a callback to get the current time
  // used to validate the servers certificate
  ArduinoBearSSL.onGetTime(getTime);

  establishConnection();
}

void loop() {}
```

This fails on setting the Certificate and to use the ecc slot 0, because I am using ESP8266 that does not have cryptography in it (or at least I do not know). I saw in the library that there is another method in the BearSSL - void setEccCert(*br_x509_certificate* cert); , but I do not know how to initialize *br_x509_certificate* (here is the [ref][2]).

I decided to try something else, too, reading the certificate with SPIFFS, then adding to WiFiClientSecure. Unfortunately, I cannot load the private key to make client connection.
```
#include "FS.h"             // File system commands to access files stored on flash memory
#include <ESP8266WiFi.h>    // WiFi Client to connect to the internet
#include <PubSubClient.h>   // MQTT Client to connect to AWS IoT Core
#include <NTPClient.h>      // Network Time Protocol Client, used to validate certificates
#include <WiFiUdp.h>        // UDP to communicate with the NTP server
#include "secrets.h"

// Utility macros and defines
#define NTP_SERVERS "pool.ntp.org", "time.nist.gov"

// Translate secrets.h defines into variables used by the sample
static const char* ssid = SECRET_WIFI_SSID;
static const char* password = SECRET_WIFI_PASS;
static const char* iot_hub_broker = SECRET_BROKER;

// callback function that will be called when the device receive a message
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();
}

// Memory allocated client variables
static WiFiUDP ntp_UDP;
static NTPClient time_client(ntp_UDP, "pool.ntp.org");
static WiFiClientSecure esp_client;
static PubSubClient mqtt_client(iot_hub_broker, 8883, callback, esp_client);

// Auxiliary functions
static void configureX509CertificateConnection() {
  time_client.begin();
  while(!time_client.update()) {
    time_client.forceUpdate();
  }

  esp_client.setX509Time(time_client.getEpochTime());
  Serial.println("Time client and ESP client are set up.");

  // Attempt to mount the file system
  if (!SPIFFS.begin()) {
    Serial.println("Failed to mount file system");
    return;
  }

  // Load certificate file from file system
  File cert = SPIFFS.open("temperature-sensor-1-all.pem", "r");
  if (!cert) {
    Serial.println("Failed to open certificate from file system");
  } else {
    Serial.println("Successfully opened certificate file");
  }

  // Load private key file from file system
  File private_key = SPIFFS.open("/temperature-sensor-1-private.pem", "r");
  if (!private_key) {
    Serial.println("Failed to open private key from file system");
  }
  else {
    Serial.println("Successfully opened private key file");
  }

  delay(1000);

  // Load private key to client connection
  if (esp_client.loadPrivateKey(private_key)) {
    Serial.println("Private key loaded to client connection");
  }
  else {
    Serial.println("Private key not loaded to client connection");
  }
}

static void connectToWiFi() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to WiFi: ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

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

/*
 * Establishses connection with the MQTT Broker (IoT Hub)
 * Some errors you may receive:
 * -- (-.2) Either a connectivity error or an error in the url of the broker
 * -- (-.5) Check credentials - has the SAS Token expired? Do you have the right connection string copied into arduino_secrets?
 */
void connectToMQTT() {
}

static void establishConnection() {
  if (WiFi.status() != WL_CONNECTED) {
    connectToWiFi();
  }

  configureX509CertificateConnection();
}

// Arduino setup and loop main functions.
void setup() {
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  Serial.begin(115200);

  establishConnection();
}

void loop() {}
```

P.S. I have it up and running on Raspberry Pi, but I have to make some experiments using the Arduino and ESP8266.

P.S.2. I am using [Arduino with Atmega328P with integrated ESP8266 chip][3], but working only with the ESP8266. Additionally, I am using Arduino IDE 1.8.19 and installed the Azure IoT SDK C library (and some other required ones).

P.S.3. Additionally, I could find [X509 certificate sample][4], but it is using the Paho Mqtt Client and I am not able reproduce it on Arduino.

  [1]: https://github.com/s-gregorini003/azure-iot-arduino-nano-33-iot/blob/master/nano33iothub/nano33iothub.ino
  [2]: https://github.com/arduino-libraries/ArduinoBearSSL/blob/master/src/BearSSLClient.h
  [3]: https://elimex.bg/product/82814-k2218-razvoina-platka-s-wifi-esp8266-i-mega328p-uno-r3
  [4]: https://github.com/Azure/azure-sdk-for-c/blob/main/sdk/samples/iot/paho_iot_hub_twin_sample.c

title: Connect Arduino + ESP8266 to Azure IoT Hub Device via X509 certificate

Answers: 0


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

title: PSF WiFi module - Is it similar to ESP8266

Answers: 1

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


body:
I previously succeed in uploading the code to DFRDuino Nano (Arduino Nano Compatible) (with wrong digital pins) but after changing pin I cannot upload it again.

From the [document][1], I changed back the pins 0 (RX) and 1 (TX) are used for serial communication.

In arduino ide (1.8.19), I choosed **board: Arduino Nano** and **Processor: ATmega328P(Old Bootloader)**

The error:
```
. . .

avrdude: Version 6.3-20190619

        Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

        Copyright (c) 2007-2014 Joerg Wunsch

        System wide configuration file is "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.57.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf"

        Using Port                    : COM3

        Using Programmer              : arduino

        Overriding Baud Rate          : 57600

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00

avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

avrdude done.  Thank you.

An error occurred while uploading the sketch

```

I have reset both the board and computer but without luck. I changed another board and got the same error.

Any idea how to solve it?

**UPDATE:**

I uploaded the empty code to reset the board but it yielded the same error.

  [1]: https://wiki.dfrobot.com/Arduino_Nano_328__SKU__DFR0010_

title: Cannot upload sketch to DFRduino nano

Answers: 0


body:
this is the code I used:

    #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[] = "xxxx";        // 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
                "\r\n");
              client.print("<!DOCTYPE HTML>\r\n");
              client.print("\r\n");
              client.print("
\r\n");
              client.print("Accelerometro X: ");
              client.print(AcX);
              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(10);

        // 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;

        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;

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

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

    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();
    }

This is what I see in the serial monitor with a baud of 115200:
```
[WiFiEsp] Initializing ESP module
[WiFiEsp] Initilization successful - 1.5.4
Attempting to connect to WPA SSID: Vodafone-A61356555
[WiFiEsp] Connected to Vodafone-A61356555
You're connected to the network
SSID: Vodafone-A61356555
IP Address: 192.168.1.30

To see this page in action, open a browser to http://192.168.1.30

[WiFiEsp] Server started on port 80
[WiFiEsp] New client 0
New client
GET / HTTP/1.1
Host[WiFiEsp] TIMEOUT: 428
Client disconnected
[WiFiEsp] New client 0
New client
GET / HTTP/1.1
Host[WiFiEsp] TIMEOUT: 428
Client disconnected
```

title: ESP8266 TIMEOUT: 428

Answers: 0


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

title: Share interrupt service between class

Answers: 1

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/


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

title: String() vs char for simple flow control

Answers: 2

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


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

title: Char Array in PreProcessor

Answers: 1

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


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

title: GY-521 output and degrees

Answers: 1

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/