# Question
Title: Serial.parseInt works for first menu but now in a sub menu
I am trying to use the `Serial` object to print some lines giving the users some options to select by entering an int. It works at this main menu. But when the user selects 1 I use `Serial` again to print some lines and collect another int. But in this submenu it prints the line, waits a second and then continues back out to the main menu. Below is my entire sketch:

```
int menu = 0;

void setup() {
  // put your setup code here, to run once:
  //Starting the serial comm
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (menu == 0) {
    //Prints the menu to the serial port
    Serial.println("Select an option:");
    Serial.println("-----------------");
    Serial.println("1) Do Submenu");

    menu = getSerialInt();
  }

    //Used to calibrate the pen height
  if (menu == 1) {
    int calibrating = 1;
    while (calibrating == 1) {          //While loop that will continue until "0" is sent in the serial port
      Serial.println("Enter a pen value: ");
      int penMove = getSerialInt();

      Serial.println("You entered: ");
      Serial.println(penMove);
      if (penMove == 0) {
        calibrating = 0;
      }
    }
    menu = 0;   //Sets the menu variable back to 0
  }
}

int getSerialInt() {
  int retInt;
  Serial.flush();

  while (!Serial.available()) {}  //Waits for an input on the serial device
  retInt = Serial.parseInt();       //Takes the Serial input and looks for an integer
  Serial.flush();

  return retInt;
}

```

Thanks in advanced for any help trying to debug this.

# Answer
Based off this thread: https://forum.arduino.cc/t/parseint-clears-serial-available-but-leaves-terminator-in-serial-buffer/515199/8

And some other threads talking about carriage returns, I rewrote `getSerialInt` to call parseInt() twice to trow away the carriage return:

```
int getSerialInt() {
  int retInt;
  Serial.flush();

  while (!Serial.available()) {}  //Waits for an input on the serial device
  retInt = Serial.parseInt();       //Takes the Serial input and looks for an integer
  Serial.parseInt(); // throw away carage return
  Serial.flush();

  return retInt;
}

```

There is probably a better way to do this...
> -1 votes

---
Tags: serial, input, print
---


title: Drivers for CH9102X serial port chip

text:
# Question
Title: Drivers for CH9102X serial port chip
Some ESP-family cheap boards manufacturers had recently moved to CH9102X serial port chip (from CP2102), and it seems the drivers for CH9102X are hard to find.

Where can I download them?

# Answer
It can be found on manufacturer's website: http://www.wch.cn/search?q=CH9102&t=downloads

Please note, that some drivers' downloading pages are only available in Chinese, so make sure you open Chinese (not English) site version.

Windows CDC driver: http://www.wch.cn/downloads/CH343CDC\_ZIP.html

Windows SER driver: http://www.wch.cn/downloads/CH343SER\_ZIP.html

MacOS driver: http://www.wch.cn/downloads/CH34XSER\_MAC\_ZIP.html

P.S. For Windows 7 x64 I recommend using the first one (CDC). SER driver didn't work for me because of signing issues.
> 5 votes

---
Tags: esp8266, esp32
---


# Question
Title: Pressed Buttons are permanently low and one of them is not working
I am a beginner to Arduino, and I'm having a problem in a project that I am currently working on.

I was just beginning to write the code, after preparing the components and the wiring, and suddenly two of my buttons never stopped outputting, despite my instructions to only output when the buttons are low, and the other one doesn't do anything at all.

I am using three buttons, one of them is a interruptor switch.

Here is my code:

```
#include <Adafruit_NeoPixel.h>

#define PIN 3    // input pin Neopixel is attached to
#define NUMPIXELS 28 // number of neopixels in strip

#define TRAVAO 8
#define PISCA 13
#define QUATRO_PISCAS 11

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int redColor = 0;
int greenColor = 0;
int blueColor = 0;

void setup() {
  pixels.begin();

  pinMode(TRAVAO, INPUT_PULLUP);
  pinMode(PISCA, INPUT_PULLUP);
  pinMode(QUATRO_PISCAS, INPUT_PULLUP);

  Serial.begin(9600);
}

void loop() {
  if(digitalRead(TRAVAO) == LOW) {
    Serial.print("bbb");
  }

  if(digitalRead(PISCA) ==  LOW) {
    Serial.print("ccc");
  }

  if(digitalRead(QUATRO_PISCAS) ==  LOW) {
    Serial.print("ddd");
  }

  delay(1);
}

```

Here is my arduino:

# Answer
> 2 votes
Here's your problem:

```
#define TRAVAO 8

```

As you can see from your wiring diagram, nothing is connected to pin 8.

---
Tags: programming, button, wires
---


# Question
Title: How do I run 4 LEDs sequentially based off of a push button input?
I am trying to create a program that runs 4 LEDs sequentially while also being able to do other things with different inputs and outputs. Because of this, I am using the millis function and not the delay. I have the code working but not exactly how I want it. It runs through the LEDs and turns them off then runs through again like it is supposed too but there are two problems:

1. It will pass through the first if statement, then the first again then to the second, then it will go through the first, the second, then the third, etc. I want it to cascade through the if statements, keeping the LED from the previous steps on without repeating. It is causing the LEDs to flash super quick.
2. The code still runs even if the input is read as LOW as it is dependent on millis. I somehow need it to start from the beginning every time the button is pushed and reset when the button is not pressed.

below the code is a picture of the serial monitor showing the program running through every if statement and not staying in one and moving to the next. If needed, I can add a video showing what the LEDs do.

below is the code

```
//Code to build 4 sequentially run LEDs that reset everytime there is not input
int RTS_IN  = A0; //input button

//Output LEDs, assigning them to pins
int LED_5 = 5;
int LED_6 = 6;
int LED_7 = 7;
int LED_8 = 8;

//1 second for each time interval
unsigned long Time1 = 1000;
unsigned long Time2 = 2000;
unsigned long Time3 = 3000;
unsigned long Time4 = 4000;
unsigned long Time5 = 5000;

//variables for holding millis values
unsigned long currentMillis;
unsigned long newMillis = 0;

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

  pinMode(RTS_IN, INPUT);
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  currentMillis = millis();

  //using sequential method if the input button pressed and held
  if(digitalRead(RTS_IN) == HIGH)
  {
    sequential();
  }
  //keeping LEDs OFF if button has been released
  else
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

//method to run LEDs sequentially
void sequential()
{

  //if statement checking to see if a second has passed to allow the first led to turn on
  if(currentMillis - newMillis >= Time1)
  {
    Serial.println("5 is on");

    digitalWrite(LED_5, HIGH);
    delay(1);

    //if statement checking to see if 2 seconds has passed to allow the second led to turn on
    if(currentMillis - newMillis >= Time2)
    {
      Serial.println("6 is on");

      digitalWrite(LED_6, HIGH);
      delay(1);

      //if statement checking to see if 3 seconds has passed to allow the third led to turn on
      if(currentMillis - newMillis >= Time3)
      {
        Serial.println("7 is on");

        digitalWrite(LED_7, HIGH);
        delay(1);

        //if statement checking to see if 4 seconds has passed to allow the fourth led to turn on
        if(currentMillis - newMillis >= Time4)
        {
          Serial.println("8 is on");

          digitalWrite(LED_8, HIGH);
          delay(1);

          //if statement to turn off LEDs and wait a second before turning the first back on
          if(currentMillis - newMillis >= Time5)
          {
            Serial.println("All off");

            digitalWrite(LED_5, LOW);
            digitalWrite(LED_6, LOW);
            digitalWrite(LED_7, LOW);
            digitalWrite(LED_8, LOW);

            //this is in order to add a period of this process to each of the
            //interval times to keep up with millis without this, they would all stay on
            Time1 = Time1 + 5000;
            Time2 = Time2 + 5000;
            Time3 = Time3 + 5000;
            Time4 = Time4 + 5000;
            Time5 = Time5 + 5000;
            delay(1);

          }
        }
      }
    }
  }
}

```

updated code below with if else statements and the other programming combined

```

const int RTS_IN  = A0;
const int LTS_IN = A1;

//break signal
const int BS_IN  = A2;
const int BS_OUT = 11;

//reverse signal
const int RS_IN  = A3;
const int RS_OUT = 10;

const int NR_OF_LEDS = 4;
const int RIGHTLEDS[NR_OF_LEDS] = { 6, 7, 8, 9 };
const int LEFTLEDS[NR_OF_LEDS] = { 5, 4, 3, 2 };
const int interval = 100;

int nrOfRightLedsOn = 0;
int nrOfLeftLedsOn = 0;

unsigned long t = 0;

void StateRight();
void StateRightProcess();

void StateLeft();
void StateLeftProcess();

boolean oldSwitchStateRS = LOW;
boolean newSwitchStateRS = LOW;
boolean oldSwitchStateBS = LOW;
boolean newSwitchStateBS = LOW;

void setup()
{
  Serial.begin(9600);
  pinMode(RTS_IN, INPUT);
  pinMode(LTS_IN, INPUT);

  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    pinMode(RIGHTLEDS[led], OUTPUT);
  }

  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    pinMode(LEFTLEDS[led], OUTPUT);
  }

}

void loop()
{
  StateRight();
  StateLeft();

  newSwitchStateBS = digitalRead(BS_IN);
   if(newSwitchStateBS != oldSwitchStateBS)
  {
    if(newSwitchStateBS == HIGH)
    {
      digitalWrite(BS_OUT, HIGH);
    }
    else
    digitalWrite(BS_OUT, LOW);
    oldSwitchStateBS = newSwitchStateBS;
  }

 newSwitchStateRS = digitalRead(RS_IN);
  if(newSwitchStateRS != oldSwitchStateRS)
  {
    if(newSwitchStateRS == HIGH)
    {
      digitalWrite(RS_OUT, HIGH);
    }
    else
    digitalWrite(RS_OUT, LOW);
    oldSwitchStateRS = newSwitchStateRS;
  }

}

void StateRight()

{
  if(digitalRead(RTS_IN) == LOW)
  {
    SwitchRightLedsOff();
    nrOfRightLedsOn = 0;
    t = millis() + interval;
  }
  else if (nrOfRightLedsOn < NR_OF_LEDS)
  {
    StateRightProcess();
  }
  else
  {
    if(millis() >= t + interval)
    {
      t = millis();
      SwitchRightLedsOff();
      nrOfRightLedsOn = 0;
    }
  }
}

void StateRightProcess()
{
  if(millis() >= t + interval)
  {
    t = millis();
    digitalWrite(RIGHTLEDS[nrOfRightLedsOn], HIGH);
    nrOfRightLedsOn++;
  }
}

void SwitchRightLedsOff()
{
  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    digitalWrite(RIGHTLEDS[led], LOW);
  }
}

void StateLeft()
{
  if(digitalRead(LTS_IN) == LOW)
  {
    SwitchLeftLedsOff();
    nrOfLeftLedsOn = 0;
    t = millis() + interval;
  }
  else if (nrOfLeftLedsOn < NR_OF_LEDS)
  {
    StateLeftProcess();
  }
  else
  {
    if (millis() >= t + interval)
    {
      t = millis();
      SwitchLeftLedsOff;
      nrOfLeftLedsOn = 0;
    }
  }
}

void StateLeftProcess()
{
  if (millis() >= t + interval)
  {
    t = millis();
    digitalWrite(LEFTLEDS[nrOfLeftLedsOn], HIGH);
    nrOfLeftLedsOn++;
  }
}

void SwitchLeftLedsOff()
{
  for (int led = 0; led < NR_OF_LEDS; led++)
  {
    digitalWrite(LEFTLEDS[led], LOW);
  }
}

```

