body:
tavis’ answer nailed down your problem: your program is completely
unresponsive when it is blocked in the first `while` loop of the
`loop()` function. Here I will try to give you some hints on how to
avoid this situation, but first some general comments:

> ```c++
> if (pres_len < (unit_delay*3) && pres_len > 50)
> ```

The threshold should be `unit_delay*2`, maybe with a longer
`unit_delay`. In Morse, a dot is one unit, and a dash is three units. If
you have to set a threshold, it should be somewhere in the middle.
Otherwise, a perfectly valid dash of 2.99 units would be mistaken
for a dot.

Also, a function returning anything but `void` should _always_ return a
value. What is this function supposed to return if `press_len` is
smaller or equal than 50? And if it is exactly equal to
`unit_delay*3`? The best way to make sure you did not forget any case is
to have an `else` at the end that returns a default value in case no
condition matches:

```c++
else
    return '?';  // we could not understand
```

In this particular case, it seems to me like you already did the
debounce prior to calling the function, so it could be simplified to

```c++
char getSymbol()
{
    if (pres_len < 2 * unit_delay)
        return '.';
    else
        return '-';
}
```

Note that giving functions meaningful names is an important step in
making the code easy to understand and reason about.

> ```c++
> if(i2>=2)
> {
>   i1++;
>   i2=0;
> }
> else
> {i2++;
> }
> ```

All this serves no useful purpose, as you do not use `i1` or `i2` after
`setup()`. Removing useless stuff is also important for the clarity of
the code.

> ```c++
> Serial.println("This code is not exist!");
> ```

It should say “I cannot understand this code!”, but it may well exist.

Now, to the core of the issue. If you want the program to be responsive,
you should embrace _non-blocking programming_. This means getting rid of
`delay()` (see [Blink Without Delay][bwod]) and getting rid of blocking
loops, like the two `while` loops at the top of `loop()`. A very useful
approach is to program your system as a [finite state machine][fsm].
Please, take the time to read and digest these two resources.

Next, as an example, I can point you to a Morse decoder of mine that is
based on the finite state machine concept. You do not have have to look
at my code, which may be too low level for your taste, but look at [the
documentation of the program internals][int]. It explains how the state
machines are built and interact with one another. Below is a state
diagram taken from that documentation. It shows the state machine that
takes the debounced “rise” and “fall” events as inputs, and generates
“dot”, “dash”, “end-of-char” and “end-of-word” symbols as outputs:

[![state diagram of Morse decoder][1]][1]

[bwod]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
[fsm]: https://majenko.co.uk/blog/finite-state-machine
[int]: https://github.com/edgar-bonet/tiny-morse-decoder/blob/master/internals.md
[1]: https://i.stack.imgur.com/VOcCD.png


sender: user

message:
Send button only works when pressed immediately after

I am new to Arduino and I am trying to create a Morse code based "chat".

I can submit a message in Morse code using the send button (the one on the right,) and when I press the button on the left and the whole decoded message should appear on the screen. However, this is not happening unless I press the send button immediately after introducing the Morse code. Can anyone help me out? I tried changing the delay period, but nothing seems to make it send how it should.

As I said, I am a beginner, so please go easy on me.

This is my code:
```
/* String tone = "-... ..- -. .- ";

  Morse code - Receiver

  modified on 14 Apr 2019
  by Saeed Hosseini @ Electropeak
  https://electropeak.com/learn

*/
#include <LiquidCrystal.h>
// Create an LCD object. Parameters: (RS, E, D4, D5, D6, D7):
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);
String code = "";
int len = 0;
char ch;
int ok;
char new_char;
int i1=0;
int i2=1;
const int but_send=8;
const int but = 12;
const int led = 13;
String a="";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
int buttonState = 0;

char MakeString()
{
  if (pres_len < (unit_delay*3) && pres_len > 50)
  {
    return '.';                        //if button press less than 0.6sec, it is a dot
  }
  else if (pres_len > (unit_delay*3))
  {
    return '-';                        //if button press more than 0.6sec, it is a dash
  }
}

void Morse_decod()
{
  static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
                             "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                             ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
                            };
  int i = 0;
  while (morse[i] != "!")
  {
    if (morse[i] == code)
    {
      Serial.print(char('A' + i));
      a=a+char('A' + i);
      //lcd.print(char('A' + i));
      Serial.print(" ");
      if(i2>=2)
      {
        i1++;
        i2=0;
      }
      else
      {i2++;
      }
      break;
    }
    i++;
  }
  if (morse[i] == "!")
  {
    Serial.println("");
    Serial.println("This code is not exist!");
  }

  code = "";
}
void sendText()
{
  Serial.println(digitalRead(but_send));
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  //if (digitalRead(but_send) == HIGH) {
    // turn LED on:
     //gitalWrite(led, HIGH);
  if(ok==1){
    Serial.println(a);}
  ok=0;

    //}
  //else {
    // turn LED off:
    //Serial.println("NIMIC");
  //}
 delay(200);
}
void setup() {
  Serial.begin(9600);
  pinMode(but, INPUT_PULLUP);
  pinMode(but_send, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  lcd.setCursor(i1, 12);
  lcd.begin(16, 2);

}
void loop() {
label:
  while (digitalRead(but) == HIGH) {}
  old_pres = rel_time;
  pres_time = millis();
  digitalWrite(led, HIGH);
  while (digitalRead(but) == LOW) {}
  rel_time = millis();
  digitalWrite(led, LOW);
  pres_len = rel_time - pres_time;
  space = pres_time - old_pres;
  if (pres_len > min_delay)
  {
    code += MakeString();
  }
  while ((millis() - rel_time) < (unit_delay * 3))
  {

    if (digitalRead(but) == LOW)
    {
      goto label;

    }

  }

  Morse_decod();
 delay(1000);
  if (digitalRead(but_send) == LOW)
  {
    ok=1;
    //Serial.println("A intrat aici");
    sendText();
    //delay(100);

  }

 //Serial.println(digitalRead(but_send));

}
```

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

This is what should happen all the time, not only after pressing the send button very fast:
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/60JV4.png
  [2]: https://i.stack.imgur.com/OmIUT.png

If needed, I can send a link from my tinkercad simulation.

sender: assistant

body:
Both tavis and Edgar Bonet have hit the nail on the head, and Edgar has provided you with an excellent tutorial.

You are unlikely to get this to work properly in the Tinkercad browser simulator because it runs at different speeds depending on the complexity of the code it is running. And the complexity varies when you press buttons, which throws the timing out as the Morse button is pressed.

However, I managed to get it roughly working in Tinkercad as follows.

[![Tinkercad Morse code][1]][1]

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

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte MORSE_BUTTON_PIN = 6;
const byte SEND_BUTTON_PIN = 7;
const byte MORSE_LED_PIN = 8;

const unsigned long DEBOUNCE_DELAY_ms = 50;
const unsigned long MORSE_UNIT_1 = 500;  // milliseconds.
const unsigned long MORSE_UNIT_2 = 2 * MORSE_UNIT_1;  // milliseconds.
const unsigned long MORSE_UNIT_5 = 5 * MORSE_UNIT_1;  // milliseconds.

const String MORSE_CODES[] =
{
  ".-", "-...", "-.-.", "-..", ".",
  "..-.", "--.", "....", "..", ".---",
  "-.-", ".-..", "--", "-.", "---",
  ".--.", "--.-", ".-.", "...", "-",
  "..-", "...-", ".--", "-..-", "-.--",
  "--.."
};

String symbol;
String message;

Debouncer morse_button(MORSE_BUTTON_PIN, DEBOUNCE_DELAY_ms);
Debouncer send_button(SEND_BUTTON_PIN, DEBOUNCE_DELAY_ms);

void setup()
{
  Serial.begin(115200);
  pinMode(MORSE_BUTTON_PIN, INPUT);
  pinMode(SEND_BUTTON_PIN, INPUT);
  pinMode(MORSE_LED_PIN, OUTPUT);
  // Set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Hello, world!");
}

void loop()
{
  static unsigned long press_begin_time = 0;
  static unsigned long release_begin_time = 0;
  static bool measure_the_gap = false;

  morse_button.Update();
  send_button.Update();

  if (morse_button.Fall())
  {
    // Remember when the morse button was pressed and
    // switch on the LED.
    int timestamp = millis();
    digitalWrite(MORSE_LED_PIN, HIGH);
    press_begin_time = timestamp;
  }

  if (morse_button.Rise())
  {
    // Remember when the morse button was released and
    // switch off the LED.
    int timestamp = millis();
    digitalWrite(MORSE_LED_PIN, LOW);
    release_begin_time = timestamp;
    int pressed_time = timestamp - press_begin_time;
    if (pressed_time > MORSE_UNIT_2)
    {
      // Dash.
      //Serial.print("-");
      symbol += "-";
    }
    else
    {
      // Dot.
      //Serial.print(".");
      symbol += ".";
    }
    measure_the_gap = symbol.length() > 0;
  }

  if (measure_the_gap)
  {
    unsigned long timestamp = millis();
    //Serial.println("Measuring the gap.");
    if (((timestamp - release_begin_time) > MORSE_UNIT_2))
    {
      // A long gap between presses signifies the end of a symbol.
      //Serial.println("Long gap");
      //Serial.println(symbol);
      measure_the_gap = false;
      message += DecodeSymbol(symbol);
      symbol = "";
    }
  }

  if (send_button.Fall())
  {
    // Print the Morse string.
    //Serial.println(message);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print(message);
    message = "";
  }

  // Delay for Tinkercad simulator.
  // Not needed for real hardware.
  delay(10);
}

