body:
Q: What is the logic behind Arduino inlining `HardwareSerial::_rx_complete_irq()` for receiving serial data (but NOT `_tx_udr_empty_irq()`), and when is it advisable?

From the bottom of the `HardwareSerial` class in [HardwareSerial.h][1]:

    // Interrupt handlers - Not intended to be called externally
    inline void _rx_complete_irq(void);  // <======= inline!
    void _tx_udr_empty_irq(void);        // <======= NOT inline! Why?

Furthermore, what is the design logic behind putting one of the serial ISR function definitions in a header file vs in a source file? Also, when is this good design and what are the tradeoffs, and when is it illegal or not permitted by the language, compiler or anything else?

Here is the exact scenario that made me think of this question:

----------

See here for the HardwareSerial implementation files: https://github.com/arduino/ArduinoCore-avr/tree/master/cores/arduino

Here is the main header file. https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.h

# The inline ISR `_rx_complete_irq()`:

 - Line 138 of ["HardwareSerial.h"][1] declares the inline ISR for when serial data is received:

        inline void _rx_complete_irq(void);

   - This ISR is called whenever "there are unread data present in the receive buffer." ([ATmega328 Datasheet][2] 20.7.3 p190)
   - Line 40 and 48-50 of ["HardwareSerial0.cpp"][3] is where the ISR is set up:

            ISR(USART_RX_vect)  // line 40
            {                   // line 48
              Serial._rx_complete_irq();  // line 49
            }                   // line 50

    - Line 101-121 of ["HardwareSerial_private.h"][4] implements the inline `_rx_complete_irq()` function:

            void HardwareSerial::_rx_complete_irq(void)
            {
              if (bit_is_clear(*_ucsra, UPE0)) {
                // No Parity error, read byte and store it in the buffer if there is
                // room
                unsigned char c = *_udr;
                rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;

                // if we should be storing the received character into the location
                // just before the tail (meaning that the head would advance to the
                // current location of the tail), we're about to overflow the buffer
                // and so we don't write the character or advance the head.
                if (i != _rx_buffer_tail) {
                  _rx_buffer[_rx_buffer_head] = c;
                  _rx_buffer_head = i;
                }
              } else {
                // Parity error, read byte but discard it
                *_udr;
              };
            }

# The NON-inline ISR `_tx_udr_empty_irq()`:

 - Line 139 of ["HardwareSerial.h"][1] declares the ISR for transmitting serial data: `void _tx_udr_empty_irq(void);`
   - This ISR is triggered by the "USART Data Register Empty" flag and is called whenever the transmit buffer has passed its value to the shift register and now is "ready to receive new data" ([ATmega328 Datasheet][2] 20.11.2 p200)
   - Its implementation is on lines 89-113 of ["HardwareSerial.cpp"][5]

            void HardwareSerial::_tx_udr_empty_irq(void)
            {
              // If interrupts are enabled, there must be more data in the output
              // buffer. Send the next byte
              unsigned char c = _tx_buffer[_tx_buffer_tail];
              _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;

              *_udr = c;

              // clear the TXC bit -- "can be cleared by writing a one to its bit
              // location". This makes sure flush() won't return until the bytes
              // actually got written. Other r/w bits are preserved, and zeroes
              // written to the rest.

            #ifdef MPCM0
              *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
            #else
              *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0)));
            #endif

              if (_tx_buffer_head == _tx_buffer_tail) {
                // Buffer empty, so disable interrupts
                cbi(*_ucsrb, UDRIE0);
              }
            }

**Why the difference? Why inline one ISR and not the other?**

Again, from the bottom of the `HardwareSerial` class in [HardwareSerial.h][1]:

    // Interrupt handlers - Not intended to be called externally
    inline void _rx_complete_irq(void);  // <======= inline!
    void _tx_udr_empty_irq(void);        // <======= NOT inline! Why?

**Why the somewhat complicated set of 3+ files?
Mainly:**

 - HardwareSerial.h
 - HardwareSerial_private.h
 - HardwareSerial.cpp

I first documented this to myself and wondered about it on 31 Jan. 2018, while studying the Arduino source code. I'd like to hear some more insight on the topic from other developers.

  [1]: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.h
  [2]: http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
  [3]: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial0.cpp
  [4]: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial_private.h
  [5]: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.cpp

title: What is the logic behind Arduino inlining `HardwareSerial::_rx_complete_irq()` for receiving serial data (but NOT `_tx_udr_empty_irq()`)?

Answers: 1

body:
> What is the logic behind Arduino inlining HardwareSerial::_rx_complete_irq() for receiving serial data (but NOT _tx_udr_empty_irq()), and when is it advisable?

There's a couple of reasons which end up with this arrangement:

1. The RX interrupt has to be fast as we're reacting to an external stimulus. The TX interrupt doesn't have to be fast as it's only used to move data from the buffer to the UART.

We need to be able to respond rapidly to incoming data so we can store it away in the RX ring buffer in time to handle the next byte that arrives. Not really a problem at low baud rates, but when it comes to higher ones every cycle that can be shaved off that interrupt time is beneficial.  The TX interrupt, though, really doesn't matter. All it does is load the next byte into the outgoing UART buffer, and it doesn't matter if that takes a little longer, so there's no need to shave off the extra instruction cycles consumed by making a function call.

2. The TX interrupt is called from multiple places but the RX isn't.

The RX interrupt code is only ever called when the interrupt fires. That means it's only ever going to be called through one execution path.  However the TX interrupt code is not only called by the interrupt itself, but by other areas of the code. For example, if interrupts are disabled then the `write` function will manually poll the UART for the buffer state and manually call the interrupt function to send the data (see [line 262 of HardwareSerial.cpp](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.cpp#L262)).

If the TX interrupt code were inlined then there would be lots of places throughout the code where that block would be duplicated causing code bloat. That's code bloat with no reason (See point 1) so it's something to be avoided.

> Furthermore, what is the design logic behind putting one of the serial ISR function definitions in a header file vs in a source file?

Inlining can only be done within a single *translation unit*. If you want a function to be inlined in multiple translation units (HardwareSerial0.cpp, HardwareSerial1.cpp, etc) then you would have to have it within those translation units. And that means that you need it in the header1. Since the TX interrupt is not wanted to be inlined it can be put in a CPP file instead.

> Why the somewhat complicated set of 3+ files?

Simple: management. It's easier to manage the (rather complex UART) code if it's broken down into different areas.  You have a common base object in HardwareSerial.cpp which is then used by the code for each individual UART in the HardwareSerial[0-3].cpp files.  You have a single header file that defines the class and all its methods and data (HardwareSerial.h). And then you have the "private" header with any inline functions in it that is included where it's needed.

True you could merge the HardwareSerial.h and the HardwareSerial_private.h into one, but this way the inline functions are excluded from translation units where they aren't needed. This way you don't get those chunks of code included in your sketch. True the linker will discard them as they're not used, but it's just tidier this way - the functions are only included in those translation units where those function are actually used.

----

Notes:

1. This code was written before the compiler had support for *Link Time Optimization* which allows inlining between translation units. The compiler may have moved on, but there is no point in changing code that works perfectly fine.


body:
I have an arduino mega 2560 and a recently purchased HC-08 module and the connection is as the following:

**Arduino** | **HC-08**

VCC - VCC

GND - GND

14TX3 - TXD

15TX3 - RXD

When I power up the arduino it shows that flashing light and I am able to see it on my android phone but would only reject the connection every time I tried to pair. Also I am not able to send or receive any data from it at all, here is my code:

```
#include <SoftwareSerial.h>

SoftwareSerial hc08(15,14) // RX pin, TX pin;

void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  hc08.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (hc08.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(hc08.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    hc08.write(Serial.read());
  }
}
```

I'd really appreciate help on how to get it working.

title: Using HC-08 bluetooth module with arduino

Answers: 2

body:
```
void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  Serial3.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (Serial3.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(Serial3.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    Serial3.write(Serial.read());
  }
}
```

body:
I think this is the problem on the hardware setting. It should be:
Arduino | HC-08

VCC - VCC

GND - GND

14RX3 - TXD

15TX3 - RXD

Variable declare:
SoftwareSerial hc08(14,15) // RX pin, TX pin;


body:
I am trying to use serial communication to open and close a Blue Robotics Newton gripper. The gripper works with normal commands, but when I try to use serial communication to control it, it is extremely slow and my commands do not correspond to the action I would like. For example, I'll write a "o" in the serial monitor and the gripper will not open.

Does anyone know what is wrong?

 ```
#include "Servo.h"

#define GRIPPER_PWM_PIN   10    // Gripper PWM output pin
#define OPEN_TIME         5.0   // Gripper open time (seconds)
#define CLOSE_TIME        5.0   // Gripper close time (seconds)

#define OPEN_PWM_US       1100  // Gripper open PWM output (us)
#define CLOSE_PWM_US      1900  // Gripper close PWM output (us)
int incomingByte =0; // for incoming serial data
Servo gripper;

void setup() {
  // Attach gripper to proper pin
  gripper.attach(GRIPPER_PWM_PIN);
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

}

void loop() {
  if (Serial.available() > 0){
    incomingByte = Serial.read();
    if (incomingByte == 'o')
    {
      // Open the gripper
      gripper.writeMicroseconds(1100);
      // Let the gripper open up (microseconds)
      delay(OPEN_TIME*1000);
    }

    if (incomingByte == 'c')
    {
      // Close the gripper
      gripper.writeMicroseconds(1900);
      // Let the gripper close for a while (microseconds)
      delay(CLOSE_TIME*1000);
    }
  }
}
 ```

title: How to fix serial communication?

Answers: 1

body:
You have a big 5s delay in your code, right after both serial commands. You don't need a delay there; it does not do anything. But it makes your code unresponsive. So you can simply remove it.

