# Question
Title: Digital pin output voltage drops when driving a relay
I'm trying to trigger eight different 5 V relays using an Arduino Atmega 2560. The relays (70Ω coil) are powered by an external 5 V source, and I'm trying to trigger them through a driving stage which contains for each relay an NPN transistor (2N3904) and a 1 kΩ resistor directly connected to digital pin of the Arduino.

The relays in my application are supposed to be driven 2 by 2, not all of them at once.

My problem is that I don't succeed in triggering the relay with digital pins of my Arduino; once I connect it to the resistor, the voltage of the digital pins drops from 5 V to 0.4 V or less. The transistor needs only 7 mA to be triggered, the output current of the Atmega2560 pins is 20 mA max.

I tried with an external 5 V source, it triggers correctly showing 10 mA maximum of current through the driving stage.

# Answer
> 1 votes
Your circuit will no longer work. The original transistor you used was a NPN, you have changed it to a PNP connected somehow as a low side driver. It is important to show the emitter, as it tells us what type of transistor it is, leaving it out as you have done causes many of us to assume you have done it correctly ie the emitter is connected to the ground. Here is a Copy of a circuit from electronics-tutorials that uses a simple MOSFET: https://www.electronics-tutorials.ws/blog/relay-switch-circuit.html Note the 10K resistor from the port pin to ground, that guarantees it will be off during reset and setup.

# Answer
> 0 votes
If the coil is 70 ohms and it's driven by 5V, it should draw about 5/70 = 71 mA. That's pushing the 2n3904 a bit hard, and doesn't even account for inductive effects. (It's a small-signal transistor.) Do you have an NPN power transistor to try, just as a test? If its current gain (beta) is too low, use a Darlington configuration by combining it with your 2n3904. (2n3904 base from digital out resistor, emitter drives power NPN base directly, both collectors are connected together to the bottom of the coil, and the power NPN emitter is the effective emitter of the just-created "super transistor" with high beta and power handling.) Be sure to use an anti-kickback rectifier (1n4001)across the relay coil.

# Answer
> 0 votes
Good Job, you are right on, the transistor is rated at 200 mA which is adequate for the job. The flyback diode will protect your system and the transistor. the drain source drop would be maybe 0.01V on a bad day depending on the RDSon. You will probably need a little lower value base resistor depending on the gain of your transistor. I would use something between 220 and 510 ohm. It should work fine. Using a darlington would hurt you instead of the ~.7 volts drop across the collector it would become about 1.4 volts, leaving the relay with 3.6V assuming you are actually getting 5V. My preference would be a small logic level avalanche rated MOSFET. Use a 50 Ohm resistor in the gate circuit and it will be just fine. Use something like a 10K pull down resistor between the gate and source, that will guarantee that it will be off during reset.

---
Tags: arduino-mega, relay
---


# Question
Title: Is there accurate connection procedure for connection between an esp32 and ultrasonic sensor(HC-SR04)?
I am currently working on a project which integrates esp32 and HC-SR04 and send the data from HC-SR04 to my own domain. The connection diagram is this  And the code which I use is this,

```
const int trigPin = 5;
const int echoPin = 18;
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701

long duration;
float distanceCm;
float distanceInch;

void setup() {
 Serial.begin(115200); // Starts the serial communication
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}

void loop() {
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);

 distanceCm = duration * SOUND_SPEED/2;

 distanceInch = distanceCm * CM_TO_INCH;

 Serial.print("Distance (cm): ");
 Serial.println(distanceCm);
 Serial.print("Distance (inch): ");
 Serial.println(distanceInch);

 delay(1000);
}

```

But the module doesn't give out the distance. Can anyone suggest a better method for connection. Thanks in advance!

# Answer
Suriya,

You aren't crazy - it appears the ESP32 GPIO pins (at least the ones I tested) won't drive the HC-04 sonar sensor trigger pin sufficiently high to trigger a sonar pulse. I tested the NewPingExample.pde code example from the NewPing library's 'example' folder on both a MEGA2560 and a ESP32\_DevKitC\_V4. The MEGA implementation worked right off the bat, but I never could get the ESP module to work. So, I took a look at the Trigger/Echo pin (by default the NewPing.h file uses the 'Single Pin' mode, so you have to make sure the TRIGGER\_PIN and ECHO\_PIN defines use the same pin). The two scope traces below are from the MEGA2560 and the ESP32. As you can see, the ESP32 output only goes to 1.865V - not high enough to actually trigger the device. The MEGA implementation output goes to over 3V and consistently triggers the echo (the big rectangle to the right of the narrow trigger signal).

You might want to try using the STMicro VL53L0X time-of-flight LIDAR chip instead - it is much smaller, uses less current, and doesn't suffer from self-interference if you plan to use more than one sensor. See this post on my blog site for some ideas
> 1 votes

---
Tags: esp8266, arduino-ide, sensors, esp32, project
---


# Question
Title: How I can populate a buffer from data read from SPI?
I have wired a Macronix MX35LF1GE4AB Flash memory into an arduino Uno using Logic Level Shifters. What I try to do with it is to dump its contents.

In order to do so, I am implementing the following sketch:

```
#include <SPI.h>

#define LASTBLOCK 1023
#define LASTPAGE 63
#define LASTBYTE 2111

#define PAGE_READ 13h
#define PAGE_READ_CACHE_SEQUENCIAL 03h
#define READ_FROM_CACHE 3Bh
#define PAGE_READ_CACHE_END 3Fh

#define BUFFER_LEN 2111

int page_to_read = 1;
int block_to_read = 1;

// We store each page to Microcontroiller's ram
byte buffer[BUFFER_LEN];

void setup() {
 SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
// Serial.begin(9600);
}

void loop() {

  // I need to reset the counts before reading any block
  if(page_to_read > LASTPAGE){
    page_to_read = 1;
    block_to_read ++;

  }

  if(block_to_read > LASTBLOCK){
    return ;
  }

  if(page_to_read == LASTPAGE){
     SPI.transfer(PAGE_READ_CACHE_END);
  } else if (page_to_read == 1) {
     SPI.transfer(PAGE_READ);
     SPI.transfer(PAGE_READ_CACHE_SEQUENCIAL);
  }

  SPI.transfer(READ_FROM_CACHE);

  page_to_read++;
}

```

Now what I want is to populate the buffer `byte buffer[BUFFER_LEN]` with data, so I can send them over a serial port.

How I can achieve that?

# Answer
> 1 votes
> ```
> #define BUFFER_LEN 2111
> byte buffer[BUFFER_LEN];
>
> ```

That will definitely not work because the Uno has 2048 bytes of RAM, some of which are needed by the system. The serial buffers, for example, are 64 bytes each.

---
Tags: arduino-uno, spi, flash
---


title: Alternatives to Radio Transceivers

text:
# Question
Title: Alternatives to Radio Transceivers
So i am creating a haunt project that needs a way of detecting when an Arduino passes it and makes that Arduino do something. the problem I'm having is that none of the transmitter and receiver that has a small enough range that won't interfere with other patrons walking through on the other side of the wall. does anyone have any ideas what i can use?

# Answer
> 1 votes
There is a discussion of a similar question at the Arduino forum where they leaned towards passive UHF RFID tags.

If your budget stretches to it, there would be a range of active RFID tags that might suit.

There’s a good intro to RFID at Sparkfun, and Wikipedia has a good starting reference point.

---
Tags: arduino-uno
---


# Question
Title: How do I fix my code so that it reads text from the serial monitor?
I have created a code that should print out "Enter true to deactivate alarm" in the serial monitor, then store the user's answer and print "alarm off" if they enter true and "alarm on" otherwise. However, it is returning "alarm on" every time, even if I enter true. Here is my code:

```
String deactivate = "";
void setup() {
  Serial.println("Enter \"true\" to deactivate alarm");
}
void loop() {
  while (Serial.available() == 0){}
  deactivate = Serial.readString();
  if (deactivate.equals("true"))
  {
    Serial.println("alarm off");
  }
  else
  {
    Serial.println("alarm on");
  }
}

```

Any help here would be greatly appreciated, I'm new to Arduino and we've been stuck on this step for weeks; I am just really at a loss trying to figure out why it isn't working.

# Answer
You didn't set the `Serial` port:

```
Serial.begin(9600);

```

Add this in the `setup` function. Also check in your serial monitor if the speeds are equal.

If this still doesn't work, print the `deactivate` variable after assigning, and its length, and every character to see if it adds a newline character or any other unexpected character.

Then if it is a whitespace character, use a function to strip the whitespace, or change the comparison.
> 1 votes

# Answer
Often is the case coders will add "debugging" print statements to aid in understanding what is occurring in their code. Printing out what you received may help in understanding unexpected results.

That said, consider using Serial.readStringUntil() in place of Serial.readString(). From the linked to page:

> Returns
>
> The entire String read from the serial buffer, up to the terminator character
> 1 votes

---
Tags: serial, string, input
---


# Question
Title: Can I power up an Arduino Uno via the 5 V pin while USB is connected at the same time?
I want to use Grbl to control a diy CNC machine. I need to communicate with the CNC using Grbl and this is done via the PC's USB port.

So the PC's USB port is connected to the Arduino Uno which is connected to the shield and the shield and Arduino are powered from an external 5 V power source.

Can someone advise me if this is a power conflict (all grounds are common)?

# Answer
Powering from the 5V pin and USB at the same time should be avoided. This is because the circuit that controls the power from the USB is triggered from the VIN / barrel jack and needs to be above about 6.5V to cause the USB power to be isolated.

It won't damage your Arduino, but there is a chance that your computer may be unhappy and shut the USB port down. 5V shouldn't cause any damage though, but it may detect that something isn't quite as it should be and take steps to protect itself.

One possible "fix" is to take any suitable disposable USB cable and strip some of the plastic outer casing from it (a couple of inches should do the job) and spread out the wire and foil shielding (assuming it exists). Locate the red wire and cut it. Join the red wires together again through a diode (ideally Schottky to reduce voltage drop) with the anode towards the computer and the cathode (stripe) towards the Arduino. This will isolate any reverse power while still providing the USB 5V to the USB interface chip's VBUS pin.
> 2 votes

---
Tags: arduino-uno, power, usb
---