# Answer
> 5 votes
To be honest, I don't understand exactly the problems, but I try to give some guideline and hope you can use the idea to fix your problems.

What you need is a so called 'state machine'.

I think (according to your problem) that you have 6 states:

```
0 Idle (no sequence)
1 One LED on
2 Two LEDs on
3 Three LEDs on
4 Four LEDs on
5 No LEDs on

```

For this you can best use an `enum` type and global variable with similar values:

```
enum EState
{
    Idle,
    OneLedOn,
    TwoLedsOn,
    ThreeLedsOn,
    FourLedsOn,
    NoLedsOn
}

EState _state;

```

You need a function to check the new state, depending on the current state. In words something like:

```
current     When                          Action           New
state                                                      state
--------    ----------------------------  ---------------- -----
Idle        digitalRead(RTS_IN) == HIGH   Start counter    OneLedOn
                                          Switch on LED 0
OneLedOn    digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
            5 seconds have passed         Switch on LED 1
                                          Start counter    TwoLedsOn
TwoLedsOn   digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
            5 seconds have passed         Switch on LED 2
                                          Start counter    ThreeLedsOn
ThreeLedsOn digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
            5 seconds have passed         Switch on LED 3
                                          Start counter    ThreeLedsOn
FourLedsOn  digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
            5 seconds have passed         Switch LEDs off
                                          Start counter    NoLedsOn
NoLedsOn    digitalRead(RTS_IN) == LOW    Switch LEDs off  Idle
            5 seconds have passed         Switch on LED 0
                                          Start counter    OneLedn

```

(if you would draw one circle for each state and arrows between them, a so called UML State Diagram, you will see a much clearer way to depict the states and flows).

I don't have a compiler so I do it out of my head.

```
void Process()
{
    switch (_state)
    {
    case EState::Idle:
        if ((digitalRead(RTS_IN) == HIGH)
        {
            _time = millis();
            digitalWrite(LED_5, HIGH);
            _state = EState::OneLedOn;
        }
        break;
    case EState::OneLedOn:
        if ((digitalRead(RTS_IN) == LOW)
        {
            SwitchLedsOff();
            _state = Idle;
        }
        else if (millis() > time + 5000)
        {
            _time = millis();
            digitalWrite(LED_6, HIGH);
            _state = EState::TwoLedsOn;
        }
        break;
    case EState::TwoLedsOn:
       ...
}

```

The function `SwitchLEDsoff` sets all LEDs to low, and you only need one `unsigned long _time` global variable which you update when a new state starts and check in most states.

Note that high likely you can optimize this (like making each state its own function and removing almost duplicated code), but the main goal is to let you understand how to use a state machine and to use it in this sketch and future sketches.

**Update**

The following sketch is the same as yours but:

* Optimized for reducing code duplication (`ProcessState`)
* Introduced constants
* Introduced array for LEDs to iterate over
* Removed the state, instead used `_nrOfLedsOn`
* Removed idle state, handled separately now
* Prefixed global variables with an underscore (personal preference)
* Better names for variables/functions
* Used prototypes to put functions in logical order (high level to low level)

Code:

```
const int RTS_IN  = A0;
const int NR_OF_LEDS = 4;
const int LEDS[NR_OF_LEDS] = { 5, 6, 7, 8 };
const int DURATION = 300;

int _nrOfLedsOn = 0;
unsigned long _time = 0;

void ProcessState();
void ProcessLedsState();
void SwitchLedsOff();

void setup()
{
    Serial.begin(9600);
    pinMode(RTS_IN, INPUT);
    for (int led = 0; led < NR_OF_LEDS; led++)
    {
        pinMode(LEDS[led], OUTPUT);
    }
}

void loop()
{
    ProcessState();
}

void ProcessState()
{
    if (digitalRead(RTS_IN) == LOW)
    {
        SwitchLedsOff();
        _nrOfLedsOn = 0;
        _time = millis() + DURATION + 1;
    }
    else if (_nrOfLedsOn < NR_OF_LEDS)
    {
        ProcessLedsState();
    }
    else
    {
        if (millis() > _time + DURATION)
        {
            _time = millis();
            SwitchLedsOff();
            _nrOfLedsOn = 0;
        }
    }
}

void ProcessLedsState()
{
    if (millis() > _time + DURATION)
    {
        _time = millis();
        digitalWrite(LEDS[_nrOfLedsOn], HIGH);
        _nrOfLedsOn++;
    }
}

void SwitchLedsOff()
{
    for (int led = 0; led < NR_OF_LEDS; led++)
    {
        digitalWrite(LEDS[led], LOW);
    }
}

```

---
Tags: arduino-uno, programming, led, millis, timing
---


# Question
Title: How to set the eeprom initial value when flashing an ESP32
As I use the EEPROM to persist data such as for provisioning the WiFi (SSID and password), I'd like to make sure that the *very first time* the ESP32 runs, it finds the initial '\0' for the SSID so that it does not run into the WiFi connection code block.

For this I need to set the initial values into the EEPROM when I flash the firmware.

I use platform IO.

How to do that?

# Answer
> 1 votes
The ESP32 does not have a real EEPROM; instead, the data is stored in the external flash in the non-volatile storage (NVS) partition. The problem is, that the structure of this partition is proprietary. Only the SDK knows "where to find what" within NVS and any access to this partition is done using the SDK.

Unfortunately, the `EEPROM.h` library uses the NVS partition to store its values. As the way how data is stored within NVS is closed source, you can't build a flash image that is guaranteed to work in different sketches or different versions of the SDK. So, if you need to upload pre-made non-volatile data, the `EEPROM.h` library is practically useless.

A convenient alternative is to put that data in a file and store that file in a filesystem like `SPIFFS.h`. This way, you define how data is stored/accessed yourself, so it's much less likely you run into problems when the core experiences changes.

Data upload is straight forward using `esptool.py`.

---
Tags: esp32, eeprom, flash
---


title: Wiring multiple LCD displays to Arduino

text:
# Question
Title: Wiring multiple LCD displays to Arduino
I have multiple LCD displays and one Arduino and I just want to show some text on each display separately.

Is it possible to Wiring multiple LCD Displays for the single Arduino board?

Or maximum how many display can I connect one single Arduino?

# Answer
For HD44780 based displays all the data, register select and read/write pins can be shared. A display only exists at the moment the E pin is toggled. They are designed to share a microprocessor's data bus.

So if you have 50 displays then you can (theoretically, see "fan out" below) run them from 50 "E" pins plus 6 (or 10 depending on if you want to run in 4 or 8 bit mode) shared pins.

Here's an example with 2 displays in 4-bit mode - just replicate for more:

simulate this circuit – Schematic created using CircuitLab

Note: power, ground and contrast connections omitted for brevity.

As you can see the LCDs share all their pins except the E pin. A third display will connect to the same pins, except its E pin would be unique.

## Fan out

Fan out is an important concept in digital electronics. An IO pin can only deliver a certain amount of current and each device a pin connects to adds "load" to that pin. Too many devices and the IO pin will struggle to control the devices properly.

To combat this a "bus transceiver" (such as the 74HC245) is commonly used. If one IO pin is capable of driving, for the sake of argument, 5 devices, and one bus transceiver is also capable of driving 5 devices then the IO pin could drive 5 bus transceivers giving you control over a potential 25 devices.
> 2 votes

---
Tags: lcd
---


# Question
Title: ESP32 Access Point and HTTP Web Server, how to send multiple parameters?
I made this minimal example in order to figure out how to get requests (or whatever they are called) to display in the serial monitor. However, none of the query parameters (in the URL) can be seen in the serial monitor at 115200 baud.

The files are below and here: https://github.com/adamelli/MinimalExamples/tree/main/22-1-25\_query\_parameters\_submitButton

# File structure

sketch (folder)

* sketch.ino
* data (folder)
    + index.html
    + selection.html

# sketch.ino

```
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <painlessMesh.h>

const char* ssid = "Wireless Controller";
const char* password = "12345678";

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

void sendMessage() {
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

AsyncWebServer server(80);

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}
IPAddress IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

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

  // Initialize SPIFFS
  if (!SPIFFS.begin(true))
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  WiFi.softAP(ssid, password);
  delay(500);
  WiFi.softAPConfig(IP, gateway, subnet);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

// Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", String(), false );
  });

  // Index.HTML NAVIGATION BUTTIONS ************************************************

  server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", String(), false);
  });

  server.on("/selection.html", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/selection.html", String(), false );
  });

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
  {

    int paramsNr = request->params();
    Serial.println(paramsNr);

    for (int i = 0; i < paramsNr; i++)
    {
      AsyncWebParameter* p = request->getParam(i);
      Serial.print("Param name: ");
      Serial.println(p->name());

      Serial.print("Param value: ");
      Serial.println(p->value());

      Serial.println("------");
    }

    request->send(200, "text/plain", "message received");
  });

  server.begin();
}

void loop() {}

```

# index.html

```
<!DOCTYPE html>
<html>
<body>

  <h1>Main Menu</h1>

<p><a href="/selection.html"><button class="button">Selection</button></a></p>

<p><a href="/notMinimal.html"><button class="button">Oblivion</button></a></p>

</body>
</html>

```

# selection.html

```
<!DOCTYPE html>
<html>
<body>
<!-- -->
<form action="/" method="get">

    <label for="size" style="font-size: 22px">Shape Size:</label>

    <select name="size" id="size" style="font-size: 22px;">
      <option value="1"> 1   </option>
      <option value="2"> 1/2 </option>
        </select>

    <p><label for="speed" style="font-size: 22px">Speed:</label>

    <select name="speed" id="speed" style="font-size: 24px">
      <option value="1">          Slowest </option>
      <option value="2" selected> Regular </option>
    </select></p>

  <p><a href="/selection"><button class="submit" name="circle" value="3">Circle</button></a></p>

  <p><a href="/selection"><button class="submit" name="square" value="4">Square</button></a></p>

</form>

</body>
</html>

```

The data files must be uploaded via "Tools" → "ESP32 Sketch Data Upload".

How is the data (size and speed) viewable in the serial monitor? What needs to change?

# Answer
You have two handlers for "/":