I guess you wanted to do some timed thing there and accidentally left it there.  But in general you should not use any big `delay()` in any code. As you have seen, it makes your code unresponsive, as the Arduino doesn't do anything during this time. Instead look at the `BlinkWithoutDelay` example, that comes with the Arduino IDE (Its a really important principle to learn). It uses the `millis()` function (or alternatively the `micros()` function) to check, if it is time to do something. If yes, it will execute this, if not, it will exit fast and give the rest of the code an opportunity to execute. Much like you would bake a pizza: You start the baking and then regularly  check the clock, if it is time to take the pizza out. In between you can do other things, like reacting go messages on your phone. Its the same principle, just in code.


body:
I have an Arduino UNO connected to ESP32 through voltage divider with TX0 from Uno to RX2 to ESP32. My goal is to send data from my Uno to my ESP32 through `HardwareSerial`. Here's my code for the Uno:

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

    void loop() {
    int t = 100;
    String myString = String(t);
    Serial.println(t);
    delay(5000);
    }
Here I assign an `int` to 100 and then cast it to `String` so I can send it on my ESP32's side. My code for ESP32 is:

    #define RXD2 16
    #define TXD2 -1

    HardwareSerial Serial2(1); // Use UART channel 1

    void setup() {
    Serial.begin(9600);
    Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
    }

    void loop() {
    if(Serial2.available() >= 1){
    Serial.print("Data received:");
    Serial.print(Serial2.readString());
    }
    }
The serial monitor on ESP's side is printing only "100" on every 5 seconds but if I disconnect the Uno from my Port, the ESP's monitor keeps printing "100" even tho it shouldn't.
However, **IF** I type `Serial.println("100");` then I get "Data received: 100" on ESP's side and if I unplug the Uno, the ESP's monitor doesn't print anything or with other words it works properly. Is there a way I can fix this?

title: Uno to ESP32 - HardwareSerial repeats value on ESP32's side even though Uno is disconnected

Answers: 0


body:
I have been working on getting an Atmega32u4 connected to USB. I lifted the connections from the Arduino Micro schematic for the preliminary schematic shown here. When I connect the chip to USB, the system (Ubuntu 18.04) does not appear to recognize it.

I was able to burn the Caterina-Micro bootloader via my Pololu USB AVR Programmer as well as through ArduinoISP to confirm that everything was uploaded correctly. The following is the output of avrdude using the pololu programmer:

> $ avrdude -p m32u4 -P /dev/ttyACM0 -c avrispv2 -U flash:w:Caterina-Micro.hex
>
> avrdude: AVR device initialized and ready to accept instructions
>
> Reading | ################################################## | 100%
> 0.00s
>
> avrdude: Device signature = 0x1e9587 (probably m32u4) avrdude: NOTE:
> "flash" memory has been specified, an erase cycle will be performed
>          To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "Caterina-Micro.hex" avrdude:
> input file Caterina-Micro.hex auto detected as Intel Hex avrdude:
> writing flash (32730 bytes):
>
> Writing | ################################################## | 100%
> 8.21s
>
> avrdude: 32730 bytes of flash written avrdude: verifying flash memory
> against Caterina-Micro.hex: avrdude: load data flash data from input
> file Caterina-Micro.hex: avrdude: input file Caterina-Micro.hex auto
> detected as Intel Hex avrdude: input file Caterina-Micro.hex contains
> 32730 bytes avrdude: reading on-chip flash data:
>
> Reading | ################################################## | 100%
> 6.76s
>
> avrdude: verifying ... avrdude: 32730 bytes of flash verified
>
> avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
>
> avrdude done.  Thank you.

Using a Saleae Logic Analyzer, I sniffed the following USB communications. It seems to me that the atmega is transmitting properly but not receiving any responses but I am not certain.

I confirmed that the USB cable in use was working by plugging it into an Arduino Micro that I have. System was able to identify Arduino Micro, Arduino Uno and pololu AVRisp.

I am hoping that there is an easily assignable cause to the issues that I am experiencing. If any addition information is required, please ask.

title: Arduino Micro Breadboard USB Not Connecting

Answers: 0


body:
After working with an Arduino Uno at work, I am looking to buy myself a board for some projects/experiments at home. The nano size seems like a great option, especially the one without soldered headers, as it is very flexible and easy to fit in projects with limited space. More specifically, I am interested in nano 33 ble and nano 33 ble sense.

My question is, apart from price does anyone know of any other disadvantages the sense board might have on comparison to the 33 ble?

Does it consume more power if the sensors are not used in a projects (just from being integrated in the board’s circuit)?

Also, does the light intensity sensor work like an LDR (photoresistor)? E.g. will I be able to do things like turn on LEDs automatically when it is dark, based on the sensor’s readings?

title: Arduino nano 33 ble vs ble sense. Power consumption, etc

Answers: 1