# Question
Title: How to fix HC05 burning even after while using voltage regulator?
I'm using two circuits for my wireless head mouse project, one of them is a transmitter circuit with Arduino Pro Micro, HC05 Bluetooth module, Elechouse Voice Recognition Module V3.1, GY-521 module based on the MPU6050 sensor. The receiver circuit (Arduino Pro Micro + HC05 Bluetooth) will receive the sensor readings from the transmitter circuit. Both modules were powered by USB from the laptop initially. They worked fine. To make the transmitter circuit completely detached from the laptop, I used a 9V battery, and a voltage regulator of 5V. The receiver circuit was still c. I should mention that I was using voltage dividers for both of the transmitter, and receiver circuit's HC05 Bluetooth modules. onnected to the laptop USB.

. After using the voltage regulator, the module was working fine but suddenly the HC-05 burnt, led stopped working. Transmission failed. HC05 of the receiver module also burnt after 2 minutes. Why did this happen? What's the solution?

Circuit connection: Hc05 connection same for transmitter & receiver circuit HC05 Tx -\> Arduino Rx Hc 05 rx -\> 2k ohm -\> gnd Hc05 rx -\> 1k ohm -\> hc05 tx Hc05 vcc -\> arduino 5v Hc05 gnd -\> arduino gnd

Voice Recognition Module tx -\> arduino 8 Rx -\> Arduino 9 Vcc- 5v Gnd - gnd

Mpu6050 sda - Arduino 2 Scl- Arduino 3 Vcc - 5V Gnd- Gnd

Voltage regulator connection: The connection was 9V battery +ve to input, -ve to ground, output to Arduino 5V

# Answer
> 1 votes
Your voltage divider pins are backwards the HC05 RX pin needs the divider, not the TX pin. Its tx would be 3.3v out and the arduino pin wouldn't care it would still work.

Most likely while you were testing before the HC05 was probably already slowly dying.

the HC05 has a very basic 3.3v regulator on board but only a little over 5V input can fry things. I have always put 75-100ohm in series with the 5V in just in case.

Your circuit is basically good but the the RX/TX pins on the HC05 need reversing. Analog V. regulators are fairly crude and will vary voltage some.

5.000v accuracy is never dead on. I have seen as high as 5.7V out and that would not be good.

Also the HC05 RX pin is receiving a 5V signal back, sourcing thru the HC05 chip.

Even the Arduino help site warns against 5V if it can be avoided.

from Arduino's site https://create.arduino.cc/projecthub/electropeak/getting-started-with-hc-05-bluetooth-module-arduino-e0ca81

```
Sending Data to Arduino via Bluetooth
HC05 module has an internal 3.3v regulator and that is why you can connect it to 5v voltage. But we strongly recommend 3.3V voltage, since the logic of HC05 serial communication pins is 3.3V. Supplying 5V to the module can cause damage to the module.

```

# Answer
> 0 votes
You said "I should mention that I was using voltage dividers for both of the transmitter, and receiver circuit's HC05 Bluetooth modules."

Voltage dividers are not a good way to lower voltage for power components. The voltage output will vary based on load, and they also dissipate the excess voltage as heat, so you need high current resistors.

Post a schematic of your system with the specific batteries, regulators etc that you are using.

---
Tags: power, mpu6050, hc-05, arduino-pro-micro
---


# Question
Title: String type replace function can't replace with no char
I want to replace the ":"(colon) in the MAC address with no char (remove the ":").

But I can't find any good solution.

String.replace(), can't replace with (void).

**Note: String.replace(':',(char)0)** *//also doesn't work*

String.remove() is ugly and requires that you know exactly where each iteration is (indexOf()), and this method doesn't return anything, it updates the string directly so you have to call : String.remove() for each occurence.

and String.substring() has most of the same problems as remove, except that it does return the substring, so you can do: String.substring(i,l).substring(i2,l)...

```
#include <WiFi.h>
String MAC;
char ssid[] = "WiFi SSID"
char psw[] = "WiFi PSW"
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  WiFi.begin(ssid,psw);
  MAC = WiFi.macAddress();
}

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

  Serial.println("MAC Address unformatted")
  Serial.println(MAC);
  String MAC_f = MAC.replace(':', ' ');
  // Now print the MAC without the ":"
  Serial.println(MAC_f);
  // This replaces the ':' with a space.  I want to replace(remove) the ':' with no char
  // Looking for an elegant, simple, 1 liner to accomplish this.

  /* This looks horrible */
  MAC_f = MAC.substring(0,2)+MAC.substring(3, 5)+MAC.substring(6, 8)+MAC.substring(9, 11)+MAC.substring(12, 14)+MAC.substring(15, 17);
  /* .remove also looks terrible */
  MAC_f = MAC;
  MAC_f.remove(2,1);
  MAC_f.remove(2,1);
  // ...

}

```

# Answer
> 3 votes
Don´t use `String()` manipulations inside `loop()`. It causes heap fragmentation and program failure. Use a char array instead:

```
char MAC[18] = "01:23:45:67:89:AB"; // including terminating zero

for (int src = 0, dst = 0; src < sizeof(MAC); src++)
   if (MAC[src] != ':') MAC[dst++] = MAC[src];

```

# Answer
> 3 votes
As stated by Mat, the empty string in C++ is `""`. This works:

```
MAC_f = MAC;
MAC_f.replace(":", "");

```

That being said, I concur with SBF's answer: `String` object are not friendly with the Arduino's memory. SBF's solution is better than `String::replace()`.

# Answer
> 0 votes
others a right that String is not totally Arduino friendly, WiFi.macAddress() returns String, SO

though written for ESP32 this is an approach i used

```
 // Get the station interface MAC address.
 // @return String MAC, no camas
String getMacAddress(void)
{
    WiFi.mode(WIFI_AP_STA);   // required to read NVR before WiFi.begin()
    uint8_t baseMac[6];
    esp_read_mac( baseMac, ESP_MAC_WIFI_STA );  // Get MAC address for WiFi station
    char macStr[18] = { 0 };
    sprintf(macStr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
    return String(macStr);
}
// END getMacAddress()

```

---
Tags: string
---


# Question
Title: What GSM module I should use for HttpClient, ArduinoHttpClient, WebSockets etc.?
I need to use some API in my project. So I'm gonna use such libraries as listed in the title? What GSM/SIM module do I need for this purpose? I've checked 800L and similar - it only can use plain http, and only via AT command. At least based on this, that's not what I really need. Thanks in advance.

# Answer
> 1 votes
The TinyGSM library implements the Arduino Client class required by networking super libraries you mention in the question.

TinyGSM supports the SIM800 modems.

---
Tags: gsm, http
---


title: why is my char array empty

text:
# Question
Title: why is my char array empty
following sketch will run totally fine and as expected :

```
#include <Wire.h>

#include "SparkFun_External_EEPROM.h"
ExternalEEPROM ExtEEPROM;
char username[33] = "";
char password[65] = "";

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Wire.begin();
  #define EEPROM_ADDRESS 0b1011000 // 0x58
  ExtEEPROM.setMemorySize(256000/8); // 256kbit = 32kbyte
  ExtEEPROM.setPageSize(64); // 64 byte page size.
  ExtEEPROM.enablePollForWriteComplete();
  ExtEEPROM.setPageWriteTime(10); // max. ms for AT24C128
  if (ExtEEPROM.begin(EEPROM_ADDRESS, Wire) == false)
  {
    Serial.println("No memory detected. Freezing.");
    while (1);
  }
  Serial.println("Memory detected!");

  String uuu = "myusername";
  String ppp = "mypassword";

  uuu.toCharArray(username, sizeof(username) - 1);
  ppp.toCharArray(password, sizeof(password) - 1);
  Serial.print("password=");Serial.println(password);
  ExtEEPROM.put(0, username);
  //delay(100);
  ExtEEPROM.put(0 + sizeof(username), "greatnewpassword");
}

void loop() {
  char xxx[33] = "";
  ExtEEPROM.get(0, xxx);
  Serial.print("xxx=");Serial.println(xxx); // prints the username

  char yyy[33] = "";
  ExtEEPROM.get(0 + sizeof(username), yyy);
  Serial.print("yyy=");Serial.println(yyy); // prints the password
  delay(1000);
}

```

However, if I replace `ExtEEPROM.put(0 + sizeof(username), "greatnewpassword");` to `ExtEEPROM.put(0 + sizeof(username), password);`, then `yyy` prints empty in the serial monitor. Why?

# Answer
problem seems to be the lib I am using. I think it can not handle data overlapping page size.

if I replace from this

```
char username[33] = "";
char password[65] = "";

```

to this:

```
char username[16] = "";
char password[16] = "";

```

everything works fine as it saves and reads from the EEPROM via I2C.
> 1 votes

# Answer
As Majenko already mentions:

> .get() and .put() should only be used for atomic, self-contained, types like int or float, not pointers like char \*.

Not sure what atomic means here, but you may .put and .get any data type, especially a struct.

```
struct EPROMData {
  char username[33];
  char password[65];
};
EPROMData data {"myusername","mypassword"};

void setup() {
   ...
   ExtEEPROM.put(0,data);
}
void loop() {
   EPROMData d;
   ExtEEPROM.get(0,d);
   Serial.print("user="); Serial.println(d.username);
   ...
}

```

Sure, if the data type is a pointer or a String object (containing a pointer only), you won't be happy with .put / .get
> 2 votes

# Answer
`.get` and `.put` are being passed a char pointer, not the contents of a char array. Thus you're not writing the content of the string but the address in memory where it's being stored.

With a string literal that is fixed and never changes, so what you write and what you read are fine. With a variable though the address could be anything, and storing the address of some RAM where a string is stored is pointless.

`.get()` and `.put()` should only be used for atomic, self-contained, types like `int` or `float`, not pointers like `char *`.

Instead you need to be using the `.read(address, buffer, size)` and `.write(address, buffer, size)` functions to read and write the contents of your char arrays.
> 1 votes

---
Tags: esp8266, c++, eeprom
---


# Question
Title: How exactly do Bicycle LEDs work? (Arduino Project)
Table of contents:

1. What I want to achieve
2. Problem I'm facing
3. What I've tried
4. Possible Hypotheses

What I want to achieve

Hi guys, I’m working on a DIY LED Light project to install on my bicycle, where I want to re-create how the actual LED bicycle lights work:

\[Stage 1\] Press button once: LED lights up forever until button is pressed again \[Stage 2\] Press button twice: LED blinks forever until button is pressed again \[Stage 3\] Press button thrice: LED turns off (goes back to original state)