char DecodeSymbol(String& symbol)
{
  //Serial.print(symbol);
  //Serial.print(": ");
  char ch = '?';
  for (int i = 0; i < 26; i++)
  {
    if (symbol == MORSE_CODES[i])
    {
      ch = 'A' + i;
      break;
    }
  }
  //Serial.println(ch);
  return ch;
}
```

For debouncing the buttons, I used this [debouncer][2] that I've put on GitHub. For Tinkercad, you will need to copy and paste that debouncer code (the debouncer.h file followed by the debouncer.cpp file) into the top of the Tnkercad code file because Tinkercad doesn't allow you to include your own code files.

  [1]: https://i.stack.imgur.com/rIJPR.png
  [2]: https://github.com/TimMathias/Arduino-Debouncer


message:
Adafruit OLED 7 Pin Display - Abbreviations

I can't remember for the life of me how exactly I set up this screen in previous models, partially because the references I'm using in my code have different names from the pins on the Adafruit display.

My code identifies the following digital pins for the following display pins:

    OLED_MOSI = 12
    OLED_CLK = 11
    OLED_DC = 10
    OLED_CS = 8
    OLED_RESET = 9

My Arduino is then attached from the following pins to those labelled on the OLED display as"

    12 -> SDA
    11 -> SCK
    10 -> DC
    8 -> CS
    9 -> RES
    5V -> VDD
    GND -> GND

In other words, I am interpreting the following as being equivalent:

    RES = RESET
    SCK = SCK
    MOSI = SDA

Is there anything within the information I've provided that is wrong / may cause the screen to malfunction?

Thank you very much in advance.

body:
* `DC` selects between `D`ata and `C`ommands.
* `CS` is the `C`hip `S`elect
* `SDA` is the `S`erial `DA`ta.
* `SCL` is the `S`erial `CL`ock.

These four together form what the documentation calls the "4-wire serial interface". It's not quite like SPI, owing to the presence of the `DC` pin (which is why it doesn't use SPI terminology), but close enough that SPI can be used to communicate with it.

In SPI the pin that sends data from the Arduino to the slave is known as the `MOSI` - `M`aster `O`ut `S`lave `I`n.  Some microcontrollers also call this `SDO` - `S`erial `D`ata `O`ut, where it's "out from the master's perspective".


message:
Struggling to understand how Bluetooth serial is related to USB on Arduino

I've recently acquired a Bluetooth module to attach to my Arduino Uno, but I'm trying to draw parallels to the standard method of communication that I'm familiar with, which seems to be just directly reading or writing to sensors through methods like digitalRead and digitalWrite, respectively. Additionally however, it seems like it's also possible to connect to a serial console, through the `Serial` class. These make sense, and I've used both individually (serial console viewed by the built-in Serial window in Arduino IDE, and serial write done through `Serial.print/println()`).

However, in the Bluetooth module I purchased (HW-10), there are pinouts that connect to the TX/RX ports, which I've currently left unconnected since I'm not using the Bluetooth module or any other serial module. My question is, once I connect these, does this completely replace the connection through USB that is currently used to interface with the Uno?

If so, I had a set of specific functionalities in mind for whether these would be "replaced" by connecting the module through the 4 pinouts (TX, RX, VCC, GND):

**1. Serial:** Can I write and access the serial monitor through the IDE by connecting to 9600 baud, both in code and in the Serial Monitor

**2. Pins:** Do these connections also allow me to write and read signals from all of the pins, including analog and digital

**3. Sending code:** Can I still send code through Bluetooth without needing a USB connection?

Apologies if this question seems really obvious or specific, I'm confused as I've read a bunch of wording saying that the Bluetooth module uses a "serial connection", when I only understood serial functionality as being a method of outputting text, not controlling the Arduino. Thanks in advance for help!

body:
> I don't actually know what a UART is

UART (Universal Asynchronous Receiver Transmitter) is the technical term for the communication interface, which is called `Serial` in Arduino speak. It's often called UART, because that is more precise, since there are many different communication protocols, which also work serially (meaning transferring data bits one after another in contrast to parallel, where multiple bits are transferred simultaneously), like I2C, SPI or USB. All serial protocols, but totally different from the Arduino `Serial` interface. Yes, this is a bit confusing. I guess the Arduino term `Serial` was coined to make the learning curve less steep for beginners (hiding complexity can also make things confusing unfortunately).

So UART is the same as the Arduino `Serial` interface.

> once I connect these, does this completely replace the connection through USB that is currently used to interface with the Uno?

Here it is good to know, how the USB communication works on the Uno. The microcontroller on the Uno (Atmega328p) does not have a native USB interface. So it cannot speak to USB itself. For that there is an extra microcontroller on the board (I think an Atmega32u4). This controller has a native USB interface and it acts as a USB to `Serial` bridge (it creates a virtual serial interface on the PC and translate between that and its physical `Serial`/UART interface). The Atmega328p (which you program with your code) has it's RX and TX pins connected to the RX and TX pins on the Atmega32u4, which can then translate between the `Serial`/UART protocol and the USB protocol. Thus the Atmega328p doesn't know anything about USB. I just talks via `Serial`/UART to the Atmega32u4. In fact it also doesn't know anything about bluetooth. Most bluetooth modules for Arduino are also just bluetooth-`Serial` bridges

Now you need to know, that `Serial`/UART is made for one-to-one connections. With multiple devices you can get problems, when multiple devices try to send data at the same time. I this case (BT module RX to Arduino TX and vice versa) you would get garbled data, if you try to simultaneously send data from bluetooth and USB to the Arduino. The signals would overlap on the Arduinos RX pin, corrupting the data.

That means, that you don't want to send from both interfaces. In fact it is the easiest way to just use one `Serial`/UART  interface for only one device. If you leave the Serial Monitor (or any other Serial communication program) closed on the PC, the PC will not interfere with the communication. Though you need to disconnect the bluetooth module, when you write your program to the Arduino, since this is done via `Serial` and you don't want it to meddle with the data.

So in result the bluetooth module will not "replace" the connection through USB. It will be added and it is your duty to prevent data corruption.

> 1. Serial: Can I write and access the serial monitor through the IDE by connecting to 9600 baud, both in code and in the Serial Monitor

Yes. You don't need to use 9600 baud necessarily. The only requirement is, that you use the same baud number in both sketch and Serial Monitor. That number just represents the speed, that the data is send in. Both sender and receiver need to agree on the same communication speed, or the receiver will not be able to read the data. Imagine someone talking to you, but talking twice the speed with that you are able to understand the words. You will not be able to understand much, because the speaker is just too fast. Either you would need to change your hearing/understanding speed or the sender needs to change it's speaking speed, to make the two match.

9600 baud is just one of the standard baudrates, though one of the lower ones. If you need it to be faster (maybe because you are sending much data in fast succession), you might want to use a higher baudrate.

> 2. Pins: Do these connections also allow me to write and read signals from all of the pins, including analog and digital

That is up to you. `Serial`/UART is just a communication interface. How it is used is up to you. You already have seen, that it is often used to output text for a user to read over the `Serial` interface, often used as a way to debug the code by sending specific text at specific places in the code. Since that connection works in both ways, you can also program the Arduino to receive commands over `Serial`/UART and then act upon them.

Here the overlaying communication protocol comes in. `Serial`/UART just transmits a series of bytes over its two lines. It doesn't care, what these bytes mean. It can be text (for example encoded via the ASCII standard, as the Serial Monitor does), or it can be just some binary data. Also there is no concept of "messages". There are only individual bytes and you don't have control over when exactly they are sent. So to make meaningful use of `Serial`/UART you need to use an extra communication protocol on top of `Serial`/UART, that the receiver understands.

When you send text to the Serial Monitor you are the receiver. Thus you would send text (because you can understand text) and a natural way for humans to distinguish individual messages is to use a delimiter character. In normal text that can be a period, though in this field going to a new line has somewhat evolved to the standard (so the delimiter character is the newline character `'\n'`). If you read the delimiter character (either yourself on the Serial Monitor, or the Arduino in your program), that marks the end of the message. You can also use that text based approach in your Arduino program (and I would say that is the easiest way). Though you don't need to. You could also use any binary protocol on it (or even invent your own protocol).

I would suggest you look at the examples in the Arduino IDE, that involve `Serial` and maybe try some tutorials on the web. There are many of them available.

> 3. Sending code: Can I still send code through Bluetooth without needing a USB connection?

You don't need an USB connection for `Serial`/UART to work. In fact the Atmega328p, which you program on the Uno, doesn't care about the USB connection at all. It only knows `Serial`/UART.

---

I hope that gave you a good overview over that topic. When you understand these core concepts you will be able to understand the tutorials and examples on the internet.


message:
Two servos for robot (head & chest) movement at different speeds at once

I have an Arduino Uno and two Hi-tec servos (HS-40 & 5055 digital) that I'm using for a basic robot build. I'm trying to have one servo(HS-40) turn the head back and forth (left to right) slightly faster than the other servo (HS-5055) controlling the upper torso.

I would like to have each servo working at the same time but not at the same speed without waiting for one servo to complete its movement.

I tried a sketch with a delay of 45-50 which seems to work fine for the movement speed and 0-75 degrees is ideal for the head travel and 0-65 degrees for the torso travel. I would like to have this movement to be repeated continuously so the robot mimics like it is looking side to side or left to right naturally.

Please help as I tried many sketches but can't find one that works like this. I tried modifying other code but can't get them work. Any help will be greatly appreciated.

How do modify this code so just the second servo runs at 40 which will slow down just enough? Also this is not my code, but it's one that seems to be close to what I'm trying to do.

```
#include <Servo.h>

Servo servo1;
Servo servo2;

int i = 0;

void setup() {
  servo1.attach(8);
  servo2.attach(9);
}