```
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", String(), false );
  });

```

and

```
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
  {

    int paramsNr = request->params();
    Serial.println(paramsNr);

    for (int i = 0; i < paramsNr; i++)
    {
...

```

Only one will be called when you load the top level page. You'll need to combine them to both serve `index.html` and process the parameters being passed to it.
> 2 votes

---
Tags: esp32, web-server, http
---


# Question
Title: ATTiny85 won't boot if PIN2 is not pulled high
I had some problem setting up a working ATTiny85 outside of its development board.
Connection on my breadboard:

```
pulled high (10K R)  -- 1  PIN 8  -- VCC (+5V)
     trouble here!!  -- 2  PIN 7  --
                     -- 3  PIN 6  -- LED
               GND   -- 4  PIN 5  --

```

as you can guess pins are referred to actual chip's pins enumeration.
My simple test code:

```
void setup() {
  pinMode(1, OUTPUT);
}
void loop() {
  if (analogRead(A1) > 512) {
    digitalWrite(1, HIGH);
    delay(250);
    digitalWrite(1, LOW);
    delay(250);
  } else {
    digitalWrite(1, HIGH);
    delay(1000);
    digitalWrite(1, LOW);
    delay(1000);
  }
}

```

I'm using Arduino IDE v1.8.13 with digistump avrboards v1.6.7.

I flashed t85\_default micronucleus v2.5 bootloader in my chip with fuses set to lfuse:0xe1, hfuse:0xdd, efuse:0xfe.
The problem is that if I power the chip with PIN2 not pulled high it won't start execution of the code, it won't blink. If it’s started from pulled high, it will start code about 5s after power on. If it’s started pulled low code won’t execute until is pulled high. As I pull high, even just for a second, PIN2 it will start blinking and executing code.

Is it normal? I think I have missed something.

# Answer
> 3 votes
Well, I've made *some* headway. I hope to update this with something more helpful though.

I don't have a digispark or even the correct Zener diodes to replicate the necessary parts of it. However, I did install t85\_default.hex on an ATTiny85 with some alterations to the hex file to place break instructions in a few strategic places. And then I ran avarice/debugwire against it.

The basic problem is that it's trying to tune the internal oscillator against the USB frames by looking at the D- pin. Basically, it's stuck in `tuneOsccal`.

```
988  00001d06 <tuneOsccal>:
   1     1d06:       b3 9b           sbis    0x16, 3 ; 22
   2     1d08:       fe cf           rjmp    .-4             ; 0x1d06 <tuneOsccal>
   3     1d0a:       07 d0           rcall   .+14            ; 0x1d1a <countFrame>
...

```

So if you want to avoid this, you need to compile with that feature off, and there is a feature to do that.

I have not yet run one with this feature disabled. But I did compile t85\_default once, using `make CONFIG=t85_default` and found it necessary to remove the `START_WITHOUT_PULLUP` from the first line of the t85\_default/bootloaderconfig.h file.

The code mentions the existence of `OSCCAL_SAVE_CALIB`, which lets you specify your own OSCCAL value, assuming the factory one for the chip isn't good enough for whatever reason. But there doesn't seem to be any guidance on how you're supposed store it or where. Looking at the code though, if enabled, you can see it loads the OSCCAL value from just before where the bootloader starts.

A simple way to put it there without messing with command-lines and linker scripts would be to just edit the the t85\_default.hex that results from building with `OSCCAL_SAVE_CALIB` enabled, and add an extra record for setting the osccal value at the correct address, which I guess would be 0x19FA, so:

:0119FA00**XX***SS*

Where **XX** is whatever you've determined your OSCCAL value is and *SS* is the checksum value, or `0x100 - ((0x14 + XX) & 0xFF)` in this case. Or, if you want to be lazy, put whatever you want for *SS* and let AVRDude complain tell you what it's supposed to be when it tries to load the .hex file. It will report the expected value in decimal, which you can convert to hex and patch into the file, and run AVRDude again.

# Answer
> 1 votes
I had the same problem, I changed to firmware micronucleus-1.11-upgrade.hex (from 2.3 to 1.11) and it was solved, you can find ir here https://github.com/micronucleus/micronucleus/tree/v1.11/upgrade/releases

---
Tags: attiny, attiny85
---


# Question
Title: Convert from raw data to float from DDSU666-H
Hi professers, i am trying to read the data from DDSU666-H ( Smart metter) CHINT using modbus RTU, i only get the raw data but i don't know how to convert it to float , in the code below is about Voltage , real data is 233,4V but in the serial is like this, can some one help me to convert this one to float 233,4V, thank you so much!

```
 Here is my code, i get it from modbusmaster library.
/*

  RS485_HalfDuplex.pde - example using ModbusMaster library to communicate
  with EPSolar LS2024B controller using a half-duplex RS485 transceiver.

  This example is tested against an EPSolar LS2024B solar charge controller.
  See here for protocol specs:
  http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf

  Library:: ModbusMaster
  Author:: Marius Kintel <marius at kintel dot net>

  Copyright:: 2009-2016 Doc Walker

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

#include <**ModbusMaster**.h>

/*!
  We're using a MAX485-compatible RS485 Transceiver.
  Rx/Tx is hooked up to the hardware serial port at 'Serial'.
  The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE      50
#define MAX485_RE_NEG  52

// instantiate ModbusMaster object
**ModbusMaster** node;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void setup()
{
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  // Modbus communication runs at 115200 baud
  **Serial1**.begin(9600);
  **Serial**.begin(9600);

  // Modbus slave ID 1
  node.begin(12, **Serial1**);
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}
void loop()
{
  uint8_t i, result;
  uint16_t data[2];
  union
  {
    uint32_t j;
    float f;
  } u;
  // Read 16 registers starting at 0x3100)
  **Serial**.println("-----------------------");
  result = node.readHoldingRegisters(0x2000, 2);
  if (result == node.ku8MBSuccess)
  {
    for (i = 0; i < 2; i++)
    {
      data[i] = node.getResponseBuffer(i);
    }
    **Serial**.println(data[0]);
    **Serial**.println(data[1]);
    u.j = ((unsigned long)data[1] << 16 | data[0]);
    **Serial**.println(u.f);
  }

```

# Answer
> 2 votes
Seems the data sheet does not specify the endianness. Or maybe it does, but you are not showing it. From the numbers you get, it appears that the floats come in big-endian order, whereas your code assumes little-endian.

Change the assignment of `u.j` as follows:

```
u.j = ((unsigned long)data[0] << 16 | data[1]);

```

---
Tags: programming
---


# Question
Title: Maximizing SPI-speed between Arduino DUE and RA8875 display driver
For a project I would like to be able to control my RA8875 display driver as quick as possible using an Arduino due.

I started from the Adafruit library and replaces all "digitalWrites" with direct port manipulation.

Apart from that I wanted to also use that maximum possible SPIspeed. In the adafruit datasheet I didn't find any specification of the maximum SPIspeed of the controller. In an older datasheet I only found the max speed in relation to the system clock. But I have no idea what that is. .

After googling, the max spi speed of the RA8875 seems to be 12Mhz (source).

So I decided to just try different SPIspeeds. Though I do found the library's Adafruit\_RA8875.cpp file a bit confusing since it defines *uint32\_t spi\_speed* multiple times based on the architecture.

* Once starting at line 48
* Once starting at line 134
* Once starting at line 164

And the chosen speeds for each architecture are not consistent between those 3 assignments.

I decided to replace line 66:

> SPI.beginTransaction(SPISettings(spi\_speed, MSBFIRST, SPI\_MODE0));

with:

> SPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI\_MODE0));

and tried other speeds. But it always resulted in a black screen on my display.

# Answer
> 2 votes
To speed up the RA8875, you should start with small clock frequency to initialize the RA8875 including the pll configuration and then you can make the clock frequency faster. It works with me.

---
Tags: arduino-due, tft
---


# Question
Title: Can I configure an Arduino via NFC using PN532 with an iPhone as the source?
It seems clear that Apple has intentionally limited the possibilities with NFC, so I understand that I'm going against the grain here. However, I need to support Android and Apple for my device setup, so I'm hoping to work around the Apple restrictions by making my Arduino receive data from an iPhone by posing as an RFID card and accepting a write from my Adafruit PN532 breakout board. I've got my Arduino Uno connected to the board and successfully reading from RFID cards. So the question is can I do a read from an iPhone? I've been experimenting with NFCTools on my iPhone to see if I can stimulate any behavior on my Arduino by running the Adafruit example programs and putting my phone near the reader while activating a write. I haven't had any success yet.

My idea is to avoid requiring Bluetooth for Arduino setup. My configuration is very simple so I don't need anything with high bandwidth. The configuration is done rarely and always by a person who is nearby. It seems like leaving out Bluetooth capability out of my device will save on cost and power consumption (though I don't know how much). It would be really slick too since my customer wouldn't need to go into settings to connect with Bluetooth. Instead they just put their phone near the device and it gets configured!

# Answer
> 1 votes
My understanding is that the PN532 is a reader/writer and will only want to communicate with passive nfc devices (an RFID card). Therefore, with a phone you cannot really communicate between the two in the way you want. Basically both your phone and the PN532 are going to only look for a passive device.

---
Tags: arduino-uno, adafruit, nfc
---


# Question
Title: What's with the debug error messages, like VMDPE_1|1_VMDPE?
I'm using visual micro for visual studio, and I understand this kind of thing is caused by conflicting serial data when I try to read and print to the main serial at the same time, right?

Well, I need to read serial data from the main serial on my Mega 2560, and then I need to see it on my LCD screen, which is controlled by the board via SPI. I know I can use those two at the same time because I'm doing it with my transmitting arduino and I can see that it's transmitting correctly.

When I try to view my serial data in the serial port, I get nothing but a stream of these error codes, or whatever they are. They generally look like this: VMDPE\_1|1\_VMDPE. Usually there are some numbers in there too, like: MDPE\_1|2571143\_VMDPE. I sort of expected that, since you can't read and write at the same time on one serial. But that would be fine, because my project is not going to be plugged into a PC anyway.

So of course I try to pipe my data directly to the LCD screen so I can plug my recieving arduino into external power and not have to see the error messages, which I thought were coming from the debugger of my compiler. Here's my code:

```
//on the receiver side

#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>

char incoming[3];

void setup() {
    Serial.begin(9600);
    //TFT_BL_ON;      // turn on the background light
    //Tft.TFTinit();  // init TFT library
    //Tft.setDisplayDirect(DOWN2UP);
    //TFT_BL_ON;      // turn on the background light
    //Tft.drawString("INCOMING:", 20, 301, 3, RED);
    Serial.println(incoming);

}

void loop() {

    if (Serial.available()) {

        Serial.readBytesUntil(',', incoming, 3 ) ;

        //Tft.fillRectangle(64, 236, 45, 165, BLACK);

        //Tft.drawString(incoming, 65, 235, 4, WHITE);
        Serial.println(incoming);

    }
}

```