body:
The [official page for the Nano 33 BLE Sense](https://store.arduino.cc/usa/nano-33-ble-sense) mentions various things including the [datasheet for the light sensor](https://content.arduino.cc/assets/Nano_BLE_Sense_av02-4191en_ds_apds-9960.pdf). That appears to be much more sophisticated than an LDR.

According to the sensor documentation (above):

> Upon  power-up,  POR,  the  device  initializes  and  immedi-ately enters the low power SLEEP state. In this operational state  the  internal  oscillator  and  other  circuitry  are  not  active,  resulting  in  ultra-low  power  consumption.

You would have to read the documentation for the other devices to check these things. Personally I haven't used one, and Arduino claim it "is a completely new board". So, you may not find a lot of people that can answer those questions.

Keeping power consumption low is quite a complex field. You need to look at clock speeds, sleep states, peripheral power consumption and so on.


body:
Is there a way to tell if an Arduino MKR GSM 1400 has lost power and has to rely on the connected battery?

Ideally, I'd like to do this without adding additional circuitry. Alternatively, can I connect VIn to an analogue input pin?

On the [schematic][1], there are two lines that seem promising. One named VBATT\2.4B that go into PB09 of U1 via a voltage divider and another named VBAT\1.4B. Also the BQ24195L is an I2C device which would probably be connected the the main micro controller.

What I need to do is to send an SMS as soon as the incoming power is lost to notify a user that the power supply has tripped. Does anyone have any code samples?

  [1]: https://content.arduino.cc/assets/MKRGSM_V2.3_sch.pdf

title: Arduino MKR GSM 1400: Can I tell from code if the power has tripped

Answers: 1

body:
`VBATT/2.4B` is used for measuring the batter voltage using the internal ADC of the MCU. It can't really tell if the battery is being used or not - except by maybe monitoring it over time and see if the voltage goes up or down.

However the BQ24195 is where all your hope lies.  It has a status register that can tell you all sorts of things.

For example it can tell you if there is incoming power, and what that incoming power is coming from (a USB host, a USB power adaptor, or operating in OTG mode). It can also tell you what the battery is doing - if it's charging, or not for example.

A quick google search throws up [this library](https://github.com/arduino-libraries/Arduino_BQ24195) specifically for the purpose.


body:
I have a system that involves an Arduino Due connected to a Raspi 4 through UART in which the Due sends a heartbeat signal over UART for the pi to receive and send back as confirmation. One of the events that I need to handle is re-establishing the UART connection between the two devices if the program receiving UART on the pi (or the pi itself) fails for any reason and reboots. At the moment, I have the initial heartbeat working (as long as the pi program starts first) but when I stop the pi program to simulate a fatal error and restart it, the Due doesn't seem to receive heartbeat confirmation until it's reset as well.

Is there a clean way to reset just the one Serial connection from the Arduino script? I thought of using `Serial.end()` and `Serial.begin()` but that's really ugly and I'd prefer to avoid it. None of the other Serial library methods seem to provide the ability to reset the connection.

I'm using Serial2 at 115200 baud.

Edit: Including relevant heartbeat code:
```c++
#include <DueTimer.h>

bool heartbeat = true;

void rx_heartbeat() {
  int received_data;

  if (Serial2.available() > 0) {
    received_data = Serial2.read();
    heartbeat = true;
    Serial.println("beat");
  }
}

void setup() {
  Serial2.begin(115200);
  Timer1.attachInterrupt(heartbeat_ISR).setFrequency(1).start();
}

void loop() {
  rx_heartbeat();
}

void heartbeat_ISR() {
  if (heartbeat) {
    heartbeat = false;
  } else {
    // no heartbeat returned - stop normal operation
  }
  Serial.println("heart");
  Serial2.write(255);
}
```

title: Reset a UART connection on a Due

Answers: 1

body: Silly me forgot to actually upload the code that fixed my issue. The code shown in the question is correct and works as intended.


body:
I have been working on making a HID compatible Gamepad using Pro Micro and HC-05 module. I have successfully configured the class of HC-05 module to appear as an Input device(A gamepad) on my PC without changing the firmware of the HC-05. However, after the bluetooth device gets paired there is no option showing to connect to it. My question is how do I start the blutooth connection?

Note: The class of device [calculator][1] tells you the hex for the class of device you want to make.
[![enter image description here][2]][2]

  [1]: https://www.ampedrftech.com/
  [2]: https://i.stack.imgur.com/2cdc8.png

title: Gamepad connection using Pro Micro(ATMEGA32u4 + HC-05

Answers: 0


body:
I have been trying to get a button matrix to work but im not experienced enough in programming.

I Have tried to read up but i don't know how to execute so some help would be greatly appreciated.

I want the keypad to function as a game controller of sorts. when i pres the 1 key on the keypad i want the read light to light up and only go out when i release the button. code was copied from "mstanley" on arduino forum.

Q: How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

I Was testing with leds now, the code is identical, digitalWrite(1, HIGH); then digitalWrite(1, LOW); this can easily get exchanged for joystic.PressButton 1 and Joystick.ReleaseButton 1

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

```
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5,4,3,2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char holdKey;
unsigned long t_hold;

void setup()
{
  Serial.begin(9600);

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop(){
  char key = keypad.getKey();

   if (key){
     holdKey = key;
     Serial.println(key);
   }

   if (keypad.getState() == HOLD) {
      if ((millis() - t_hold) > 100 ) {
          switch (holdKey) {
              case '1':
                  digitalWrite(11, HIGH);
                  delay(200);
                  digitalWrite(11, LOW);
                  break;
              case '2':
                  digitalWrite(12, HIGH);
                  delay(200);
                  digitalWrite(12, LOW);
                  break;
              case '3':
                  digitalWrite(13, HIGH);
                  delay(200);
                  digitalWrite(13, LOW);
          }
          t_hold = millis();
      }
   }
}
```

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

title: Keypad as game input device?

Answers: 2

body:
> How do i use the Keypad.h library to get my keypad press to run one
> line of code when i press a button and another line when i release the
> button

**Edit 1:**

    void loop() {
      char key = keypad.getKey();

      if (key != NO_KEY) {
        Serial.println(key);
      }

      if (keypad.isPressed('*'))
      {
      randomr = random(10, 2000);
      Serial.println(randomr);
      }

}
______________

From the link: https://playground.arduino.cc/Code/Keypad/ you can find all the functions supported by the Keypad library.

One relevant function is

    KeyState getState()

It returns the current state of any of the keys.
The four states supported are IDLE, **PRESSED**, **RELEASED**, and HOLD.

Hence you can use this function for the keys you are interested in.
Also, if helpful consider this function as well.

    setHoldTime(unsigned int time)

Set the number of milliseconds the user will have to hold a button until the HOLD state is triggered.

_______________________________
You can find the keypad.h library in action here. I motivate you to also try the code with this online Arduino emulator

you already have a builtin function defined to get the status of the key pressed

    void loop() {
      char key = keypad.getKey();

      if (key != NO_KEY) {
        Serial.println(key);
      }
    }

I have a poorly taken screenshot for the same for your quick reference.

Original Arduino emulator link: (you can play with the logic)
[![enter image description here][1]][1]

https://wokwi.com/playground/keypad
______________________________

*Disclosure*: I use wokwi.com, to create interesting tools and libraries for the Arduino community
https://github.com/wokwi

for a more free demonstration of the libraries:
https://github.com/wokwi/arduino-libraries

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

body:
I [did a post about keypad handlers](http://www.gammon.com.au/forum/?id=14175). I'm reluctant to mention it because we aren't supposed to post "link only" answers.

It refers to a [library available on GitHub](https://github.com/nickgammon/Keypad_Matrix) which handles keypads. In particular you can have a callback function for both the keydown and the keyup, for multiple keys.

> How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

That seems to be what you want to do.

Example code:

<!-- language: lang-c++ -->

    /*
     *
     * Example of using Keypad_Matrix with a 4x4 keypad matrix.
     *
     */

    #include <Keypad_Matrix.h>

    const byte ROWS = 4;
    const byte COLS = 4;

    // how the keypad has its keys laid out
    const char keys[ROWS][COLS] = {
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'},
    };

    const byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
    const byte colPins[COLS] = {2, 3, 4, 5}; //connect to the column pinouts of the keypad

      // Create the Keypad
    Keypad_Matrix kpd = Keypad_Matrix( makeKeymap (keys), rowPins, colPins, ROWS, COLS );

    void keyDown (const char which)
      {
      Serial.print (F("Key down: "));
      Serial.println (which);
      }

    void setup()
    {
      Serial.begin (115200);
      Serial.println ("Starting.");
      kpd.begin ();
      kpd.setKeyDownHandler (keyDown);
    }

    void loop()
    {
      kpd.scan ();
      // do other stuff here
    }

You can also use `setKeyUpHandler` to do another function when a key is released. You can also call `isKeyDown` to see if a key is down (eg. when pressing key A is key B also down?).

Note that (as mentioned in the linked post) you need to use diodes to stop having false (ghost) key presses if more than two keys are pressed at once.


body:
I'm new to using the esp32 as a microcontroller. I'm currently working on a so-to-say remote control. Since I want to use the esp32 with an external battery I need to put it in deep-sleep after I pressed some buttons to preserve battery.

All that works fine I've connected a small touchpad to put the esp32 into deep sleep mode using the `esp_deep_sleep_start()` function . The controller itself goes to sleep and can be woken up using the following 2 lines:

```
  touchAttachInterrupt(T0, wakeCallback, TOUCH_THRESHOLD);
  esp_sleep_enable_touchpad_wakeup();
```

In order to communicate with my Raspberry Pi 'Base Station' I decided to use BLE.
My server is configured the following way (where `bleServer`, `bleCharacteristic` and `bleService` are global variables):

```
  BLEDevice::init("esp-32-remote");
  bleServer = BLEDevice::createServer();
  bleServer->setCallbacks(new ServerCallbacks());

  bleService = bleServer->createService(SERVICE_UUID);
  bleCharacteristic = bleService->createCharacteristic(
                        CHARACTERISTIC_UUID,
                        BLECharacteristic::PROPERTY_READ |
                        BLECharacteristic::PROPERTY_WRITE
                      );

  bleCharacteristic->addDescriptor(new BLE2902());
  bleService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
```

Upon regular restart using the buttons everything works fine. I can connect to the device using python and the bluepy library.

If I now wake the controller I can't do anything anymore. The `setup()` function gets called and there are no errors, nor does the controller crash due to any code errors (seemingly).

Then the loop function gets called once, and thats it. I can't connect to the device anymore until I press the hardware reset button.

The questions that arise are:
 * might there be some error in the way I shutdown the bluetooth module?
 * Does the loop function work after being woken up from deep sleep?

Maybe one of you has an idea regarding my issue. If there are more information that I need to provide, don't hesitate to tell me, I'm new to the whole mcu topic and I don't know whats best to provide here.

title: ESP32 start BLE after deep sleep

Answers: 2

body:
Does the loop function work after being woken up from deep sleep? YES

loop function isn't magical.  its just a function that gets called over and over.  In other words, if it gets called once, it can be called again except if
 - it did something to deactivate itself
 - never reached the end

during that first call.  Check that you are not activating some sort of state inside the loop or going into a blocking call awaiting a signal that is never sent.

For good measure, make sure to reset all your variables to their expected states - expecting something to be 0 or set via the original definition may be insufficient.  This is something that occurs on a power reset so if reset is making it work again, thats a likely culprit.  Use a bare minimum of code in the loop for debug so you can figure it out.

body:
There's a good tutorial [here](https://randomnerdtutorials.com/esp32-ble-server-client/) on how to connect the BLE server client to the ESP32. And a Good fix [here](https://stuvel.eu/post/2022-05-01-esp32-ble-advertisement-fixed/) for reconnection issues.

Below is a piece of prototype code I wrote for BLE server client connectivity:

    class MyServerCallbacks: public BLEServerCallbacks {
        void onConnect(BLEServer* pServer) {
          deviceConnected = true;
          deviceDisconnected=false;
          interface->onBoardLED->led[0] = interface->onBoardLED->LED_GREEN;
          interface->onBoardLED->statusLED(100, 1);
          BLEDevice::startAdvertising();
        };

        void onDisconnect(BLEServer* pServer) {
          deviceConnected = false;
          interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
          interface->onBoardLED->statusLED(100, 1);
          interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
          interface->onBoardLED->statusLED(100, 1);
          interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
          interface->onBoardLED->statusLED(100, 1);
          pServer->getAdvertising()->start();
        }
    };

    class pCharacteristicTX_Callbacks: public BLECharacteristicCallbacks {
        void onWrite(BLECharacteristic *pCharacteristic) {
          std::string rxValue = pCharacteristic->getValue();

          if (rxValue.length() > 0) {
            String msg="";
            mserial->printStrln("*********");
            mserial->printStr("Received Value: ");
            for (int i = 0; i < rxValue.length(); i++) {
               msg=msg+String(rxValue[i]);
               mserial->printStr(String(rxValue[i]));
            }

            mserial->printStrln("");
            mserial->printStrln("*********");

            //valueReceived=msg;
          }
        }

        void onRead(BLECharacteristic *pCharacteristic) {
          mserial->printStrln("*********");
          mserial->printStr("onRead...");
          pCharacteristic->setValue("OK");
        }

      };

    class pCharacteristicRX_Callbacks: public BLECharacteristicCallbacks {
        void onWrite(BLECharacteristic *pCharacteristic) {
          std::string rxValue = pCharacteristic->getValue();

          mserial->ble=false;

          if (rxValue.length() > 0) {
            String msg="";
            mserial->printStr("Received Value: ");
            for (int i = 0; i < rxValue.length(); i++) {
               msg=msg+String(rxValue[i]);
               mserial->printStr(String(rxValue[i]));
            }

            msg.trim();
            $BLE_CMD=msg;
            mserial->ble=true;
            newCMDarrived=true;
          }
        }

        void onRead(BLECharacteristic *pCharacteristic) {
          mserial->printStrln("*********");
          mserial->printStr("onRead...");
          pCharacteristic->setValue("OK");
        }

      };

    //------------------------------------------------------------------

    // Create the BLE Device
      BLEDevice::init("Smart Concrete Curing");  // Give it a name

      // Create the BLE Server
      pServer = BLEDevice::createServer();
      pServer->setCallbacks(new MyServerCallbacks());

      // Create the BLE Service
      pService = pServer->createService(SERVICE_UUID);

      // Create a BLE Characteristic

      pCharacteristicTX = pService->createCharacteristic(
                          CHARACTERISTIC_UUID_TX,
                          BLECharacteristic::PROPERTY_NOTIFY
                        );

      pCharacteristicTX->addDescriptor(new BLE2902());

      pCharacteristicRX = pService->createCharacteristic(
                          CHARACTERISTIC_UUID_RX,
                          BLECharacteristic::PROPERTY_READ   |
                          BLECharacteristic::PROPERTY_WRITE  |
                          BLECharacteristic::PROPERTY_NOTIFY |
                          BLECharacteristic::PROPERTY_INDICATE
                        );

      pCharacteristicTX->setCallbacks(new pCharacteristicTX_Callbacks());
      pCharacteristicRX->setCallbacks(new pCharacteristicRX_Callbacks());

      interface->init_BLE(pCharacteristicTX);

      // Start the service
      pService->start();

on this particular code, I'm using light sleep , so to go to sleep :

          btStop();
          delay(1000);
          WiFi.disconnect(true);
          WiFi.mode(WIFI_OFF);

          changeMcuFreq(interface, interface->MIN_MCU_FREQUENCY);

and to wake up :

    changeMcuFreq(interface, interface->WIFI_FREQUENCY);
    btStart();


body:
I'm just reading through a header files for task code in ESP8266 SDK.

I found this line and wondering what does the word `PRIVILEGED_FUNCTION` after the function arguments braces means ?

    void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;

`PRIVILEGED_FUNCTION` is defined here, but why it's used after the function braces ?

    /* Ensure API functions go in the privileged execution section. */
 #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
 #define PRIVILEGED_DATA __attribute__((section("privileged_data")))

title: A word after function arguments braces

Answers: 1

body:
That's impossible to tell without looking in the source code for that SDK.

However it will just be a pre-processor macro which probably expands out to one or more *attributes*, some of which may be specific to the XTensa LX106 compiler.

----

Update after your edit:

It places the function in the `privileged_function` section. That section is then placed into a specific area of memory by the linker.

To further examine what it does you will have to look in the linker script to see how it handles that section, and what that means from the chip's perspective, by cross-referencing that with the chip's technical datasheet.


body: I need to send gyroscope values and a voice command flag and counter with a start and end marker through serial in the format <2,4,5,6> through Arduino Software serial using the HC05 Bluetooth module between Arduino Micro boards. I can send values in the struct format. But it seems that the order of the struct gets changed after a few seconds of receiving on the other side. How can I send these values in the mentioned format? I am new to this. Please help me out. It would also help if I could get suggestions on how to receive and parse this data of this format in the correct order/way.

title: How to send and receive multiple integer values through serial comm for Arduino Micro and HC05 bluetooth?

Answers: 1

body: Try Google Protobuf it's really awsome. I use it every time when I connect C# app to STM but it can be used in this case as well. U use Protobuf to encode your message and COBS do remove zeros from message so you can slap it on the end to know when the packet ends


body: I have an already programmed STM32MCU. But I don't have the source code. I understand it is difficult to get the source code from the IC. I have heard some people can get the binary file from the IC which I can flash to another Arduino. Any guide or material will be helpful. I tried my luck with google. but didn't find any good resources on this matter.

title: How to extract the binary from STM32 MCU

Answers: 1

body:
you can download the flash content using a ST-Link probe and [STM32CubeProg][1] tool. you can't flash it to just "any" arduino board; it must be the exact same chip or same family MCU, if the IOs and peripherals used are the same.

  [1]: https://www.st.com/en/development-tools/stm32cubeprog.html


body:
I have a project to make where I have to read tags out of 5 RFID Readers and when every tag is in correct reader to open a relay. The schematic is the same with [Annaane's][1] with the difference I have 5 Readers, so I didn't make one.
I also have made the board that i have attached so I can connect all the common pins together (MISO, MOSI, SCK, RESET, 3.3V and GND)

The SDA SS pins are connected directly to pins 3-7 of Arduino.
My code works just fine when powering arduino through my Laptop's USB port but since it have to be installed somewhere I tried the following ways to power it:

1) USB coming from a Xiaomi 5v Phone Charger to Arduino's USB port
2) USB coming from this to Arduino's USB Port. It is being powered from a 12v 1amp power supply from and old router.
3) The 12v 1amp power supply from and old router.
4) L7805CV and it's suggested circuit from the datasheet

My problem is that none of these ways seem to work properly. What I mean is that I cant get readings from the Readers as it should do. I have an LED which lights up when it read a tag but at these cases it only lights up only on some of the readers. The strange part is that when I am charging my laptop and powering arduino through its usb port it doesnt work either.

Any help please?

[![This is the board underneath][2]][2]
[![From above][3]][3]

  [1]: https://github.com/Annaane/MultiRfid/blob/master/Wiring.jpg
  [2]: https://i.stack.imgur.com/BZfit.jpg
  [3]: https://i.stack.imgur.com/RY9pt.jpg

title: Issue with different ways of powering

Answers: 0


body:
I'm trying to control a self-balancing car, but it seems that the MPU6050 get dirty once my motors operate a full velocity.
I'm controlling my motors with the module L298N and with the PWM signal (pin 5, 6, 9 and 10 from the arduino).
I have read about decoupling it, with capacitors, but I don't know exactly how should I do it.

This is my code. It's a little messy (sorry for that, it just I'm still figuring out what is going on) and also an image of my project:

```
#include <PID_v1.h>
#include <LMotorController.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

#define MIN_ABS_SPEED 20

MPU6050 mpu;

#define DEBUG
//#define OFFSET_1

//#define STOP

// MPU control/status vars
bool dmpReady = false; // set true if DMP init was successful
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorFloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi]    Euler angle container

//PID
//double originalSetpoint = 175.8;
#ifdef OFFSET_1
      double originalSetpoint = 225;
#else
      double originalSetpoint = 184;
#endif

double setpoint = originalSetpoint;
double movingAngleOffset = 0.1;
double input, output, output_left, output_right, error;
int moveState=0; //0 = balance; 1 = back; 2 = forth
double Kp = 40;
double Kd = 0.05;
double Ki = 5;
PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

double motorSpeedFactorLeft = 1;
double motorSpeedFactorRight = 1;
double motorSpeedFactorForward = 1;
double motorSpeedFactorBackward = 1;

//MOTOR CONTROLLER
int ENA = 5;
int IN1 = 6;
int IN2 = 7;
int IN3 = 8;
int IN4 = 9;
int ENB = 10;
//LMotorController motorController(ENA, IN1, IN2, ENB, IN3, IN4, motorSpeedFactorLeft, motorSpeedFactorRight);

//timers
long time1Hz = 0;
long time5Hz = 0;

volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady()
{
  mpuInterrupt = true;
}

void setup()
{

  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  Wire.setClock(400000);  // Set the SCL clock speed to 400kHz
  //Wire.setClock(200000);  // Set the SCL clock speed to 400kHz
  //TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
  //Fastwire::setup(200, true);
#endif

  Serial.begin(115200);
  mpu.initialize();

  devStatus = mpu.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity

  #ifdef OFFSET_1
      mpu.setXGyroOffset(0);
      mpu.setYGyroOffset(0);
      mpu.setZGyroOffset(0);
      mpu.setZAccelOffset(16372);
      mpu.setYAccelOffset(5);
      mpu.setXAccelOffset(2);
    #else
      mpu.setXGyroOffset(-52);
      mpu.setYGyroOffset(-12);
      mpu.setZGyroOffset(53);
      mpu.setZAccelOffset(2420);
      mpu.setYAccelOffset(2881);
      mpu.setXAccelOffset(-784);
    #endif

  // make sure it worked (returns 0 if so)
  if (devStatus == 0)
  {

    //mpu.CalibrateAccel(6);
    //mpu.CalibrateGyro(6);
    // turn on the DMP, now that it's ready
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    attachInterrupt(0, dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    dmpReady = true;

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();

    pid.SetMode(AUTOMATIC);
    pid.SetSampleTime(10);
    pid.SetOutputLimits(-255, 255);
  }
  else
  {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

}
void loop()
{
  #ifdef STOP
      return;
  #endif

  // if programming failed, don't try to do anything
  if (!dmpReady) return;

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize)
  {
    pid.Compute();

    output = 255;
    output_left = output * motorSpeedFactorLeft;
    output_right = output * motorSpeedFactorRight;
    if(input > (setpoint))
    {
      output_left = output_left*motorSpeedFactorForward ;
      output_right = output_right* motorSpeedFactorForward;

      Move_Forward();
    }
    else if(input < (setpoint))
    {
      output_left = output_left*motorSpeedFactorBackward ;
      output_right = output_right* motorSpeedFactorBackward;
      Move_Backward();
    }
    else
    {
      Stop();
    }
  }
  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus & 0x10) || fifoCount == 1024)
  {
    // reset so we can continue cleanly
    mpu.resetFIFO();
    Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
  }
  else if (mpuIntStatus & 0x02)
  {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);

    // track FIFO count here in case there is > 1 packet available
    // (this lets us immediately read more without waiting for an interrupt)
    fifoCount -= packetSize;

    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(euler, &q, &gravity);
    input = (euler[1] * 180 / M_PI + 180);
    error = input - setpoint;
//    Serial.print("\tOutput: ");
//    Serial.print(output);
    Serial.print("\tError: ");
    Serial.println(error);

  }
}

void Move_Forward() //Code to rotate the wheel forward
{

  //******RIGHT******//
      analogWrite(5, -1*output_right);
      analogWrite(6, 0);

  //******LEFT******//
      analogWrite(9, -1*output_left);
      analogWrite(10, 0);

      digitalWrite(11, HIGH);
      digitalWrite(12, LOW);
}

void Move_Backward() //Code to rotate the wheel forward
{
  //******RIGHT******//
      analogWrite(5, LOW);
      analogWrite(6, 1*output_right);

  //******LEFT******//
      analogWrite(9, 0);
      analogWrite(10, 1*output_left);

      digitalWrite(11, LOW);
      digitalWrite(12, HIGH);
}

void Stop() //Code to rotate the wheel forward
{
      analogWrite(11, LOW);
      analogWrite(12, LOW);
      analogWrite(5, LOW);
      analogWrite(6, LOW);

      digitalWrite(9, LOW);
      digitalWrite(10, LOW);
}
```
[![enter image description here][1]][1]

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

title: Possible noise from the motors

Answers: 1

body:
Well, I have to said that at the beginning I didn't think that the arrangement that @Majenko mentioned will work.
First I tried connecting the capacitor with cables, but it still give me noise. Once I soldered it directly to the motors the noise decrease a lot.

Thanks to all. This is the image of the arrangement that I made:
[![enter image description here][1]][1]

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


body:
I have a Arduino UNO WiFi Rev2 board that runs WiFiServer serving as a web server. The server listens and accepts clients using `server.available()`. I also want a loop that controls a servo in concurrent of the server.

I looked at [ArduinoThread](https://github.com/ivanseidel/ArduinoThread) and tried to implement my web server with it.
```c++
class WebServer : public Thread
{
private:
    // Some method definition omitted
    WiFiServer server;
    void accept_and_process();

public:
    void run() override;
}

void WebServer::accept_and_process()
{
    Serial.println("Waiting for client");
    // listen for incoming clients
    WiFiClient client = server.available();
    // Process client
}

void WebServer::run()
{
    this->accept_and_process();
    this->runned();
}
```
But the code does not run in parallel with code in `void loop()` it only ran code inside loop function and does not accept client as expected
This is the code I ran the server with
```c++
void setup()
{
    Serial.begin(9600);
    WebServer webserver = WebServer();;

    webserver.setInterval(100);
    webserver.run();
}

void loop()
{
    Serial.println("Hello");
    delay(1000);
}
```
How would I run the server concurrent to another function.

title: Run function concurrent to server.available()

Answers: 1

body:
There is no “parallel” on a single core arduino. All you need to do is program both things in a non blocking fashion. Don’t use delay or while loops waiting on things and you can do both things so fast it seems like they are parallel. Put a call to server.available() in loop and then if it returns an invalid client object then the rest of the loop runs.  If it returns a valid client object then you can quickly do what you need with the server and then get back to everything else.

As noted in the comments, server.available is not blocking.  It doesn't wait for anything to come, it simply returns whether there is a connection available or not.


body:
If I want to operate the NodeMCU on the 3.3V input with 2.5V to 3.6V; can I use any of the 3.3V pins to do so?

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

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

title: Can you power the ESP8266E-12 with any of the 3.3V pins?

Answers: 1

body:
On the nodeMCU board all the 3.3v pins have continuity. That means they all do the same thing. And yes, you can apply ~3.3v to them. I have trouble with voltages under ~2.8 though, 2.5v is likely not going to work.

Use a buck+boost to keep it 3.3v if needed. For cheap dc/dc converters, I strongly prefer ones with XL semi chips; clean enough to please the ESPs.


body:
I'm prototyping my Weather Station on Wemos D1 mini pro (ESP8266) with BME280 sensor and Nextion Display. The problem is that my display doesn't show data from the sensor and from the internet (openweathermap.org), it's only showing the static numbers which I assigned in Nextion Editor.
Here's my code (I hid the ssid, password, apikey and CityID):

    #include "Wire.h"
    #include <ESP8266WiFi.h>
    #include <ArduinoJson.h>
    #include "SparkFunBME280.h"
    BME280 mySensor;
    float hums;
    float temps;
    float pres;

    float tempitod;
    float humitod;
    float pressitod;
    String data;
    String result;

    char ssid[] = "";
    char pass[] = "";
    String APIKEY = "";
    String CityID = "";

    WiFiClient client;
    char servername[] = "api.openweathermap.org";

    void setup() {
      Serial.begin(9600);
      Serial.print("restart");
      Wire.begin();
      Wire.setClock(400000);
      mySensor.setI2CAddress(0x76);
      mySensor.beginI2C();
      WiFi.begin(ssid, pass);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
    }

    void loop() {
      hums = mySensor.readFloatHumidity();
      temps = mySensor.readTempC();
      pres = mySensor.readFloatPressure();
      getWeatherData();
      NextionData();
      Serial.print("Humidity: ");
      Serial.print(hums, 2);
      Serial.print(" Temp: ");
      Serial.print(temps, 2);
      Serial.print(" Pressure: ");
      Serial.print(pres, 2);
      Serial.println();
      delay(3000);
      }

    void getWeatherData()
    {
      if (client.connect(servername, 80)) {
        client.println("GET /data/2.5/weather?id=" + CityID + "&units=metric&APPID=" + APIKEY);
        client.println("Host: api.openweathermap.org");
        client.println("User-Agent: ArduinoWiFi/1.1");
        client.println("Connection: close");
        client.println();
      }
      while (client.connected() && !client.available()) delay(1);
      while (client.connected() || client.available()) {
        char c = client.read();
        result = result + c;
      }
      client.stop();
      result.replace('[', ' ');
      result.replace(']', ' ');
      char jsonArray [result.length() + 1];
      result.toCharArray(jsonArray, sizeof(jsonArray));
      jsonArray[result.length() + 1] = '\0';
      StaticJsonBuffer<1024> json_buf;
      JsonObject &root = json_buf.parseObject(jsonArray);
      String location = root["name"];
      String country = root["sys"]["country"];
      float temperature = root["main"]["temp"];
      float humidity = root["main"]["humidity"];
      String weather = root["weather"]["main"];
      String description = root["weather"]["description"];
      float pressure = root["main"]["pressure"];
      Serial.println(temperature);
      Serial.println(humidity);
      Serial.println(pressure);

      tempitod = temperature;
      humitod = humidity;
      pressitod = pressure;
    }

    void NextionData() {
      data = "tempitod.txt=\"" + String(tempitod, 1) + "\"";
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      delay(500);
      data = "humitod.txt=\"" + String(humitod, 1) + "\"";
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      delay(500);
      data = "pressitod.txt=\"" + String(pressitod, 1) + "\"";
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      delay(500);
      data = "temps.txt=\"" + String(temps, 1) + "\"";
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      delay(500);
      data = "hums.txt=\"" + String(hums, 1) + "\"";
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      delay(500);
      data = "pres.txt=\"" + String(pres, 1) + "\"";
      Serial.print(data);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);
      delay(500);
    }

The screen seems to be working fine, but it but doesn't gather data from the Wemos (and BME280). Could the problem be with bauds? I set the bauds in my code for 9600 but I don't know whether it changes anything. The strangest part is that, the debugger in Nextion Editor shows correct measurements.

Nxtion display looks like this right now (it doesn't gather data)

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

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

And the view from debugger looks like this (it gathers data correctly from the internet and BME280 sensor):

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

  [2]: https://i.stack.imgur.com/6H3bb.png

I don't know why Nextion doesn't display measurements.

Here's also photo from connecting Nextion to Wemos D1 mini. Maybe something is bad connected?:

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

  [3]: https://i.stack.imgur.com/lmFP2.jpg

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

  [4]: https://i.stack.imgur.com/PJKYO.png

I connected D7 pin from Wemos to RX on Nextion, and D4 pin from Wemos to TX on Nextion.

title: Nextion Display won't show data

Answers: 0


body:
I have a task where I should do SPI transactions in interrupt mode. Means I have to handle data in IRQ handler (both for tx and rx bytes). How should I approach?
I have a arduino board (2560) and a CAN shield (seeed studio) with SPI interface.

Edit:
From the website: https://www.arduino.cc/en/reference/SPI

> With most SPI devices, after SPI.beginTransaction(), you will write
> the slave select pin LOW, call SPI.transfer() any number of times to
> transfer data, then write the SS pin HIGH, and finally call
> SPI.endTransaction()

My question is - the function SPI.transfer() is handled in what way?
Are the bytes transfered/received in interrupt handler or by polling?

title: SPI transactions in Arduino

Answers: 1

body:
I have a [lengthy reference question about SPI](https://arduino.stackexchange.com/questions/16348/how-do-you-use-spi-on-an-arduino) which may help you.

To transfer **outwards** you do not need to use an interrupt. Nor is it polled. The data is simply placed in the SPI register and the hardware clocks the data out at the defined SPI rate.

To transfer **inwards** you are just reading the register. However to know **when** you need to read it, you would probably put the reading inside an interrupt routine.

I suggest you read the link above, and then if you want, you might expand your question more.

The source for the SPI transfer which I think applies to the Atmega2560 is as follows:

<!-- language: lang-c++ -->

    // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
      inline static uint8_t transfer(uint8_t data) {
        SPDR = data;
        /*
         * The following NOP introduces a small delay that can prevent the wait
         * loop form iterating when running at the maximum speed. This gives
         * about 10% more speed, even if it seems counter-intuitive. At lower
         * speeds it is unnoticed.
         */
        asm volatile("nop");
        while (!(SPSR & _BV(SPIF))) ; // wait
        return SPDR;
      }

You can see that there is brief polling (the "while" line) for the register which the processor maintains to show whether the transmission has ended. Then the register is read and returned. So yes, there is polling there.

Now if you use an interrupt (see link above) then you will know that the flag has been set, and therefore there will be no delay (in the polling).


body:
I have the following code (I realise String isn't very efficient, but this sketch doesn't have to be)

debugOutput gets called every loop, but I only want to spam the serial bus (to debug) if the status changes.

However, it runs once, despite changes to the pins being made.

    String prevState = "";
    void debugOutput() {
      String s = "";
      //s = s + digitalRead(6) ? "1" : "0";
      //s = s + digitalRead(5) ? "1" : "0";
      s = s + digitalRead(4) ? "1" : "0";
      s = s + digitalRead(3) ? "1" : "0";
      s = s + digitalRead(2) ? "1" : "0";
      if(!prevState.equals(s)) {
        Serial.println("State Change: "+s);
        //strcpy(s, prevState);
        prevState = s;
      }
    }

My suspicion is it was because of the pointers being the same, but I declare a new string every time this function runs. Just in case, I tried to swap this to strcpy, which isn't valid since I'm using String instead of character arrays.

What can I do, I'm really confused.

This is the Serial output, btw

`State Change: 1` So it's clear to me that my string appending isn't even working as expected.

title: How can I copy and compare a string?

Answers: 2

body:
I'm not sure why string appending using + was failing, but changing it from

`s = s + digitalRead(2) ? "1" : "0";`

to

`s += digitalRead(2) ? "1" : "0";`

fixed my issue.

body:
There is this thing called "operator precedence" that defines the hierarchy of operators.

The `?:` will be calculated after the `+`. That's why

    s = s + digitalRead(2) ? "1" : "0";

actually means

    s = (s + digitalRead(2)) ? "1" : "0";

But you want

    s = s + (digitalRead(2) ? "1" : "0");


body:
I have a system where an Arduino controls a DSLR camera for environmental monitoring. The Arduino can power on/off the camera and control the shutter (through the standard plug for a external shutter). The Arduino record and transmit the status of the system (battery voltaje, time of the last shot, etc.).
**I want the Arduino to be able to access the camera's SD card while the camera is powered off**. In order to check if the pictures were actually taken and check available memory (I don't need to write to the card).

So my questions are:

 1. If I create a contraption to connect a single card to the camera and the arduino. The fact that the card is connected to one device (although not been used) will interfere in the operation of the other?
 2. Should I consider the use of a multiplexer or something alike to completely disconnect the data lines from one device while the other is using the card?

title: Connect one SD card to two devices

Answers: 1

body:
An SD card has two interfaces: The SPI interface is what is used by the Arduino (it is rather slow). The second one is a parallel interface, which is capable of way bigger transmission speed. It is most likely, that the camera uses that interface, since it has to transmit rather big data packets in a short time. But as I remember some pins are used for both interfaces.

We cannot know, what happens inside the camera. But providing voltage to a digital pin of a microcontroller, while it is not powered, (as it would happen, when you drive the SD card while the camera is off) can be harmful. We must assume, that this would also happen with your camera, or you risk damaging it.

Using multiplexers (or - if you find no fitting one - some simple transistors) to disconnect the camera, when you want to connect with the Arduino, seems a good idea to me. Disconnect all lines, including the supply voltage. The ground line has to stay together, though you should check with a multimeter, if the SD slot ground is the same as the shutter connector ground (if they are not, you don't want to connect these grounds). Is most likely is, but you should check it to be sure.


body:
I am using the ESP32 in soft access point mode. In other words I specify my wifi username and password on the ESP32 and I am able to connect to it from my phone.

So I am not using any router or internet connection. Only my phone and the esp32.

If my phone is the only device on the network created by the esp32 do I have to worry about HTTPS? People say HTTP is not secure and I also know how easy it is to see http traffic with Wireshark. **But if no one else has access to the network I guess http is secure correct?** If no one knows the wifi password will my http requests be encrypted? Moreover, if I connect from my computer instead than my phone via wifi to the ESP32 and send UDP packets will those be encrypted?

title: Is WiFi traffic encrypted on ESP32?

Answers: 2

body:
If you provide a password for you network, it will be encrypted. Thats the point of the password. When you look at the function description in the [WifiAP.cpp file of the Wifi class][1] for the ESP32, the description suggests, that it will be encrypted with WPA2, which is currently the standard in Wifi encryption. (Though that can depend on the actual library, that you are using)

> do I have to worry about HTTPS?

That depends on your needs. In IT security is a scale, not a binary. Using HTTP on a WPA2 protected network can be considered safe on the one side and unsafe on the other. You need to thing about, if your project needs that additional layer of encryption through HTTPS.

For example: If you control your Smart Home with that ESP32, which may be able to open your windows or even the door, I would consider that critical. Then I would take every bit of security, that I can get, as there are ways to break into a WPA2 protected wifi network.

An example in the other direction: I'm currently building a game, which gets configured on a smartphone via the Wifi network of an ESP32. The network is encrypted to prevent casual attackers from messing with my current game run, but the project has so low security needs, that I will not bother with HTTPS. It's just a game, that will not that often being used, and the possibility of an attack on it is very low.

So it's about risk assessment (as with all security in IT).

> if I connect from my computer instead than my phone via wifi to the ESP32 and send UDP packets will those be encrypted

The mentioned types of encryption (WPA2 and HTTPS) happen on two different layers of the network communication. With WPA2 your complete wifi data of that network is encrypted. So the UDP packet is also encrypted, but only in that wifi network, and it can be read by any authenticated user of the network. HTTPS works in a layer above that, so that your packet would be encrypted, even if it would move out of that Wifi network. For learning more about network layers, refer to the [OSI model][2].

---

Apart from the security perspective: When you use HTTPS you also need to think about the certificate, that you are using. If you use a self-signed one, your browser will present you a warning about that, everytime you open that site. To prevent that, you either need to trust that certificate on all your devices, or you need to use an officially signed certificate (which might be a problem for a pure local project).

  [1]: https://github.com/espressif/arduino-esp32/blob/9d547a8a441f70755c5b9d385e1092c1728da098/libraries/WiFi/src/WiFiAP.cpp#L87
  [2]: https://en.wikipedia.org/wiki/OSI_model

body:
WiFi with WPA2 (which is what you get when you specify a password) is encrypted.

As long as your HTTP requests *only* go over that connection and nowhere else then yes, they are encrypted and as secure as WPA2 (which isn't unbreakable, but not easy to break).

HTTPS adds encryption for use over the internet which in general is *not* encrypted.


body:
i'm trying to use an external flash memory Winbond 25q64jvsiq for my Arduino Nano based project for audio recording purposes, to have extra memory for recording 1 byte audio samples, since Arduino nano SRAM memory is too small (8kb), to store at least 1 second of 8 kHz 8 bit samples audio. I'm trying to understand the basics of  bytes storing in my external memory. I'm using SPIMemory library for that, and i can't find a function to erase 1 byte, there is only sectorErase() function. So i wonder is it even possible to erase a single byte of external memory?

Here is a part of code where i try to rewrite (erase one byte and write a new one) a next byte when the button pressed, but when it erase a sector it erases not the one byte but all bytes behind it, and i want to manipulate it more accurate, and erase only one byte:

```
if(!digitalRead(5)){      //button pressed
     if(e<3){
      e++;
      flash.eraseSector(count);    //erasing a byte
      flash.writeByte(count,e,NOERRCHK); // write a new value
      }  else {
        e=0;
        flash.eraseSector(count);
        flash.writeByte(count,e,NOERRCHK);
        }
     }

title: Erasing 1 byte of external Flash memory (winbond)

Answers: 1

body:
For a flash chip, no it's not possible to erase a single byte.

The closest you can do is to read an entire sector into memory, erase that sector, modify your in-memory copy, then write the sector back.

You would be better using an SPI SRAM or PSRAM chip instead of a flash chip.


body:
I have a small project where I connected a Hall sensor (see picture) to an Arduino Mega. The blue wire is connected to pin 45, the red wire to +5V, and the black wire to GND.

[![Hall-Sensor AZDelivery KY-003][1]][1]

At the beginning I initialize the pin used to read the sensor as follows.

    #define HALL_PIN 45

    void setup()
    {
      pinMode(HALL_PIN, INPUT);
    }

I have written a function to read out the sensor. While there is no magnet nearby, the sensor returns HIGH. If a magnet approaches in the correct orientation, the sensor returns LOW. The function should return *true* if a magnet is nearby, i.e. if the read value is LOW.

I have noticed that my program logic sometimes does not work reliably after seemingly irrelevant changes to the code. After commenting out more and more code to narrow down the problem, I came across the following discovery.

**Implementation 1:**

In the first implementation, I initially read out the value of the Hall sensor. Next, I send the value to the serial port. The serial monitor in the Arduino IDE outputs the number 1 (HIGH). This is the expected behavior as during testing there is no magnet nearby. Based on the subsequent program behavior I can confirm that the function returns *false*. I can let the Arduino run for minutes and the behavior remains stable.

    bool readHallSensor()
    {
      int s = digitalRead(HALL_PIN);

      Serial.println(s); // The serial monitor outputs 1 (HIGH)

      return s == LOW; // Returns false
    }

**Implementation 2:**

With the second implementation I do not write the read value to the serial port. As expected, the serial monitor in the Arduino IDE remains empty. The function, however, now returns *true*. Apart from commenting out the marked line and flashing the sketch to the Arduino, I did not make any changes (again no magnet nearby). Also in this case I can let the Arduino run for minutes and the behavior is stable.

    bool readHallSensor()
    {
      int s = digitalRead(HALL_PIN);

      // Serial.println(s); // No output to the serial monitor

      return s == LOW; // Returns true
    }

My first suspicion was that the delay caused by writing to the serial port is what makes the difference. I asked an electrical engineer whether Hall sensors might need short breaks between successive readings. He denied my assumption, and indeed, if I simply insert a *delay(300);* after reading the value (without writing to the serial port) the behavior does not change and is identical to implementation 2.

I can switch back and forth between the two implementations and flash them to the Arduino as many times as I like. The behavior is always as described above for both cases. I cannot make any sense of this, as the behavior seems to lack any (programming) logic. Has anyone ever made similar observations and can give me a hint what might cause this? Thank you in advance.

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

---

I haven't found the problem yet, but I have come a step closer. The issue has reappeared in a similar project on the same Arduino. I use a new Hall sensor with pull-up, which is read out wrong again under certain circumstances (always read out as LOW, no matter if a magnet is nearby). The problem seems to occur only when I use a certain pin. The pin in question on my Arduino Mega this time is pin 37. If I connect the Hall sensor to another pin (I have tested 34 and 36), it works fine. If I connect a previously working Hall sensor to pin 37, it will not work anymore (always evaluated as LOW). The only explanations that make sense to me at the moment are that either the Arduino Mega is damaged or that there are side effects, maybe caused by external libraries using certain pins without my knowledge and incorrectly initializing them.

title: Why do my Hall sensor readings change when I write them to the serial port?

Answers: 1

body:
The 3144 requires a pull-up resistor. It only sinks when a magnet is present. It doesn't source, so the pin is floating if no magnet is present.

You can use the internal pull-up resistor by using `pinMode(HALL_PIN, INPUT_PULLUP);`


body:
dears Engineers.. i got stuck with this issue couldn't understand.. please help with explanations.

first i was upset of my ultrasonic sensor reading deviations, that is i examine my sensor indoor and at quite environment,, so what makes this noisy output readings??!!!

so i tried to dig into the pulseIn function and tracking the timing of each instruction in the code..
after reading the library.., i decided to use pulseInLong function.
following is a result of some iterations timing in microseconds:
```
Ultrasonic Sensor HC-SR04 Test
with Arduino UNO R3
Start ~ trig LOW  ~ 10us delay ~ trig High ~ 10us delay~ trig High ~   pulseIn    ~   Duration
0          8          12          8          12          4          7352          137976
4          4          12          8          12          8          7336          137960
4          8          12          8          12          8          7352          137976
4          8          12          8          12          8          7356          137980
4          8          12          8          12          8          7352          137976
4          8          12          8          12          8          7356          137980
4          8          12          8          12          8          7360          137984
4          8          12          8          12          8          7364          137996
0          8          12          8          12          8          7364          137992
4          8          12          8          12          8          7372          137996
4          8          12          4          12          8          7380          138004
0          4          12          8          12          8          7372          137996
0          4          12          8          12          8          7348          137968
4          8          12          4          12          8          7372          137996
4          8          12          8          12          4          7376          138004
4          8          12          8          12          8          7380          138008
0          8          12          8          8          8          7352          137980
4          8          12          4          12          8          7352          137976
4          8          12          4          12          8          7368          137992
4          8          12          8          12          8          7340          137964
4          8          12          4          12          8          7352          137980
4          8          12          4          12          8          7360          137984
12          8          12          8          12          8          7368          137996
4          8          12          8          12          8          7348          137972
4          8          12          8          12          12          7360          137984
0          8          12          8          12          8          7344          137968
4          8          12          8          12          8          7352          137976
4          8          12          8          12          8          7364          137988
4          8          12          4          12          8          7360          137984
4          8          12          8          12          4          7372          138000
```

first i wondered why there are different execution time for the same instruction??!
for example digitalWrite(trig_pin,LOW or High) varies in range 4 ~ 12 microseconds!!????

more strange when i found elapsed time after delay 10us, micros() function shows only 8 us??!!!

all these in range of 16 us,, so i expected maybe due to some instruction cycles or unprecise clock...etc.

but the BigBang i shocked when read this huuuuuge difference in pulseIn timing measurment;
i reset the timer befor the function and just after it, so i got an elapsed time in range of 7350 us. in the same time the resultant measured time from the function in range of the  138000 us?????!!!!!!

put in mind that pulseInLong is a blocking function..as you will see below, it loops in a while loop until timeout (so return 0) or pulse generated and measured before timeout then return pulse elapsed time.

first i suspected in this number maybe not microseconds. inspected the function deeply, ??!!!
i found it using the exact micros() function such i do in the code?

```* ATTENTION:
 * this function relies on micros() so cannot be used in noInterrupt() context
 */
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
 // cache the port and bit of the pin in order to speed up the
 // pulse width measuring loop and achieve finer resolution.  calling
 // digitalRead() instead yields much coarser resolution.
 uint8_t bit = digitalPinToBitMask(pin);
 uint8_t port = digitalPinToPort(pin);
 uint8_t stateMask = (state ? bit : 0);

 unsigned long startMicros = micros();

 // wait for any previous pulse to end
 while ((*portInputRegister(port) & bit) == stateMask) {
  if (micros() - startMicros > timeout)
   return 0;
 }

 // wait for the pulse to start
 while ((*portInputRegister(port) & bit) != stateMask) {
  if (micros() - startMicros > timeout)
   return 0;
 }

 unsigned long start = micros();
 // wait for the pulse to stop
 while ((*portInputRegister(port) & bit) == stateMask) {
  if (micros() - startMicros > timeout)
   return 0;
 }
 return micros() - start;
}
```

anyway..i dont want to make this story long..
can someone explain what is going on to me please?!

thanx

here is arduino code i used

```#define echoPin 2 // attach pin D2 Arduino to pin Echo of HC-SR04
#define trigPin 3 //attach pin D3 Arduino to pin Trig of HC-SR04

// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement

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

  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
  Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed

  Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
  Serial.println("with Arduino UNO R3");
  Serial.println("Start ~ trig LOW   ~   10us delay   ~   trig High   ~   10us delay   ~   trig High    ~    pulseIn    ~   Duration");

}

void loop() {
  // put your main code here, to run repeatedly:
  // Clears the trigPin condition
  int indx = 0;
  int arr[7] = {0};
  double last = micros();

  arr[indx] = micros() - last;
  indx++;
  last = micros();

  digitalWrite(trigPin, LOW);

  arr[indx] = micros() - last;
  indx++;
  last = micros();

  delayMicroseconds(10);

  arr[indx] = micros() - last;
  indx++;
  last = micros();
  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds

  digitalWrite(trigPin, HIGH);
  arr[indx] = micros() - last;
  indx++;
  last = micros();

  delayMicroseconds(10);
  arr[indx] = micros() - last;
  indx++;
  last = micros();

  digitalWrite(trigPin, LOW);
  arr[indx] = micros() - last;
  indx++;
  last = micros();

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseInLong(echoPin, HIGH);
  arr[indx] = micros() - last;

  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  // Displays the distance on the Serial Monitor

  for (int i = 0; i <= indx; i++)
  {
    Serial.print(arr[i]);
    Serial.print("     \t    ");
  }
  Serial.print(duration);
  Serial.println();

}
```

title: help explain pulseIn function with arduino and Ultrasonic sensor

Answers: 2

body:
> Why do I receive the **big difference** in time measurement between
> elapsed time while execution the pulseInLong function and its return
> duration measurement?

The answer lies in the choice of the way it is implemented.
The delay function itself is helpful but the accuracy is not great when precision is needed. Here is the official note from the [site][1]:

 1. This function works very accurately in the range of **3 microseconds
    and up**. We cannot assure that delayMicroseconds will perform
    precisely for smaller delay-times.
 2. As of Arduino 0018, delayMicroseconds() **no longer disables
    interrupts**

If you want to really be precise, I recommend to use hardware timers. I believe it will suffice. to know more about using hardware timers you can refer to

https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

https://maker.pro/arduino/projects/timer-interrupts-improve-your-arduino-programming-skills

  [1]: https://www.arduino.cc/reference/en/language/functions/time/delaymicroseconds/

body:
I see at least three reasons for the behavior you notice:

1. `micros()` has a resolution of 4 µs. If you could call it at a
   period fixed to exactly 10 µs, you would see the time deltas
   alternate between 8 and 12 µs. But then `micros()` takes some
   time to execute, so if you use it to time a function that takes
   10 µs to execute, you will read 12 µs more often than 8.
2. There is a timer interrupt firing every 1024 µs. Any process
   that gets interrupted will show an execution time longer than normal.
   This is the likely cause of `digitalWrite()` taking occasionally a
   lot longer than usual.
3. `pulseIn()` waits for the start of the pulse before it starts to
   measure its duration. Its execution time can then be significantly
   longer than the pulse duration it reports.

> i expected maybe due to some instruction cycles or unprecise clock.

The same clock is used for sequencing the CPU instructions and for
timing them. So the clock precision has no effect on the timings you
measure.

**Edit**: There is an extra issue here, which is the overflow of
`arr[6]`. The execution time of `pulseInLong()` may be something like
138,424 µs. Since an `int` on the Uno is 16 bits, this value wraps
modulo 216 to 7,352, which is the value shown in the first
line of the output.


body:
I have coded a fix for a major problem with the Arduino `map` function (in `Arduino.h` & `arduino/avr/cores/arduino/WMath.cpp`).

I submitted it as a comment to [map function causes huge errors when mapping to small intervals due to integer truncation #10382][1] but heard nothing so far.

I thought it might be handled quicker if I can submit it as a Pull Request with Unit Tests to A) expose how and why `map` is faulty and B) show how my solution fixes the problem.

  [1]: https://github.com/arduino/Arduino/issues/10382

title: Where are the Arduino Function Unit Tests kept? I want to submit a fix for a faulty Arduino function

Answers: 0


body:
Hardware: Arduino Uno
Software Version: 1.8.13

My sketch has an interrupt service routine that triggers with the rising edge of digital pin 2.
What I want to do now is detaching the interrupt as soon as it has been triggered once and reattaching it as soon as a certain amount of time (>1s) has passed.

However despite of trying I haven't found a possibility to do this.

I have tried detaching it in the ISR itself and reattaching it in the main loop with a delay after manually clearing the interrupt flag. However with this approach the time the interrupt is detached for depends on the point of time the interrupt is triggered, which is undesirable.

Is there a better solution for this? Thank you in advance for every answer

title: Is it possible to detach an interrupt for a certain ammount of time

Answers: 1

body:
The standard way to do this is just as you described (but with the non-blocking coding style like in the `BlinkWithoutDelay` example): Detach in the ISR and setting a flag and a timestamp. Then in the main code check the flag and the time since the timestamp was took. In code that looks somewhat like this (Note, that I left out some arguments of the attaching/detachting functions):

    volatile byte flag = 0;
    volatile unsigned long timestamp = 0;
    #define REACTIVATE_INTERVAL  1000

    void ISR_function(){
        detachInterrupt(...);
        flag = 1;
        timestamp = millis();
    }

    void setup(){
        attachInterrupt(..., ISR_function, ...);
    }

    void loop(){
        if(flag && millis() - timestamp > REACTIVATE_INTERVAL){
            flag = 0;
            attachInterrupt(..., ISR_function, ...);
        }
        // Rest of your main code from here on
    }

For this to work correct, you must of course use a non-blocking coding style in your main code, meaning no `delay()`s (except for really small ones) and no blocking `while` loops. If you have those in your main code, you should rewrite it to be non-blocking. Not only for this feature, but for any further extension of your project. A non-blocking coding style is an important principle to embrace, especially microcontrollers.

---

Without a non-blocking coding style, you would need to use a timer interrupt, to reattach the pin interrupt. While that is totally possible, it does not make much sense to configure extra peripherals of the Arduino just for this.


body:
I received my NRF24L01 Module today but I'm having a hard time finding any resources about this particular combination of modules!

https://i.stack.imgur.com/Tiwyj.jpg

I tried searching up the v200 1812A but no results...You would think the seller would have some documentation on his page but nothing.

Does anyone know what I'm dealing with here?

Thank you!

title: What NRF24L01 module is this?

Answers: 1

body:
They are transparent bridge modules that are designed specifically to work together. It's intended to be kind of like a wireless UART.

[This AliExpress Seller](https://www.aliexpress.com/item/32981140607.html) details how to use them.

You need one UART and one USB module. You plug the UART module into the USB module and plug the USB module into your computer. After about 10 seconds the modules are paired together.

You then separate them, and you can connect the UART module to your Arduino or other board.

Now you have a wireless UART between your computer and your Arduino.

Alternatively, since they have an STM32F0 chip controlling them you could hack them to do other things using `stm32duino`.


body:
I'm currently trying to send data from esp32 to my android app that I made. The sensor readings are showing in the serial monitor, however, what's showing on my app are either @ or &. Please help and thank you. I'm new to bluetooth coding.

Here's the code:

    #include "BluetoothSerial.h"
    int sensorPin = 35;
    int sensorreading;

    BluetoothSerial SerialBT;

    void  setup ()
    {
        Serial.begin(115200);
        SerialBT.begin("ESP32_ABO");
        pinMode (sensorPin, INPUT);
    }
    void  loop ()
    {
       sensorreading = analogRead(sensorPin);
       String toSend = String (sensorreading);
       sendData(toSend);}

    void sendData(String textToSend){

       Serial.print(sensorreading);
       SerialBT.write(textToSend[sensorreading]);
    }
    delay(1000);}

title: ESP32 nodemcu serialbt sending data

Answers: 1

body:
You see very different output via bluetooth and Serial Monitor, because you are sending completely different things. On the Serial Monitor you see the sensor reading, since that is exactly, what you send:

    Serial.print(sensorreading);

The `print()` function will convert the integer variable `sensorreading` into human readable text (meaning ASCII encoded text) and send this over Serial.

But then you do this:

    SerialBT.write(textToSend[sensorreading]);

`textToSend` is a `String` object here. So with the parentheses `[ ]` you are taking one character of that string. You try to use the `sensorreading`th character. Since `sensorreading` comes from an `analogRead()`, it is most likely, that is value is rather big, meaning bigger than the length of the string. So you are basically reading some random memory, that happens to lie behind your string variable. The `write()` function will then send that random data out over your bluetooth serial interface, without any conversion.

I guess you want to transmit the data over bluetooth also in human readable form. So just use the same code as with the `Serial` interface (for the Serial Monitor).

And remove all that manual conversion of the measured analog value to a `String`. That is not needed. If you want to also display some text, you can just use multiple `print()` commands, like this:

    Serial.print("Value: ")
    Serial.print(sensorreading);
    Serial.print(" units");

---

Note, that it is rather bad to use the `String` object at all. The `String` class uses dynamic memory allocation, which leads to memory fragmentation, which can eat up your available memory. This is not as important on chips with rather big memory (as the ESP32) than on chips with smaller memory (like the Atmega328p, which is used in Arduino Uno and Nano), but you should still keep that in mind. Instead of the `String` class you would work with `char` arrays, aka C-strings.


body:
I'm trying to change values such that the arduino uno outputs comes from what is input, with the code,

```
int PinOutput = 11;
int PinInput = A0;
int inph;
int inpl;
int input;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(PinInput, INPUT);
pinMode(PinOutput, OUTPUT);
delay(100);
}

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

  {

    input = Serial.read();

  }

 else
{

    input = 255;

}
    inpl = analogRead(PinInput)/4;
    Serial.println(inpl);
    analogWrite(PinOutput,input);
    delay(10);
    inph = analogRead(PinInput)/4;
    Serial.println(inph);
    analogWrite(PinOutput,input/2);
    delay(10);

}
```

Where pin 11 is connected with an RC circuit to pin A0. Will this code take a value through pin 11 and output it to pin A0? I'm checking if this should work right, so I can then check the python code that goes with it. As of now it mostly stalls, but maybe it's a problem with the python code. I'm trying to make it sustain the number put in. Python code I've tried with is,

```
import serial
import time