void loop() {
  for (i = 0; i < 70; i++) {
    servo1.write(i);
    servo2.write(i);
    delay(50);
  }
  for (i = 70; i > 0; i--) {
    servo1.write(i);
    servo2.write(i);
    delay(50);
  }
}
```

body:
Heres a little sketch you can try.  It uses timing to accomplish the different servo speeds.  It won't give you the exact servo travel each loop but it sounds like you might not mind if it randomly is off by a few degrees each loop.

    #include <Servo.h>
    Servo servo1;
    Servo servo2;
    int i = 0;
    void setup() {
      Serial.begin(9600);
      servo1.attach(8);
      servo2.attach(9);
    }

    int sweep_time = 3500; // 70 * 50ms = 3500

    int head_degrees = 75; // sweep degrees for the head to move
    int body_degrees = 65; // sweep degrees for the body to move

    int millis_per_head_move = sweep_time / head_degrees;
    int millis_per_body_move = sweep_time / body_degrees;

    void loop() {
      int i = 0; int j = 0;
      unsigned long now_millis = 0;
      unsigned long start_sweep = millis(); // mark the time when we start the first sweep

      while ( millis() - start_sweep < sweep_time ) {  // keep moving first sweep until sweep time has elapsed
        now_millis = millis() - start_sweep;
        if (now_millis % millis_per_head_move == 0 ) servo1.write(i++);
        if (now_millis % millis_per_body_move == 0 ) servo2.write(j++);
        delay(1);
      }
      Serial.print(i); Serial.print(" "); Serial.println(j);

      start_sweep = millis();  // mark the time when we start the second/back sweep
      while ( millis() - start_sweep < sweep_time ) {  // keep moving second sweep until sweep time has elapsed
        now_millis = millis() - start_sweep;
        if (now_millis % millis_per_head_move == 0) servo1.write(i--);
        if (now_millis % millis_per_body_move == 0) servo2.write(j--);
       delay(1);
      }
      Serial.print(i); Serial.print(" "); Serial.println(j);
    }


body:
Thanks for the answer from @tavis

Here is the simulation of their code and it answers your questions aptly.
[![enter image description here][1]][1]

The code (same as above, except the sweep time change)

    #include <Servo.h>
    Servo servo1;
    Servo servo2;
    int i = 0;
    void setup() {
      Serial.begin(9600);
      servo1.attach(8);
      servo2.attach(9);
    }

    int sweep_time = 1000; // 70 * 50ms = 3500

    int head_degrees = 75; // sweep degrees for the head to move
    int body_degrees = 65; // sweep degrees for the body to move

    int millis_per_head_move = sweep_time / head_degrees;
    int millis_per_body_move = sweep_time / body_degrees;

    void loop() {
      int i = 0; int j = 0;
      unsigned long now_millis = 0;
      unsigned long start_sweep = millis(); // mark the time when we start the first sweep

      while ( millis() - start_sweep < sweep_time ) {  // keep moving first sweep until sweep time has elapsed
        now_millis = millis() - start_sweep;
        if (now_millis % millis_per_head_move == 0 ) servo1.write(i++);
        if (now_millis % millis_per_body_move == 0 ) servo2.write(j++);
        delay(1);
      }
      Serial.print(i); Serial.print(" "); Serial.println(j);

      start_sweep = millis();  // mark the time when we start the second/back sweep
      while ( millis() - start_sweep < sweep_time ) {  // keep moving second sweep until sweep time has elapsed
        now_millis = millis() - start_sweep;
        if (now_millis % millis_per_head_move == 0) servo1.write(i--);
        if (now_millis % millis_per_body_move == 0) servo2.write(j--);
        delay(1);
      }
      Serial.print(i); Serial.print(" "); Serial.println(j);
    }

Link to the simulation:
https://wokwi.com/arduino/projects/303847722463527490

Here is another example with three Servo motors running at three different sweep times:
https://wokwi.com/arduino/projects/299552195816194570

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


message:
Arduino Mega reading from external sensor Issue

I have one external sensor and I want it to be connected with Arduino. The sensor came up with a usb cable and the pin out diagram is also given in the data sheet .

When I simply connect the the cabe which came along the sensor (E322968) with no Arduino board involved, but through Arduino IDE and setting baud rate to 115200 I am able to see the output in serial monitor of the Arduino .
[![enter image description here][1]][1]

 I want to capture this data to some variables for further manipulation. In the data sheet the pinout is specified as
[![enter image description here][2]][2]

Please help me get the data to Arduino variable .

What I tried is connected,
1. the RX1 or Arduino mega to the TX1 of the sensor (pin2) and
2. from Arduino VCC(5v) to VCC of the sensor :: pin(1)
3. ground to gnd of sensor, (pin5)

  [1]: https://i.stack.imgur.com/4u9Ae.png
  [2]: https://i.stack.imgur.com/r47Gg.png

body:
> the RX1 or Arduino mega to the TX1 of the sensor (pin2) and

That will not work. These pins are for RS232, which uses the same communication protocol (UART) as the Arduino, but it uses different voltage levels. But fortunately your sensor has also RX and TX pins at TTL level (Transistor-Transistor-Logic). You want to connect these to the Arduino.

One thing to keep in mind: The sensor logic seems to work at 3.3V (voltage on the RX and TX lines). If you also want to send data to the sensor, you may need to step down the 5V of the Uno to the 3.3V of the sensor on its RX line (since 5V might damage the sensor). You can use a simple voltage divider with 2 resistors or a proper level shifter (which uses transistors) (voltage dividers limit the communication speed, though 115200baud should not be a problem).


message:
Arduino does not boot when SPI lines are loaded

i connected an Arduino Nano to an external SPI Flash using [THIS](https://it-blackbox.blogspot.com/2018/04/spi-arduino-nano.html) tutorial (russian) and the SPIMemory library. While accessing the Flash works well, i have encountered the following issue:

**The Problem: When the SPI MISO line is pulled high by the flash while the Arduino boots, it does not start**, for example because it was rebooted while accessing the flash. I have to power down the Flash before it boots again. But even then, it takes unusually long to boot.

I know that the Atmega328p allows reprogramming via SPI, but to my knowledge this should not cause this behavior since the SPI lines do not change (starting the programming mode would require a command to be sent immediately after restart). Is there any way to prevent this behavior? (Except disabling SPI programming via fuse bits, this would be my last choice)

**EDIT**

Programming the Arduino via ISP does work, however i added some series resistors to the flash to prevent accidentally driving the SPI lines from multiple sources.

The problem seems to come from the MISO line, when it is pulled to VCC the Arduino does not start. This is not mentioned in the data sheets anywhere and i am not sure how to prevent this (sketch below to show the wiring).

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

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

body:
I honestly can't imagine why a sketch like that would hang in this scenario. But I'm confident that my answer can solve the issue.

My guess is that the following happens:
The flash is selected (CS pulled low by atmega) at the moment at which the reset happens. At this moment, the master will stop generating a clock signal and CS will be floating.
Thus, the flash will not be deselected *reliably* due to the floating CS and MISO will remain in the state it was before the reset occured (HIGH if it was transmitting a logic 1, LOW for 0). Basically, the SPI communication of the flash will be stuck with MISO being actively pulled to logic high or low.

IDK why this causes the sketch to freeze, but if you add a pullup resistor to the flash's CS, it should be deactivated by default (and also after a reset of the atmega as pins will be inputs/floating by default). As a result, the flash can not actively pull MISO and should therefore barely affect the atmega at all.

I suggest you add the mentioned pullup and see if that makes any difference. If it doesn't I'm going to delete this answer, but it was a bit too long for a comment ;).

Edit: I also just saw that you are missing the pullup resistor on the reset pin. That could well be the actual problem.


message:
Sending a struct over i2c

How would you send a struct from an i2c slave when requested by an i2c master?

**Slave Struct Respdonder Sketch (Seeeduino Xiao)**

    #include <Wire.h>

    struct TransmitData
    {
      int a;
      int b;
      int c;
      int d;
      float e;
      float f;
      float g;
      float h;
    };

    TransmitData data;

    void setup()
    {
      Serial.begin(9600);
      Wire.begin(2);
      Wire.onRequest(requestEvent);

      data.a = 1;
      data.b = 2;
      data.c = 3;
      data.d = 4;
      data.e = 5.1;
      data.f = 6.1;
      data.g = 7.1;
      data.h = 8.1;
    }

    void loop()
    {
      delay(100);
    }

    void requestEvent()
    {
      Serial.print("sending ("); Serial.print(sizeof data); Serial.println(" bytes)");
      Wire.write((byte *)&data, sizeof data);
    }

**Master Struct Requester/Reciever Sketch (Arduino MEGA)**

    #include <Wire.h>

    struct TransmitData
    {
      int32_t a;
      int32_t b;
      int32_t c;
      int32_t d;
      float e;
      float f;
      float g;
      float h;
    };

    TransmitData data;

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

    void loop() {
      Serial.print("requesting ("); Serial.print(sizeof data); Serial.print(" bytes)... ");
      if (Wire.requestFrom(2, sizeof data)) {
        Wire.readBytes((byte*) &data, sizeof data);
        Serial.println("done");

        Serial.println(data.a);
        Serial.println(data.b);
        Serial.println(data.c);
        Serial.println(data.d);
        Serial.println(data.e);
        Serial.println(data.f);
        Serial.println(data.g);
        Serial.println(data.h);
      }
      else {
        Serial.println("could not connect");
      }
      delay(500);
    }

The serial output on the slave device is:

    sending (32 bytes)

The serial output on the master device is:

    requesting (24 bytes)... done
    1
    0
    2
    0
    0.00
    0.00
    5.10
    6.10

body:
`int` isn't guaranteed to be the same size across platforms. Use fixed width integer types instead.

https://en.cppreference.com/w/cpp/types/integer

    struct TransmitData
    {
      int32_t a;
      int32_t b;
      int32_t c;
      int32_t d;
      float e;
      float f;
      float g;
      float h;
    };


message:
Code For Lighting RGB Led

I am doing [this][1] simple introductory exercise to light an RGB Led, but I am confused about the code in the exercise. The following is the code:

    /* Adafruit Arduino - Lesson 3. RGB LED
    */

    int redPin = 11;
    int greenPin = 10;
    int bluePin = 9;

     //uncomment this line if using a Common Anode LED //#define
     COMMON_ANODE

    void setup() {
    pinMode(redPin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(bluePin, OUTPUT);   }

    void loop() {
      setColor(255, 0, 0);  // red
      delay(1000);
      setColor(0, 255, 0);  // green
      delay(1000);
      setColor(0, 0, 255); // blue
      delay(1000);
      setColor(255, 255, 0);  // yellow
      delay(1000);
      setColor(80, 0, 80);  // purple
      delay(1000);
      setColor(0, 255, 255);  // aqua
      delay(1000); }

    void setColor(int red, int green, int blue) {
    #ifdef COMMON_ANODE
         red = 255 - red;
         green = 255 - green;
         blue = 255 - blue;
    #endif
      analogWrite(redPin, red);
      analogWrite(greenPin, green);
      analogWrite(bluePin, blue);   }

In this code, why were they able to carry out setColor before expanding upon what it means later through `void setColor(int red, int green, int blue)`? Should that portion of the code come earlier or does it matter? Also I don't quite understand how the definition of the colors red, green, and blue were defined towards the bottom. I know what 255 would indicate maximum brightness, but why do you have to subtract the color from 255? Any help would be much appreciated.

  [1]: https://learn.adafruit.com/adafruit-arduino-lesson-3-rgb-leds/arduino-sketch

body:
> why were they able to carry out setColor before expanding upon what it means later

You are correct in C that is the case. However the Arduino IDE adds "function prototypes" to the top of your code automatically. That means you no longer have to abide by the "define before use" of C and C++.

> I know what 255 would indicate maximum brightness, but why do you have to subtract the color from 255?

This is for if your LED is "common anode" instead of "common cathode". With a common anode LED you write a LOW to turn it on and a HIGH to turn it off - this is the exact opposite of a common cathode.

So to set the brightness of a common anode LED you need to use the opposite value, and since PWM goes from 0-255 the opposite is 255-0: 255 is off, and 0 is fully on.


message:
Control laser diode from digital pin

I have a 200mw laser module that came with a 3v 1A power supply. I want to control it from a digital pin on an arduino uno.

Can I use a simple voltage divider like this or is there some consideration to current I'd need to take into account? The laser module was quite expensive so I'm hesitant to try it out.

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

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

<!-- End schematic -->

body:
Your solution does not work, mainly because GPIOs are not intended to source current higher than a few mA. If you want the laser diode to emit a reasonable amount of power, you need to drive it with a transistor. A MOSFET-based low-side-switch would probably be the easiest solution. But note that you still need to limit the current, e.g. by using a series resistor.

Even better would be to use a constant current driver (you can use any led driver with appropriate rating).

If the power supply that came with the laser diode is a constant current source, it might be possible to switch its output directly (without resistor), but that depends on how it behaves when it is open-circuited.


message:
Is it possible to extract the firmware of an Arduino BLE or IoT board wirelessly?

I've looked at previous questions regarding sketch extraction and know that it is possible to extract the hex code from an Arduino board using avrdude from the command line.

However, I want to see if the following is possible:

 1. Connect to Arduino 33 IoT board
 2. Extract onboard Firmware as a hex file
 3. Disconnect from Arduino 33 IoT board.

I understand that getting the initial source code is not possible, but I am in particular looking to just get the hex code in a wireless manner. If it is not possible via the Arduino 33 IoT board, is there any Arduino board with which this can be done? Any help or guidance would be appreciated.

body:
Technically, the firmware can read its own application section, but it won't send it to you wirelessly (or via any interface) if such a feature isn't implemented in that firmware. If you were to implement the firmware yourself, you can do (almost) anything. But if it is a third party firmware, this will not be possible.

The reason this works with arduinos and avrdude is, because firmware up- and download are implemented in hardware (ISP, works without a bootloader).


message:
How to reset a variable just before entering a function?

I am facing a problem where the if condition in the function ```waterNowrun``` is able to execute once after the program starts as the variable ```v``` is 0 at the start, but upon starting it again the if does not execute as ```v``` is not <10.

After some debugging I had decided that ```v``` would have to be reset before entering the function, and so I set ```v``` to 0 in the loop, then what happened is that the if was always satisfied and did not go to the else.

Is it possible to do it? Maybe with interrupts or something else?

Hardware-ESP8266 based NodeMCU

**In conclusion-**

I want a reset a variable ```v``` once just before the function ```waterNowrun``` starts, how do I do it?

**My code-**

```
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "DHT.h"
#include "LiquidCrystal_PCF8574.h"