Problem I’m facing

After a bit of research, I know how to work out the code for \[Stage 1\] (by tracking the current and previous button states.) But I’m unable to make \[Stage 2\] happen.

What I’ve tried

I’ve tried to instead of tracking the previous and current button states, why not use a counter, i.e:

Counter = 0 (initial) When button is pressed once, Counter = 1 (LED lights up forever until button is pressed again)

When button is pressed one more time, Counter = 2 (LED blinks forever until button is pressed again)

When button is pressed one more time, Counter = 3 (LED switches off, goes back to original LOW state) Counter resets to = 0 again

This is my code below:

```
const int ledPin = 8;
const int buttonPin = 7;

int buttonState;
int ledState;
int counter = 0;
int newcounter;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    newcounter = counter + 1;
    delay(500);
    if (newcounter != counter) {
      switch (newcounter) {
        case 1:
            digitalWrite(ledPin, LOW);
            counter = newcounter;
            break;
        case 2:
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            digitalWrite(ledPin, LOW);
            delay(500);
            digitalWrite(ledPin, HIGH);
            delay(500);
            break;
        case 3:
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;
        default:
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;
      }
    }
  }
}

```

Possible Hypotheses (Please criticise/correct me if I’m wrong)

A) There is a problem with my code (my programming logic etc)