ser = serial.Serial('COM3', baudrate = 9600, timeout = 1)
time.sleep(1)

while 1:

    userInput = input('Get data point? ')

    ser.write(userInput.encode())

    for i in range(5):
        arduinooutput = float(str(ser.readline().decode().split('\r\n')[0].strip('\x00')))
        print(arduinooutput)
        time.sleep(0.01)

```
The numbers printed out are somewhat random, around 100, it seems, no matter the value put in.

title: Change arduino output from input

Answers: 0


body:
I would like to control a relay using Wemos D! R1 via a website from anywhere. I managed to control it using local web server and now would like to step it up further.

I'm using the following code which connects to this [website][1] and retrieve data as JSON perfectly.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>
    #include <ArduinoJson.h>

    const char* ssid = "SSID";
    const char* password = "PASS";

    void setup () {
     Serial.begin(115200);
     WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
      delay(1000);
      Serial.print(".");
        }
    }

    void loop() {
     if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
      Serial.println("");
      HTTPClient http;  //Declare an object of class HTTPClient
      http.begin("http://jsonplaceholder.typicode.com/users/1");  //Specify request destination
      int httpCode = http.GET();                                                                  //Send the request

      if (httpCode > 0) { //Check the returning code
       String payload = http.getString();   //Get the request response payload
       Serial.println("");                  // Empty Line
       Serial.println(payload);             //Print the response payload
       //////////////// Json code
         StaticJsonDocument<2000> doc;
         DeserializationError error = deserializeJson(doc, payload);
         if (error) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.c_str());
        return;
         }
         const char* sensor = doc["name"];
         const char* username = doc["username"];
         const char* email = doc["email"];
         const char* address = doc["address"];
         Serial.println(sensor);
         Serial.println(username);
         Serial.println(email);
         Serial.println(address);
       //////////////// End of Json Code
         http.end();   //Close connection
         while ( 0 < 1 ){ delay(10000); }  // to break the loop
       }
     }
     delay(10);    //Send a request every 30 seconds
    }

<!-- end snippet -->

I made a web page that makes AJAX call to a PHP file to retrieve data from MYSQL DB, but when I run it, the monitor keeps printing empty lines forever although connected successfully to my WIFI.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    $(document).ready(function(){
    $.ajax({
            url: "test.php",
            type: 'GET',
            dataType: 'json', // added data type
     data: ({mobile: 'hi'}),
            success: function(res) {
                console.log(res);
            }
        });
    });

<!-- end snippet -->

The result I'm getting from AJAX is (which you can check visiting this [link][2]:

        {"status":"ON"}

I'm using the following code on php file:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    <?php
    header('Content-type: application/json');
    require 'functions.php';
    header("Access-Control-Allow-Origin: *");
     $catrecord = mysqli_query($link,"SELECT * FROM `ard`");
      while($catinfo = mysqli_fetch_array($catrecord, MYSQLI_ASSOC)){ $Cat = $catinfo['status']; }
     $responseArray = array('status' => $Cat );

    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
     $encoded = json_encode($responseArray);
     header('Content-Type: application/json');
     echo $encoded;
    } else {
     echo $responseArray['status'];
    }
    ?>

<!-- end snippet -->

  [1]: http://jsonplaceholder.typicode.com/users/1
  [2]: https://payond.net/ard/

title: Connecting ESP8266 to website

Answers: 0


body:
I am using Neo 6M GPS module with ESP32 and 2 X 3.5V(7 v in series) 18650 lithium ion battery stepped down to 5V using LM2596 buck converter.

Problem which I am facing is when I power ESP32 using 5V output of LM2596 by connecting Vin pin and powering Neo6M using 5V output of buck converter or 3.3 V of ESP32 then my Neo 6M is unable to fix on satellite, however when removing battery and LM2596 and powering ESP32 using laptop usb cable and Neo 6M using 3V pin of ESP32 then its able to take a fix in 1 minute.

Any idea what mistake I could be doing.
Note - When using battery ESP32 is working as normal and able to connect to wifi and submit Tiny GPS++ output everysecond.

Please let me know in case more information required.

title: Neo 6M + ESP32 unable to take a fix on battery but works fine with laptop USB

Answers: 2

body: With full battery charge to 3.7V this issue was resolved also using 10uf capacitor between vcc and ground help to improve

body: You have several problems. You are telling me it is power related as the ESP runs fine but the Neo 6M failed. Reason the Neo 6M does not tolerate as wide a voltage range as the ESP32. Using a Buck converter is a mistook, you should use a SEPIC (bicl/boost in one), this will maintain the voltage to your project as the battery voltage changes with its charge etc. With the correct SEPIC converter you can parallel the batteries giving you more instantaneous current. The buck converter needs head room, that is so much voltage above the output to work properly. I doubt it is less than 2v. Using small wires will esterbate your problems. The 10uF was a good idea but you also want to add something for high frequency. This should get you going.


body:
PROBLEM

Cars regularly exceed the speed limit in our street

SOLUTION

Measure each car's speed and clearly display the speed to the driver

EXECUTION
1. Measure the time the car takes to cover a set distance (e.g. 25 meters) to calculate the speed
2. For this I'd set up two sensors and calculate the difference between the timestamps recorded between the car passing the first and second sensors -> then convert into km/h
3. Display the result on an LED screen

CHALLENGES & QUESTIONS

A. What sensors should I use here? Photoresistor with laser diode, digital or analog IR sensor, ...

B. How can I best cover the distance between the sensors and connect them to the Arduino? Long wire, wireless, connect two Arduinos, ...

Thanks!

title: Measuring car speed between two points: What sensor to use and how to cover the distance?

Answers: 1

body:
Why 25meters? If you place the two sensors 1 meter apart, you only need 1ms accuracy to get km/h (assuming a 50km/h speed limit). The Arduino can handle 1ms resolution with ease.

I'd probably go with 3-5 meters, so you don't need your setup to be that precise (i.e. distance and alignment of the two sensors). Lowering the distance also makes it less likely for two cars, from both directions, to simultaneously be inside your sensor area.

For the sensors, the biggest problem is the legal one. Having objects on/near the road could cause some liability issues. The laser solution is probably the least likely to cause this issue. Though I'm unsure about having a display next to the road.

You could go with laser and photo-transistor on one side of the road. And a reflector/mirror on the other side. I'd probably go with an IR laser, so it's invisible. You'd have to shield the photo-transistor as much as possible from ambient light, so a sudden cloud won't trigger it. You probably still need to do some filtering in software.

There are radar modules available, but I think they are pretty expensive.

Another option is a Laser range sensor, [like this one from sparkfun](https://www.sparkfun.com/products/14599)