#define BLYNK_PRINT Serial
#define DHT_PIN_DATA  12
// LCD definations
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
#define BACKLIGHT 25
#define DHTTYPE DHT22

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ymri80lFL9_xZhf6WIRHtQ1qadfafdEWOt9zBy";
char ssid[] = "-Hotspot-82DB";
char pass[] = "b35288qqafdd";
int autoSch;
int waterNow;
int morTime;
int afterTime;
int postNoon;
int eveTime;
int schTime;
int minStep;
int interval;
int count;
int flag = 0;
int soilHum = A0;
int v;
unsigned long previousMillis = 0;

DHT dht(DHT_PIN_DATA, DHTTYPE);
LiquidCrystal_PCF8574 lcdI2C;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 600000);
// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1

BLYNK_CONNECTED() {
  Blynk.syncAll();
}

BLYNK_WRITE(V0)
{
  autoSch = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V1)
{
  morTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V2)
{
  afterTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V6)
{
  postNoon = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V3)
{
  eveTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V10)
{
  waterNow = param.asInt(); // assigning incoming value from pin V1 to a variable
Serial.println("Boo BOO is BOO BOO billa");
}

BLYNK_WRITE(V4)
{
  schTime = param.asInt(); // assigning incoming value from pin V1 to a variable
}

BLYNK_WRITE(V7)
{
  minStep = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  dht.begin();
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(14, OUTPUT);
  digitalWrite(14, LOW);
  Blynk.virtualWrite(V5, 0);
  Blynk.virtualWrite(V8, 0);
  pinMode(0, INPUT_PULLUP);
  Serial.begin(9600);

  //WiFi.begin(ssid, password);
  Blynk.begin(auth, ssid, pass);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  timeClient.begin();
  Blynk.syncAll();
}

void loop()
{
  Blynk.run();
  time_run();
  lcd();
  butPress();

  timeClient.update();
  if (waterNow != 1) {
    Blynk.virtualWrite(V10, 0);
   // digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, minStep * 60);

    Blynk.syncAll();
  }
  if (waterNow == 1) {
    waterNowrun(v = 0);

  } else if (autoSch == 0) {
    auto_run1();
  } else if (autoSch == 1) {
    sch_run2();
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }
  Blynk.syncAll();
  Serial.println(timeClient.getFormattedTime());
  Serial.println(analogRead(A0));
}
void butPress() {
  if (digitalRead(0) == LOW) {
    if (flag == 0) {

      digitalWrite(14, HIGH);
      delay(3000);
      digitalWrite(14, LOW);

      flag = 1;
    }
    else {
      digitalWrite(14, LOW);
      flag = 0;
    }
  }
}

void test() {
  if (v < 10) {
    digitalWrite(14, HIGH);
    v++;
    delay(500);

  } else {
    digitalWrite(14, LOW);

  }

}

void lcd() {
  //lcdI2C.clear();
  lcdI2C.setCursor(0, 0);
  timeClient.update();
  lcdI2C.print(timeClient.getFormattedTime());

  if (autoSch == 0) {
    lcdI2C.setCursor(9, 0);
    lcdI2C.print("Auto     ");
  } else {
    lcdI2C.print(" Sch   ");
  }

  if (digitalRead(14) == 1) {
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now           ");
  }
  else
  {

    if (int(timeClient.getHours()) < 6 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else if (int(timeClient.getHours()) < 12 && afterTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 12n ");
    } else if (int(timeClient.getHours()) < 14 && postNoon == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at:14pn ");
    } else if (int(timeClient.getHours()) < 18 && eveTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 18e ");
    } else if (int(timeClient.getHours()) >= 18 && morTime == 1 && autoSch == 0) {
      Blynk.syncAll();
      lcdI2C.selectLine(2);
      lcdI2C.print("Auto Wtr at: 6a ");
    } else {
      lcdI2C.selectLine(2);
      lcdI2C.print("My name is billa");
    }

  }

}

void waterNowrun(int v) {
  /*
    Serial.println (currentMillis);
    Serial.println (previousMillis);
    Serial.println(interval);
  */

  if (v < 10) {

    Serial.println("Boo Boo");

    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    lcdI2C.selectLine(2);
    lcdI2C.print("Wtr Now :");
    /*
      lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
      Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis - previousMillis) / 1000)));
    */
    Blynk.syncAll();
    delay(500);
    v++;
  } else {
    Blynk.virtualWrite(V10, 0);
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V8, 0);

    Blynk.syncAll();

  }
}

void sch_run2() {
  if (schTime == 1) {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  } else if (schTime == 0) {
    digitalWrite(14, LOW);
    Blynk.virtualWrite(V5, 0);
    Blynk.syncAll();
  }

}

void time_run() {
  Blynk.virtualWrite(V11, int(timeClient.getHours()));
  Blynk.virtualWrite(V12, int(timeClient.getMinutes()));
  Blynk.virtualWrite(V13, float(dht.readTempC()));
  Blynk.virtualWrite(V14, float(dht.readHumidity()));

}