But nope! I get the same error codes on my LCD screen! Even worse, now they seem to have screwed up my zigbee module! I took it off the board, plugged it into my computer, and now the XCTU utility is reading all sorts of messed up values that are total nonsense. Somehow, this seems to have overwritten the zigbee's actual SERIAL NUMBERS!!! What are they now? Take a guess!

Serial number high: E\_1|2571092\_VMDPE

Serial number low: MDPE\_1|2571143\_VMDPE

# Answer
Your `incoming` buffer is not big enough to handle the data that you're giving it. Cutting away the comments from your code:

```
char incoming[3];

```

This declares a buffer for **two** characters, allowing for the (required) `0` on the end. `println()` needs to know when to stop printing characters: it does this when it sees a `NUL` (`0`) character.

```
Serial.readBytesUntil(',', incoming, 3 ) ;

```

You're passing in that you want to read `3` characters - but that completely fills `incoming`, leaving no room for the trailing `NUL` (`0`).

```
Serial.println(incoming);

```

This then prints the first character, the second character, the third character... then the 4th, 5th, 6th, 7th etc. in memory until it *finally* reaches a `NUL` and then quits.

What you call "debug messages" are actually printed gibberish in memory... To fix it, you need to make `incoming` larger.

Also, it's a good idea when using buffers like this to use the `sizeof()` function, as follows:

```
Serial.readBytesUntil(',', incoming, sizeof(incoming)-1 ) ; // Note the -1!

```
> 2 votes

# Answer
I have seen the same messages, using VS2017 and Arduino Unu and Visual Micro. Messages start with "DPV..." or "VMDPV...".

The solution is to upload the sketch to the Arduino using Release mode. Then the hidden debug serial prints that Visual Micro seems to put in are gone.
> 0 votes

# Answer
I had the same problem. The problem seems to come from AVR Studio serial debugging. If you turn off the serial debugger the problem will go away. Remember to also turn of **"Automatic Software Debugging (Release/Debug)"**, as shown below.
> 0 votes

---
Tags: debug
---


# Question
Title: How to determine when a sensor's output signal changes significantly?
Starting with an analog signal from any sensor, how do I automatically determine if there is a real signal change or a reset? Below is the sample code that better explains my goal:

```
value = sensorRead();

if (millis() > t + 1000) {
  value_old = value;
  t         = millis();
}
float d = value - value_old;
if (d < -3) {
  print("signal change")
  myfunction(); //ex. bink led
}

```

So if `value(current) = 0.5` and `value_old = 100` there has been a real change in signal, even if, because of noise, the value is not exactly 0.

It's very raw code, and I'd like to use a more professional approach that can detect both increments and decrements. Ideally, a suitable library, or alternatively a more efficient algorithm, would be ideal.

# Answer
> 4 votes
There is no simple and universal way of deciding what is to be considered a “significant” change. My recommendation would be to create an algorithm by playing with the data on your computer:

* Upload a sketch to your Arduino that simply reads the sensor and transmits the readings to your computer via `Serial`.
* Capture a long run of such readings in a file.
* Graph the readings and look carefully at the graphs: what would *you* consider a significant change? What criteria could you use to decide that a change is significant? Devise an algorithm to take this decision.
* Implement and test the algorithm on your computer, using the recorded data.
* Port the code to the Arduino.

Below are two examples that maybe could give you some ideas. First comes the simplest I can think of: it says the change is significant if the current value is far enough from a previously recorded value. That recorded value is only updated after a significant change has been detected.

```
bool changed_significantly(int value) {
    const int change_threshold = 4;  // tune to taste
    static int old_value;
    bool changed = abs(value - old_value) >= change_threshold;
    if (changed)
        old_value = value;
    return changed;
}

```

It would be used like this:

```
void loop() {
    int value = sensorRead();
    if (changed_significantly(value))
        Serial.println("Signal changed.");
}

```

Note that, with this algorithm, a very slow drift would periodically trigger the detection of significant changes. If this is not what you want, you may prefer to only detect changes that happen fast enough. This can be detected by the use of a high-pass filter. The function below implements a simple low-pass filter (exponentially weighted moving average) and compares the current input to the previous output. The difference is equivalent to a high-pass filter. If that difference is large enough, a significant change is detected, then the filter is reset in order to prevent it from being repeatedly triggered by a drift:

```
bool changed_significantly(int value) {
    const float change_threshold = 4;   // tune to taste
    const float filter_constant = 0.1;  // this one also
    static float filtered_value;
    float delta = value - filtered_value;
    bool changed = abs(delta) >= change_threshold;
    if (changed)
        filtered_value = value;
    else
        filtered_value += filter_constant * delta;  // low-pass filter
    return changed;
}

```

---

**Edit**: some details about the filter.

This high-pass filter alone could be simplified as this:

```
float filter(float x)
{
    static float y;
    float delta = x - y;
    y += filter_constant * delta;
    return delta;
}

```

Note that, if this function returned `y`, we would have a conventional first-order low pass filter (exponentially weighted moving average). Since it returns instead the difference between the input and the previous low-pass-filtered value, it behaves as a high-pass filter. Its transfer function is

H = (z − 1) / (z + k − 1)

where k is the filter constant. This constant is related to the cut-off frequency as

fc ≈ k fs / (2π)

where fs is the sampling frequency. Note that, for frequencies significantly smaller than the cut-off, the filter behaves like a scaled derivative:

H x ≈ 1/(k fs) dx/dt

---
Tags: sensors, signal-processing, analog-sampling, data, algorithm
---


title: Wind speed measuring using Hall sensor

text:
# Question
Title: Wind speed measuring using Hall sensor
Hi! I require your help regarding a problem I’m encountering. I am trying to measure wind speed using Hall sensor, Neodymium magnet & below mentioned code. But I only get “0” value for both RPM & KPH values. Can you help me to solve this?

```
volatile byte revolutions;

unsigned int rpmilli;
float speed;

unsigned long timeold=0 ;

void setup()
{
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(2), rpm_fun, RISING);

    revolutions = 0;
    rpmilli = 0;
    timeold = 0;
}

void loop()
{
    if (revolutions >= 1) {
         //Update RPM every 20 counts, increase this for better RPM resolution,
         //decrease for faster update

         // calculate the revolutions per milli(second)
         rpmilli = revolutions/(millis()-timeold);

         timeold = millis();
         revolutions = 0;
         // WHEELCIRC = 2 * PI * radius (in meters)
         // speed = rpmilli * WHEELCIRC * “milliseconds per hour” / “meters per kilometer”

         // simplify the equation to reduce the number of floating point operations
         // speed = rpmilli * WHEELCIRC * 3600000 / 1000
         // speed = rpmilli * WHEELCIRC * 3600

         speed = rpmilli 1.288053600;

         Serial.print(“RPM:”);
         Serial.print(rpmilli * 60000 ,DEC);
         Serial.print(" Speed:");
         Serial.print(speed,DEC);
         Serial.println(" kph");
    }
}

void rpm_fun()
{
    revolutions++;
}

```

# Answer
```
rpmilli = revolutions/(millis()-timeold);

```

All variables in this line are of type `int`, so this is an integer division. When the time delta in ms is larger than the number of revolutions it counted, this always returns 0. You need to change this to:

```
rpmilli = ((float)revolutions)/(millis()-timeold);

```

and change `rpmilli` to float.
> 3 votes

---
Tags: arduino-uno, hall-effect
---


# Question
Title: DC Motor not running with the L298N (Green) card
I have a DC motor connected to a L298N (Green) controller. The controller is receiving electricity but the motors aren't. This is how we wired everything

Our code:

```
#include <SoftwareSerial.h>

int IN1 = 13;
int IN2 = 12;

int IN3 = 8;
int IN4 = 9;

void setup(){
  Serial.begin(9600);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

}

void loop(){
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  delay(2000);
}

```

The DC motor is not responding at all

Edit: Why is the motor not receiving electricity? How can we connect the card to the Arduino UNO correctly and get the motors running?

# Answer
> 3 votes
**First:** The connection between the 5V pin of the L298N and Arduino Vin is not correct here. The L298N 5V pin is an output. You could use it to power the Arduino. But then you would have to connect it to the 5V pin of the Arduino. Vin is connected to the linear voltage regulator. You need about 7V here to get the Arduino running reliably, because the regulator needs some headroom for regulating it down to 5V and the battery deplets over time a bit. Since you are powering the Arduino over USB you can remove this connection.

**Second:** The standard 9V block batteries, that you use, are not meant for providing the power for something like a motor. They are made for low power applications (like smoke detectors). So you will need a different battery type. Which exactly is dependent on further factors. You could start with putting AA batteries in series (enough to get to the voltage, that you need for your motors). Or you can buy a LiIon or LiPo battery (including the corresponding charging board). I'm not enough of a battery expert myself to go more detailed with the recommendations on direct batteries.

If you want it easy you might want to use a standard USB power bank. These give you 5V and (depending on the product) about 1 or 2A of current. Using a standard power bank has the advantage, that you get well regulated voltage, relatively high current and it already has the correct charging electronics.

With a USB-C power bank a corresponding PD board (Power Delivery) you can even get up to 12V from the power bank. Haven't tried this myself yet. Have a look at this video from GreatScott on Youtube. Looking at a standard online marketplace (we all know which one) and searching for "USB-C PD board" gave some promising results.

---
Tags: motor, l298n
---


# Question
Title: ESP32 Access Point using ESPAsyncWebServer, how to send multiple parameters between submenu and main (index) menu while still retaining page layout?
I am trying to figure out how to get requests (or whatever they are called) to display in the serial monitor, yet not change the HTML page bodies.

The user selects their choices in the submenu (`selection`). Once clicking the submit button there, they return to the original main index menu and simultaneously the query parameters are sent to the ESP32 of the user's selections.

Based off another very similar question I asked, it works so that the query parameters (in the URL) can be seen in the serial monitor. Although, then the main menu is cleared out and left with "message sent".

Alternatively, the main menu can remain the same, but the query parameters are not sent. So one works but not the other, and vise versa.

The files are below and here: https://github.com/adamelli/MinimalExamples/tree/main/22-1-25\_query\_parameters\_submitButton

# File structure

sketch (folder)

* sketch.ino
* data (folder)
    + index.html
    + selection.html

# sketch.ino

```
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <painlessMesh.h>

const char* ssid = "Wireless Controller";
const char* password = "12345678";

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

void sendMessage() {
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

AsyncWebServer server(80);

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}
IPAddress IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

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

  // Initialize SPIFFS
  if (!SPIFFS.begin(true))
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  WiFi.softAP(ssid, password);
  delay(500);
  WiFi.softAPConfig(IP, gateway, subnet);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  server.on("/selection.html", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/selection.html", String(), false );
  });

// Main menu index page works
//  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
//    request->send(SPIFFS, "/index.html", String(), false );
//  });

// Query parameters works
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
  {

    int paramsNr = request->params();
    Serial.println(paramsNr);

    for (int i = 0; i < paramsNr; i++)
    {
      AsyncWebParameter* p = request->getParam(i);
      Serial.print("Param name: ");
      Serial.println(p->name());

      Serial.print("Param value: ");
      Serial.println(p->value());

      Serial.println("------");
    }

    request->send(200, "text/plain", "message received");
  });

  server.begin();
}

void loop() {}

```