B) Maybe its not a code/program problem? It could be due to the design of the electric circuit (because I’ve seen videos on YouTube where LEDs can be made to blink using capacitors and transistors. But how does the sequence from Stages 1 to 3 happen in a bicycle LED light? (https://www.youtube.com/watch?v=cXCExzIBNsA)

I’ll be eternally grateful if anyone will be able to help! Thank you!!

# Answer
> 1 votes
you are not stating what results you are getting.

I do see you are not presetting your state variables.
This is always good practice to avoid random startup conditions.

you have logic that will only run when the button is held your if (newcounter != counter) and switch statement only run while the button is pressed. move them outside of the button state check and look to change things ONLY if the button changed.

try this; it will only act on button change not continiously so changes only happen on each press

i will leave you to play with the switch conditions

```
const int ledPin = 8;
const int buttonPin = 7;

int buttonState, chngButtonState = 0;
int ledState;
int counter = 0;
int newcounter;

void setup() {
  chngButtonState = buttonState;
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  digitalWrite(ledPin, HIGH);
}

void loop() {
      buttonState = digitalRead(buttonPin);
      if (buttonState == HIGH && !buttonState == chngButtonState ) {     // read once only if changed button state changed not on every loop
        newcounter = counter + 1;
        delay(500);
        chngButtonState = buttonState;      // mae them equal again
        }                // NOTE I moved 1 of the } from the bottom

        if (newcounter != counter) {
          switch (newcounter) {
            case 1:
                digitalWrite(ledPin, LOW);
                counter = newcounter;
                break;
            case 2:
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                digitalWrite(ledPin, LOW);
                delay(500);
                digitalWrite(ledPin, HIGH);
                delay(500);
                break;
            case 3:
                digitalWrite(ledPin, HIGH);
                counter = 0;
                break;
            default:
                digitalWrite(ledPin, HIGH);
                counter = 0;
                break;
          }
        }
    }

```

now just play with the Switch statements to get your results.

**pinMode(buttonPin, INPUT);**

your button wiring is not clear.

Likely, you have the button connected to VCC and pin 7. You still should have a pulldown resistor from the arduino pin7 to GND to get reliable states.

However; if the button is from a pin7 to GND and no pullup the state will also not change.

If so; change **pinMode(buttonPin, INPUT);** to **pinMode(buttonPin, INPUT\_PULLUP);** and no external pullup resistor is needed.

# Answer
> 0 votes
Think of the "stages" you identified as states or modes of operation, and the button presses cycle between the stages.

Then for "stage 2", you re-write it as a function that doesn't mostly block and idle for 3.5 seconds, but that immediately returns control back to the `loop()` so you can check for more button presses quickly:

```
// this function is patterned after the example in
// https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
void stage2(void){
  const unsigned long interval = 500;
  static unsigned long last = 0;
  if(millis() - last >= interval){
    last += interval;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}

```

and then you switch on stage in the event loop:

```
      switch (stage) {
        case 0: // idle
            break;
        case 1: // on
            digitalWrite(ledPin, LOW);
            counter = newcounter;
            break;
        case 2: // blinking
            stage2();
            break;
        case 3: // turn off
            digitalWrite(ledPin, HIGH);
            stage = 0;
            break;
        default:
            digitalWrite(ledPin, HIGH);
            counter = 0;
            break;
      }
      ...

```

This switch-case takes almost no time, and returns control to the event loop, so the user interface can respond quickly to other button presses, or check for other tasks.

I didn't re-write the rest of your code, but these are the key differences between your code and what's running in a bike light:

1. Use state variables and state machines to change the mode of operation.
2. Avoid trapping the processor in "blocking" code that uses delays(), for(;;), while();, etc... Depend instead on the event loop (`loop()` in the Arduino), to return control to your functions.

There is a simulation of a Bike Light using these coding patterns on Wokwi at https://wokwi.com/arduino/projects/325075981102482003

---
Tags: led
---


# Question
Title: How to combine servo shield with peristaltic pump?
I am creating a project where I need 16+ (possibly up to 20) servos to open/close liquid flow through tubing, which in turn will be controlled by a peristaltic liquid pump (https://www.adafruit.com/product/1150). Since the adafruit servo shield (https://www.adafruit.com/product/1411) gives you access to 16 servos per shield, it seems like the obvious option. However, this shield wont be able to drive a peristaltic pump. I've been told I can put a adafruit servo shield on top of a adafruit motor shield (https://www.adafruit.com/product/1438), but is this really the most effective way to build this project? I want to have a system that is as compact and cheap as possible, using already-available electronics (although I suppose one option is to build a shield myself, but having not done that before it would take me a very long time).

I am quite new to arduino and its accessories, so I apologise if this is a very simple question.

Best, N

# Answer
nn123,

Never apologize for asking the simple questions! The only reason I've learned in my life is for asking these kinds of questions. We all have to start somewhere, and should never be embarrassed for what we don't know. The key is being willing to learn and ask for help.

Here's a simple solution to your problem.

The shield is a great idea for you to use. It's very simple to wire (it plugs in :), you have power management system on the shield, and you can control the entire thing with I2C. So I'd definitely stick with that.

In order to drive a DC motor (pump), all you need is a sort of low power MOSFET to power this. You can look up thousands of tutorials on how to power a motor with an Arduino. Here is one for reference.

If you don't want to buy individual components and perfboard to construct your own circuit, you can buy a motor driver from Adafruit just like this one. Remember Adafruit always gives you incredibly good instructions for all their products if you're ever stuck.

This board is perfect for powering low-power motors. Your pump only pulls a maximum of 300mA at 12V, and that shield can do up to 3.6A peak (probably more like 2A continuous). The shield is also a H-bridge, which means you can power the motor forwards & backwards (not sure if this is useful to you).

To hook up the motor driver all you would need is 2 digital pin PWM pins (like 5&6) to control it forward/backwards.

Comment if you have any questions and good luck with the project!
> 1 votes

---
Tags: motor, servo, shields, adafruit
---


# Question
Title: Wind speed measuring using Hall effect Anemometer
I need your help regarding a problem I am facing while measuring wind speed. In my sketch I get a reading every 20 counts which the magnet goes past the sensor. I need to change it in order to get a reading every 20 seconds. How can I do it with minimum changes to the sketch?

```
volatile byte revolutions;

float 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 >= 20) {
    //Update RPM every 20 counts, increase this for better RPM resolution,
    //decrease for faster update

    // calculate the revolutions per milli(second)
    rpmilli = ((float)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 * 0.6597 * 3600;

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

void rpm_fun()
{
  revolutions++;
}

```

# Answer
You can use the `millis()` function to measure time intervals and do things regularly in these intervals. Refer to the `BlinkWithoutDelay` example, that comes with the Arduino IDE, or to one of the many tutorials for the `millis()` function on the web.

Basically you will need to do the following:

1. Declare a timestamp variable to hold the time when the data was displayed last time (in global scope):

```
 unsigned long timestamp = 0;

```
2. Declare the interval, that you want the display to happen in:

```
 #define DISPLAY_INTERVAL  20000

```
3. In your if statement check if the time difference between now and the timestamp is bigger than the interval

```
 if(millis() - timestamp > DISPLAY_INTERVAL){

```

Note that you should do `millis()` comparisons always this way (by calculating the difference), so that the rollover of `millis()` will not affect the result.
> 2 votes

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


title: Esp32: is OTA compatible with FREERTOS

text:
# Question
Title: Esp32: is OTA compatible with FREERTOS
Can I use OTA along with FreeRTOS tasks on ESP32. I ask this because in the following example OTA seems to be enabled if FreeRTOS is disabled. Can for example upload firmware that runs on both cores over OTA? Example taken from OTA template project by Andrea's Speiss

# Answer
You can't *not* use FreeRTOS. The whole ESP-IDF is based around it. The Arduino `setup()` and `loop()` run in their own FreeRTOS thread.

If you "turn off" FreeRTOS then nothing will work.

Whatever that "template" is from it's of no use to you.
> 1 votes

# Answer
I was also believing that it is not possible but I handle it thanks to this post below;

https://github.com/SensorsIot/ESP32-OTA/issues/8

I applied what ever shared and it works like a charm together both FreeRTOS and OTA features.

As summary you need to create 2 custom header which includes your wifi credentials and OTA function. The remaining is same mostly.

credentials.h

```
#pragma once
const char* mySSID = "SSID of your AP";
const char* myPASSWORD = "Password of your AP";

```

OTA.h

```
#ifdef ESP32
#include <WiFi.h>
#include <ESPmDNS.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#endif

#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#if defined(ESP32_RTOS) && defined(ESP32)
void ota_handle( void * parameter ) {
  for (;;) {
    ArduinoOTA.handle();
    delay(3500);
  }
}
#endif

void setupOTA(const char* nameprefix, const char* ssid, const char* password) {
  // Configure the hostname
  uint16_t maxlen = strlen(nameprefix) + 7;
  char *fullhostname = new char[maxlen];
  uint8_t mac[6];
  WiFi.macAddress(mac);
  snprintf(fullhostname, maxlen, "%s-%02x%02x%02x", nameprefix, mac[3], mac[4], mac[5]);
  ArduinoOTA.setHostname(fullhostname);
  delete[] fullhostname;

  // Configure and start the WiFi station
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  // Wait for connection
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // Port defaults to 3232
  // ArduinoOTA.setPort(3232);

  // No authentication by default
  // ArduinoOTA.setPassword("admin");

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });

  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });

  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });

  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("\nAuth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("\nBegin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("\nConnect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("\nReceive Failed");
    else if (error == OTA_END_ERROR) Serial.println("\nEnd Failed");
  });

  ArduinoOTA.begin();

  Serial.println("OTA Initialized");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

#if defined(ESP32_RTOS) && defined(ESP32)
  xTaskCreate(
    ota_handle,          /* Task function. */
    "OTA_HANDLE",        /* String with name of task. */
    10000,            /* Stack size in bytes. */
    NULL,             /* Parameter passed as input of the task */
    1,                /* Priority of the task. */
    NULL);            /* Task handle. */
#endif
}

```

OTA Template sketch.ino

```
#define ESP32_RTOS  // Uncomment this line if you want to use the code with freertos only on the ESP32
                    // Has to be done before including "OTA.h"

#include "OTA.h"
#include "credentials.h"

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");

  setupOTA("TemplateSketch", mySSID, myPASSWORD);

  // Your setup code
  /*  Example
  pinMode(2, OUTPUT);
  */
}

void loop() {
#ifdef defined(ESP32_RTOS) && defined(ESP32)
#else
  ArduinoOTA.handle();
#endif

  // Your code here
  /* Example
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  delay(1000);
  */
}

```
> 1 votes

---
Tags: esp32, ota
---


# Question
Title: 'MeDCMotor' does not name a type error inside mBlock
I was using a 3rd party programming enviroment, mBlock 3.4.5 for making C++ Arduino programmes with a graphical programming language. I was compiling a program and the following eroor came up.

```
project_Untitled0_0.ino:65:1: error: 'MeDCMotor' does not name a type
project_Untitled0_0.ino:66:1: error: 'MeDCMotor' does not name a type
project_Untitled0_0.ino: In function 'void move(int, int)':
project_Untitled0_0.ino:85:7: error: 'motor_9' was not declared in this scope
project_Untitled0_0.ino:85:24: error: 'M1' was not declared in this scope
project_Untitled0_0.ino:86:7: error: 'motor_10' was not declared in this scope
'MeDCMotor' does not name a type

```

I took another look at the program and there were some lines of code that seem they are added in the program by deafult:

```
MeDCMotor motor_9(9);
MeDCMotor motor_10(10);
void move(int direction, int speed)
{
      int leftSpeed = 0;
      int rightSpeed = 0;
      if(direction == 1){
            leftSpeed = speed;
            rightSpeed = speed;
      }else if(direction == 2){
            leftSpeed = -speed;
            rightSpeed = -speed;
      }else if(direction == 3){
            leftSpeed = -speed;
            rightSpeed = speed;
      }else if(direction == 4){
            leftSpeed = speed;
            rightSpeed = -speed;
      }
      motor_9.run((9)==M1?-(leftSpeed):(leftSpeed));
      motor_10.run((10)==M1?-(rightSpeed):(rightSpeed));
}

```

Since the program does not recognise the MeDCMotor class the program failed to upload.

I am running Windows 10 home edition on a 64-bit laptop.

Is there a way to remove the lines of code that prevent me from uploading the sketch or are there other ways to solve it?

# Answer
> 1 votes
I looked at some entries in a google search for *error: 'MeDCMotor' does not name a type*, such as , ,  and . The first three of those latter four links directly address the question you ask, and none of them answer it clearly, except to suggest re-downloading or re-installing the makeblock library. While the fourth link addresses a “does not name a type” error for another library, rather than for makeblock, it has a relatively clear explanation of the problem for that other library:

> So, as supplied, the ArduinoByteBuffer.zip file had a complex set of sub-directories, and the two files ByteBuffer.ccp and ByteBuffer.h were located one level down in: \ArduinoByteBuffers\ByteBuffer\
>
> When I 'installed' the library, it went into the directory:
>
> > C:\Documents and Settings\Al\My Documents\Arduino\libraries\ArduinoByteBuffers\ByteBuffer\ByteBuffer.ccp C:\Documents and Settings\Al\My Documents\Arduino\libraries\ArduinoByteBuffers\ByteBuffer\ByteBuffer.h
>
> To solve the problem I moved them up a level to:
>
> > C:\Documents and Settings\Al\My Documents\Arduino\libraries\ArduinoByteBuffers\ByteBuffer.ccp C:\Documents and Settings\Al\My Documents\Arduino\libraries\ArduinoByteBuffers\ByteBuffer.h
>
> That seemed to be the key - moving the two files (\*.ccp and \*.h) out of the subdirectory.

Instead of following ordinary C or C++ library-finding rules, the Arduino IDE copies sets of files into a temporary directory according to its own rules when compiling a sketch. You'll need to move your makeblock library files around to match up with Arduino IDE conventions.

# Answer
> 1 votes
In the MakeBlock, menu "choice of extensions", uncheck all the extensions, keeping only the one called "Makeblock" checked:

---
Tags: programming, arduino-ide, sketch
---


title: Communicate with Sparkfun CAN Bus Shied

text:
# Question
Title: Communicate with Sparkfun CAN Bus Shied
i have a Arduino Mega 2560 R3 and a Sparkfun CAN Bus Shied. Im using the SparkFun\_CAN-Bus\_Arduino\_Library-master. I want to communicate over SPI (they have diffrent SPI pins), so i had to change it in defaults.h Changes:

#define P\_MOSI B,2 // new pin: 51, orginal: #define P\_MOSI B,3

#define P\_MISO B,3 // new pin :50, orginal: #define P\_MISO B,4

#define P\_SCK B,1 // new pin :52, orginal: #define P\_SCK B,5

#define MCP2515\_CS B,0 // new pin:53, orginal: #define MCP2515\_CS B,2

i connected the pins:

Arduino Mega Pin - Sparkfun pin

51 - 11

50 - 12

52 - 13

53 - 10

also connected: 5v, gnd, rst, (pin 2)
Before i realized that spi pins are diffrent, the can init from demos dont worked. After changes, init worked but e.g. CAN\_Write\_Demo i can not see the data in PCAN-View. There is nothing.

I read that PCAN-View is not compatible with my lib so i try the MCP\_CAN\_lib-master, same problem. I also tried it with Vector CAN, with both libraries same problem.

Why can't I see the messages?

I also tried other demos e.g. CAN\_Read\_Demo and sent a can message with PCAN-View but get nothing.

When i run write demos, it dousnt even send anything and when i run read demos e.g. sending from PCAN-View, status from PCAN-View changes instant to BUSHEAVY.

Thank you for helping.

# Answer
CAN will not send messages into the ether. It must have another node to acknowledge the message. That node needs to be configured for the same bit rate. I use the MCP-CAN\_lib-master by Cory Fowler and it works great. You can try the following and if it does not work I would suggest you start with two UNOs and two MPC2515 and get them to work first, the send and receive code is in the examples included with the library. Be careful there are at least three different crystals on the MPC2515 boards, select the correct one. Also be sure the bus is terminated on both ends, that should simply adding a jumper to the CAN module. Hopefully the bus is several feet long, I have heard of problems with short buses although I have never experienced it. Another hint be sure the grounds for all modules are connected. I know that is not necessary but makes getting it started much easier. Also start with something in the 125/250 Kbit rate.
> 0 votes

---
Tags: arduino-mega, spi, can-bus
---


# Question
Title: Looking for help with an improved vibration sensing method for Arduino
I am trying to test how vibration waves move through different material...ie how sensitive certain components are. I am needing a vibration sensor that will send me back some kind of measurement say in the form of an integer between 1 and (a number).

I have tried the 801S with an Arduino board and it was successful. The problem though is it just returns a 1 for vibration and 0 for none. To get the results I had to keep retesting and moving the material further and further away to get it to fail.

I also tried a HiLetgo piezoelectric analog sensor. It does return a number...but the results are all over the place...from 5 to 250. I have a device that supplies a consistent "tap" to be measured...so the HiLetgo had to be letgo.

I did research SE and found this question Vibration sensor for arduino but it does not answer my question.

# Answer
I did some experiments a year or so ago to sense vibration through a (physical) office desk top using the inbuilt accelerometer and gyroscope of an Arduino Uno Wi-Fi Rev2. That chip is an LSM6DSM but I would think that any such module (e.g., MPU6050) connected to any Arduino could be useful.

There’s a good comparison article at Seeed Studios introducing vibration sensors for Arduino.

Update. Looking at the similar question linked by the OP I see several comments that the MPU6050 which I suggested would have poor resolution. You may have to study data sheets (or experiment) to find the best device for your purpose.

Second update. This white paper, “Measuring vibration with accelerometers” has some good engineering notes about selecting suitable accelerometers for different purposes.
> 1 votes

---
Tags: sensors
---


# Question
Title: Cannot read values stored in bool* pointer
I'm trying to read values stored in a bool\* pointer from a modbus coil call.

I'm using modbus-esp8266 library. it's all ok with Input Registers and Holding Registers but i cannot read the result of a coil read.

```
#include <ModbusRTU.h>
#include <SoftwareSerial.h>

SoftwareSerial S(D2, D1);
ModbusRTU mb;

bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors
  if (event != Modbus::EX_SUCCESS) {
    Serial.print("Error result: 0x");
    Serial.print(event, HEX);
  }
  return true;
}

void setup() {
  Serial.begin(115200);
  S.begin(9600, SWSERIAL_8N1);
  mb.begin(&S);
  mb.master();
}

void loop() {
bool* coils;
  if (!mb.slave()) {    // Check if no transaction in progress
    mb.readCoil(1, 1, coils, 1, cb); // Send Read Hreg from Modbus Server
    while(mb.slave()) { // Check if transaction is active
      mb.task();
      delay(10);
    }
    Serial.println(*coils);

  }
  delay(1000);
}

```

I get this kind of error when trying to print \*coils

```
Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads

```

How to get the boolean result value from it?

# Answer
When programming an Arduino you are actually writing in the language C. As such you can search the internet for C programming answers of which there is likely 50 years of answers.

You have defined "coils" as a pointer. This is done by preceding the name with an asterisk where it is defined. In this line of code:

```
bool* coils;

```

This means you are using coils to store the memory location of where the actual value is to be stored. However, in the case of the code in the posted question, the memory location of where the actual value is to be stored is never defined.

*This is like going on a bad clue hut. You receive instructions to obtain the next clue at a specific location. But when you get there you find no further instructions.*

Beginning programmers often find pointers confusing. But later find pointers very useful tools that simplify many otherwise complex programs.

Consider dropping the asterisk in front of "coils" on the two lines of code where is exists and try running the program again.

---

Added later:

Guessing, it may be that the call to readCoil function assumed to be defined in ModbusRTU.h requires a pointer to be passed to in as the 3rd formal variable parameter. This is more advanced C programming. If true, then keep your original code but add a line of code setting the value of "coils" to the address of a new bool variable. Perhaps something along these lines:

```
bool* coils;
bool coils_value;
coils = &coils_value;

```
> 0 votes

---
Tags: pointer, modbus
---


# Question
Title: Pulsein() function blocks other tasks from running silmultaneously
I am using a zumo bot with a reflectance sensor used to follow a black line. I want to use an arduino to make the zumo bot stop once it gets a certain distance from an obstacle.

I have an ultrasonic sensor (HC-SR04) which ive connected to the bot.

Both of these tasks work independently but once i merge the code together(so it follows the line aswell as stoping when it detects an object using the ultrasonic sensor), it doesn't work properly.. (the zumo bot no longer follows the line)

I THINK it is to do with the pulsein() function blocking any other tasks but not sure.

My code is below. Can anyone help please?

```

#include <Wire.h>
#include <ZumoShield.h>

ZumoBuzzer buzzer;
ZumoReflectanceSensorArray reflectanceSensors;
ZumoMotors motors;
Pushbutton button(ZUMO_BUTTON);
int lastError = 0;

// This is the maximum speed the motors will be allowed to turn.
// (400 lets the motors go at top speed; decrease to impose a speed limit)
const int MAX_SPEED = 400;
#define echoPin A4
#define trigPin A5

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

void setup()
{
  reflectanceSensors.init();

  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT

  // Initialize the reflectance sensors module

  // Wait for the user button to be pressed and released
  button.waitForButton();

  // Turn on LED to indicate we are in calibration mode
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);

  // Wait 1 second and then begin automatic sensor calibration
  // by rotating in place to sweep the sensors over the line
  delay(1000);
  int i;
  for(i = 0; i < 80; i++)
  {
    if ((i > 10 && i <= 30) || (i > 50 && i <= 70))
      motors.setSpeeds(-200, 200);
    else
      motors.setSpeeds(200, -200);
    reflectanceSensors.calibrate();

    // Since our counter runs to 80, the total delay will be
    // 80*20 = 1600 ms.
    delay(20);
  }
  motors.setSpeeds(0,0);

  // Turn off LED to indicate we are through with calibration
  digitalWrite(13, LOW);

  // Wait for the user button to be pressed and released
  button.waitForButton();

  Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed
  Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
  Serial.println("with Arduino UNO R3");

}

void loop()
{

  unsigned int sensors[6];

  // Get the position of the line.  Note that we *must* provide the "sensors"
  // argument to readLine() here, even though we are not interested in the
  // individual sensor readings
  int position = reflectanceSensors.readLine(sensors);

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Our "error" is how far we are away from the center of the line, which
  // corresponds to position 2500.
  int error = position - 2500;

  // Get motor speed difference using proportional and derivative PID terms
  // (the integral term is generally not very useful for line following).
  // Here we are using a proportional constant of 1/4 and a derivative
  // constant of 6, which should work decently for many Zumo motor choices.

  int speedDifference = error / 4 + 6 * (error - lastError);

  lastError = error;

  // Get individual motor speeds.  The sign of speedDifference
  // determines if the robot turns left or right.
  int m1Speed = MAX_SPEED + speedDifference;
  int m2Speed = MAX_SPEED - speedDifference;

  if (m1Speed < 0)
    m1Speed = 0;
  if (m2Speed < 0)
    m2Speed = 0;
  if (m1Speed > MAX_SPEED)
    m1Speed = MAX_SPEED;
  if (m2Speed > MAX_SPEED)
    m2Speed = MAX_SPEED;

  motors.setSpeeds(m1Speed, m2Speed);

  //if (distance <20){
  //  motors.setSpeeds(0,0);
 // }

////////////////////////////////////////////

  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  // Displays the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

}

```

# Answer
It is quite likely due to blocking. The description of the `pulseIn()` function in the Arduino site's reference section says:

> Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go from LOW to HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds or gives up and returns 0 if no complete pulse was received within the timeout.

If you can limit the range within which you want to stop the vehicle, try setting a timeout on `pulseIn()` that will return control once the maximum sound travel time has passed. Maybe that will give you enough response to correct the vehicle's steering. Slowing the vehicle's velocity will help, too (it won't be able deviate as far from it's path as quickly).

Otherwise, you'll probably need a non-blocking equivalent to `pulseIn()`.
> 5 votes

---
Tags: arduino-uno, sensors, robotics, pulsein
---


title: Per-Arduino calibration files?

text:
# Question
Title: Per-Arduino calibration files?
I am planning on having an array of embedded devices in my garden, and each of these is going to have its own analog moisture sensor. Each moisture sensor needs to be individually calibrated.

In an ideal world, I would have the same software on each embedded device, with a configuration file holding the calibration for the attached analog moisture sensor, so that I can minimize the development and CI/CD work.

Is this possible with Arduino, or would I be better off with an embedded device with addressable flash, like an ESP32?

# Answer
As Edgar Bonet already mentioned, the embedded EEPROM is good to try. I give some options below though:

* In case the configuration file (data) is max. 1 KB, you can use the embedded/internal EEPROM of the Arduino UNO.
* In case the configuration file is larger you have multiple options:
    + On the ESP32 you can use 4 KB EEPROM.
    + If it is higher, on the ESP32 you also can use the SPIFFS file system stored in EEPROM.
    + For other MCUs (ESP32 included), you can use external EEPROM with various sizes, based on SPI or I2C.
* If you want to use a very large configuration file, you could use an SD card, which is much slower of course, which is normally SPI based and can be used on both Arduino and ESP32.

So for a comparison between Arduino Uno / ESP32

```
MCU         Solution            Speed Size   External    Wearout
                                             Hardware
----------- ------------------  ----- ------ -------- --------------
Arduino     Internal EEPROM     High  1 KB      No    EEPROM Wearout
ESP32       EEPROM Simulation   High  4 KB      No    Flash Wearout

ESP32       SPIFFS File System  High  <Flash    No    Flash Wearout
                                      Size

Both        External EEPROM     High  <1MB *   Yes    EEPROM Wearout
Both        SD Card             Slow  <256GB   Yes          -

```

\*Typically 4 KB to 1 MB, using SPI or I2C
> 5 votes

---
Tags: analog, calibration
---


# Question
Title: How can I SPI "Latch" (LE/CS/SS) for a specific number of SCLK cycles?
## Context

I am working on a project which includes 13 cascaded STMicroelectronics LED1642GWs. These LED drivers are essentially 16bit shift registers, whereby the buffered serial data can be loaded to a number of different registers dependant on the required function.

The function is selected through the use of "digital keys", which is selected by number of CLK cycles for which the LE (CS/SS) pin is HIGH. For example, LE being HIGH for 1-2 CLK cycles will switch the 16 outputs as per the buffered bits, whereas LE being HIGH for 3-4 CLK cycles will load the 16 bits to a brightness register.

## Question

How can I toggle my LE/CS/SS pin for a specific number of SCLK cycles? I had intended to use the SPI Libary, however I'm not sure this can be supported.

**Many Thanks!**

# Answer
I've achieve this by "bit-banging" via a modified `shiftOut()` of ArduinoCore-avr/cores/arduino/wiring\_shift.c, essentially allowing for two data lines on the same clocking:

```
void keyedShiftOut(
  uint8_t dataPin,
  uint8_t clockPin,
  uint8_t latchPin,
  uint8_t bitOrder,
  uint16_t val,
  uint16_t key)
{
    uint8_t i;

    for (i = 0; i < 16; i++)  {
        if (bitOrder == LSBFIRST) {
            digitalWrite(dataPin, val & 1);
            val >>= 1;
            digitalWrite(latchPin, key & 1);
            key >>= 1;
        } else {
            digitalWrite(dataPin, (val & 0x8000) != 0);
            val <<= 1;
            digitalWrite(latchPin, (key & 0x8000) != 0);
            key <<= 1;
        }

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

```

I used this to implement the sequence described within the data sheet (Figure 24. Brightness register setting) to set all of my 16 Brightness Registers to a half setting (0x7FFF) with a timed LE providing the digital key. This scoped out as:

Running on my Arduino Nano 33 IoT this clocked at 150kHz which is sufficient for my application.
> 4 votes

---
Tags: spi, shift-register, timing
---


title: sim800l ftp error after http request

text:
# Question
Title: sim800l ftp error after http request
I am using esp32 CAM by Arduino IDE and send an image file by ftp using SIM800l GSM/GPRS module to a server and every thing is ok .
I can perform http request also and read some data from a website and every thing is ok.

Problem is ftp for large file and http request can not work at the same time . if I send AT+HTTPINIT after AT+FTPEXTPUT=1 , it fails or if I send AT+FTPEXTPUT=1 after AT+HTTPINIT again it fails .

I close http connection by AT+SAPBR=0,1 but problem exist

How to solve this problem? How is possible to clear the setting done in the the sim800l without restarting the module by AT+CFUN=1,1 ?

# Answer
I found the way to solve the problem .
Http request must be terminated with command AT+HTTPTERM . After this command large ftp works and command AT+FTPEXTPUT=1 is without error . After termination of ftp if we want to do http request again the command AT+FTPEXTPUT=0 must be executed
> 1 votes

---
Tags: arduino-uno, esp32, sim800
---


# Question
Title: VSCode vs. Arduino IDE - same program, different behavior
I've got this simple program for testing DS18B20 temperature sensors.

```
#include "OneWire.h"
#include "DallasTemperature.h"

#define ONE_WIRE_BUS D3

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup()
{
  Serial.begin(19200);
  sensors.begin();
  delay(1000);  //time for serial to connect
  Serial.print(sensors.getDeviceCount());
  Serial.println(" sensors found");
  Serial.print(sensors.getDS18Count());
  Serial.println(" DS18 sensors found");
}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures

  Serial.print("Temperature for Device 1 is: ");
  Serial.println(sensors.getTempFByIndex(0));

  Serial.print("Temperature for Device 2 is: ");
  Serial.println(sensors.getTempFByIndex(1));

  delay(5000);

}

```

I'm compiling for the Wemos D1 mini. When I compile on the Arduino IDE, the code runs as expected. It reports two devices, then gives the temperature reading from each device. When I compile using VSCode and the Arduino extension, the code compiles and uploads successfully, the program reports 2 devices, just like the Arduino IDE compilation does, but then it prints -196.60 for the temperature reading, which is the "no device" value.

Same breadboard, same host computer - the only difference is the IDE. I'd much prefer to stick with VSCode, but if the resulting executable is wrong, then it's a non-starter.

Why the different results? More importantly, how do I get the VSCode to produce the same (correct) output as the Arduino IDE?

UPDATE: Apparently the issue has something to do with the serial monitor. The project I'm actually trying to build has an OLED display for the temperature. The temperature is correct if the VSCode serial monitor is closed. Open the monitor and the incorrect values appears. Close the monitor and the correct values appear again.

UPDATE 2: The problem remains over a range of serial port speeds, from 19200 to 115200. I didn't try outside that range.

UPDATE 3: Code compiled using VSCode but run observing through the Arduino IDE serial monitor has the correct behavior - ie, shows the correct temperatures.

# Answer
> 3 votes
Further testing by OP isolated a bug in the Arduino Extension for VSCode which was logged as an issue at https://github.com/microsoft/vscode-arduino/issues/1467

---
Tags: arduino-ide, ds18b20, vscode
---


# Question
Title: LiquidCrystal issue with HD44780 display
Here my sample code for an Arduino Leonardo-based custom board:

```
#include <LiquidCrystal.h>

const int rs = 3, en = 0, d4 = 4, d5 = 30, d6 = 12, d7 = 6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup()
{
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);

  Serial.begin(115200);

  lcd.begin(16, 2);
  lcd.print("Hello world");
}

void loop()
{
}

```

And here my schematic:

The MCU is an ATmega32U4. Running the code above the display is completely empty, I also tried to change the values of R4 and R5 but nothing changes. I don't see anything, not even the background of each character.

The display is a common HD44780 compatible one.

I retrieved the pin numbers from here:

> /opt/arduino-1.8.19/hardware/arduino/avr/variants/leonardo/pins\_arduino.h

Am I missing anything?

# Answer
The error is, that V0 has VDD level by the way you connected the resistors. The "lower end" of your ladder needs to be at GND, pin 1.

The pin 15 (A) is the anode of the backlight, and is not connected to the LCD driver circuit. BTW, to lit the backlight, you need to connect pin 16 (K), too. See the data sheet for details.

Use a potentiometer for V0, wiper to V0 and the ends to VDD and GND, respectively.

Just a side note: From the back of my memory, V0 can be commonly connected by a single resistor or directly to GND, since the wiper of the potentiometer was mostly at the GND end. It will give *some* contrast, depending on the temperature.
> 3 votes

---
Tags: lcd, arduino-leonardo, display
---


# Question
Title: How do I modify the value of a variable when I press a switch
I am new to arduino and I want to make a project where I have a motor spinning clockwise then when a button is pressed it spins anti-clockwise and if it is pressed again it goes back to clockwise etc... Unfortunately I am having trouble getting this to work. How I was aiming to make it work was to have a variable and whenever a button is pressed the value of that variable changes from HIGH to LOW to HIGH and so on and based on that variable the motor spins in either direction. I have got this code so far:

```
const int buttonPin = 8;     // the number of the pushbutton pin

// variables will change:
int buttonState = 0;         //variable to change status

void setup() {

 Serial.begin(9600);
 pinMode(buttonPin, INPUT);
}

void loop() {
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
 Serial.print("Digital value: ");
 Serial.println(buttonState);
 delay(150);
}

```

# Answer
You've made a good start by first working with the button by itself (no motor) to keep your experiments simple. You've probably noticed that buttonState changes when you press *or* release the button, where your description says you want it to change each time you *press* the button. That means you have to ignore the releases, and invert the buttonState only on the presses.

Make that change next.

When you test that, you may discover that the buttonState changes several times when you press it once. Mechanical switches may make/break... several times at each change. (It's called bouncing even though it isn't "bouncing" but the two contacts grating across one another. The result is the same.) There are several ways to deal with that, but the simplest is to wait 20-30 milli-seconds after you first see a change; read it again, and if it is still in the new state, accept that, otherwise ignore it. That time delay is approximate; you might need to adjust it for a particular button.

Once you've decided that the button really has been pressed, then change the direction of the motor.
> 2 votes

# Answer
I would recommend that you "debounce" the button input first. Instead of re-inventing the wheel, you could use an existing library: Bounce2.

Using the conditioned input, you could simply manipulate a counter to determine state.

```
// Connect one end of a N.O. push button switch to
// GND and the other end to pin 2 of the Arduino.
#include <Bounce2.h>
byte buttonState = 0;
const byte modeButtonPin = 2;
const unsigned long debouncerInterval = 50;  // Time in ms.

Bounce modeButton = Bounce();

void setup(){
  Serial.begin(9600);
  pinMode(modeButtonPin, INPUT_PULLUP);
  modeButton.attach(modeButtonPin);
  modeButton.interval(debouncerInterval);
}

void loop(){
  if(modeButton.update()){
    if(modeButton.read() == 0){
      buttonState++;
      if(buttonState > 1){buttonState = 0;}
      Serial.println(buttonState);
    }
  }
}

```
> 1 votes

# Answer
First I would make create an enumeration type and motor direction variable (instead of the button state):

```
enum EMotorDirection
{
    CLOCK_WISE,
    COUNTER_CLOCK_WISE
}

EMotorDirection _motorDirection = CLOCK_WISE;

```

Then read the button and when it has changed (make a variable \`\_previousButtonState), adjust the motor direction.

```
int _previousButtonState = LOW;

```

In the `loop` function:

```
int buttonState = digitalRead(buttonPin);
// Debounce buttonState;
if (buttonState != _previousButtonState)
{
   if (_motorDirection == CLOCK_WISE)
   {
       _motorDirection = COUNTER_CLOCK_WISE;
   }
   else
   {
       _motorDirection = CLOCK_WISE;
   }
   SwitchMotorDirection();

   _previousButtonState = buttonState;
}

```

And create the function `SwitchMotorDirection`

```
void SwitchMotorDirection()
{
   if (_motorDirection == CLOCK_WISE)
   {
       // Control motor clock wise
   }
   else
   {
       // Control motor counter clock wise
   }
}

```

The above example is not compiled, and also it could be smaller, but serves as a explanatory example, with the advantage to separate the UI (button), state machine (state variable), and hardware (motor).

Below is the complete code, which compiles. The bouncing has to be implemented (check the link for that above), and the actual motor driving.

```
// Types

enum EMotorDirection
{
    CLOCK_WISE,
    COUNTER_CLOCK_WISE
};

// Constants
const int _buttonPin = 8;     // the number of the pushbutton pin

// Global variables
int             _previousButtonState = LOW;
EMotorDirection _motorDirection      = CLOCK_WISE;

// Function prototypes
void SwitchMotorDirection();

// Functions

void setup()
{
  Serial.begin(9600);
  pinMode(_buttonPin, INPUT);
}

void loop()
{
  int buttonState = digitalRead(_buttonPin);
  // Debounce buttonState;
  if (buttonState != _previousButtonState)
  {
     if (_motorDirection == CLOCK_WISE)
     {
         _motorDirection = COUNTER_CLOCK_WISE;
     }
     else
     {
         _motorDirection = CLOCK_WISE;
     }
     SwitchMotorDirection();

     _previousButtonState = buttonState;
  }
}

void SwitchMotorDirection()
{
   if (_motorDirection == CLOCK_WISE)
   {
       // Control motor clock wise
   }
   else
   {
       // Control motor counter clock wise
   }
}

```
> 0 votes

---
Tags: button, variables
---


# Question
Title: Servo keeps resetting position when there is no difference in received value?
So I'm working on a code that basically receives x and y coordinates and stores them in a variable. Whenever a coordinate is received, it goes through a conditional statement to store them in a variable, x and y, then passes it to a servo mover function. This servo motor function then moves according to what's given. It works well, **but**, as the values get updated over time, the servo' position always resets then goes back to where it was, again and again. Even when the coordinates are kept the same, it just resets then returns to its position over and over again.

How do I make it so that not only **does it not** reset then return to where it was but instead make it move to where it is supposed to go, but also to stop it from resetting anyway when the position is kept the same?

The below code is what I tried to do to basically alleviate the "position reset when coordinate is the same" issue. Unfortunately, it did not work.

```
bool constant = false;
// Rest of code inbetween, irrelevant to issue

// Relevant codes below
void statusCodes() {
  if (received_str == "1") {
    Serial.println("Raspberry Pi - Connection Established");
  } else if (received_str == "2") {
    Serial.println("Raspberry Pi - Data Received");
  } else if (received_str == "100") {
    Serial.println("Raspberry Pi - Status OK");
  } else if (received_str[0] == '(' ) {
    Serial.println("Coordinates Received, Ready to Delete Target!");
    if (constant == true) { // checks if this constant boolean is true
      movement = false;
    } else {
      movement == true;
    }
    int r = sscanf(received_str.c_str(), "(%d, %d)", &x, &y);
    Serial.print("X: ");
    Serial.println(x);
    Serial.print("Y: ");
    Serial.println(y);
  }
}

void onDetectTarget() {
  x = map(x, 0, 1023, 0, 180);
  y = map(y, 0, 1023, 0, 180);
  if (movement == true) {
    for (pos = 0; pos <= x; pos += 1) {
      myservo.write(pos);
      delay(15);
    }
    movement = false; // corrected
    pos = 0; // corrected

  }
}

void compareOldNew() {
  x_old = x;
  y_old = y;
  delay(900);
  if (x == x_old && y == y_old) {
    constant = true;
  } else {
    constant = false;
  }
}

```

# Answer
In `onDetectTarget()` you use this for loop

```
for (pos = 0; pos <= x; pos += 1) {
  myservo.write(pos);
  delay(15);
}

```

So every time `movement` is true, the servo will run again from zero to the target position. So it won't "reset", but it will approach the new target value always from the zero position. You have two options to correct that:

* If you just want to reach the target position, just replace the for loop with a single `myservo.write(x)`.
* If you want the servo to move slower to its new target position, you need to save the last set position of the servo in a variable and then run the for loop from that value up to the new target value. So declare a corresponding variable (for example on global scope):

```
  int current_pos = 0;

```

Then run the for loop from that position to the new target position:

```
  for(pos = current_pos; pos <= x; pos += 1)

```

And after the for loop you can set `current_pos` to the new servo position:

```
  current_pos = x;

```

And I guess this happens also, when the values don't change, because you never change the `constant` variable. You haven't implemented any check if the values are constant. (At least you haven't shown such a code and you claim the rest of the code is irrelevant)
> 3 votes

---
Tags: arduino-ide, arduino-nano, i2c, motor, servo
---


# Question
Title: Can't type backslash (\) with Keyboard library
I'm trying to make a macro keyboard, where I can press a single button and it will open programs for me.

I'm trying to type this, for example: "c:\windows"

but it gets typed out like this: cÑ}windows

I tried using double backslash (\\), but it still isn't working

```
#include <HID-Project.h>
#include <HID-Settings.h>

#include <Keypad.h>

#define L_ALT KEY_LEFT_ALT
#define TAB KEY_TAB
#define WIN KEY_LEFT_GUI
#define ENTER KEY_RETURN

const byte FILAS = 4;
const byte COLUMNAS = 4;
//define the cymbols on the buttons of the keypads
char Keys[FILAS][COLUMNAS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte pinesFilas[FILAS] = {9, 8, 7, 6};
byte pinesColumnas[COLUMNAS] = {5, 4, 3, 2};

char TECLA;

Keypad teclado = Keypad( makeKeymap(Keys), pinesFilas, pinesColumnas, FILAS, COLUMNAS);

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

void loop() {
  TECLA = teclado.getKey();

  if (TECLA) {

    switch (TECLA) {
      case '1':
        Serial.print("Tecla 1 presionada");
        break;
      case '2':
        Serial.print("Tecla 2 presionada");
        break;
      case '3':
        Serial.print("Tecla 3 presionada");
        break;
      case 'A':
        Serial.print("Tecla A presionada");

        break;
      case '4':
        Serial.print("Tecla 4 presionada");

        Keyboard.press(WIN);
        Keyboard.write('r');
        Keyboard.release(WIN);
        delay(100);
        Keyboard.print("C:\Program Files (x86)\AIMP\AIMP.exe");   //Here's the problem
        //Keyboard.write(ENTER);
        break;
      case '5':
        Serial.print("Tecla 5 presionada");
        break;
      case '6':
        Serial.print("Tecla 6 presionada");
        break;
      case 'B':
        Serial.print("Tecla B presionada");
        break;
      case '7':
        Serial.print("Tecla 7 presionada");
        break;
      case '8':
        Serial.print("Tecla 8 presionada");
        break;
      case '9':
        Serial.print("Tecla 9 presionada");
        break;
      case 'C':
        Serial.print("Tecla C presionada");
        break;
      case '*':
        Serial.print("Tecla * presionada");
        break;
      case '0':
        Serial.print("Tecla 0 presionada");
        break;
      case '#':
        Serial.print("Tecla # presionada");
        break;
      case 'D':
        Serial.print("Tecla D presionada");
        break;
    }
  }
}

```

# Answer
You have to keep in mind that the Arduino doesn't send characters to the computer. Instead, it simulates key presses, and the computer has to translate those into characters, according to some keyboard layout. By default, the Keyboard library assumes the US keyboard layout.

If you are using another layout, you have to tell the library when initializing it. E.g.

```
Keyboard.begin(KeyboardLayout_es_ES);

```

would work with a Spanish keyboard layout.

C.f. the documentation of `Keyboard.begin()`.

If you are using an unsupported layout, you may need to write your own layout file and add it to the library. You may then contribute it upstream so that it becomes part of future versions of the Keyboard library.

Alternatively, you could switch your layout to US in your OS.

**PS**: The Keyboard library only supports international keyboard layouts since version 1.0.3, released on 2021-11-04.
> 3 votes

---
Tags: arduino-leonardo, keyboard, hid
---


# Question
Title: Trying to keep my main code running unless an input is LOW for a certain amount of time
I have code that creates a sequential signal with 4 LEDS. It cascades to the right. This works when I hold down the input button. What I need help with is having the code run exactly the same when there is an input signal of .5s HIGH --\> .5s LOW (repeat). So what I am thinking in terms of pseudo-code is a code that keeps reading a HIGH signal as long as the signal is not low for more than .5s.

```
//LED outputs
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//right turn signal
int RTS_IN  = A0;

//state variable for switch case statements
int stateRightTurn = 0;

//time variable
unsigned long t = 0;
//interval is the time spacing between case statements
unsigned long interval = 100;
//time for shutting off the code
unsigned long off = 600;

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

  //inputs
  pinMode(RTS_IN,  INPUT);

  //right turn signal output from left to right
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  StateRight();

}

//sequential turn signals
void StateRight()
{

   switch (stateRightTurn)
    {

    case 0: //idle
          if (digitalRead(RTS_IN) == HIGH)
          {
              Serial.println("0000");
              t = millis();
              SwitchRightLedsOff();
              stateRightTurn = 1;
          }
          break;

      case 1: //One LED On
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("1111-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("1111-HHHHHHHH");
              t = millis();
              digitalWrite(LED_5, HIGH);
              stateRightTurn = 2;
          }
          break;

      case 2: // Two LEDs On
          if (digitalRead(RTS_IN) == LOW)
              {
                  Serial.println("2222-LOWLOWLOW");
                  SwitchRightLedsOff();
                  stateRightTurn = 0;
              }
              else if (millis() > t + interval)
              {
                  Serial.println("2222-HHHHHHHH");
                  t = millis();
                  digitalWrite(LED_6, HIGH);
                  stateRightTurn = 3;
              }
          break;

      case 3: //Three LEDs On
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("3333-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("3333-HHHHHHHH");
              t = millis();
              digitalWrite(LED_7, HIGH);
              stateRightTurn = 4;
          }
          break;

      case 4: //Four LEDs On
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("4444-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("4444-HHHHHHHH");
              t = millis();
              digitalWrite(LED_8, HIGH);
              stateRightTurn = 5;
          }
          break;

      case 5: //No LEDs on
          if (digitalRead(RTS_IN) == LOW)
          {
              Serial.println("5555-LOWLOWLOW");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          else if (millis() > t + interval)
          {
              Serial.println("55555-HHHHHHHH");
              SwitchRightLedsOff();
              stateRightTurn = 0;
          }
          break;
    }
}

//method to switch LEDs off
void SwitchRightLedsOff()
{
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

```

# Answer
> 1 votes
If I understand your requirements correctly, you could use a variable to determine if your sequential lights should be flashing or not. If the input signal is `LOW` for more than 1/2 second, the variable should change to `LOW`, telling the Arduino to stop flashing your sequential lights.

Let's pretend that your input signal is at the correct voltage and is very accurate with it's time keeping. At the 501ms mark, with no `HIGH` input signal, your lights should stop flashing.

A simple timer and state variable may work. Here is a test sketch.

```
// Sketch uses 1144 bytes (3%) of program storage space.
// Global variables use 19 bytes (0%) of dynamic memory.
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

    MillisTimer(unsigned long timeInMilliSeconds):
      m_timeInMilliSeconds(timeInMilliSeconds),
      m_timerActive(0),
      m_previousMillis(0){
    }

    bool Update(){
      if(m_timerActive && (millis() - m_previousMillis >= m_timeInMilliSeconds)){
        m_previousMillis += m_timeInMilliSeconds;
        return 1;
      }
      else{
        return 0;
      }
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_previousMillis = millis();
    }

    byte IsActive(){
      return m_timerActive;
    }

};

// Make a copy of the object to work with.
MillisTimer MyTimer(501);

byte inputPin = 2;
byte signalActive = 0;

void setup(){

  // NOTE: Pull-down resistor required if input floating.
  pinMode(inputPin, INPUT);
  MyTimer.Start();

  // Timer status indicator for testing purposes.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

}

void loop(){

  if(digitalRead(inputPin) == HIGH){
    signalActive = 1;
    MyTimer.ReStart();
  }

  if(MyTimer.Update()){
    signalActive = 0;
  }

  // Test ouput of "signalActive" variable using built in LED on an Uno.
  if(signalActive == 1){
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else{
    digitalWrite(LED_BUILTIN, LOW);
  }

}

```

# Answer
> 1 votes
Assuming that `digitalRead(RTS_IN)` is the input, I'd read it once at the top of the loop and save the timestamp if it is HIGH, and then use the condition `millis() - timestamp <= 500` as a latched input variable.

I'd also do the rest of the Input (i.e.: millis()) at the top of the function, convert the time comparisons from absolutes into intervals, and consider factoring the not-enabled case out of the switch's cases.

Untested code:

```
//LED outputs
int LED_5 = 6;
int LED_6 = 7;
int LED_7 = 8;
int LED_8 = 9;

//right turn signal
int RTS_IN  = A0;

//state variable for switch case statements
int stateRightTurn = 0;

//time variable
unsigned long t = 0;
//interval is the time spacing between case statements
unsigned long interval = 100;
//time for shutting off the code
unsigned long off = 600;

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

  //inputs
  pinMode(RTS_IN,  INPUT);

  //right turn signal output from left to right
  pinMode(LED_5, OUTPUT);
  pinMode(LED_6, OUTPUT);
  pinMode(LED_7, OUTPUT);
  pinMode(LED_8, OUTPUT);

}

void loop()
{
  StateRight();

}

//sequential turn signals
void StateRight()
{
  const int latchInterval = 500; // ms
  static unsigned long lastHigh = -latchInterval; // initialize into the rolled-over past
  unsigned long now = millis();
  int inState = digitalRead(RTS_IN);
  if (inState == HIGH) { //update timer
    lastHigh = now;
  }
  bool enabled = (now - lastHigh <= latchInterval) ; // latched on for 500 ms after off

  switch (stateRightTurn)
  {
    case 0: //idle
      if (enabled)
      {
        Serial.println("0000");
        t = now;
        SwitchRightLedsOff();
        stateRightTurn = 1;
      }
      break;

    case 1: //One LED On
      if (!enabled)
      {
        Serial.println("1111-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("1111-HHHHHHHH");
        t = now;
        digitalWrite(LED_5, HIGH);
        stateRightTurn = 2;
      }
      break;

    case 2: // Two LEDs On
      if (!enabled)
      {
        Serial.println("2222-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t >  interval)
      {
        Serial.println("2222-HHHHHHHH");
        t = now;
        digitalWrite(LED_6, HIGH);
        stateRightTurn = 3;
      }
      break;

    case 3: //Three LEDs On
      if (!enabled)
      {
        Serial.println("3333-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("3333-HHHHHHHH");
        t = now;
        digitalWrite(LED_7, HIGH);
        stateRightTurn = 4;
      }
      break;

    case 4: //Four LEDs On
      if (!enabled)
      {
        Serial.println("4444-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("4444-HHHHHHHH");
        t = now;
        digitalWrite(LED_8, HIGH);
        stateRightTurn = 5;
      }
      break;

    case 5: //No LEDs on
      if (!enabled)
      {
        Serial.println("5555-LOWLOWLOW");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      else if (now - t > interval)
      {
        Serial.println("55555-HHHHHHHH");
        SwitchRightLedsOff();
        stateRightTurn = 0;
      }
      break;
  }
}

//method to switch LEDs off
void SwitchRightLedsOff()
{
  digitalWrite(LED_5, LOW);
  digitalWrite(LED_6, LOW);
  digitalWrite(LED_7, LOW);
  digitalWrite(LED_8, LOW);
}

```

---
Tags: arduino-uno, led, time, millis
---


title: Conversion from ASCII uint8_t to string

text:
# Question
Title: Conversion from ASCII uint8_t to string
I am sending a string from a Raspberry Pi to an ESP32 via BT. I am getting one ASCII value per line. How to convert it into one whole String? I tried as follows, but I get an error while running the method `printReceivedMEssage(buffer)`:

invalid conversion from 'uint8\_t {aka unsigned char}' to 'uint8\_t\* {aka unsigned char\*}' \[-fpermissive\]

```
uint8_t buffer;

void printReceivedMessage(const uint8_t* buf) {
  char string_var[100];
  size_t bufflen = sizeof(buf);

  for (int i = 0; i < bufflen; ++i) {
    Serial.println(static_cast<char>(buf[i]));
  }

  memcpy( string_var, buf, bufflen );
  string_var[bufflen] = '\0'; // 'str' is now a string
  Serial.print("string_var=");
  Serial.println(string_var);
}

void loop() {
  buffer = (char)SerialBT.read();
  Serial.println(buffer); // THIS SHOWS AN ASCII VALUES ONE PER LINE
  printReceivedMessage(buffer); // ERROR
  delay(1000);
}

```

# Answer
> 2 votes
There are multiple problems with your code. They suggest, that you don't know what strings really are.

In C/C++ strings are actually arrays of characters (`char`). A `uint8_t` is the same size of a single character, so you can only save a single character in it. For saving a string, you would need an array of them. So `buffer` should be declared like

```
uint8_t buffer[20] = "";

```

Now `buffer` can hold a string of 19 characters. The 20th character is the terminating null character `\0`, which marks the end of a string. You must always leave enough space for the null character to terminate your strings correctly.

**Serial reading:** There are many ways how you can read from Serial. Look at the `Serial.readStringUntil()` function, which will read from Serial until it reaches a specified character. This way you can easily divide the continuous stream of bytes from Serial into distinct messages. It is common to end all ASCII encoded messages with a newline `\n` character to mark the end of the message. With `Serial.readStringUntil('\n')` (note the single quotes for a single character) you will read until it reaches the newline character (or it times out). You can then process the read string as a full message.

**Providing a string as parameter to a function:** In C/C++ you cannot just provide an array as parameter to a function as other variables. It is a bit more complex. That is because internal the array consists just of a few bytes in a row and the variable just points to the first element of it. It is a pointer (thats a specific C/C++ term). Pointers are marked with `*`, which you already did with your

```
void printReceivedMessage(const uint8_t* buf)

```

function. So the parameter is just a pointer to a `uint8_t`. That also explains the error message, because you provided an `uint8_t`, but the function expects a pointer to `uint8_t` instead. While you still can access the array data through this parameter (given you have implemented what I wrote above about the array), `sizeof(buf)` will only give you the size of the pointer (2 bytes on most Arduino platforms). So you need to add a parameter and also provide the size of the array. Or you can utilize the correct termination of strings with the null character and get the length of the string with `strlen()`. That functions iterates the pointer of the array, until it finds the null character and gives you the resulting length.

---
Tags: string, serial-data
---


# Question
Title: Poor man's serial sniffer: reading Serial.print logs of an Arduino esp32 dev kit from another
(I use ESP32 dev kits with Arduino api.)

My dev kit 1 is running my firmware; and I want to measure the current it draws, therefore I don't like to plug the USB in.

As I need to read the logs from the dev kit 1, I want to plug another dev kit that collects the log from the first through the UART.

The dev kit 1 firmware is as it is, but on the dev kit 2, I wrote such a thing:

```
#include <Arduino.h>
#include <Hardware.h>

HardwareSerial Reader();

void setup() {
    Serial.begin(115200);
    Reader.begin(115200, SERIAL_8N1, 16, 17);

}

void loop() {
    while(Reader.available()) {
        Serial.print(Reader.read());
    }
}

```

The wiring is as follows:

| Dev kit 1 | Wiring | Dev kit 2 (sniffer) |
| --- | --- | --- |
| TXD | \<=\> | RXD (16) |
| RXD | \<=\> | TXD (17) |
| GND | \<=\> | GND |

But this doesn't work, that is I can't see anything on the dev kit 2 serial on my computer. Any idea?

\[UPDATE\] As suggested by @juraj, I simply wire TX to TX, RX to RX and GND to GND and removed the Serial.begin(115200) from the firmware running on dev kit 1. Dev kit 2 firmware is as simple as:

```

void setup() {
  Serial.begin(115200);
  //Serial.printf("Serial2 logger RX (%d)<=>TX & TX(%d)<=>RX @ 115200 bauds", RX, TX); Serial.println();
}

void loop() {
  static unsigned lastHeartbeat = 0;

  const unsigned now =millis();
  if (now-lastHeartbeat > 4000) {
    lastHeartbeat = now;
    Serial.println("Heartbeat");
  }
}

```

Note that on dev kit 1, I commented out the line `Serial.begin(115200)`.

No kit 1 logs appears on my computer.

The wiring of this setup:

# Answer
I finally managed to make it work.

## The final wiring:

| Kit 1 | kit 2 |
| --- | --- |
| The firmware to spy | The firmare that spys |
| RXD | 17 |
| TXD | 16 |
| GND | GND |

## The spying firmware uses Serial2

```

#define USE_READER true

#if USE_READER
#define USE_SERIAL2 true

#if USE_SERIAL2
    #define TX 17
    #define RX 16
    #define Reader Serial2
#else
    #include "SoftwareSerial.h"
    #define TX 12
    #define RX 13
    SoftwareSerial Reader;
#endif
#endif

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

#if USE_READER
  Serial.printf("Serial logger RX (%d)<=>TX & TX(%d)<=>RX @ 115200 bauds", RX, TX); Serial.println();

  #if USE_SERIAL2
  Reader.begin(115200);
  #else
  Reader.begin(115200, SWSERIAL_8N1, RX, TX, false);
  #endif
  #endif
}

void loop() {
  static unsigned lastHeartbeat = 0;

  const unsigned now =millis();
  if (now-lastHeartbeat > 4000) {
    lastHeartbeat = now;
    Serial.println("Heartbeat");
  }

  #if USE_READER
  if (Reader.available()) {

    Serial.write(Reader.read());
  }
  else {
    #endif

    //Serial.print(".");
    delay(500);

    #if USE_READER
  }
  #endif
}

```

## The spied firmware

You leave it as it is. Don't remove `Serial.begin(115200);`.

## The breadboard photo:
> 0 votes

---
Tags: serial, esp32
---


# Question
Title: Can I use Data Logger Shield with Arduino Sensor shield V5.0?
so I did a little research on this but the answer to my particular problem did not exist.

I have a data logger shield created by deek robot (deek-robot.com) which seems pretty similar to adafruits data logger shield so I assume they would use the same pins, about this one I can research and find the pins.

but in case of the sensor shield I could not find anything specially since there is no reference on the manufacturer on the board and only referred to as "Arduino Sensor Shield V5.0",as this is a shield for sensors and has almost every pin available on it I would assume it can use most of the data pins and depends on which pins I connect.

Now my question is that can I use these shields together if I want to use those digital pins already used by the data logger? or I can use them together only if I leave out the digital pins 10 to 13 out of use on my sensor shield?

# Answer
The 'data logging' shield by Adafruit and Deek Robot has two devices.

First device is the SD card which uses SPI bus. Every SPI device on the SPI bus has to have a select pin CS. On this shield the SD card has pin 10 as the CS pins.

The second device on the data logger shield is a RTC clock. The RTC clock is on the I2C bus.

So the data logger shield uses the I2C pins, the SPI pins and a pin for CS. Arduino in Uno and Mega R3 form factor have the SPI as a 2x3 header and the I2C pins SDA and SCL are last two pins on the header near the USB connector.

**On Uno the data logging shield uses pin 10 as CS, 11, 12, 13 as SPI and A4, A5 as I2C.**

If you have the version of the data logging shield which can be used on boards other than Uno, then:

* On Mega it uses pin 10 as CS, 50, 51, 52 as SPI and 20, 21 as I2C.
* On Leonardo it uses pin 10 as CS, 2, 3 as I2C (and the SPI pins which are only on the SPI header).
* On Arduino Zero the shield uses pin 10 as CS, 11, 12, 13 as SPI (and the I2c pins are only on the SDA/SCL header).

The 'sensor shield' doesn't have any devices. So it makes no difference in pins usage. With or without the 'sensor shield' if you have the 'data logging' shield attached, you can use only the pins not used by the 'data logging' shield.

Since SPI and I2C are a bus, you can wire additional SPI devices to the SPI pins and additional I2C devices to the I2C pins, but you can't use these pins for anything else if they are configured for the bus.
> 3 votes

---
Tags: arduino-uno, sensors, shields, datalogging
---