void auto_run1() {
  if (morTime == 1 && String(timeClient.getFormattedTime()) > "06:00:00" && String(timeClient.getFormattedTime()) < "06:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (afterTime == 1 && String(timeClient.getFormattedTime()) > "12:00:00" && String(timeClient.getFormattedTime()) < "12:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (postNoon == 1 && String(timeClient.getFormattedTime()) > "14:00:00" && String(timeClient.getFormattedTime()) < "14:20:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else if (eveTime == 1 && String(timeClient.getFormattedTime()) > "12:59:00" && String(timeClient.getFormattedTime()) < "13:01:00") {
    digitalWrite(14, HIGH);
    Blynk.virtualWrite(V5, 255);
    Blynk.syncAll();
  }
  else  {
    //(String(timeClient.getFormattedTime() == "06:20:00" || "12:20:00" || "14:20:00" || "13:48:00"))
    //waterNowrun();
    /*
      Blynk.virtualWrite(V10, 0);
      digitalWrite(14, LOW);
      Blynk.virtualWrite(V5, 0);
      Blynk.virtualWrite(V8, 0);
      Blynk.syncAll();
    */
  }
}
```

body:
The purpose of the waterNowrun function and 'v' seems to be to turn on some water and keep it running for 10 iterations, before turning it off?

I would split the waterNowrun into two functions:

    void waterOn() {
        Serial.println("Boo Boo");
        digitalWrite(14, HIGH);
        Blynk.virtualWrite(V5, 255);
        lcdI2C.selectLine(2);
        lcdI2C.print("Wtr Now :");
        /*
          lcdI2C.print((minStep * 60) - ((currentMillis - previousMillis) / 1000));
          Blynk.virtualWrite(V8, ((interval / 1000) - ((currentMillis -     previousMillis) / 1000)));
        */
        Blynk.syncAll();
        delay(500);
    }

    void waterOff() {
        Blynk.virtualWrite(V10, 0);
        digitalWrite(14, LOW);
        Blynk.virtualWrite(V5, 0);
        Blynk.virtualWrite(V8, 0);
        Blynk.syncAll();
    }

In the loop() I would do

    ...
    if (waterNow != 1) {
        waterOff();
    }
    if (waterNow == 1) {
        if (v < 10) {
            waterOn();
            v++;
        }
        else {
            waterOff();
            v = 0;
        }
    } else if (autoSch == 0) {
        auto_run1();
    } else if (autoSch == 1) {
        sch_run2();
    } else {
        waterOff();
    }
    ...

But do yourself a favour and rename v to waterPeriod or something that is easier to remember.


body:
It isn't clear what behavior you expect from `v`, especially since you have two of them - the global `v` at the head of your program, and the parameter `v` of the function `waterNowrun(int v)`.

My understanding of what you want is that the function should maintain control of `v`. If so,

 - Get rid of the global `v`';
 - In `loop()`, don't pass anything to `waterNowrun()`
 - Inside `waterNowrun()` declare `static int v = 0;`. That initialization to zero will only happen once, before the program starts (not on every entry to the function, even though it kind of reads like that). From then on, only your `waterNowrun()` function can change `v`.

That may not be the only logic change you need to make - I don't understand what you're trying to do with `v` and can't critique that. But at least now `v` will be entirely controlled from within the function, and it will not change between invocations of the function.

Some background: A static variable declared within a function is like a global in that it has a fixed memory address for the entire program run; unlike a local (including a function parameter) that gets reallocated in memory each time the function is entered (and therefore must be initialized on every entry). But *unlike* a global, it is invisible - not known about - anywhere outside of that function.


message:
How to connect an Output to a Pullup Input of another arduino

:tldr; Could problems occur if one connects a HIGH Output of one arduino to a PULLUP_INPUT of another while using differed power sources?

Hi I'm building some devices for a LARP Dungeon (think Escape room).

For that we have interfaces, riddles and switches(triggers).
Interfaces provide access to sound/light/DMX sytems for riddles.
Riddles check conditions and send state information to the interfaces.

To keep things simple, states are boolean (like riddle is solved, a critical mistake has been made,..)

I would like to use PULLUP_INPUTs on the receiving end so I can use simple switches to GND as controls. In some cases a switch might be connected directly to an interface. Mostly there is a riddle in-between. In those cases an OUTPUT of the riddle's Arduino will be connected to the PULLUP_INPUT of the Interface's Arduino. There will be multiple riddle Arduinos connected to one or even multiple Interfaces.
Due to cable length, differed power sources etc. the potential to GND of the involved Arduinos might be differed. So I assume this difference will flow over the pullup resistor of the interfaces into their 5V. The internal PULLUP is ~20kOhms so current should not be a problem but can the voltage, which might be a little higher than the one of the input, cause problems?

Or would it be better to set the Output of a riddle Arduino to INPUT while the signal line should be HIGH so it gets a high impedance? Switching between: OUTPUT:LOW while active and INPUT while inactive.

body:
Connecting any signal that is within the voltage range of the receiving Arduino is safe. So if you use Arduino UNOs or similar with a 5V operating level, you can connect any signal between 0 and 5V to an input. It does not matter whether the input is in pull-up-mode or not. So connecting an output to an input of another Arduino (or even of the same Arduino) is safe. In addition to the signal values, you do need to connect the ground of both Arduinos.

The only thing you must _not_ do is connect two outputs together (because if one of them is high and the other is low, you have a shortcut that will potentially fry one or both of the boards). And you would need to be careful if you used different types of Arduinos, like a Uno and a Due, because they run at different voltage levels.


message:
Teensy 4.1 serial communication with 7N2 (7 databits no parity 2 stopbits)

I have ported a project from arduino Due to a teensy 4.1

In the project I read data from a sensor which speaks serial at 7 databits, no parity and 2 stopbits (no configurable).

Now it seems that [teensy does not support this dataformat][1].
Could I read my sensor in a way using teensy 4.1? I could maybe use softwareserial but the format does not seem to be configurable.

  [1]: https://www.pjrc.com/teensy/td_uart.html

body:
There is no difference between 7N2 and 8N1. You just have the most significant bit of your data value being the first of the two stop bits.

To transmit just set the most significant bit to 1.

To receive just ignore the most significant bit.

For example:

```c++
Serial.write(val | 0x80);
```
And:
```c++
uint8_t val = Serial.read() & 0x7F;
```


message:
Mass testing of Arduinos

I am using Arduino for an IoT class (40 students). I have set up a test program to check all sensors and actuators used in the class (we need to recycle for next semester). However, I would also like to check the Arduino's themselves (and also NodeMCU´s) in case some of the units have been broken. I have an idea of testing input/output of each pin to make sure its working - using LEDs and buttons, but if anyone has some ideas to improve testing, it would be great to hear from you.

body: Testing microcomputers is a very complicated task. In your case I would suggest writing some programs to do exactly what you are saying. Then let the students do the testing. When the class starts you have to teach them the basics, this will check the computers etc and also the test equipment on there benches. At the end of testing they will have knowledge of the basics they will need to continue with the class. You can also have the students do this at the end of the semester to get a head start on any problems.


body:
I'd add a second Arduino to supply a HIGH and LOW signal to the Arduino being tested (to test the INPUT), and to verify that the tested Arduino can output HIGH and LOW. Testing inputs, outputs, and being able to upload you test sketch will catch the most common problems.

Testing the regulator would be my next thing, but that also depends on whether you're previous course was using the regulator.


body: When I make a new (Uno-like) board, I test for shorts and opens with sketch that blinks each pin in sequence. @Gerben's suggestion to test the inputs as well makes a lot of sense for your application. Plus the basic ability to power up (working barrel-connector input & voltage regulator, working USB connector and USB communication) would another test I'd make. I'd probably boards that have a socketed chip for my future purchases (if you're not already).


body:
There are a number of open issues which need to be addressed in order to narrow the scope of this project to a manageable and reasonable effort.  For instance:

 1. Which Arduino (board and processor) are you using?  Does the board power off a regulated USB 5 volt source?  Or does it use a regulator which needs testing?
 2. How many GPIO pins are there? Will they be used to drive, sense or both?
 3. Are there any Analog pins?  Do they need to be tested over a range or just a select voltage?
 4. Are there any PWM outputs which need to be tested?

To simplify testing we might make some assumptions.  For example:

 1. If the GPIO aspect of a pin works any PWM feature for that pin may be assumed functional.
 2. If a given voltage at a Analog Input pin results in a reasonable analog to digital conversion then all other reasonable voltages will result in the expected analog to digital conversion.

For testing many UUTs (Units Under Test), it is almost always better to build a fixture.  This might be simple cables connected to another (carefully controlled) Arduino all the way to a bed-of-nails [In Circuit Tester (ICT)][1].

The ["Make a Pogo Pin Test Jig" project][2] at [Adafruit][3] addresses many of these concerns at a level that may be suitable to implement at the college level.

  [1]: https://en.wikipedia.org/wiki/In-circuit_test
  [2]: https://learn.adafruit.com/how-to-make-a-pogo-pin-test-jig
  [3]: https://www.adafruit.com/


body:
A _complete_ test would obviously be something fairly complex, and would
probably require building some sort of rig. You can, however, perform a
_minimal_ test that checks for common failure modes, without connecting
any extra hardware.

I assume the pin I/O stages are the easiest thing to break. You can then
check that, when you read a pin that is set to `OUTPUT`, you get the
value that the pin is supposed to be outputting. You can leverage the
stray capacitances of floating pins to test them as inputs: the
capacitance should make the pin “remember” its previous output value for
some time, and that time should be really short if the internal pull-up
is enabled.

The following program tests pins 2–13 and A0–A5 of an Uno. It checks
that:

1. a pin set to `OUPUT` `LOW` reads `LOW`
2. a pin set to `OUPUT` `HIGH` reads `HIGH`
3. a pin switched from `OUPUT` `HIGH` to `INPUT` reads `HIGH`
4. a pin switched from `OUPUT` `LOW` to `INPUT` reads `LOW`
5. a pin switched from `OUPUT` `LOW` to `INPUT_PULLUP` reads `LOW`, then
   switches to `HIGH` less than a microsecond later

Pins 0 and 1 are not tested, as they are connected to the serial port.
On the other hand, if you can upload a sketch, you know those pins work
at least as RX/TX.

Note that the program uses direct port access, as the Arduino functions
for accessing the pins are too slow for this kind of tests. If all
works, the program prints “All tests passed.”. Otherwise specific error
messages are printed, followed by “Some tests failed.”

```c++
#include <avr/cpufunc.h>
#include <util/delay.h>

int failures = 0;

static void log_failure(char port_name, const char * reason)
{
    failures++;
    Serial.print("FAIL: Port ");
    Serial.print(port_name);
    Serial.print(", read ");
    Serial.println(reason);
}

static inline __attribute__((always_inline))
void test_port(const char port_name, uint8_t mask,
    volatile uint8_t *pin, volatile uint8_t *ddr, volatile uint8_t *port)
{
    *port = 0;
    *ddr = mask;   // OUTPUT LOW
    _NOP();
    if ((*pin & mask) != 0)
        log_failure(port_name, "OUTPUT LOW");
    *port = mask;  // OUTPUT HIGH
    _NOP();
    if ((*pin & mask) != mask)
        log_failure(port_name, "OUTPUT HIGH");
    *ddr = 0;      // INPUT_PULLUP
    *port = 0;     // INPUT -> HIGH
    _NOP();
    if ((*pin & mask) != mask)
        log_failure(port_name, "INPUT HIGH");
    *ddr = mask;   // OUTPUT LOW
    *ddr = 0;      // INPUT -> LOW
    _NOP();
    if ((*pin & mask) != 0)
        log_failure(port_name, "INPUT LOW");
    *port = mask;  // INPUT_PULLUP
    _NOP();
    uint8_t r1 = *pin;
    _delay_us(1);
    uint8_t r2 = *pin;
    if ((r1 & mask) != 0 || (r2 & mask) != mask)
        log_failure(port_name, "INPUT_PULLUP");
}

void setup()
{
    Serial.begin(9600);
    TIMSK0 &= ~_BV(TOIE0);  // disable timer interrupt

    test_port('B', 0x3f, &PINB, &DDRB, &PORTB);  // PB0..PB5
    test_port('C', 0x3f, &PINC, &DDRC, &PORTC);  // PC0..PC5
    test_port('D', 0xfc, &PIND, &DDRD, &PORTD);  // PD2..PD7

    if (failures == 0)
        Serial.println("All tests passed.");
    else
        Serial.println("Some tests failed.");
}

void loop(){}
```

As an extension, analog inputs could be tested in a manner similar to
test 5: if the analog sampling is done at the right time, you can
get a reading that is somewhere mid-range.


message:
AccelStepper Library Help - Simultaneous Motor Driving

I’m working on a 4 wheeled robot driven with stepper motors. I have a Raspberry Pi that sends a random (based on input image) pulse count to the Arduino board serially and then steps that amount. I’m using an Arduino CNC board to drive all 4 stepper motors, just FYI. My problem is that currently my steppers will not simultaneously move. I’ve read over the documentation for the AccelStepper library pretty well and tried some of the example code with no luck. I have a lot of function/ parsing code prior to the actual stepper code. It’s almost at the end, the function called ‘yMovement’.
Currently, the int value is received then yStepper moves, then yStepper1 moves after.

My updated code now makes them move simultaneously but the done command does not behave as before.

```
#include <AccelStepper.h>

const int stepperCount = 4;
AccelStepper FLStepper(AccelStepper::FULL2WIRE, 2, 5);
AccelStepper FRStepper(AccelStepper::FULL2WIRE, 3, 6);
AccelStepper BRStepper(AccelStepper::FULL2WIRE, 4, 7);
AccelStepper BLStepper(AccelStepper::FULL2WIRE, 12, 13);

bool movementComplete = false;

// defines pins numbers

//Front left wheel
const int stepX = 2;
const int dirX  = 5;

//Front right wheel
const int stepY = 3;
const int dirY  = 6;

//Back left wheel
const int stepZ = 4;
const int dirZ  = 7;

//Back right wheel
const int stepA = 12;
const int dirA  = 13;
const int enPin = 8;

char split = ':';         //this is the character that would be used for seperating the different parts of your commands
                          //the syntax for commands would be:   command:value1:value2

int listSize = 5;                                     //the amount of commands in the list
String commands[] = {"hello", "add", "sub", "YMOV", "XMOV"};     //the list of every command name

void setup()
{
  Serial.begin(115200);     //sets the data transfer rate for the serial interface
                          //9600 is good for basic testing, but should be as high
                          //as possible for both devices.
  FRStepper.setMaxSpeed(500);
  FRStepper.setAcceleration(400);
  BRStepper.setMaxSpeed(500);
  BRStepper.setAcceleration(400);

  FLStepper.setMaxSpeed(500);
  FLStepper.setAcceleration(400);
  BLStepper.setMaxSpeed(500);
  BLStepper.setAcceleration(400);

  pinMode(stepX, OUTPUT);
  pinMode(dirX, OUTPUT);

  pinMode(stepY, OUTPUT);
  pinMode(dirY, OUTPUT);

  pinMode(stepZ, OUTPUT);
  pinMode(dirZ, OUTPUT);

  pinMode(enPin, OUTPUT);

  digitalWrite(enPin, LOW);
  digitalWrite(dirX, HIGH);
  digitalWrite(dirY, HIGH);
  digitalWrite(dirZ, HIGH);
  digitalWrite(dirA, HIGH);

}

void loop()
{
  CommCheck(); //checks serial buffer for data commands
  runMotors();
}

void runMotors()
{

  if ((FLStepper.distanceToGo() != 0) || (FRStepper.distanceToGo() != 0) || (BLStepper.distanceToGo() != 0) || (BRStepper.distanceToGo() != 0))
  {

    FLStepper.run();
    //BLStepper.run();
    FRStepper.run();
    //BRStepper.run();
    movementComplete = true;
  }
  if (movementComplete == true)
  {
    CommConfirm();
    movementComplete = false;
  }
  //if ((FLStepper.distanceToGo() == 0) && (FRStepper.distanceToGo() == 0) && (BLStepper.distanceToGo() == 0) && (BRStepper.distanceToGo() == 0))
  //if ((FLStepper.distanceToGo() == 0) || (FRStepper.distanceToGo() == 0) || (BLStepper.distanceToGo() == 0) || (BRStepper.distanceToGo() == 0))
  //{
    //movementComplete = true;
  //}
}
void CommCheck()
{
  if(Serial.available())                    //checks to see if there is serial data has been received
  {
    //int len = Serial.available();           //stores the character lengh of the command that was sent
                                             //this is used for command parsing later on

    String command = Serial.readString();   //stores the command as a text string
    int len = command.length();
    //Serial.println(command);
    Serial.flush();
    //command.remove(len-2,1);                //removes characters added by the pi's serial data protocol
    //command.remove(0,2);
    //len -= 3;                               //updates the string length value for parsing routine

    int points[2] = {0, 0};                 //offset points for where we need to split the command into its individual parts

    for(int x = 0; x < len; x++)            //this loop will go through the entire command to find the split points based on
    {                                       //what the split variable declared at the top of the script is set to.
      //Serial.print("Char ");
      //Serial.print(x);
      //Serial.print("- ");
      //Serial.println(command[x]);
      if(command[x] == split)               //this goes through every character in the string and compares it to the split character
      {
        if(points[0] == 0)                  //if the first split point hasn't been found, set it to the current spot
        {
          points[0] = x;
        }
        else                                //if the first spot was already found, then set the second split point
        {                                   //this routine is currently only set up for a command syntax that is as follows
          points[1] = x;                    //command:datavalue1:datavalue2
        }
      }
    }
    CommParse(command, len, points[0], points[1]);      //now that we know the command, command length, and split points,
  }                                                     //we can then send that information out to a routine to split the data
}                                                       //into individual values.

void CommParse(String command, int len, int point1, int point2)
{
  //Serial.print("Command Length: ");
  //Serial.println(len);
  //Serial.print("Split 1: ");
  //Serial.println(point1);
  //Serial.print("Split 2: ");
  //Serial.println(point2);

  String com = command;                 //copy the full command into all 3 parts
  String val1 = command;                //this is needed for the string manipulation
  String val2 = command;                //that follow

  com.remove(point1, len - point1);     //each of these use the string remove to delete
  val1.remove(point2, len - point2);    //the parts of the command that aren't needed
  val1.remove(0, point1 + 1);           //basically splitting the command up into its
  val2.remove(0, point2 + 1);           //individual pieces
  val2.remove(val2.length()-1,1);

  CommLookup(com, val1, val2);    //these pieces are then sent to a lookup routine for processing
}

void CommLookup(String com, String val1, String val2)
{

  int offset = 255;                   //create a variable for our lookup table's offest value
                                      //we set this to 255 because there won't be 255 total commands
                                      //and a valid command can be offset 0, so it's just to avoid
                                      //any possible coding conflicts if the command sent doesn't
                                      //match anything.

  for(int x = 0; x < listSize; x++)   //this goes through the list of commands and compares
  {                                   //them against the command received
    if(commands[x] == com)
    {
      offset = x;                     //if the command matches one in the table, store that command's offset
    }
  }

  switch(offset)                //this code compares the offset value and triggers the appropriate command
  {
    case 0:                                 //essentially a hello world.                       |  Syntax: hello:null:null
      CommHello();                          //this activates the hello world subroutine        |  returns Hello!
      break;
    case 1:                                 //adds both values together and return the sum.    |  Syntax: add:value1:value2
      CommAdd(val1.toInt(), val2.toInt());  //this activates the addition subroutine           |  returns value1 + value2
      break;
    case 2:                                 //subtracts both values and return the difference  |  Syntax: subtract:value1:value2
      CommSub(val1.toInt(), val2.toInt());  //this activates the subtraction subroutine        |  returns value1 - value2
      break;
    case 3:
      yMovement(val1.toInt(), val2.toInt());
      break;
    case 4:
      xMovement(val1.toInt(), val2.toInt());
    default:                                        //this is the default case for the command lookup and will only
      Serial.println("Command not recognized");     //trigger if the command sent was not known by the arduino
      break;
  }
}

void CommHello()                               //each of these routines are what will be triggered when they are successfully processed
{
  Serial.println("Hello!");
  CommConfirm();
}

void CommAdd(int val1, int val2)
{
  Serial.println(val1 + val2);
  CommConfirm();
}

void CommSub(int val1, int val2)
{
  Serial.println(val1 - val2);
  CommConfirm();
}

void yMovement(int val1, int val2)
{
  if (val1 < 0) {
    int yMoveNew = (val1 * (-4));
    //Serial.println(val1 * (-1));
    //delay(500);

    FRStepper.moveTo(-yMoveNew);

    BRStepper.moveTo(-yMoveNew);

    FLStepper.moveTo(-yMoveNew);

    BLStepper.moveTo(-yMoveNew);

    //delayMicroseconds(500);
  }

  else {

    int yMoveNew = (val1 * 4);
    //Serial.println(val1);
    //delay(500);
    FRStepper.moveTo(yMoveNew);

    BRStepper.moveTo(yMoveNew);

    FLStepper.moveTo(yMoveNew);

    BLStepper.moveTo(yMoveNew);

    //delayMicroseconds(500);

  }
}

void xMovement(int val1, int val2)
{
  if (val1 < 0) {
    int xMoveNew = (val1 * (-4));
    //Serial.println(val1 * (-1));
    //delay(1000);
    FLStepper.moveTo(-xMoveNew);

    BLStepper.moveTo(-xMoveNew);

    FRStepper.moveTo(-xMoveNew);

    BRStepper.moveTo(-xMoveNew);

    //delayMicroseconds(500);
  }

  else {

    int xMoveNew = (val1 * 4);
    //Serial.println(val1);
    //delay(1000);
    FLStepper.moveTo(xMoveNew);

    BLStepper.moveTo(xMoveNew);

    FRStepper.moveTo(xMoveNew);

    BRStepper.moveTo(xMoveNew);

    //delayMicroseconds(500);

  }
}
void CommConfirm()
{
  Serial.println("Done");

}

```

body:
With the `AccelStepper.move()` function, you are setting the target position of the motor. Then you run the motor with `AccelStepper.runToPosition()`. But that is a blocking function. It will not exit, until the motor reached it's target position. So you just picked the wrong function from the `AccelStepper` library.

---

**Small adjacent about simultaneous action on microcontrollers:** Since most microcontrollers, like in the Arduino, only have one core, they can only do exactly one thing at a time. But you can still execute things one after another, but so fast, that a human would say, they where happening at the same time. For this we need to divide down the actions into small chunks, that are executed very fast. In your case we have the big actions of running multiple motors to their target positions. Each of these big actions take long in total, but we can divide them down. And with stepper motors that is really easy, because one step would be one small chunk of that action.

So we want to go through our code very fast, successively checking for each motor, if it is time to do a step with it. If yes, we only do that one step. Then we proceed further to the next motor.

---

The `AccelStepper` library helps you in doing this `checking if it is time to do a step`. This is what happens in the `AccelStepper.run()` function. You just need to call it regularily, fast enough to not miss the time for a step.

So the solution is to remove all the calls to `AccelStepper.runToPosition()` and instead call the `AccelStepper.run()` function for all your stepper motors directly in the `loop()` function.


message:
What kind of distance sensor are optimal to measure distances to surfaces at an angle to the sensor?

I want to try measuring the orientation of an object by measuring the distance between a "flat" surface to the surface of the rotated object. The problem I assume is that if the surface being measured is at an angle to the distance sensors, the beamed lights from laser or infrared proximity sensors, for example, would be reflected at an angle and not return to the sensors at all.
[![enter image description here][1]][1]
Would this actually happen, or am I misunderstanding some properties of these sensors? Which sensors would work in this kind of application, and which sensors would not work for sure (I read from another post that ultrasonic sensors would definitely not work in this case)?

(Added a crude sketch of the problem I think is going to happen)

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

body:
Using ultrasonic sensors would be a very sensible solution in your use case.

I am currently working on a similar project with a company in Denmark, where the objective is to detect cars on parking spaces. For this task, I used two of these ultrasonic sensors from DFRobot for the prototype:

https://www.dfrobot.com/product-1935.html

They were very easy and simple to setup on an Arduino UNO and worked perfectly fine even when two were sensing at once.
Though I have to mention, that they need a serial connection each, but this can be worked around using a multiplexer or a developer board with more serial connections.

I also found that the ultrasonic sensors work better than time of flight sensors in outdoor conditions. They are very robust and wont be as affected by dirt for instance.
A little speck on the lens of a ToF sensor and it will be rendered useless.

Ultrasonic sensors are also widely used in the car industry for parking aid solutions where they have to detect lots of different surfaces and be very precise in doing so.

Ultrasonic sensors are great. And yes, they can interfere with each other, but as long as you dont put them on top of one another, it should not be an issue.

You should be able to detect the distance to a trailer in two different places using ultrasonic sensors as long as the trailer is within the sensors range.


message:
How to add colour change to the strobe coding?

I have this strobe effect working. However, I would like to change the colour of the LEDs after each 'strobe sequence'. How can it be achieved?
The code I am using is this one:
```
    // Basic code NeoPixel
    // wwww.arduinoplatform.com

    #include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
     #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
    #endif

    // Which pin on the Arduino is connected to the NeoPixels?
    // On a Trinket or Gemma we suggest changing this to 1:
    #define LED_PIN    6

    // How many NeoPixels ar
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 6, NEO_GRB + NEO_KHZ800);

    void setup() {
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
    }

    // *** REPLACE FROM HERE ***

    void loop() {
      // Slower:
      // Strobe(0xff, 0x77, 0x00, 10, 100, 1000);
      // Fast:
      Strobe(0xFF, 0x00, 0xF8, 10, 50, 1000);
    }

    void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause){
      for(int j = 0; j < StrobeCount; j++) {
        setAll(red,green,blue);
        showStrip();
        delay(FlashDelay);
        setAll(0,0,0);
        showStrip();
        delay(FlashDelay);
      }

     delay(EndPause);
    }

    // *** REPLACE TO HERE ***

    void showStrip() {
     #ifdef ADAFRUIT_NEOPIXEL_H
       // NeoPixel
       strip.show();
     #endif

    }

    void setPixel(int Pixel, byte red, byte green, byte blue) {
     #ifdef ADAFRUIT_NEOPIXEL_H
       // NeoPixel
       strip.setPixelColor(Pixel, strip.Color(red, green, blue));
     #endif
    }

    void setAll(byte red, byte green, byte blue) {
      for(int i = 0; i < 64; i++ ) {
        setPixel(i, red, green, blue);
      }
      showStrip();
    }