# index.html

```
<!DOCTYPE html>
<html>
<body>

  <h1>Main Menu</h1>

<p><a href="/selection.html"><button class="button">Selection</button></a></p>

<p><a href="/notMinimal.html"><button class="button">Oblivion</button></a></p>

</body>
</html>

```

# selection.html

```
<!DOCTYPE html>
<html>
<body>
<!-- -->
<form action="/" method="get">

    <label for="size" style="font-size: 22px">Shape Size:</label>

    <select name="size" id="size" style="font-size: 22px;">
      <option value="1"> 1   </option>
      <option value="2"> 1/2 </option>
        </select>

    <p><label for="speed" style="font-size: 22px">Speed:</label>

    <select name="speed" id="speed" style="font-size: 24px">
      <option value="1">          Slowest </option>
      <option value="2" selected> Regular </option>
    </select></p>

  <p><a href="/selection"><button class="submit" name="circle" value="3">Circle</button></a></p>

  <p><a href="/selection"><button class="submit" name="square" value="4">Square</button></a></p>

</form>

</body>
</html>

```

The data files must be uploaded via "Tools" → "ESP32 Sketch Data Upload".

How can the definitions, `server.on("/"` be combined so the data (size/speed/shape) is viewable in the serial monitor AND where the main and submenu remain the same (with their buttons)?

I have tried...

* putting `request->send(SPIFFS, "/selection.html", String(), false);` and `request->send(200, "text/plain", "message received");` together inside  `server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)`
* sending different stuff for `request->send(200, "text/plain", "message received");` even though I still do not understand how to get it to submit data, and return to the main menu, without clearing it out with a new message (various trial and error combinations either did not allow it to compile or just made one of the pages "Not found")
* messing with HTML stuff (nothing changed)

# Answer
> 1 votes
This is not an answer per se.

Posted as an answer because of attached images.

It is unclear what you are actually asking.

I ran a python minimal web server in the same folder as index.html.

Here is the trace from the server.

```
C:\Users\qwerty\Desktop2\MinimalExamples-main\22-1-25_query_parameters_submitButton\data>py3 -m http.server 80
Serving HTTP on :: port 80 (http://[::]:80/) ...
::1 - - [27/Jan/2022 15:43:23] "GET / HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:43:24] code 404, message File not found
::1 - - [27/Jan/2022 15:43:24] "GET /favicon.ico HTTP/1.1" 404 -
::1 - - [27/Jan/2022 15:43:25] "GET /selection.html HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:43:32] "GET /?size=2&speed=1&circle=3 HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:43:34] code 404, message File not found
::1 - - [27/Jan/2022 15:43:34] "GET /notMinimal.html HTTP/1.1" 404 -
::1 - - [27/Jan/2022 15:43:39] "GET /?size=1&speed=2&circle=3 HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:45:07] "GET /?size=1&speed=2&square=4 HTTP/1.1" 200 -
::1 - - [27/Jan/2022 15:52:46] code 404, message File not found
::1 - - [27/Jan/2022 15:52:46] "GET /notMinimal.html HTTP/1.1" 404 -
::1 - - [27/Jan/2022 15:53:02] "GET /?size=2&speed=1&square=4 HTTP/1.1" 200 -

```

This is what `index.html` is called with. The data is available to index.html. You only have to parse it from the URL.

---
Tags: esp32, web-server, http
---


title: Library that pulls ID3v2 info from MP3s

text:
# Question
Title: Library that pulls ID3v2 info from MP3s
I'm using an Adafruit Music Maker with a TFT screen on my Mega 2560. I can pull ID3v1 data from the end of an MP3, but I'd like to get the ID3v2 data as I can then push the album cover art to the TFT along with the title/artist/album/etc.

My initial searches have turned up nothing for a library that pulls the ID3v2 headers. Before I start to crack that nut on my own, I want to make sure I am not overlooking something.

Has anyone used a library to pull ID3v2 data from an MP3?

# Answer
Here's what I have written so far. This pulls data from the ID3v2 header at the start of the mp3 file.

```
void frameInfo(File track, char tvalue[64], char albval[64], char artval[64],
char fname[30], bool showpic) {
uint32_t start = 10;
uint32_t lastfrm = 10;
bool done = false;

track.getName(fname,max_chars);

while (!done) {
 uint8_t buff[4];
 uint32_t ltwo[4];
 char tag[5];
 uint32_t fsize;
 track.seek(start);
 track.read((uint8_t *)tag, 4);
 tag[5] = 0;

 track.seek(start + 4);
 track.read((uint8_t *)buff,4);
 ltwo[0] = buff[0];
 ltwo[1] = buff[1];
 ltwo[2] = buff[2];
 ltwo[3] = buff[3];

 fsize = (ltwo[0] << 24) | (ltwo[1] << 16) | (ltwo[2] << 8) | ltwo[3];
 start = start + 10;

if (tag[0] == 'T' && tag[1] == 'I' && tag[2] == 'T' && tag[3] == '2') {
  uint32_t i;
  int vlen = 0;
  char val[fsize];

  track.seek(start);
  track.read((uint8_t *)val, fsize);
  for (i=0;i<fsize;i++) {
    if (isAlphaNumeric(val[i])) {
      tvalue[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      tvalue[vlen] = val[i];
      vlen++;
    }
  }
  tvalue[vlen] = '\0';
}
else if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'L' && tag[3] == 'B') {
  uint32_t i;
  int vlen = 0;
  char val[fsize];

  track.seek(start);
  track.read((uint8_t *)val, fsize);
  for (i=0;i<fsize;i++) {
    if (isAlphaNumeric(val[i])) {
      albval[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      albval[vlen] = val[i];
      vlen++;
    }
  }
  albval[vlen] = '\0';
}
else if (tag[0] == 'T' && tag[1] == 'P' && tag[2] == 'E' && tag[3] == '1') {
  uint32_t i;
  int vlen = 0;
  char val[fsize];

  track.seek(start);
  track.read((uint8_t *)val, fsize);
  for (i=0;i<fsize;i++) {
    if (isAlphaNumeric(val[i])) {
      artval[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      artval[vlen] = val[i];
      vlen++;
    }
  }
  artval[vlen] = '\0';
}

else if (tag[0] == 'A' && tag[1] == 'P' && tag[2] == 'I' && tag[3] == 'C') {
  uint32_t i;
  int vlen = 0;
  char val[30];
  char test[30];
  uint8_t raw[fsize - 11];

  track.seek(start);
  track.read((uint8_t *)val, 11);
  for (i=0;i<11;i++) {
    if (isAlphaNumeric(val[i])) {
      test[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      test[vlen] = val[i];
      vlen++;
    }
  }
  test[vlen] = '\0';

  if (fsize < 200000) {
    track.seek(start+11);
    Serial.println(fsize+11);
    //track.read((uint8_t *)pic, fsize-11);
  }

}
else {

}

start = start + fsize;
if ((start == lastfrm + 10) || start > musicPlayer.mp3_ID3Jumper(track)) {
  done = true;
}
else {
  lastfrm = start;
}

}
track.rewind();
}

```

This pulls the text data for title/artist/album, but the problem is how to read the image from the header without overloading the Mega. Most of the images are around 30K bytes, but there is no room in RAM on the Mega for that kind of space. I have my sketch set to read the jpeg format, convert it to BMP, then write it to the TFT. Is there some method I could use to have the sketch write the bytes to a file on the SD card, then read them from there?
> 1 votes

# Answer
There is an SD library meant for use with the VS1053 which has some extra id3 tag support. Check it out here : https://github.com/mpflaga/Arduino\_Library-vs1053\_for\_SdFat
> -1 votes

---
Tags: arduino-mega, adafruit
---


# Question
Title: I cant get a stepper motor to work with arduino UNO
I'm using an arduino UNO with a L2989N motor controller with a nema 17 hanpose 17h3401 stepper motor. I'm using two 9 volt batteries in series to power it. I'm sure I connected them properly but it just doesn't work. I tried using the example stepper motor sketch stepper\_oneRevolution but it didn't work. I just cant pinpoint what's wrong. PS. I'm very new to this

# Answer
> 1 votes
It is highly likely your power source supplies insufficient current to power both the stepping motor and the Arduino reliably.

This is very similar to one of my past stackexchange question / answer.

Where I say ...

> Consider using a power source which can supply more current. For instance, D size cell batteries can supply much more current than a small 9 volt battery.

... all that said, stepping motors are high current devices. It may not be feasible to run stepping motors off batteries.

---
Tags: arduino-uno
---


# Question
Title: Problem with IR remote and Pushbutton for digispark
As digispark is more compact and suitable for my electrical application. Following the same procedure in brtiberio answer. I tried to convert the script from Arduino UNO to digispark, but not succeed

```
#define irPin 2
const int buttonPin1 = 0;
const int buttonPin2 = 4;
const int relay1 = 1;
const int relay2 = 3;
int Relay1State = 0;
int Relay2State = 0;
int master1State = 0;
int master2State = 0;
int button1State;
int button2State;
int lastButton1State;
long lastDebounceTime1 = 0;
int lastButton2State;
long lastDebounceTime2 = 0;
long debounceDelay = 50;
void setup() {
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  digitalWrite(relay1, Relay1State);
  digitalWrite(relay2, Relay2State);
}

void loop() {

  int key = getIrKey();

  if(key == 7388){
    Relay1State = !Relay1State;
    if(Relay1State == true)
      digitalWrite(relay1, HIGH);
    else
      digitalWrite(relay1, LOW);
  }

  if(key == 1778){
    Relay2State = !Relay2State;
    if(Relay2State == true)
     digitalWrite(relay2, HIGH);
   else
     digitalWrite(relay2, LOW);
  }
}

int getIrKey(){
  int len = pulseIn(irPin,LOW);
  int key, temp;
  key = 0;
  //Serial.print("len=");
  //Serial.println(len);
  if(len > 6000) {
    for(int i=1;i<=32;i++){
      temp = pulseIn(irPin,HIGH);
      if(temp > 1000)
        key = key + (1<<(i-17));
    }
  }
  if(key < 0 )
    key = -key;

  //if(key)
    //Serial.println(key);

    delay(250);
  return key;
  //**********************//
  int reading = digitalRead(buttonPin1);
  if (reading != lastButton1State) {
    lastDebounceTime1 = millis();
  }
  if ((millis() - lastDebounceTime1) > debounceDelay) {

    if (reading != button1State) {
      button1State = reading;

      if (button1State == HIGH) {
        master1State = !master1State;
        Relay1State = master1State;
      }
    }
  }

  digitalWrite(relay1, Relay1State);
  lastButton1State = reading;

  //*******************************//
  int reading2 = digitalRead(buttonPin2);
  if (reading2 != lastButton2State) {
    lastDebounceTime2 = millis();
  }
  if ((millis() - lastDebounceTime2) > debounceDelay) {

    if (reading2 != button2State) {
      button2State = reading2;

      if (button2State == HIGH) {
        master2State = !master2State;
        Relay2State = master2State;
      }
    }
  }

  digitalWrite(relay2, Relay2State);
  lastButton2State = reading2;
}

```