```

body:
I guess you want to cycle through a list of defined colors with your strobe effect. For that you can save the colors in a 2-dimensional array and then cycle through the array with a for loop. The 2-dimensional array is then a group of colors, each defined by the 3 numbers for a RGB value. Somewhat like this:

    #define NUM_COLORS   5
    byte colors[NUM_COLORS][3] = {
        {0xFF, 0, 0},
        {0, 0xFF, 0},
        {0, 0, 0xFF},
        {0xFF, 0xFF, 0},
        {0, 0xFF, 0xFF}
    };

    void loop(){
        for(int i=0;i<NUM_COLORS;i++){
            Strobe(colors[i][0], colors[i][1], colors[i][2], 10, 50, 1000);
        }
    }

Note, that this is not a complete code, but only the interesting parts. You can incorporate this into your code. You can change the number of colors and the colors itself to your liking (I only took some example values, that are easy to recognize).


message:
Smooth Servo movement for robotic arm: An ongoing answer and soluton

This is not and will not be a duplicate.
This is a thread meant to share a solid soliton I figured out with the rest of the community and update it as I optimize it, ad-hoc.
So I had visited StackExchange Arduino community to check if there is a better way to make a servo move smoother, since if we assing a new position to a servo that is attached on an arm, it moves like an attacking karateka.

I found these threads:

https://arduino.stackexchange.com/questions/29966/smooth-servo-control-library
(Dat-ha provided a piece of code that I suggest a correction here)

I also checked this:
https://arduino.stackexchange.com/questions/1241/my-servo-wont-sweep-smoothly

I will self-answer and update this thread, as I make a full arm code working properly and include instructions for the rest of the people to save everyone some time. I still haven't added the capacitor that is suggested on the threads but I will ASAP.

body:
      #include <Servo.h>
        Servo servo1;
        int previousangle1;
        int dc;
        void setup()
          {
            dc = 10;    // Delay calibration
            servo1.attach(11);  // connect Servo to pin 11
            pinMode(A0, INPUT); // Connect potentiometer or Joystick x or y pin to A0 input
            previousangle1 = 90; // Initialize position to 90 degrees (180 degree servo)
          }

        void loop()
          {

          int val1 = analogRead(A0); // Read the potentiometer position
          int angle1 = map(val1, 0, 1023, 0, 180); // Map the value to be used with servo

          if(angle1>previousangle1)
          {
            for(int i=previousangle1; i<=angle1; i++)
            {
              servo1.write(i); //turn servo by 1 degrees
              delay(dc);        //delay for smoothness
            }
          }
          // Fix: This needed to be an else if
          // Original piece of code had it as a second stand alone if
          else if(angle1<previousangle1)
          {
            for(int j=previousangle1; j>=angle1; j--)
            {
              servo1.write(j);
              delay(dc);
            }
          }
          delay(dc);
          previousangle1 = angle1;
          }

What you need to do now, is make similar code, with different variables for all 4 servos.
I still have to check the addition of a capacitor to make it work even better.

Original code is taken from here:
https://arduino.stackexchange.com/a/29970/76974

I will edit this, adding code for the rest of the servos later on.


body:
Your original solution uses blocking code (the for loops with `delay()` calls in them). Surely that works, but it can easily get you in trouble, when extending the project with more functionalities (since nothing else can be done during the sensor movement). So I would suggest a way to ditch all blocking for loops and delays, so that other code can run during the servo movement. For this we can use `millis()` and the coding principle from the `BlinkWithoutDelay` example, that comes with the Arduino IDE.

    #include <Servo.h>

    Servo servo1;
    int set_angle = 0;
    int current_angle = 90; // setting starting angle to 90 degrees
    unsigned long servo_timestamp = 0;
    #define SERVO_INTERVAL    10   // changing the servo position every 10ms, defines the speed of the servo

    void setup()
    {
        servo1.attach(11);  // connect Servo to pin 11
        pinMode(A0, INPUT); // Connect potentiometer or Joystick x or y pin to A0 input
    }

    void loop(){
        if(millis()-servo_timestamp > SERVO_INTERVAL){
            servo_timestamp += SERVO_INTERVAL; // increment our timestamp by the servo interval
            // Measure the new set_angle only, if we really want to move the sensor
            int val1 = analogRead(A0); // Read the potentiometer position
            set_angle = map(val1, 0, 1023, 0, 180); // Map the value to be used with servo

            // Increment or decrement the current angle according to the set_angle
            // and don't change it, when we already are at the set_angle
            if(set_angle > current_angle){
                current_angle++;
            } else if(set_angle < current_angle){
                current_angle--;
            }
            // Write the new angle to the servo
            servo1.write(current_angle);
        }
    }

For learning more about the non-blocking coding style using `millis()`, you can google for it and look at the `BlinkWithoutDelay` example. There are many resources for this on the web. The combination of timestamp and `millis()` if statement executes the code inside the if statement at the regular interval `SERVO_INTERVAL`. There we read the potentiometer and calculate the new setpoint for the servo angle. Then we increment or decrement the current angle by 1 depending on the set angle. And then we write that new angle to the servo.

You can change the speed by either changing `SERVO_INTERVAL` or by in-/decrementing `current_angle` by more than only 1.

The code outside the if statement still runs at full speed. So in the (a bit less than) 10ms, that the servo code isn't running, you can execute other code. Also this code will react immediately, where a blocking code would first let the servo run to the set position and only then change again.

Note: The above code isn't tested. It's purpose is to show the principle. There might be small errors, that I haven't seen.


body:
Here are the simulation results of the code from Chrisl
[![enter image description here][1]][1]

The code (same as the other answer)

    #include <Servo.h>

    Servo servo1;
    int set_angle = 0;
    int current_angle = 90; // setting starting angle to 90 degrees
    unsigned long servo_timestamp = 0;
    #define SERVO_INTERVAL    10   // changing the servo position every 10ms, defines the speed of the servo

    void setup()
    {
        servo1.attach(11);  // connect Servo to pin 11
        pinMode(A0, INPUT); // Connect potentiometer or Joystick x or y pin to A0 input
    }

    void loop(){
        if(millis()-servo_timestamp > SERVO_INTERVAL){
            servo_timestamp += SERVO_INTERVAL; // increment our timestamp by the servo interval
            // Measure the new set_angle only, if we really want to move the sensor
            int val1 = analogRead(A0); // Read the potentiometer position
            set_angle = map(val1, 0, 1023, 0, 180); // Map the value to be used with servo

            // Increment or decrement the current angle according to the set_angle
            // and don't change it, when we already are at the set_angle
            if(set_angle > current_angle){
                current_angle++;
            } else if(set_angle < current_angle){
                current_angle--;
            }
            // Write the new angle to the servo
            servo1.write(current_angle);
        }
    }

You can tweak the code and see the changes online- Link to the [arduino simulation][2]

  [1]: https://i.stack.imgur.com/n3bqZ.gif
  [2]: https://wokwi.com/arduino/projects/298559881968878089


message:
Arduino Uno R3 HID with HC-06 BT module

Im trying to make a macro pad using Arduino Uno r3 and 4x4 matrix (cherry blue clone) . I know using a pro micro is better than uno cause there isn't HID compatibility in uno but since i already have one , i want to work with this . I have already tested the macro pad after compiling and flashing a keyboard.hex file . But wondering if i buy a bt module like HC-06 (which is about 3.2$ here ) would that be able to send inputs even aftar flashing ? I have like basics coding knowledge so i have no clue what flashing actually would do to the module so . Anyone know would making that macro pad BT compatible    be possible or not ?

body:
It is unclear to me, where you flashed what, so I will describe some basics.

The Uno cannot act as a keyboard/HID device, since the microcontroller on it (the Atmega328p) doesn't have native USB capability. For connecting to USB the Uno has a USB-to-Serial chip on it (actually another microcontroller, the Atmega32u4 I think). So with the Uno you only have a serial connection, unless you hack the Atmega32u4 and program it with your own firmware (firmware is a term for software, that runs very near to the hardware, in this case directly on the microcontroller, in contrast to normal software running on an operating system on a computer; so in the middle between hard- and software, thus **firm**ware).

Flashing is the same as programming a microcontroller. It has this name, because the program is saved in flash memory on the microcontroller (that is a specific type of memory technology; the same technology, that USB sticks use for storing your data). Flashing the HC-06 means programming it with a different firmware.

All bluetooth devices use the same base technology (thought to be clear, BLE is a different technology). The role of the device depends on the characteristic/profile, that it exposes to the host. There are profiles for HID, Serial, Audio, ... .

The HC-06 is a bluetooth slave device, which acts as a bluetooth-serial-bridge (like the Atmega32u4 acts as a USB-serial-bridge). But this is a software limitation. The HC-06 has standard bluetooth hardware, but the firmware on it just gives you the Serial profile (in fact a HC-06 is mostly the same like the master device HC-05, just different firmware and corresponding breakout boards can break out other pins). So by flashing (programming) it with a different firmware, you can get different profiles. If you find a firmware, that gives you HID functionality, you can flash that to the HC-06 and use it. Though this is a bit hacky I think (haven't done it myself), so it might be a bit too much for a beginner.

**Bluetooth Slave/Master:** The bluetooth protocol uses fixed roles for the two connected devices. One is the master and one is the slave. The master controls, if the communication is really happening. For example a bluetooth headset is a slave device. You cannot connect the bluetooth headset to your bluetooth keyboard, because both are slave devices. You always need one master and one slave. The HC-05 is basically the same module as the HC-06, but it's firmware enables it do be master or slave (configurable by you). So some devices support both modes, but still in any specific connection they can only have one of the modes (need to either master OR slave at any time).

>  Anyone know would making that macro pad BT compatible be possible or not ?

Possible, yes. But I suggest you invest in buying a ready to use bluetooth HID controller (immediately found [this one from adafruit][1], though you might might cheaper versions). That will be way easier, than directly jumping into flashing a HC-06. Though that is still a possible path to go.

Another way to go would be to just use the serial functionality and write a small program for your PC, which reads from the Serial interface and issues key strokes according to the serial data. Then you don't need to reflash the HC-06.

  [1]: https://www.adafruit.com/product/1535


message:
How can I run Hello World using Serial Monitor in Tinkercad Arduino simulator?

I want to achieve printing `Hello World` in the serial monitor using Tinkercad to simulate Arduino.

[Here][1] is a very simple example code for real Arduino.

```arduino
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Hello World!");
}

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

}
```

However, putting an Uno board, typing this code, and clicking "Start Simulation" in Tinkercad doesn't show the `Hello World` message.

Is it doable? If so how?

For real Arduino, you need to select Arduino serial port and open Serial Monitor. But I can't find such an option for Tinkercad. I can't find Serial Monitor in Thinkercad.

My real purpose is to use Serial Monitor output to test code snippets. Right now I don't have real Arduino board with me, so I thought a simulator would be ideal. If I can easily check the values of variables, it doesn't have to be Serial Monitor.

Sorry if this is not a place to ask questions about simulators.

  [1]: https://arduinogetstarted.com/tutorials/arduino-hello-world

body:
I mean where would you expect it to print ```Hello World``` ... On the Serial Monitor, right? So first open it by clicking on the Serial Monitor button at the bottom of the code tab in Tinkercad.

I tried your code and it works perfectly fine.

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

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


message:
Code for ESP32 without Development Board

I'm very new to microcontrollers. I'd like to start developing for the esp32, as it has integrated wifi & bluetooth for quite cheap. This being said, i don't have a board yet. Is there a way i can emulate an esp32 board, so i can start programming and debugging my code?

As i'm very new, any advice is welcome.

Thanks

body: If you are new to microcontrollers then start with basic arduino code and components.  Since the esp chips can be coded with the Arduino framework it will be an almost seemless transition from Arduino board to ESP board.  Build some circuits on tinkercad.com, write some code, and simulate them. Once you have those basics down hopefully your esp board will have arrived and you can start building your project.


body:
Welcome to Arduino Stack exchange. There are a lot of discussions and half-completed, or project-specific models available for the ESP32 simulator. **My sincere advice is to go ahead and buy real hardware**. By the time you take to set up the simulators (download the repo, set environment variables, connect GDB debugger or other), you would have received the ESP32 hardware itself.

Why you should go for real hardware?
------------------------------------

 - An emulator can never match the timing of real ESP32 hardware. if you
   have any timing-related issue, you cannot fix it using an ESP32 emulator
 - Real issues in hardware (bounce/debounce of switches, surge current and brownout voltages, rise time and reflections etc - won't appear in the ESP32 simulators
 - EMC issues due to floating inputs, Port pin current limits or even self-heating of components are not considered in most the simulators
 - A code running on the emulator can't always run on the real hardware without modifications, especially when it involved multiple threads and priorities

Still, other options are available online but it depends on your comfort
-------------------------------------------------------------------------

 - [ESP32 Simulator by Wokwi](https://docs.wokwi.com/guides/esp32) - The ESP32 Simulator is currently in preview (affiliation disclosure)

 - [ESP32 simulator from mireq][1] - ESP-IDF contains a small amount of hardware-specific code, FreeRTOS and few multi-platform libraries. This project uses FreeRTOS port for POSIX, LWIP for TCP/IP layer and mbedtls for cryptography functions.
In addition, several useful APIs from esp-idf are implemented eg. logging. With this project, you can write a program, which will be runnable and testable on Linux.

 - [ESP32 machine emulator][2] - The purpose of this package is to enable you to test-drive (TDD) your MicroPython code in an IDE running on your computer. It seems a lot of people are test-driving python, but not many are test-driving MicroPython. That’s understandable, since many MicroPython projects are simple, and emulating real hardware in a test environment is difficult.

 - [Bridges][3] - Pretend your PC a Raspberry Pi or an ESP32 to connect I2C / SPI / GPIO / UART peripherals.

 **Note** You should also check when is the last time the projects were updated. The latest ones and active ones are always a better choice as they are expected to have better usability, and stable simulations.

______________________________
A few screenshots from Wokwi ESP32 Simulator

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

  [1]: https://github.com/mireq/esp32-simulator
  [2]: https://pypi.org/project/esp32-machine-emulator/
  [3]: https://github.com/Wei1234c/Bridges/blob/master/notebooks/readme/Bridges_readme_en.md
  [4]: https://i.stack.imgur.com/8RNql.gif
  [5]: https://i.stack.imgur.com/us5Hh.gif


message:
How to send int array with ESP8266 http post request?

I'm reading RFID cards' `UID` with an ESP8266 and trying to send that information to my web server hosted on a Raspberry Pi. I'm currently storing the `UID` in an int array, but the `http.POST();` function takes a string input. I tried adding each `UID` digit together, but that doesn't work either.

How would you go about sending the uid in the request?

My code:
```cpp
    /*
    Created by TheCircuit
*/