Any advise, please?

# Answer
Your button code is in the function `int getIrKey()`. But it never gets executed, because before it you execute `return key;`. With that you leave the function and returning the value of `key`. Everthing that comes after the return statement will not be executed.

Putting the button code in that function doesn't make sense in the first place (since the buttons are not used to "get the pressed IR key"). Instead try to put it in the `loop()` function, after the other relay code.
> 0 votes

---
Tags: ir, attiny85
---


title: SAM3X8E (Arduino Due) Pin IO registers

text:
# Question
Title: SAM3X8E (Arduino Due) Pin IO registers
How do the IO registers of Arduino Due work? On Arduino Uno just set `DDRx`, then `PINx` to read, `PORTx` to write, I'd like to do the same thing with an Arduino Due, but it has many more registers, such as `PIO_OWER`, `PIO_OSER`, `PIO_CODR`, `PIO_SODR`, etc. I find no correspondence between Arduino Uno and Arduino Due registers.

There are also some useful functions such as `pio_clear`, `pio_set`, `pio_get`, and others, all explained here:

http://asf.atmel.com/docs/3.19.0/sam3x/html/group\__sam\__drivers\__pio\__group.html

Now, I think I've understood what the three mentioned functions do, but not others, for example:

```
pio_configure (Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute)

```

I can't figure out what `ul_attribute` and `ul_type` are.

# Answer
> 7 votes
If you have a read of section 31 of the Datasheet, available from here, things may come a little clearer for you.

Here's a summary of what I know:

PIO stands for Parallel Input/Output and offers the functionality to read and write multiple register ports at a time. Where the datasheet mentions a register, for example PIO\_OWER, the Arduino library has macros for accessing them in this format REG\_PIO?\_OWER where ? is either A, B, C or D for the different ports available.

I tend to still use the slow Arduino pinMode() function to set input/output on the pins as it makes the code more readable than the acronym based registers calls such as REG\_PIOC\_OWER = 0xdeadbeef, but then use the direct registers to set the pins for performance/synchronisation. As yet, I haven't done anything with input, so my examples are all output based.

For basic usage, you would use REG\_PIO?\_SODR to set output lines high and REG\_PIO?\_CODR to set them low. For example REG\_PIOC\_SODR = 0x00000002 would set bit 1 (numbered from zero) on PORTC (this is Due digital pin 33) high. All other pins on PORTC remain unchanged. REG\_POIC\_CODR = 0x00000002 would set bit 1 on PORTC low. Again all other pins would be unchanged.

As this is still not optimal, or synchronised if you are working with parallel data, there is a register that allows you to write all 32 bits of a port with a single call. These are the REG\_PIO?\_ODSR, so REG\_PIOC\_ODSR = 0x00000002 would now set bit 1 on PORTC high and all other bits on PORTC would be set low instantly in a single CPU instruction.

Because it is unlikely that you would ever be in a situation where you need to set all 32 bits of a port at the same time, you would need to store the current value of the pins, perform an AND operation to mask out the ones you want to alter, perform an OR operation to set the ones you want set high then perform your write and again, and this is not optimal. To overcome this, the CPU itself will perform the masking for you. There is a register called OWSR (output write status register) that will mask out any bits that you write to ODSRs that don't match bits set in the OWSR.

So, now if we call REG\_PIOC\_OWER = 0x00000002 (this sets bit 1 of the OWSR high) and REG\_PIOC\_OWDR = 0xfffffffd (this clears all bits except bit 1 of the OWSR) and then call REG\_PIOC\_ODSR = 0x00000002 again, this time it would only change bit 1 of PORTC and all other bits remain unchanged. Pay attention to the fact that **OWER enables** any bits **that are set to 1** in the value you write and that **OWDR disables** any bits ***that are set to 1*** in the value you write. Even though I understood this when I read it, I still managed to make a code mistake when writing my first test code thinking that OWDR disabled bits that **weren't** set to 1 in the value I wrote.

I hope this has at least given you a bit of a start in understanding the PIO of the Due CPU. Have a read and a play and if you have any further questions, I'll try to answer them.

Edit: One more thing...

How do you know which bits of the PORTs correspond to which digital lines of the Due? Check this out: Due Pinout

# Answer
> 3 votes
There is a fairly simple equivalence for the basic direct pin access. Below is some sample code which shows how to set a digital pin high and then low. The first is for an Arduino Due, the second is for the Arduino Uno/Mega/etc.

```
const unsigned int imThePin = 10; //e.g. digital Pin 10

#ifdef _LIB_SAM_

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    Pio* imThePort = g_APinDescription[imThePin].pPort;
    unsigned int imTheMask = g_APinDescription[imThePin].ulPin;

    //Lets set the pin high
    imThePort->PIO_SODR = imTheMask;
    //And then low
    imThePort->PIO_CODR = imTheMask;

#else

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    volatile unsigned char* imThePort = portOutputRegister(digitalPinToPort(imThePin));
    unsigned char imTheMask = digitalPinToBitMask(imThePin);

    //Lets set the pin high
    *imThePort |= imTheMask;
    //Now low
    *imThePort &= ~imTheMask;

#endif

```

Everything that is needed to do that should be included by default - and if not `#include <Arduino.h>` should be sufficient to get it there.

There are actually functions available that can be called once you have the `Pio` pointer to do the setting/clearing/pullup resistors/etc. using slightly cleaner looking function calls. A full list can be found in the  header file.

# Answer
> 2 votes
This is a code example that flashes a led on pin 33. Code borrowed from above - many thanks for the very helpful explanations :) This is the beginning of a project to talk to a TFT touchscreen display with dumping of 16bit color pixel data which needs fast access to the ports. I think I have the code right - particularly the line that sets the pin low. The led is happily flashing.

```
void setup()
{
  pinMode(33, OUTPUT);
  REG_PIOC_OWER = 0x00000002;
  REG_PIOC_OWDR = 0xfffffffd;
}

void loop()
{
  REG_PIOC_ODSR = 0x00000002;
  delay(1000);
  REG_PIOC_ODSR = 0x00000000;
  delay(1000);
}

```

# Answer
> 2 votes
I actually followed the above examples and did many tests that I am comfident the results will aid anyone looking into addressing the registers directly.

```
   void setup() {
  pinMode(25, OUTPUT);
  pinMode(26, OUTPUT);
  pinMode(27, OUTPUT);
  pinMode(28, OUTPUT);
  pinMode(29, OUTPUT);
  //REG_PIOD_SODR = 0b00000000000000000000000001001111; // written in binary form
  REG_PIOD_SODR = 0x0000004F; //written in Hexadecimal form. Note the differences. Thw two, binary and Hexadecimal are the same.
  delayMicroseconds (250000);
  //REG_PIOD_CODR = 0b00000000000000000000000001001111;
  REG_PIOD_CODR = 0x0000004F;
  delayMicroseconds (2000000);

}

void loop()
{
  //REG_PIOD_ODSR = 0b00000000000000000000000001001111; // serts all the bits set to 1 HIGH and the rest set to 0 LOW
  REG_PIOD_SODR = 0b00000000000000000000000001001111; // sets all the bits set to 1 HIGH and leaves the rest untouched
  delay(500);
  REG_PIOD_CODR = 0b00000000000000000000000000000100;//1
  //REG_PIOD_CODR = 0x00000004; //identical to the line above only that it is in Hexadecimal format
  //REG_PIOD_SODR = 0b00000000000000000000000000000100; // will disable the rest bits and leave only one HIGH
  delay(500);
  REG_PIOD_CODR = 0b00000000000000000000000000000010;//2
  delay(500);
  REG_PIOD_CODR = 0b00000000000000000000000001000000;//3
  delay(500);
  REG_PIOD_CODR = 0b00000000000000000000000000001000; //4
  delay(500);
  REG_PIOD_CODR = 0b00000000000000000000000000000001; //5
  delay(500);

}

```

To explain better, all pins desired to be **OUTPUTs** are set via pinMode and then, it is very optional toenable them while at SETUP. In this case, I just wanted the pins to be made HIGH just once while at SETUP and then LOW before the loop starts. I've used REG\_PIO?\_SODR (**in this case, ? is port D so it is REG\_PIOD\_SODR**) which only make its set to 1 HIGH and the rest are left untouched. I have used both in binary and Hexadecimal format. Binary makes it easier to identify which pins to enable. For instance, bit PD0 is the right most bit in the binary number. It starts from Right going to left. For example, 0b00000000000000000000000000000001, bit 1 is PD0, PD1 will be 0b00000000000000000000000000000010 and so on. You've seen examples provided in this format, **0xfffffffd** the **x** means it is in hexadecimal format and **b** is in binary format. To convert binary to Hexadecimal, youcan use the easiest route via this link

To explain, any Hexadecimal number represents 4 binary numbers, example, Hex 0 is binary 0000, Hex F is binary 1111, Hex 4 is binary 0100, Hex A is binary 1010.

Now that is understood, going to the main loop, I have used the **REG\_PIOD\_SODR** because it gives one the freedom to address the pins one wants without touching any other pins on that port. You can use **REG\_PIOD\_ODSR** ONLY when you want to set all bits at once. This is ideal when you want many pins set HIGH and/or LOW at once. It is not the best if you want to set just a few pins HIGH/LOW and leave the rest untouched. **REG\_PIOD\_SODR** is ideal when some pins needs to be left untouched. You don't want to set one bit HIGH then all pins are HIGH. This command **REG\_PIOD\_CODR** sets the bits set 1 LOW and leave all the rest set to 0 untouched.

This code simply makes the bits selected at setup HIGH for the said time in delay then LOW for the given time. In loop, all bits selected as 1 are made HIGH and the rest untouched. The following lines simply turn the selected bits LOW one at a time until all are OFF and then the process repeats.

I hope this oversimplified explanation aided someone.

---
Tags: arduino-due, c, port-mapping
---


# Question
Title: Writing Arduino code for MPXV6115V pressure sensor
I'm attempting to use an MPXV6115V pressure sensor to monitor the constant vacuum of a suction device. I haven't been able to find a library to use with this sensor. I'm very new to Arduino but I am a software developer so would like to write some code to get this sensor working. The datasheet for this sensor can be found here. I've had some success using the code found here but this is for a different MPX pressure sensor and the output doesn't look right, I believe my constant values might need adjusting but not sure.

I've heard I may be able to use the transfer function for the basis of the code? I'm really not sure where to start with that. Could someone please explain how I can write the code to get this sensor working with the Arduino? Thank you.

# Answer
The linked code basically just does `analogRead()`s, calculates a real world value from the results and sends it over Serial. Thats also what you want to do, you just need to change the calculation.

So take the transfer function of your sensor and reorder it so that you get a formula for P:

```
P = (Vout/Vs - 0.92)/0.007652

```

with Vs being the supply voltage (5V in this case) and Vout being the output voltage. The ADC of the Arduino is 10 bits, so it gives you a value in the range of 0 to 1023 for 0V to 5V. So you get the voltage by calculating

```
voltage = analogRead(pin) / 1023.0 * 5.0;

```

Now put that into the formula above, write it as proper C++ code (for the variables use `float` as type, while `pin` is an integer and is the pin you connected the sensor to, like `A0`) and then replace the calculation in the linked code with yours - or wrote your own complete code. There isn't much to do besides `analogRead()`, the calculation and corresponding `Serial.println()` calls.
> 1 votes

---
Tags: arduino-uno, sensors
---


# Question
Title: Question about using millis for alarm conditions - Arduino
I am new to programming in general and to Arduino as well. I am working on a small project to improve my ability to write complete and kind of useful programming sketches.

I am facing a problem. I am using a few things in my circuit like 7-segment display and relays and several indicating LEDs and a buzzer.

Let's sat that when a condition occurs I want one LED to blink while everything still works fine and sends data to the display and controls relays, and I solved that with the `millis` function.

But the problem came when I tried to implement the same concept to the buzzer (which in my case I want to buzz for a pre-set amount of time, and then stop, without keeping buzzing all the time which might be too long), without using the `delay` function.

I tried many many code but nothing would work for me so far. Here is the simple code of my sketch. I hope you guys will help me find a solution

```
const byte buzzer = 13;  // buzzer_PIN
const byte switch1 = 3;  // PUSH-BUTTON PIN

/* please NOTE:
that the switch in my project will actually represent a condition to start the buzzer alarm, then maybe that condition will not exist, and after that the condition might come back and need the buzzer again
*/

unsigned const int delaytime = 500; // delay time needed between on and off states for the buzzer
unsigned long previousBuzz = 0;     // Variable for millis
unsigned long currentTime = millis();
boolean buzzPreState = true;        // Boolean made to avoid repetition for the buzzer when not needed

void setup() {
  pinMode(buzzer,OUTPUT);
  pinMode(switch1,INPUT_PULLUP);
}

void loop() {
  unsigned long currentTime = millis();
  int switchVal = digitalRead(switch1);

  if (switchVal == LOW && currentTime - previousBuzz > delaytime && buzzPreState == true) {
    previousBuzz = currentTime;
    buzzPreState = false;
    buzzerStart(5);
    buzzPreState = true;
  }
}

void buzzerStart(int repeat) {
  for (byte i=0; i<repeat; i++) {
    digitalWrite(buzzer, !digitalRead(buzzer)); // to switch buzzer ON and OFF alternatively
  }
}

```

# Answer
> 1 votes
You are missing a delay here:

```
for (byte i = 0; i < repeat; i++) {
    digitalWrite(buzzer, !digitalRead(buzzer));
}

```

Without the delay, the whole loop terminates so fast that you cannot hear anything.

Now, if you want non-blocking code, you should instead use the approach of the Blink Without Delay tutorial:

* have the program remember the current state
* when it's time to switch states (as determined by `millis()`), update the current state.