#define SS_PIN 4  //D2
#define RST_PIN 5 //D1

#include <SPI.h>
#include <MFRC522.h>

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

const char* ssid = "****";
const char* password = "****";
const char* serverName = "****";
int RELAY = 2; //D6

int UIDs[1][4] = {
  {83, 111, 39, 47}
};

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.

void setup()
{
  Serial.begin(9600);   // Initiate a serial communication
  SPI.begin();      // Initiate  SPI bus
  mfrc522.PCD_Init();   // Initiate MFRC522

  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, HIGH);

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
}

boolean compareUIDs(int a[4], int b[4]) {
  for (int i = 0; i < 4; i++) {
    if (a[i] != b[i]) return false;
  }

  return true;
}

void loop()
{
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  // mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

  int UID[4];
  for (int i = 0; i < 4; i++) {
    UID[i] = mfrc522.uid.uidByte[i];
  }

  Serial.print(UID[0]);
  Serial.print(" ");
  Serial.print(UID[1]);
  Serial.print(" ");
  Serial.print(UID[2]);
  Serial.print(" ");
  Serial.print(UID[3]);
  Serial.println();

  for (int i = 0; i < sizeof(UIDs); i++) {
    boolean success = compareUIDs(UIDs[i], UID);
    if (success) {
      Serial.println("ACCESS GRANTED");
      digitalWrite(RELAY, LOW);

      if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http;

        // Your Domain name with URL path or IP address with path
        http.begin(serverName);

        // Specify content-type header
        http.addHeader("Content-Type", "application/json");

        int httpResponseCode = http.POST("UID GOES HERE");

        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);

        // Free resources
        http.end();
      }

      delay(2000);
      digitalWrite(RELAY, HIGH);
      return;
    }
  }
}
```

body:
You could use the (awesome) ArduinoJSON library, but likely overkill for this app. I found it more useful to parse JSON than to construct it.

You could simply print to a buffer and the POST that:

```
char payload[MAX_PAYLOAD];
sprintf(payload, "{\"uid1\":%d,\"uid2\":%d,\"uid3\":%d,\"uid4\":%d}", UID[0], UID[1], UID[2], UID[3]);