The difficulty is that, whereas the program state in that tutorial is trivial (either the LED is off or it's on), in your case it is more complex. In addition to the time of the last toggle, you have to keep track of:

* whether the buzzer is off or on
* whether it is supposed to be making sound
* a counter for the buzzing cycles.

The approach I would use is to have a counter (let's call it `buzzer_remaining`) telling how many cycles it still has to complete. The counter would decrement when the pin goes `LOW`. When it reaches zero, the buzzing is done. Note that this choice implies that, when the condition for buzzing becomes true, we will start at the middle of a buzzing cycle.

Here is a tentative implementation of this approach:

```
const uint32_t buzzer_half_period = 500;  // 500 ms in each state
const uint8_t buzzer_count = 5;  // buzz for 5 cycles
uint8_t buzzer_remaining;        // remaining buzzing cycles
uint8_t buzzer_state;            // LOW or HIGH
uint32_t buzzer_last_toggle;     // millis() at last toggle time

void buzzer_start() {

    // Ignore request to start if we are already buzzing.
    if (buzzer_remaining > 0)
        return;

    // Initialize the buzzer state.
    buzzer_remaining = buzzer_count;
    buzzer_state = HIGH;
    digitalWrite(buzzer, buzzer_state);
    buzzer_last_toggle = millis();
}

// Call this periodically from loop().
void buzzer_update() {

    // Do nothing if we are not supposed to be buzzing.
    if (buzzer_remaining == 0)
        return;

    // Do nothing if it is too early to switch state.
    uint32_t now = millis();
    if (now - buzzer_last_toggle < buzzer_half_period)
        return;

    // Update the buzzer state.
    if (buzzer_state == LOW) {
        buzzer_state = HIGH;
    } else {
        buzzer_state = LOW;
        buzzer_remaining--;
    }
    digitalWrite(buzzer, buzzer_state);
    buzzer_last_toggle = now;
}

```

I resisted the temptation to put all this inside a class. It would be cleaner, but I think this “plain C” style of programming might be easier on a newcomer.

Note that calling `buzzer_start()` when the program is already buzzing has no effect: the request to start the buzzer is ignored. This is not the only possible choice: one could instead want to reset the counter in order for the buzzing to last longer. The choice I made is arbitrary, and I only made it because, in your question, the program requirements are not fully specified.

---
Tags: millis, buzzer, delay
---


# Question
Title: Code to display binary value from 1 hall sensor A3144 connected with shift register 74HC165 when magnet is brought near to it or taken away?
I have checked my connections and when I bring a magnet close to the hall sensors the voltage on them which is apprx. 4.5V becomes 0V and when I remove the magnet the sensor turns back to 4.5V. This means that all the hall sensors are responding to the magnets which makes my connections alright. I want to get 0 when magnet is brought closer to the sensor and 1 when taken away.

The below code shows 11111111 continuously and does not get affected even if magnet is brought close or taken away. I expected the code to show 00000000 until magnet is brought closer to any sensor. If magnet is brought closer to 1st sensor, it should have shown 10000000 and so forth.

```
int load = 7;
int clockEnablePin = 4;
int dataIn = 5;
int clockIn = 6;

void setup() {
Serial.begin(9600);
pinMode(load, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockIn, OUTPUT);
pinMode(dataIn, INPUT);
digitalWrite(clockEnablePin, LOW);
digitalWrite(clockIn, LOW);
}

void loop() {

//Write pulse to load pin
digitalWrite(load, LOW);
digitalWrite(load, HIGH);

//Get data from 74HC165
byte incoming = shiftIn(dataIn, clockIn, LSBFIRST);

// Print to serial monitor
Serial.print("Pin States: \r\n");
Serial.println(incoming, BIN);
delay(200);
}

uint8_t shiftIn(uint8_t dataIn, uint8_t clockIn, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i)
{
 digitalWrite(clockIn, HIGH);
 if (bitOrder == LSBFIRST)
 {
  value |= digitalRead(dataIn) << i;
 }
 else
 {
  value |= digitalRead(dataIn) << (7 - i);
 }
 digitalWrite(clockIn, LOW);
}
return value;
}

```

---

The code as well as the schematic is correct. The problem was with shift register. Thank you everyone for your suggestions.

# Answer
The connections are correct in the above diagram. I have had a terrible experience with non working shift register. Some 74HC165 don't work properly(might be duplicate). So, try buying from a verified store.

Use this code to get HIGH or LOW value as output. You can change them to 1 or 0 as per your requirement.

I used this code and it works perfect with 8 Hall switches connected to one shift register 74HC165. Don't forget to connect your pins with your Arduino Uno as depicted in the code or you can update your code as per your connections of shift register with Arduino Uno. You can increase the number of inputs by adding more shift register 74HC165 to the circuit & also you just need to update the value of number of shift chips in the below code.

```
/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS   1

/* Width of data (how many ext lines).
*/
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC   5

/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC   1

/* You will need to change the "int" to "long" If the
 * NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned int

int ploadPin        = 7;  // Connects to Parallel load pin the 165
int clockEnablePin  = 4;  // Connects to Clock Enable pin the 165
int dataPin         = 5; // Connects to the Q7 pin the 165
int clockPin        = 6; // Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
 * serial Data from the shift register chips and representing
 * the state of those pins in an unsigned integer (or long).
*/
BYTES_VAL_T read_shift_regs()
{
    long bitVal;
    BYTES_VAL_T bytesVal = 0;

    /* Trigger a parallel Load to latch the state of the data lines,
    */
    digitalWrite(clockEnablePin, HIGH);
    digitalWrite(ploadPin, LOW);
    delayMicroseconds(PULSE_WIDTH_USEC);
    digitalWrite(ploadPin, HIGH);
    digitalWrite(clockEnablePin, LOW);

    /* Loop to read each bit value from the serial out line
     * of the SN74HC165N.
    */
    for(int i = 0; i < DATA_WIDTH; i++)
    {
        bitVal = digitalRead(dataPin);

        /* Set the corresponding bit in bytesVal.
        */
        bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

        /* Pulse the Clock (rising edge shifts the next bit).
        */
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(clockPin, LOW);
    }

    return(bytesVal);
}

/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
    Serial.print("Pin States:\r\n");

    for(int i = 0; i < DATA_WIDTH; i++)
    {
        Serial.print("  Pin-");
        Serial.print(i);
        Serial.print(": ");

        if((pinValues >> i) & 1)
            Serial.print("HIGH");
        else
            Serial.print("LOW");

        Serial.print("\r\n");
    }

    Serial.print("\r\n");
}

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

    /* Initialize our digital pins...
    */
    pinMode(ploadPin, OUTPUT);
    pinMode(clockEnablePin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, INPUT);

    digitalWrite(clockPin, LOW);
    digitalWrite(ploadPin, HIGH);

    /* Read in and display the pin states at startup.
    */
    pinValues = read_shift_regs();
    display_pin_values();
    oldPinValues = pinValues;
}

void loop()
{
    /* Read the state of all zones.
    */
    pinValues = read_shift_regs();

    /* If there was a chage in state, display which ones changed.
    */
    if(pinValues != oldPinValues)
    {
        Serial.print("*Pin value change detected*\r\n");
        display_pin_values();
        oldPinValues = pinValues;
    }

    delay(POLL_DELAY_MSEC);
}

```
> 1 votes

# Answer
Preset your clockIn and clockEnablePin pins to LOW in the setup function. Do not manipulate them in the loop function. You do not need to use the delayMicroseconds() functions because the 74HC165 is a great deal faster than Arduino read/write functions.
> 0 votes

---
Tags: arduino-ide
---


title: Using Random() and Greater Than

text:
# Question
Title: Using Random() and Greater Than
Total Arduino noob, I come from a Python "background", though I barely know that, either.

I'm writing a super simple script that will turn on a bulb when the random number generator generates a number greater than 100. Obviously, I have a syntax problem or something: What am I doing wrong? Secondly, How quickly does `random` query numbers? Is it possible to slow it down? I don't need my bulb turning on 50 times a second.

Thanks! And please be kind; I know this is Googleable, I just lack the prerequisite knowledge to Google this efficiently.

<pre><code>/*

*/
int relayPin = 7;
int randomNumber = random(1001);

void setup() {
  pinMode(relayPin, OUTPUT);

}

void loop() {

if(randomNumber > 100)
  digitalWrite(relayPin, LOW);

else{
   digitalWrite(relayPin, HIGH);}

}```
</code></pre>

# Answer
There are a few things to be discussed in here.

First, the random number generation: in fact, the arduino **does not** generate random numbers. It has a list of numbers on its memory that just "seems" to be random. That's why it's called a pseudo-random number. So, you need to declare a starting point on this sequence, from which you will get the "random" numbers. This is made with "randomSeed()" in void setup. For example:

```
void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point,
                             //in this case, the analogRead value of an unconnected pin
}

```

Next, let's generate our number. The variable can be global (as you declared it outside any function), but **you must declare it with "random()" only inside "void loop"**. Otherwise, its value will be assigned just one time (that's what your code is telling it, to do it once).

Here is what I would do:

```
int relayPin = 7;
long randomNumber; //just declares the variable; it must be type "long"

void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
  pinMode(relayPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  randomNumber = random(0, 301);
  //each time the code loops, it assings another value to randomNumber
  //in this case, the number will be between 0 and 300 (301 is the excluded limit)

  if(randomNumber > 100){
    digitalWrite(relayPin, HIGH);
  }
  else{
    digitalWrite(relayPin, LOW);
  }
  delay(500); //half a second delay

}

```

If you want to have more details about how random numbers are generated in the Arduino, visit the Arduino language Reference: https://www.arduino.cc/reference/en/
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: 1 global variable consuming 19% of memory
I am working on a simple project on talking to the serial monitor, and my only global variable ("int" type, named "incomingByte") is consuming a lot of memory. There is no problem on running the scketch, but I am not satisfied to have it that way.

When I load it, I receive: "Global variables use 390 bytes (19%) of dinamic memory...". Why is it happening, and how could I fix this?

```
int incomingByte = 0; //for the incoming serial data
void setup() {
  // put your setup code here, to run once:
  randomSeed(analogRead(0)); //starts the pseudo-random sequence in a random point
  Serial.begin(9600);
  //waits for serial initialization to send the messages:
  //(Serial) returns false for serial off, and true for serial on. This is inverted with !.
  while(!Serial){
    ;
  }
  //sending instructions:
  Serial.println("Initializing...");
  Serial.println(" ");
  delay(2000);
  Serial.println("Please select an option:");
  Serial.println("1 - greetings");
  Serial.println("2 - random number");
  Serial.println("3 - calculator");
  Serial.println(" ");
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available() > 0){
    incomingByte = Serial.read(); // Serial.read() returns the first byte of incoming data

    //recognizing the command received:
    if (incomingByte == '1'){
      numberOne();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
    if (incomingByte == '2'){
      numberTwo();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
    if (incomingByte == '3'){
      numberThree();
      delay(1500);
      Serial.println("Waiting; choose another option");
      Serial.println(" ");
    }
  }
}

void numberOne() {
  Serial.println("Hello, Vitor! Good to see you!");
}

void numberTwo() {
  //sets the random number to be picked between [0, 101[
  long randomNum = random(0, 101);
  Serial.print("Your random number is: ");
  Serial.println(randomNum, DEC);
}

void numberThree(){
  Serial.println("Tool not available yet");
}

```

# Answer
A few things that count towards the “global variables” that you may not think of:

* all your literal strings, unless encapsulated within the `F()` macro; you have quite a few of them
* The `Serial` object, including its transmit and receive buffers (157 bytes on an Uno)
* The vtable for `HardwareSerial` (that's the class `Serial` belongs to, 18 bytes)
* The time-keeping variables (9 bytes).

And then, on top of that, there are the actual global variables of your code, and the static locals which, for the purpose of memory allocation, are the same as globals. An `int`, for example, takes 2 bytes on AVR and 4 bytes on most other hardware platforms.

---

**Edit**: answering the questions in a comment

> every single time I call `Serial` it will increase the memory consumption of the code?

I don't quite understand what you mean by “every time”:

* Every time you add a reference to `Serial` to a sketch, the linker will add the `Serial` object to your compiled code, and the program's RAM consumption will grow by the size of this object.
* Within a single sketch, whether `Serial` is used once or many times makes no difference: the object will be instantiated only once.

> why does the IDE considers everything that uses RAM as a global variable?

When it says “global variables” it actually means “statically allocated data”. It says “global variables” because it is targeted at beginners, and the authors assume beginners would not understand what static allocation means. Globals are the simplest form of static allocation.

> is there a difference in consumption between globals and locals?

Yes. Globals get allocated statically, i.e. at compile time. That's why the IDE can report how much space they will consume. Locals (at least non-static locals) get allocated and deallocated on the stack, at run time. Short of running the program in an emulator, it is very hard to predict how much stack space a program will consume, as this will usually depend on run-time events.
> 7 votes

---
Tags: variables, memory-usage, memory
---


title: How to swap byte order

text:
# Question
Title: How to swap byte order
**Background**

I'm reading a 24-bit ADC value into a uint32. Using SPI bus, here's the logic:

```
value = SPI.transfer(0);   // read first 8 bits (MSB first)
value <<= 8;               // shift bits left
value |= SPI.transfer(0);  // read next 8 bits
value <<= 8;               // shift bits left
value |= SPI.transfer(0);  // read final 8 bits

```

As such I'm left with this ADC reading:

```
00000000 11111111 11111111 11111111
         MSB                    LSB

```

(Ignore the leading zeros for now.)

Now I transfer this value over ethernet like so:

```
client.write((const byte*) &value, sizeof(value));

```

The problem is this:

* The value is stored as MS **bit** first.
* client.write() transmits it LS **byte** first.

I am using NodeRED as a TCP server. So at the other end, I receive the data like this:

```
11111111 11111111 11111111 00000000
     LSB          MSB

```

I understand this is the expected behavior, but I would like to switch the BYTE order around before sending, so that it is read in NodeRed native endianness.

---

**Question**

Perhaps I should do some bit shifting at the point of reading the ADC, to accommodate the fact that client.write() sends the least significant byte first, like this:

```
  byte1 = SPI.transfer(0);
  byte2 = SPI.transfer(0);
  byte3 = SPI.transfer(0);
  response = byte3;
  response <<= 8;
  response = byte2;
  response <<= 8;
  response = byte1;

```

Is this the most efficient way in terms of clock cycles?

Please note that my MCU is a Teensy 4.1, and I'm transferring 10,000 readings per second. I would like to keep the clock cycles for any necessary bitwise operations to a minimum, so that the timing of ADC readings are affected as little as possible.

# Answer
> 2 votes
You can use an array of `byte` to save the shifts at all. This solution should be the one with the least clock cycles, and with no additional memory usage.

```
static byte value[4] = { 0 };

    /* ... */

    /* value[0] is still 0. */
    value[1] = SPI.transfer(0);
    value[2] = SPI.transfer(0);
    value[3] = SPI.transfer(0);

    client.write(value, sizeof value);

```

Some notes:

1. Using an array avoids the re-interpretation of a 32 bit variable as a byte array. You read bytes from SPI, and `write()` expects a byte array. This circumvents your endianness issue completely.
2. In the call of `write()` you don't need to cast the address of `value` to `const byte *`, because the `const` is a qualifier *for the called function*. It is not allowed to change the bytes pointed to.
3. Making the array static saves you from zeroing the first byte repeatedly. BTW, it is sufficient to provide the first byte, as all other bytes are zeroed automatically. However, the last bytes will be updated on each transfer.
4. `sizeof` is an operator, not a function. However, it is quite common to use it with a type instead of an object, and then you need parentheses because of the syntax. But it is better to use the respective object, actually you mean that.

# Answer
> -1 votes
```
// reverse wire order:
client.write((const byte*) &value + 3, 1);
client.write((const byte*) &value + 2, 1);
client.write((const byte*) &value + 1, 1);
client.write((const byte*) &value,     1);

```

---
Tags: code-optimization, byte-order
---


# Question
Title: M5Stack - confused about I2C bus voltage
I've recently got one of these nice M5-Though devices (basically a water-proof M5-Core2). They have these 4-wire sockets to connect their sensors. The I2C socket has 4 pins for +5V, GND, SDA and SCL. According to the schematics (bottom of page), the SDA and SCL lines are directly connected to the GPIO pins of the ESP32. That means that most sensors connected to this socket will run the I2C bus at 5V. Even their own sensors (example) have pull-ups to 5V on the SDA and SCL lines.

Isn't this going to fry the ESP32? Different sources say that it's inputs are *not* 5V tolerant. So far, I always used the 3.3V line to power external sensors from the ESP32 (or added a level shifter).

# Answer
> 1 votes
No, it's not going to "fry" the ESP32, and here's why:

Yes, there are pullups to 5V. Those are 4.7K in your example. The IO pins are connected to 3.3V through ESD diodes. That means that any voltage over and above 3.3V plus the forward voltage of those diodes will be "diverted" away from the IO pin through the diode. IO pins have these ESD diodes built in, but this board has extra external ones added to make it more rugged.

These ESD diodes can handle a finite amount of current flowing through them - the internal ones only a small amount, but the external ones much more.

The 5V will only be a low current because it is connected with a resistor. We can even do some maths here.

Assuming the ESD diodes have a 0.3V forward voltage (as is reasonably typical) we can say that the voltage across the diode will be 5V - 3.3V - 0.3V = 1.4V.

With a 4.7K resistor as a pullup the current through the diode will be 1.4V / 4700 = 298 microamps.

That's way below the limit you'd expect of a small internal ESD diode, let alone a larger external one.

The "frying" of an IO pin happens when too much current flows through the ESD diode and it blows, "failing short", causing the IO pin to be locked in either a HIGH or LOW state for the rest of eternity. Since the current is nowhere near the kind of levels needed for that it's not going to even remotely stress the diodes, and the inclusion of external diodes makes it even safer.

---
Tags: esp32, voltage-level, m5stack
---