http.POST(payload);

```

You would `#define MAX_PAYLOAD` with a value that will be sufficient to hold all the information.

Notice that `sprintf` allows you to use any formatting options you want (e.g. hexadecimal, etc).

If you wanted to send it as an array:

```c++
sprintf(payload, "{\"uid\":[%d,%d,%d,%d]}", UID[0], UID[1], UID[2], UID[3]);
```


message:
Can't enable face detection on esp32 cam : CORRUPT HEAP: Bad head at 0x3ffe2eb4. Expected 0xabba1234 got 0x00000008 abort()

I was trying to make esp32 face recognition using the esp32 camera web server example in arduino ,
and everything works fine untill i press on face detection the frame is frozen , module restarted and put this error to serial monitor :

```

CORRUPT HEAP: Bad head at 0x3ffe2eb4. Expected 0xabba1234 got 0x00000008
abort() was called at PC 0x4008a64d on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x4008df7c:0x3ffe1c30 0x4008e1f5:0x3ffe1c50 0x4008a64d:0x3ffe1c70
0x4008a779:0x3ffe1ca0 0x400f97cb:0x3ffe1cc0 0x400f5a61:0x3ffe1f80 0x400f59f0:0x3ffe1fd0
0x40093545:0x3ffe2000 0x40082976:0x3ffe2020 0x4008a545:0x3ffe2040 0x4000bec7:0x3ffe2060
0x400d1bc9:0x3ffe2080 0x401194f5:0x3ffe2230 0x40119bfd:0x3ffe2260 0x40119cb5:0x3ffe22f0
0x4011a088:0x3ffe2310 0x40118774:0x3ffe2330 0x401187cb:0x3ffe2370 0x4008fe86:0x3ffe2390

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4

```
I tried erasing flash bt it made the same error again
I am using Arduino IDE 1.8.12 , esp32-cam
operating at 5 volts from the programmer (also tried other external power supplies)
and these are the pictures of settings : (also used wrover kit in programming settings with huge app >3mb)

[Chip name][1]
[![enter image description here][1]][1]
[ESP32 Cam][2]
[![enter image description here][2]][2]
[FTDI Programmer][3]
[![enter image description here][3]][3]
[AI THINKER][4]
[![enter image description here][4]][4]
[Settings][5]
[![enter image description here][5]][5]

I want to make a face recognition door lock , if this doesn't work could anyone refer me to how can I get facial recognition on esp32 cam with any other way?

  [1]: https://i.stack.imgur.com/uJ79S.jpg
  [2]: https://i.stack.imgur.com/CJW2q.jpg
  [3]: https://i.stack.imgur.com/NA28L.jpg
  [4]: https://i.stack.imgur.com/ybbFg.jpg
  [5]: https://i.stack.imgur.com/Re66W.jpg

body: I ran into this issue with the same setup. This Github issue seems identical to ours, and applying the fix in this comment quickly resolved it for me: https://github.com/espressif/arduino-esp32/issues/5128#issuecomment-851785970. Good luck!


body: Rollback your ESP32 board driver to 1.04. works for me ;-)


body:
I don't have enough reputation to be able to add a comment, but using the answer from [Andrew Hart][1] I was able to resolve this.  For completeness of this thread in case the [linked][2] solution ever disappears:

Locate these sections from the app_httpd.cpp:

    if (net_boxes){
        detected = true;
        if(recognition_enabled){
            face_id = run_face_recognition(image_matrix, net_boxes);
        }
        draw_face_boxes(image_matrix, net_boxes, face_id);
        free(net_boxes->score);
        free(net_boxes->box);
        free(net_boxes->landmark);
        free(net_boxes);

and

    fr_recognize = esp_timer_get_time();
    draw_face_boxes(image_matrix, net_boxes, face_id);
    free(net_boxes->score);
    free(net_boxes->box);
    free(net_boxes->landmark);
    free(net_boxes);

replace the 4 `free`'s in each block with `dl_lib_free`.

  [1]: https://arduino.stackexchange.com/users/77396/andrew-hart
  [2]: https://github.com/espressif/arduino-esp32/issues/5128#issuecomment-851785970