title: HX711 - Inconsistent Readings

text:
# Question
Title: HX711 - Inconsistent Readings
simulate this circuit – Schematic created using CircuitLab

Wiring is based on the scheme presented below -

(Reference: https://electronics.stackexchange.com/a/174580)

I am using Arduino Mega 2560, HX711 and four load cells to build a weighing scale but having a hard time calibrate the unit. I have tried different libraries and calibration schemes but none of them seem to help. I have found that the raw values corresponding to any given weight (including zero load) are not consistent. Firstly, the readings do not settle even after 10 minutes, and even if I take an average, the next time I put the same weight, I get an entirely different reading making the last average useless. I am seeing errors of the order of +/- 30 lbs when I put a known weight.

I first thought that maybe my load cells are the root cause but when hooked them up directly to Arduino and read the voltage across the bridge, I read stable constant values. Verified the voltage readings with a Voltmeter. (Yes, their resolution is not as good as HX711 but at least they are stable and consistent). I get the voltage reading close to my hand calculations.

Next, I tried testing the HX711 in different ways. In one test, I created a full-bridge using resistors other than load cells, forced the bridge out of balance but cannot read anything other than 16777215. Next, I wanted to see if the board is reacting to any voltage at all, so, I removed the bridge and did not connect anything to E+ and E- pins but supplied known voltages from a DC power supply (from 0 to 4.5V) to the A+ and A- (GND) pins. Now, it is reading only 8388607, no matter what voltage I supply. If I supply +5V or +3.3V from Arduino to the A+ and A- (GND) pins instead of DC Power supply, it then only reads 16777215.

I don't know how to interpret this behavior. How can I resolve the issue and bring the error down? Thanks for your help.

I have included the schematic below. All four Load Cells (LCs) are 3-wired (White, Black & Red). Resistance between W & B wires is around 1980 ohms while that between R & W or R & B is around 990 ohms. SO I connected the four LCs in the manner shown in the schematic. Wire colors have been labelled.

Code:

Code is pretty straightforward as I am simply reading raw values from the HX711 using the following HX711 library - github.com/queuetue/Q2-HX711-Arduino-Library.git

```
#include <Q2HX711.h>

const byte hx711_data_pin = 4;
const byte hx711_clock_pin = 8;

Q2HX711 hx711(hx711_data_pin, hx711_clock_pin);

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

void loop()
{
  Serial.println(hx711.read());
  delay(500);
}

```

# Answer
Here is is a picture of how I have seen the sensors connected. Is this how your is?
> 1 votes

---
Tags: arduino-mega, adc, op-amp
---


# Question
Title: Sparkfun CCS811 sensor not interfacing with arduino
I have sparkfun indoor air quality sensor CCS811 which needs to be interfaced with arduino. I have soldered wires on the sensors and connected with arduino. Have checked the connection with multimeter so that part works. But even using example code on library still I am not getting reading from sensor.

Code:-

```
#include <Wire.h>

#include "SparkFunCCS811.h"

#define CCS811_ADDR 0x5B //Default I2C Address
//#define CCS811_ADDR 0x5A //Alternate I2C Address

CCS811 mySensor(CCS811_ADDR);

void setup()
{
  Serial.begin(9600);
  Serial.println("CCS811 Basic Example");

  Wire.begin(); //Inialize I2C Harware

  //It is recommended to check return status on .begin(), but it is not
  //required.
  CCS811Core::status returnCode = mySensor.begin();
  if (returnCode != CCS811Core::SENSOR_SUCCESS)
  {
    Serial.println(".begin() returned with an error.");
    //while (1); //Hang if there was a problem.
  }
}

void loop()
{
  //Check to see if data is ready with .dataAvailable()
  if (mySensor.dataAvailable())
  {
    //If so, have the sensor read and calculate the results.
    //Get them later
    mySensor.readAlgorithmResults();

    Serial.print("CO2[");
    //Returns calculated CO2 reading
    Serial.print(mySensor.getCO2());
    Serial.print("] tVOC[");
    //Returns calculated TVOC reading
    Serial.print(mySensor.getTVOC());
    Serial.print("] millis[");
    //Simply the time since program start
    Serial.print(millis());
    Serial.print("]");
    Serial.println();
  }

  delay(10); //Don't spam the I2C bus
}

```

Things I tried:- 1) different combination of A4, A5 pins 2) 0x5A & 0x5B i2c address 3) using wake pin with ground 4) using 3.3 & 5V for powering sensor

What else needs to be done?

# Answer
> 1 votes
The problem was on the soldering part. SDA & 3.3V pin on sensor were slightly in contact. I modified it and started working fine.

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


# Question
Title: CH340 chip getting fried after connecting Arduino to a powerful 12V souce
I'm using a 120 W DC power supply connected in parallel with ESC and Arduino nano through Vin. However, somehow the Arduino get fried near the CH340 chip, i.e. around the big black square chip near the micro usb port on the back of the board, kept getting fried. It's working for a while, until it melted.

This didn't quite make sense, since Arduino Vin can take voltage from 6V to 12V. The ESC also had a maximum current consumption of over 30A, equivalent to 360W. Thus there wasn't an obvious reason for which Arduino ought to get fried at all.

Why CH340 chip getting fried after connecting Arduino to a powerful 12V source?

# Answer
> 1 votes
It's impossible to say for sure what is going on without proper equipment (mostly you need oscilloscope), but I'm pretty sure that due to very high current consumption of the motors, there are voltage spikes at the input of the voltage regulator. If voltage exceeds safe value (15V for most of them), then regulator fails and all the input voltage is now on the output (that's how they fail 99% if the time, not as an open unfortunately, but as a short). Then for some reasons the weakest IC is CH340G which is fried. Try to use destroyed Arduino without ESC, and see what's on the 5V pin. You say that you have currents up to 30A, but PSU is rated for 120W which means it can deliver only 10A at 12V. So at some point PSU falls into protection mode, switches off the output, and after some time tries to switch it on again. Situation with voltage spikes can be very nasty during this period. Also please post your schematic and photo of the actual wiring, this can also give us some clues.

---
Tags: arduino-nano, electronics, electricity, voltage-protection, ch340
---


title: How to connect ESP32 to HC-06?

text:
# Question
Title: How to connect ESP32 to HC-06?
I am making a small project (BT controlled "tank") and need to connect ESP32 with HC-06 (ESP32 will be in controller and HC-06 in the vehicle). Android phone communication with both ESP and HC-06 works prefectly, I can not just figure out, how to pair/connect these two modules. Any ideas?

EDIT: Just to clarify, I can not connect them, because the HC-06 has PIN and I can not figure out how to remove that PIN or connect to it with PIN from ESP32...

# Answer
You can either use a breadboard Or Female to Female Jumber wires.

Ofoucrse you can always solder yourself the two modules together with wires.

PS. Too low reputation to comment, so i insert this as answer
> 1 votes

---
Tags: bluetooth, esp32, hc-06
---


# Question
Title: How do I make Arduino IDE use a specific version of GCC in Debian?
Using Raspbian Stretch.

I installed gcc-4.9 with specified version. Then I installed arduino (2.1.0.5) which in turn pulled gcc 4.6. When I try to compile Marlin in it, it says

> Marlin requires C++11 support (gcc \>= 4.7, Arduino IDE \>= 1.6.8). Please upgrade your toolchain.

How do I make Arduino IDE use the correct version of GCC?

# Answer
> 2 votes
As Majenko pointed out, I should have used a tarball from the official site instead of the repositories. Which makes me wonder why that package wasn't deprecated or something...

# Answer
> 0 votes
Installing the Arduino package from the Debian repository (or the one for derived distros like Ubuntu) performs the useful purpose of setting up all the necessary permissions for the Arduino IDE to work. Those permissions are NOT automatically removed when you uninstall the package.

The simplest way to get a working Arduino install:
1. Install Arduino from the repo
2. Immediately uninstall it
3. Get a current version of Arduino from arduino.cc and install that

---
Tags: arduino-ide, compile, raspberrypi, gcc
---


# Question
Title: Cannot write lock byte on Arduino Pro Micro
I have an Arduino Pro Micro, with atmega32u4 chip and a caterine bootloader. However, every time I (successfully) flash some program over the USB port, the `/dev/ttyACM0` device disappears, and I cannot flash it any more over USB.

So I connect it to my stk500v2-compatible ISP programmer (MISO/MOSI/SCK go to pins 14,16 and 15 on the board; VCC,GND,RST to their counterparts). With this setup, I can flash a new Caterina bootloader onto it. The problem with flashing over the board's USB port stays, though.

So I tried to set the lock byte with the ISP programmer, which writes successfully, but then fails at verification:

```
> avrdude -p m32u4 -P /dev/ttyUSB0 -c stk500v2 -b 115200 -U lock:w:0x0F:m
...
avrdude: verification error, first mismatch at byte 0x0000
         0xcf != 0x0f

```

Is my assumption correct that the disappearing bootloader is caused by the wrongly set (un-)lock bits? If yes, why can't I set the lock byte via ISP?

# Answer
> 0 votes
Meanwhile, I managed to solve this problem. The reason for the verification error is that the two most significant bits of the Lock Byte are read-only on my variant of the Arduino Pro Micro. Which means that, if you (try to) write a value of `0x00 = 0b0000 0000`, it will result in a value of `0b1100 0000 = 0xC0` on the hardware. The solution, then, was to simply ignore those two bits.

```
> avrdude -p m32u4 -P /dev/ttyUSB0 -c stk500v2 -b 115200 -U lock:w:0xCF:m

```

---
Tags: bootloader, arduino-pro-micro, isp
---


title: default parameter class method

text:
# Question
Title: default parameter class method
I have this function (which works fine):

```
String Esper::rtcTimeString() {
  DateTime now = rtc.now();
  char buf[] = "MM/DD/YY hh:mm:ss";
  return now.toString(buf);
}

```

I'd like to have a default value of "MM/DD/YY hh:mm:ss" but also pass an argument to a parameter such as "MM/DD/YYYY" if I want to override this default behavior.

Typically, in the definitions .h file I would do something like:

```
String rtcTimeString(char ts[] = "MM/DD/YY hh:mm:ss");

```

and subsequently in the .cpp:

```
String Esper::rtcTimeString(char ts[]) {
  DateTime now = rtc.now();
  return now.toString(ts);
}

```

However that results in the same returned time string every time.

e.g.

```
1/6/2020 12:01:12
1/6/2020 12:01:12
1/6/2020 12:01:12

```

How can I implement a parameter such that the functionality is the same as in the first code block?

# Answer
You cannot pass an array of characters as an argument (implicit or not) to a function. When you write

```
String rtcTimeString(char ts[] = "MM/DD/YY hh:mm:ss");

```

The array notation is implicitly converted to a pointer. The line above is then equivalent to:

```
String rtcTimeString(char *ts = "MM/DD/YY hh:mm:ss");

```

And this is incorrect: you are initializing a pointer to *modifiable* characters using the address of an array of *constant* characters. The compiler should have warned you about this... if you enabled compiler warnings. The correct prototype should be

```
string rtcTimeString(const char* ts = "MM/DD/YY hh:mm:ss");

```

But then you cannot pass this pointer to `DateTime::toString()`, as this method expects the template string to live in a buffer it can overwrite: that's where it will write the formatted string.

I suggest this solution:

```
string rtcTimeString(const char* ts = "MM/DD/YY hh:mm:ss") {
    DateTime now = rtc.now();
    char buf[strlen(ts)+1];  // allocate a fresh buffer
    strcpy(buf, ts);         // copy the template there
    return now.toString(buf);
}

```
> 1 votes

# Answer
This basic C++ (and GIYF).

What about

```
String Esper::rtcTimeString(std::string dateTimeForamt = "MM/DD/YY hh:mm:ss")
{
  DateTime now = rtc.now();

  return now.toString(dateTimeForamt );
}

```

See, for instance, this question. Hope this helps :-)
> 1 votes

---
Tags: programming
---


# Question
Title: How to power both arduino and 1 color led strip from single power source
I'm trying to understand and adapt this tutorial:

https://learn.adafruit.com/rgb-led-strips/current-draw

to my own use. I am doing essentially the same thing, except I have this single color LED strip, and I don't fully understand how to power both the arduino and the led strip from the same power source.

I tried to wire it using the diagram above, and something started smoking (I think the IR transmitter). I don't know much about circuits, but I'm pretty sure that's not good.

In this diagram, the 9v represents DC power, the IR sensor on the left represents the transmitter, the IR on the right is the receiver, and the white LED is the LED strip, with two outputs (+ - )

In the fritzing diagram for that tutorial, they have the + from the LED strip going straight in to Vin on the uno, but they don't show how either the LED strip or the uno themselves are being powered.

Do I need two power sources?

Do I need a mosfet considering I'm only using a one color LED strip?

I've got the IR sensors working, so I don't need help with that, and I can connect one of these 12V switching power supplies to one of these DC power screw terminals to power the lights without any arduino control, so all I'm missing is how to turn the lights on and off with arduino, IE, how to go from the power supply to the arduino to the LED strip.

I don't need to PWM the LED strip - just shut it off and on.

If anyone can help me correct the fritzing diagram or explain what I'm doing wrong / what I should be doing instead, I'd greatly appreciate it.

# Answer
Note that VIN pin and the 2.5mm DC Jack are connected. So in the tutorial one of these is getting power from a +12Vdc source and the other is supplying +12V to the +12v labeled pin on the LED string. Where the R G and B pins of the strip should be connected to Collectors of NPN's. Each of the NPN's bases are driven by Arduino Output pin and all the Emitters are connected to Ground.

So +12V supplies the DC Jack (aka Vin) the Arduino's local regulator converts that to Ground. The +12V via Vin supplies the LED's. And the Digital Outputs drive the base's of the NPN's. Which in turn act like a relay closing the perspective LED's to Ground, so they can illuminate. Where a Digital ONE or HIGH or TRUE on the BASE results in 5V above ground, which causes it to have low resistance.
> 2 votes

# Answer
You asked: "Do I need a mosfet considering I'm only using a one color LED strip?"

Yes, absolutely. An Arduino logic line can only put out about 20 mA of power at 5V. That's not an unreasonable amount of power for a single low-power LED. An LED strip is likely to draw a lot more current than that, and it's pretty common for LED strips to use 12V, not 5V.

What LED strip are you using, and what input voltage and current requirements does it have?

You should be able to use a single power 12V power supply for your project. (assuming your LED strip needs 12V.) You'd feed it into the barrel jack of the Arduino. The Arduino's voltage regulator would use that to generate its 5V power. You'd also feed 12V into the power for your LED strip. You'd use a logic-level MOSFET to switch the power to the LED strip on and off. A logic level MOSFET is able to use a low current 5V signal from the Arduino to switch higher voltage, higher current loads like your LED strip with very little resistance, and thus with very little waste heat generated.
> 0 votes

---
Tags: arduino-uno, led, power
---


# Question
Title: How many UNO pins have internal pull up resistors?
As the title implies. thank you in advance.

# Answer
All of them. It's a standard feature on all IO pins in the AVR range.
> 5 votes

---
Tags: arduino-uno, pull-up
---


title: Arduino Uno Rev3 Internal Quartz

text:
# Question
Title: Arduino Uno Rev3 Internal Quartz
I'm using an Arduino Uno Rev3 Board and need to send a trigger signal at a certain frequency (20-50Hz). This trigger signal should be as accurate as possible (+/- 0.01 ms). The Arduino site states that the arduino uno has a 16MHz Quartz Crystal, but I'm measuring a frequency accuracy of about 0.35% (which would be typical for a ceramic resonator) instead of what i could expect from a quartz (0.001%). I'm using the micros() function to measure time. Am I doing something wrong? How is my frequency so inaccurate?

Thanks for your help! :)

Edit: Indeed when I have a look at the schematics, I see the ceramic resonator (Blue circle). However, there seems to be another 16 MHz part (red circle). could that be a quartz oscillator?

# Answer
The ATMega328P chip is, indeed, clocked by a ceramic resonator. The website is misleading in stating that it has a crystal (I have emailed the webmaster to try and get this corrected, though I don't hold out much hope).

The 16MHz crystal in the schematics is part of the USB interface circuitry and has nothing to do with the timing of your running code. It is purely used to clock the ATMega16U2 chip which provides USB connectivity (USB requires a higher accuracy for stable communication).

There are other boards available with better crystals - most often boards that have native USB connections, such as the Arduino Due or Leonardo, or any of the myriad of boards by other manufacturers, like Teensy or chipKIT.
> 2 votes

---
Tags: arduino-uno, oscillator-clock
---


# Question
Title: motor shield directly to PC? WITHOUT ARDUINO!
Is there a way to connect and control motor shield board WITHOUT Arduino at all. can i connect it directly to my PC ? i'm getting confused since i red lot of topics that people use existing pins on motherboard.

# Answer
This super**user** post might help.

Raspberry Pis have GPIO pins that you can use to communicate with a motor shield, but regular (intel-based) PCs usually don't. In any case, you wouldn't want to mess with motherboard pins anyway; a short circuit might easily fry your computer.

If you don't want to use an Arduino, you can use a USB-to-serial converter (such as a small FTDI circuit) along with a motor driver that uses serial communication.

However, this wouldn't be any simpler or cheaper than just using an Arduino.
> 0 votes

# Answer
To a normal PC? No. You can't. A PC doesn't have the GPIO pins etc that are needed.

You could wire it to a Pi though.
> 0 votes

# Answer
If you have a PC with a real Parallel Port ( LPT1: ) and you don't run an Operating System on it, ( or perhaps MS-DOS ) ... you can connect some leds, but you cannot use an Arduino shield directly.
> 0 votes

---
Tags: arduino-motor-shield
---


# Question
Title: "Serial" does not name a type -> How to solve this problem?
I'm trying my best to solve this problem but it didn't changed

The red line was drawn on the last Serial.println \*/

```
int cds = A0;
int led = 12;
int trig1 = 2;      // Left Trig
int trig2 = 3;      // Right Trig
int trig3 = 4;      // Front Trig
int trig4 = 5;      // Upside Trig
int echo1 = 6;      // Left Echo
int echo2 = 7;      // Right Echo
int echo3 = 8;      // Front Echo
int echo4 = 9;      // Upside Echo
int vib1 = 10;      // Left vib
int vib2 = 11;      // Right vib

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

        pinMode(trig1, OUTPUT);
        pinMode(trig2, OUTPUT);
        pinMode(trig3, OUTPUT);
        pinMode(trig4, OUTPUT);
        pinMode(echo1, INPUT);
        pinMode(echo2, INPUT);
        pinMode(echo3, INPUT);
        pinMode(echo4, INPUT);
        pinMode(vib1, OUTPUT);
        pinMode(vib2, OUTPUT);

        Serial.begin(9600);
}

void loop(){
  long duration1, value1;
  long duration2, value2;
  long duration3, value3;
  long duration4, value4;

  // Ultra Sonic Sensor Part1
  digitalWrite(trig1,LOW);                           // Trigger Output
  delayMicroseconds(2);
  digitalWrite(trig1,HIGH);
  delayMicroseconds(5);
  digitalWrite(trig1,LOW);
  duration1 = pulseIn(echo1,HIGH);                   // Read Pulse Duration
  value1 = microsecondsToCentimeters(duration1);     // Count Distance
  delay(10);

  // Ultra Sonic Sensor Part2
  digitalWrite(trig2,LOW);
  delayMicroseconds(2);
  digitalWrite(trig2,HIGH);
  delayMicroseconds(5);
  digitalWrite(trig2,LOW);
  duration2 = pulseIn(echo2,HIGH);
  value2 = microsecondsToCentimeters(duration2);
  delay(10);

  // Ultra Sonic Sensor Part3
  digitalWrite(trig3,LOW);
  delayMicroseconds(2);
  digitalWrite(trig3,HIGH);
  delayMicroseconds(5);
  digitalWrite(trig3,LOW);
  duration3 = pulseIn(echo3,HIGH);
  value3 = microsecondsToCentimeters(duration3);
  delay(10);

  // Ultra Sonic Sensor Part4
  digitalWrite(trig4,LOW);
  delayMicroseconds(2);
  digitalWrite(trig4,HIGH);
  delayMicroseconds(5);
  digitalWrite(trig4,LOW);
  duration4 = pulseIn(echo4,HIGH);
  value4 =  microsecondsToCentimeters(duration4);
  delay(10);

  //Commend Part (Vibration motor)

  // Print Out Value
  Serial.print(" dist1 =");
  Serial.print(value1);
  Serial.print("(cm)");
  Serial.print(" dist2 =");
  Serial.print(value2);
  Serial.print("(cm)");
  Serial.print(" dist3 =");
  Serial.print(value3);
  Serial.print("(cm)");
  Serial.print(" dist4 =");
  Serial.print(value4);
  Serial.print("(cm)");
  delay(10);
  //

  // Initialize PIN Mode
  digitalWrite(vib1,HIGH);
  digitalWrite(vib2,HIGH);

  // 진동모터1,2,3
  if (  value4<60  or  value3<60)
  digitalWrite(vib1,LOW);
  digitalWrite(vib2,LOW);

  delay(100);

  digitalWrite(vib1,HIGH);
  digitalWrite(vib2,HIGH);

  if (0< value1 && value1<60)
  digitalWrite(vib1,LOW);

  delay(100);

  digitalWrite(vib1,HIGH);

  if (0< value2 && value2<60)
  digitalWrite(vib1,LOW);

  delay(100);

  digitalWrite(vib1,HIGH);
}

// Function of Count Distance

long microsecondsToCentimeters(long microseconds)
{
  return microseconds/29/2;
}

        int cdsValue = analogRead(cds);

        Serial.print("cds =  ");
        Serial.println(cdsValue);

        if (cdsValue < 38 ) {
                digitalWrite(led, HIGH);
        } else {
                digitalWrite(led, LOW);
        }

```

# Answer
> 1 votes
Your code would be a lot easier to read and find mistakes in if you formatted it. I see that you did that in the IDE, but in your question, you need to highlight all of the code, then click the "{}" button to make it look like code in your question.

When I pasted your code into my IDE and auto-formatted it, the answer was immediately clear: after the function `microsecondsToCentimeters()` you have written some code that is not inside any function. C and C++ don't allow that. The error message wasn't very helpful - the compilers easily get confused by our mistakes - but in this case, looking at the formatted code made it clear.

*All of the executable code in a C or C++ program (Arduino IDE uses C++) must be inside a typed and named function.* Since that is what the compiler was looking for, it seems to have interpreted the word "Serial" as a function type, but no type was defined with that name.

I'm not sure where you intended the lines from the end of `long microsecondsToCentimeters()` to go, but they need to be inside of a function, somewhere.

---
Tags: serial
---


title: Arduino uno wifi rev2 stuck inside loop

text:
# Question
Title: Arduino uno wifi rev2 stuck inside loop
It might be a stupid question but I can't figure it out. While running the code below. I want to open the box when the code matches the code in API. This all works. I can even close the box afterwords. But then I am stuck inside my loop. after the box is closed I want the screen to say box closed and then I want the void loop() to start again. so my screen asks for a code again. I tried using break and exit but no luck so far. entire code:

```
/* hardware libraries*/
#include <Key.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>

/*Wifi and request libraries*/
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h>

#define HIGH 0x1
#define LOW 0x0

/* wifi credentials*/
char ssid[] = "ssid";        // your network SSID (name)
char pass[] = "password";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;

int status = WL_IDLE_STATUS;
char server[] = "parcelbox.1819.caro.deweze.nxtmediatech.eu";
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

LiquidCrystal_I2C lcd(0x27, 16, 2); // lcd object
Servo myservo; //servo object
boolean boxOpenend = false ;

/* Keypad*/
const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {3, 4, 5, 6};
byte colPins[COLS] = {9, 8, 7};

Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String value = "";

void setup() {
  lcd.begin(); //start lcd
  Serial.begin(9600);
  myservo.attach(A0); // attach servo to pin
  lcd.backlight(); // start screen light

  /* connect to wifi */
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < "1.0.0") {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to wifi");
  printWifiStatus();
}

void loop() {
  lcd.clear();
  lcd.print("Geef bestelcode");
  char customKey = customKeypad.getKey();   // get the key pressed
  value = value + String(customKey);
  lcd.setCursor(0, 1);
  lcd.print(value);
  if (customKey == '#') {

    String response_Status = "";
    Serial.println("\nStarting connection to server...");

    // if you get a connection, report back via serial:
    if (client.connect(server, 80)) {

      value.remove(16);
      Serial.println(value);
      Serial.println("connected to server");

      // Make a HTTP request:
      client.println("GET /api/boxes/1444/code/" + value + " HTTP/1.1");
      client.println("Host: parcelbox.1819.caro.deweze.nxtmediatech.eu");
      client.println("Connection: close");
      client.println();
    }
    // if there are incoming bytes available
    // from the server, read them and print them:
    StaticJsonBuffer<500> jsonBuffer;

    while (client.connected()) {

      String response = "";
      bool begin = false;

      while (client.available() || !begin) {
        char c = client.read();

        if (c == '{') {
          begin = true;
        }
        if (begin) response += (c);
        if (c == '"}') {
          break;
        }
        delay(1);
      }
      int start = response.indexOf("status\":\"") + 11;
      int end = start + 3;
      response_Status = response.substring(start, end);

      JsonObject& root = jsonBuffer.parseObject(response);

      if (!root.success())
      {
        Serial.print("parseObject(");
        Serial.print(response);
        Serial.println(") failed");
        break;
      }

      Serial.println(response_Status);
      if (response_Status == "200") {

        Serial.println("200");
        boxOpenend = true;

        while (boxOpenend) {

          lcd.clear();
          lcd.print("Box openend ,press");
          lcd.setCursor(0, 1);
          lcd.print(" * to close");

          myservo.write(0);// rotate the servo to open
          delay(175);

          char key = customKeypad.getKey();   // get the key pressed
          //value = value + String(key);

          if (key == '*') {
            myservo.write(90); // rotate the servo to lock
            value = "";                           // clear the string
            boxOpenend = false;

          }
          // box gaat terug toe maar ik blijf in deze loop zitten want lcd scherm blijft staan op "Box geopend , druk * om te sluiten
        }

      }
      else if (response_Status != "200") {

        Serial.println("not 200");

        lcd.clear();
        lcd.print("wrong code or");
        lcd.setCursor(0, 1);
        lcd.print("already deliverd");

        delay(175);
        value = "";
        exit;
      }
      //hier net hetzelfde
      break ;
    }
    // if the server's disconnected, stop the client:
    if (!client.connected()) {
      Serial.println();
      Serial.println("disconnecting from server.");
      client.stop();

      // do nothing forevermore:
      while (true);
    }
    exit;
  }

  if (customKey == '*') {
    myservo.write(90);                   // rotate the servo to lock
    value = "";                           // clear the string
  }

  delay(175); // for optimal lcd screen view
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

```

This is where the code get's stuck. It keeps on showing box opened press * to close. even when I press * and the box closes it keeps on saying this

```
while (boxOpenend) {

          lcd.clear();
          lcd.print("Box openend ,press");
          lcd.setCursor(0, 1);
          lcd.print(" * to close");

          myservo.write(0);// rotate the servo to open
          delay(175);

          char key = customKeypad.getKey();   // get the key pressed
          //value = value + String(key);

          if (key == '*') {
            myservo.write(90); // rotate the servo to lock
            value = "";                           // clear the string
            boxOpenend = false;

          }
          // box gaat terug toe maar ik blijf in deze loop zitten want lcd scherm blijft staan op "Box geopend , druk * om te sluiten
        }

      }

```

It might have a simple solution that I'm just not thinking of but it really bothers me!

UPDATE , We made a little progress as to figuring out why it wont work. the code that we are running now is:

```
/* hardware libraries*/
#include <Key.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>

/*Wifi and request libraries*/
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h>

#define HIGH 0x1
#define LOW 0x0

/* wifi credentials*/
char ssid[] = "XXXXXXX";        // your network SSID (name)
char pass[] = "XXXXXXX";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;

int status = WL_IDLE_STATUS;
char server[] = "parcelbox.1819.caro.deweze.nxtmediatech.eu";
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

LiquidCrystal_I2C lcd(0x27, 16, 2); // lcd object
Servo myservo; //servo object
boolean boxOpenend = false ;

/* Keypad*/
const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {3, 4, 5, 6};
byte colPins[COLS] = {9, 8, 7};

Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String value = "";

void setup() {
  lcd.begin(); //start lcd
  Serial.begin(9600);
  myservo.attach(A0); // attach servo to pin
  lcd.backlight(); // start screen light

  /* connect to wifi */
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < "1.0.0") {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to wifi");
  printWifiStatus();
}

void loop() {
  lcd.clear();
  lcd.print("Geef bestelcode");

  char customKey = customKeypad.getKey();   // get the key pressed
  value = value + String(customKey);

  lcd.setCursor(0, 1);
  lcd.print(value);

  if (customKey == '#')
  {
  Serial.println("PRESSED #");
    String response_Status = "";
    Serial.println("\nStarting connection to server...");

  Serial.println("RESULT OF CLIENT.CONNECT()");
  Serial.println(client.connect(server, 80));

    // if you get a connection, report back via serial:
    if (client.connect(server, 80) == 1)
  {
    Serial.println("IK BEN HIER");
    value.remove(4);
    Serial.println(value);
    Serial.println("connected to server");

    // Make a HTTP request:
    client.println("GET /api/boxes/1444/pin/" + value + " HTTP/1.1");
    client.println("Host: parcelbox.1819.caro.deweze.nxtmediatech.eu");
    client.println("Connection: close");
    client.println();
  }
  else
  {
    Serial.println("client.connect() not successfull");
  }

    // if there are incoming bytes available
    // from the server, read them and print them:
    StaticJsonBuffer<500> jsonBuffer;

    if (client.connected())
  {
    Serial.println("CLIENT CONNECTED");

    String response = "";
    bool begin = false;

    while (client.available() || !begin) {
      char c = client.read();

      if (c == '{') {
        begin = true;
      }

      if (begin) {
        response += (c);
      }

      if (c == '"}') {
        break;
      }

      delay(1);
    }

    int start = response.indexOf("status\":\"") + 11;
    int end = start + 3;

    response_Status = response.substring(start, end);
    Serial.println(response_Status);

    // response successfull
    if (response_Status == "200")
    {
      Serial.println("RESPONSE 200");
      Serial.println("response state == 200");

      // First open the box
      // 0° means open
      Serial.println("OPEN BOX");
      myservo.write(0);
      delay(175);

      lcd.setCursor(0, 0);
      lcd.print("                ");
      lcd.setCursor(0, 0);
      lcd.print("Box opened ,press");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      lcd.setCursor(0, 1);
      lcd.print(" * to close");
    }
    else
    {
      Serial.println("RESPONSE NOT 200");
      Serial.println("not 200");

      lcd.clear();
      lcd.print("Foute code of");
      lcd.setCursor(0, 1);
      lcd.print("al afgeleverd");

      delay(175);
    }
    }

  // reset the value
  value = "";
  }

  // lock box and reset value
  if (customKey == '*')
  {
    Serial.println("CLOSE BOX");
    myservo.write(90);
    value = "";
    client.stop();
  }

  delay(175); // for optimal lcd screen view
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

```

this is the serial output:

it's clear that the first request the check the code goes thru but when you try a second time it comes out empty. We did some research and we found that in some cases the servo could affect the request in a bad way. Just not sure if that is correct and how to fix this

# Answer
> 2 votes
```
/* hardware libraries*/
#include <Key.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>

/*Wifi and request libraries*/
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h>

#define HIGH 0x1
#define LOW 0x0

/* wifi credentials*/
char ssid[] = "sidd";        // your network SSID (name)
char pass[] = "pass";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;

int status = WL_IDLE_STATUS;
char server[] = "parcelbox.1819.caro.deweze.nxtmediatech.eu";
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

LiquidCrystal_I2C lcd(0x27, 16, 2); // lcd object
Servo myservo; //servo object
boolean boxOpenend = false ;

/* Keypad*/
const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {3, 4, 5, 6};
byte colPins[COLS] = {9, 8, 7};

Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String value = "";

void setup() {
  lcd.begin(); //start lcd
  Serial.begin(9600);
  myservo.attach(A0); // attach servo to pin
  lcd.backlight(); // start screen light

  /* connect to wifi */
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  /*
    // check for the WiFi module:
    if (WiFi.status() == WL_NO_MODULE) {
      Serial.println("Communication with WiFi module failed!");
      // don't continue
      while (true);
    }

    String fv = WiFi.firmwareVersion();
    if (fv < "1.0.0") {
      Serial.println("Please upgrade the firmware");
    }

    // attempt to connect to Wifi network:
    while (status != WL_CONNECTED) {
      Serial.print("Attempting to connect to SSID: ");
      Serial.println(ssid);
      // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
      status = WiFi.begin(ssid, pass);

      // wait 10 seconds for connection:
      delay(10000);
    }
    Serial.println("Connected to wifi");*/
  createConnection();
}

void loop() {
  lcd.clear();
  lcd.print("Bestelcode / pin");

  char customKey = customKeypad.getKey();   // get the key pressed
  value = value + String(customKey);

  lcd.setCursor(0, 1);
  lcd.print(value);

  if (customKey == '#')
  {
    createConnection();
    Serial.println("PRESSED #");
    String response_Status = "";
    Serial.println("\nStarting connection to server...");

    Serial.println("RESULT OF CLIENT.CONNECT()");
    Serial.println(client.connect(server, 80));

    // if you get a connection, report back via serial:
    if (client.connect(server, 80) == 1)
    {
      int valueLen = value.length();
      if(valueLen == 5){
      Serial.println("IK BEN een pin ");
      value.remove(4);
      Serial.println(value);
      Serial.println("connected to server");

      // Make a HTTP request:
      client.println("GET /api/boxes/2025/pin/" + value + " HTTP/1.1");//1444
      client.println("Host: parcelbox.1819.caro.deweze.nxtmediatech.eu");
      client.println("Connection: close");
      client.println();
      }
      if(valueLen ==17){
      Serial.println("IK BEN een bestelcode");
      value.remove(16);
      Serial.println(value);
      Serial.println("connected to server");

      // Make a HTTP request:
      client.println("GET /api/boxes/2025/code/" + value + " HTTP/1.1");//1444
      client.println("Host: parcelbox.1819.caro.deweze.nxtmediatech.eu");
      client.println("Connection: close");
      client.println();

        }
        else{

          Serial.println("invalid amount of numbers code");
          /*lcd.clear();
          lcd.print("ongeldige code");*/

          }
    }
    else
    {
      Serial.println("client.connect() not successfull");
    }

    // if there are incoming bytes available
    // from the server, read them and print them:
    StaticJsonBuffer<500> jsonBuffer;

    if (client.connected())
    {
      Serial.println("CLIENT CONNECTED");

      String response = "";
      bool begin = false;

      while (client.available() || !begin) {
        char c = client.read();

        if (c == '{') {
          begin = true;
        }

        if (begin) {
          response += (c);
        }

        if (c == '"}') {
          break;
        }

        delay(1);
      }

      int start = response.indexOf("status\":\"") + 11;
      int end = start + 3;

      response_Status = response.substring(start, end);
      Serial.println(response_Status);

      // response successfull
      if (response_Status == "200")
      {
        Serial.println("RESPONSE 200");
        Serial.println("response state == 200");

        // First open the box
        // 0° means open
        Serial.println("OPEN BOX");
        myservo.write(0);
        delay(175);

        lcd.setCursor(0, 0);
        lcd.print("                ");
        lcd.setCursor(0, 0);
        lcd.print("Box open ,druk");
        lcd.setCursor(0, 1);
        lcd.print("                ");
        lcd.setCursor(0, 1);
        lcd.print("* om te sluiten");
        delay(5000);
      }
      else
      {
        Serial.println("RESPONSE NOT 200");
        Serial.println("not 200");

        lcd.clear();
        lcd.print("Foute code of");
        lcd.setCursor(0, 1);
        lcd.print("al geleverd");

        delay(2500);
      }
    }

    // reset the value
    value = "";
  }

  // lock box and reset value
  if (customKey == '*')
  {
    Serial.println("CLOSE BOX");
    myservo.write(90);
    value = "";
    client.stop();
  }

  delay(175); // for optimal lcd screen view
}
void createConnection() {

  // This new line is required to disconnect the previous connection otherwise
  // it will try to use the old connection and never reconnect if the connection fails
  status = WiFi.disconnect();

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10);
  }
  // you're connected now, so print out the status:
  printWifiStatus();

}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

```

I had to rewrite my wifi connection into a function outside my setup. Because the program only established a connection in the beginning and closed it after my first request. By giving it it's own function I could call it inside my loop whenever the user would enter a code the program could reestablish a connection. My program now runs how I need it to run.

# Answer
> 1 votes
Although I can not verify my code, I tried to modify your program. Probably it does not compile and you have to do some corrections. I changed it in a way I would expect it to work and hopefully I understood your intentions.

At least we could use this version as a base to elaborate a working one together.

```
#include <Key.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h>

#define HIGH 0x1
#define LOW 0x0

char ssid[] = "ssid";
char pass[] = "password";
int keyIndex = 0;

int status = WL_IDLE_STATUS;
char server[] = "parcelbox.1819.caro.deweze.nxtmediatech.eu";

WiFiClient client;

LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo myservo;

/* Keypad*/
const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {3, 4, 5, 6};
byte colPins[COLS] = {9, 8, 7};

Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String value = "";

void setup()
{
  lcd.begin();
  Serial.begin(9600);
  myservo.attach(A0);
  lcd.backlight();

  if (WiFi.status() == WL_NO_MODULE)
  {
    Serial.println("Communication with WiFi module failed!");
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < "1.0.0") { Serial.println("Please upgrade the firmware"); }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED)
  {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
    delay(10000);
  }

  Serial.println("Connected to wifi");
  printWifiStatus();
}

void loop()
{
  lcd.clear();
  lcd.print("Geef bestelcode");
  char customKey = customKeypad.getKey();
  value = value + String(customKey);
  lcd.setCursor(0, 1);
  lcd.print(value);
  if (customKey == '#')
  {
    String response_Status = "";
    Serial.println("\nStarting connection to server...");

    if ( client.connect( server, 80 ) )
    {
      value.remove(16);
      Serial.println(value);
      Serial.println("connected to server");

      // Make a HTTP request:
      client.println("GET /api/boxes/1444/code/" + value + " HTTP/1.1");
      client.println("Host: parcelbox.1819.caro.deweze.nxtmediatech.eu");
      client.println("Connection: close");
      client.println();
    }

    StaticJsonBuffer<500> jsonBuffer;

    if ( client.connected() )
    {
      String response = "";
      bool begin = false;

      // I do not understand why you have to use  || ! begin
      // If the client has no content available, you can not read some
      // It doesn't matter if begin is true or false.
      // Or am I missing something?
      while ( client.available() || ! begin )
      {
        char c = client.read();

        if ( c == '{' )  { begin = true;    }
        if ( begin )     { response += (c); }
        if ( c == '"}' ) { break;           }

        delay(1);
      }

      // Why do you parse the json text for a special
      // attribute and then parse it again into a json object
      // where you can read this attribute?
      int start = response.indexOf("status\":\"") + 11;
      int end = start + 3;
      response_Status = response.substring(start, end);

// I commented this out because you do not use the root variable
// in the following code
//      JsonObject& root = jsonBuffer.parseObject(response);
//      if (!root.success())
//      {
//        Serial.print("parseObject(");
//        Serial.print(response);
//        Serial.println(") failed");
//        break;
//      }

      Serial.println(response_Status);
      if (response_Status == "200")
      {
        Serial.println("response state == 200");

        // First open the box

        // 0° means open
        myservo.write(0);
        delay(175);

        // Then inform the user how to close it

        lcd.clear();
        // I added the cursor positioning.
        // As far as I know clear does not reset the cursor.
        lcd.setCursor(0, 0);
        lcd.print("Box openend ,press");
        lcd.setCursor(0, 1);
        lcd.print(" * to close");

        // then check if the user wants to close it
        char key;
        do
        {
          key = customKeypad.getKey();
          if (key == '*')
          {
            // 90° means locked
            myservo.write(90);
            value = "";
          }
        }
        while( key != '*' );

      }
      else
      {
      // I replaced the else if by a simple if
      // as (response_Status != "200") is the else case
      // of (response_Status == "200")
        Serial.println("response state != 200");

        lcd.clear();
        // "set cursor" added
        lcd.setCursor(0, 0);
        lcd.print("wrong code or");
        lcd.setCursor(0, 1);
        lcd.print("already deliverd");

        delay(175);
        value = "";
      }
      // I change the while loop into an if block
      // so you don't need a break; here
    }

// Here you could enter a halt state without a reason.
// Even you won't expect to halt here.
//    if (!client.connected())
//    {
//      Serial.println();
//      Serial.println("disconnecting from server.");
//      client.stop();
//
//      // do nothing forevermore:
//      while (true);
//    }
  }

  if (customKey == '*')
  {
    // 90° means locked
    myservo.write(90);
    value = "";
  }

  // for optimal lcd screen view
  delay(175);
}

void printWifiStatus()
{
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

```

**EDIT**

This edit is related to the updated version of your program.

If you close the box with a key press you also stop the client with the last line.

Please remove the following line from the program.

```
// lock box and reset value
if (customKey == '*')
{
  Serial.println("CLOSE BOX");
  myservo.write(90);
  value = "";
  // remove this as you can not connect a stopped client
  // client.stop();
}

```

---
Tags: loop, arduino-uno-wifi
---


# Question
Title: How can I interrupt a delay() when a button is pressed?
I have created a device that allows my son to track time spent on activities and exchanges that time into a time he can use with his electronics (eTime).

Full code in GITHUB

I am having trouble coding the part of the code that handles the countdown from his earned eTime. As it is right now it can count down and give him a warning when his eTime has run out, but the process can't be interrupted.

I would like to have him be able to stop his eTime and use the remainder later. I tried putting the function in a while loop.

```
while(digitalRead(button_9)==LOW){
    delay(60000);
    avail_time -= 1;
    if(avail_time<0){
      playAlarm();
      return;
}

```

This one registers the keypress but ignores the delay.

I have also tried using a for loop to count down and another to check every second for a keypress.

```
void useTime() {
  for(int i=avail_time+1; i>0; i--){
    displayTime(i);
    for(int minute=60; minute>0; minute--){
      if(digitalRead(button_9)==HIGH){
        avail_time = i;
        return;
      }
      delay(1000);
    }
  }
  while(digitalRead(button_9)==LOW){
    tone(buzzer, 2000);
    }
  noTone(buzzer);
  avail_time=0;
  displayOptions();
  return;
 }

```

That one does not register the keypress.

# Answer
> 1 votes
You can use the millis function to check the current 'time'. If you store this, and later call this function again, by subtracting you can see how much time has been passed. so instead of `delay(500)` you use `if (millis() - timeStamp >= 500) { ...` to continue your code.

As others said in comments, you also need to debounce to prevent multiple button triggers.

**Edit: Debouncing**

There is not a library for debouncing (at least not one on the Arduino site), but you can easily copy the needed code from the following sketch:

Arduino Debounce

---
Tags: arduino-uno, programming, arduino-ide, code-review
---


title: Function to control servos

text:
# Question
Title: Function to control servos
I'm trying to control 6 servos while writing a lean code. I think the function call isn't correctly yet and I think that the variables (pos\_n, open\_n, servo\_1) in the for loop do not get inserted, but instead the string just gets inserted.

I think I have come a long way to not make this a bulky code.

What changes makes this function working, so that the call openValve(1) and openValve(2); work for both servos?

```
#include <Servo.h>
const int buttonPin = 2;
int buttonState = 0;

Servo servo_1;
const int pos_1 = 0;
const int open_1 = 105;
const int clos_1 = 10;
//Servo servo_2;
//const int pos_2 = 0;
//const int open_2 = 104;
//const int clos_2 = 9;

String servo_n, pos, pos_n, servo, openServo, open_n;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  servo_1.attach(11);
}

void loop() {
  openValve(1); // call the function
  while (true);
}

void openValve(n) {
  int n = 3;
  pos = "pos_";
  pos_n = (pos + n);
  Serial.println(pos_n);

  servo = "servo_";
  servo_n = servo + n;
  Serial.println(servo_n);

  openServo = "open_";
  open_n = openServo + n;
  Serial.println(open_n);

  // DONT USE STRING BUT THE VARIABLE CONTENTS ??
  for (pos_n = pos_n; pos_n <= open_n; pos_n += 1) {
    servo_n.write(open_n);
    delay(10);
  }
}

```

# Answer
> 1 votes
I think you are totally misunderstanding, about variables and types and how using multiple servos with 1 function can work, and that this is your real question and not the thing with inserting variables (whatever you mean by that).

You are trying to put together a string and use it as variable name. That does not work. A string is only a variable/instance of type/class `String`. It cannot have methods of the `Servo` class. Also function parameters each have their own type. You cannot provide a value of a different type to this parameter. `Servo.write()` takes an integer value. It cannot use a String value. Thus the code inside the for loop is nonsense and won't compile. I would suggest doing some C++ tutorials from the web, that explain, how variables work in C++.

Instead you have to use multiple variables of the type `Servo`, one for each servo motor, that you are using. These variables are instances of the `Servo` class, which implements all the servo related functions (like write) Each motor gets it's own pin on the Arduino. You can put these `Servo` objects into an array, so that they can be indexed by an integer number. For example you can define the following variable in the global scope:

```
#define N_SERVOS 6
Servo servos[N_SERVOS];

```

This creates an array of type `Servo` with 6 elements. Each element is one independent servo object. (Note, that I used a define to easily change the number of attached servos when changing the code). You can reach an individual servo object by indexing it:

```
servos[3].write(pos);

```

This would write a new position to servo 4 (4 because array indices are starting from 0). Now we need to attach each Servo object to one pin of the Arduino. I would create an extra array, which contains the corresponding pin numbers - also at global scope:

```
int servo_pin[N_SERVOS] = {6, 7, 8, 9, 10, 11};

```

Here I used pins 6 to 11, but you can change them, as you like. Then in the `setup()` function we loop over our servo elements and corresponding pin numbers and attach the servo objects to the pins:

```
for(int i=0;i<N_SERVOS;i++){
    servo[i].attach(servo_pin[i]);
}

```

And now you can rewrite your `openValve()` function corresponding to that. I don't understand, what you wanted the servo to do in the for loop, so I will leave this to you. First you need to correct the syntax at the function declaration. You didn't specify the type of the parameter `n`. It has to look like:

```
void openValve(int n){

```

And then you shouldn't declare a new variable with the same name, so delete the line `int n=3;`. Then you can delete all the weird string concatiation. Then you need to fix the for loop (as I wrote I will leave that to you, since you didn't explain, what the servo should actually do there). And finally you need to rewrite the servo write line like described above:

```
servo[n].write(new_pos);

```

Note, that `new_pos` is just a placeholder here, for whatever values you need to write to the servo (as already said, I don't understand, what exactly you want the servo to do).

---

> what I then should use instead of the String object?

The `String` class from the Arduino framework can get you into memory trouble (to be exactly memory fragmentation). You can read Majenko's blog post about Arduino Strings for further explanations.

Instead you should use `char` arrays aka C-Strings. You create a buffer with a fixed length, that is big enough to hold the biggest chunk of data, that you need to process. Let's say you need at max 30 characters. Every C-String is terminated by a zero ('\0'). This zero also needs space in the buffer. So the actual buffer size is 31.

```
char string_buffer[31];

```

You can even directly initialize it with a string value:

```
char string_buffer[31]="Teststring";

```

You can use `sprintf()` to put a formatted string into the buffer. For example a string with a number:

```
sprintf(string_buffer, "Number: %d", 50);

```

will put the string "Number: 50" to the buffer and will terminate it with a zero.

---
Tags: arduino-uno, servo, variables, functions
---


# Question
Title: Arduino GPS Simulator: SoftwareSerial Issues
For my project, i need my Arduino Uno to simulate a GPS. To do this, I need to:

* Generate a 5V Pulse once a second (no problem)
* Send a $GPRMC NMEA sentence with the current time over RS-232 (i've got an RS-232 shield)

The GPRMC message i need to send is the following:

$GPRMC,075832.293,A,4042.695,N,07400.796,W,,,080120,000.0,W\*63

Where the first part is the time, and needs to change. I basically implemented it as:

```
// Setup
String prefix = "$GPRMC,";
String gprmc  = "075832.293";
String suffix = ",A,4042.695,N,07400.796,W,,,080120,000.0,W*63";
String all = prefix + gprmc + suffix;
char* buff = (char*) malloc(sizeof(char)*all.length()+1);

```

Then, in the loop-code i update the time and want to send the message:

```
//...inside the condition that gets executed once a second
gprmc = String(gprmc.toFloat()+1);
all = prefix+gprmc+suffix;
all.toCharArray(buff, all.length()+1);
mySerial.write(buff);

```

I'm using an RS-232 shield, which shows me when a message is being sent by blinking an LED. However, is only seems to work, if i shorten the all string, i.e.: Works:

```
all = prefix+gprmc;

```

Does not work:

```
all = prefix+gprmc+suffix;

```

Is it possible that the message is just too long to send? Is there a way I can fix this? Because it's crucial to send the whole message.

Note: I'm currently working on an Arduino Uno, but I'm switching to an arduino Leonardo today. I currently have low memory available (77% used). could this add to the problem?

Thank you so much for your help!! :)

# Answer
> 2 votes
First off, some comments about your code:

* Never use `String` unless it is absolutely unavoidable
* Unless you have a `free()` to balance your `malloc()` you will run out of memory almost immediately
* There is never any need to concatenate strings to send through serial like that.

Instead of what you are currently doing, just scrap the `String` usage and your `buf` variable completely. There is no need to concatenate things together - serial sends data one character at a time, so you're gaining nothing by concatenating and only causing yourself more problems.

How you *should* be doing it:

```
// The changing value as a float
float gprmc=75832.293;
// Print the prefix
mySerial.print(F("$GPRMC,"));
// Pad the value with zeroes
if (gprmc < 10) mySerial.print(F("0"));
if (gprmc < 100) mySerial.print(F("0"));
if (gprmc < 1000) mySerial.print(F("0"));
if (gprmc < 10000) mySerial.print(F("0"));
if (gprmc < 100000) mySerial.print(F("0"));
// Print the value with 3 decimal places
mySerial.print(gprmc, 3);
// Finally print the suffix
mySerial.println(F(",A,4042.695,N,07400.796,W,,,080120,000.0,W*63"));

```

Note the use of the `F()` macro to further reduce RAM usage by keeping the string constants in flash memory.

---
Tags: arduino-uno, softwareserial, gps, rs232
---


# Question
Title: Is it possible to use the Arduino Due's specials pins for digital writing and reading?
Hello the arduino documentation on the due specifies the pin mapping of the pins.I am making a custom board using the dues schematics and i am running still a bit low on pins. Also some of the special pins offer a better position for traces.

So is it possible digitalWrite()/digitalRead() the specials pins such as:

* RX (0-3)
* TX (0-3)
* SDA (0-1)
* SCL (0-1)
* CANRX
* CANTX
* LED RX
* LED TX
* MISO
* MOSI
* SCLK

As for the SPI and i2c lines i will be using them for the original purpose,but i would like to take the opportunity to know anyway.

I do not own a due so unfortunately i can not test it

# Answer
> 1 votes
Yes, although you may need to modify the variant files to allow access to them.

Every function on the SAM3X8E is a "multiplexed" function. That is, it shares pins with other functions. For example CANTX0 is an alternative function on pin PA0.

You can find all the alternative function mappings on page 40 of the datasheet.

You may find that many of these pins already have an Arduino pin number assigned to them in the variant file. If that is the case then you can just use it as you would any digital IO pin.

I have included the comments from the variant files here for quick reference:

```
/*
 * DUE Board pin   |  PORT  | Label
 * ----------------+--------+-------
 *   0             |  PA8   | "RX0"
 *   1             |  PA9   | "TX0"
 *   2       TIOA0 |  PB25  |
 *   3       TIOA7 |  PC28  |
 *   4       NPCS1 |  PA29  |
 *           TIOB6 |  PC26  |
 *   5       TIOA6 |  PC25  |
 *   6       PWML7 |  PC24  |
 *   7       PWML6 |  PC23  |
 *   8       PWML5 |  PC22  |
 *   9       PWML4 |  PC21  |
 *  10       NPCS0 |  PA28  |
 *           TIOB7 |  PC29  |
 *  11       TIOA8 |  PD7   |
 *  12       TIOB8 |  PD8   |
 *  13       TIOB0 |  PB27  | LED AMBER "L"
 *  14       TXD3  |  PD4   | "TX3"
 *  15       RXD3  |  PD5   | "RX3"
 *  16       TXD1  |  PA13  | "TX2"
 *  17       RXD1  |  PA12  | "RX2"
 *  18       TXD0  |  PA11  | "TX1"
 *  19       RXD0  |  PA10  | "RX1"
 *  20             |  PB12  | "SDA"
 *  21             |  PB13  | "SCL"
 *  22             |  PB26  |
 *  23             |  PA14  |
 *  24             |  PA15  |
 *  25             |  PD0   |
 *  26             |  PD1   |
 *  27             |  PD2   |
 *  28             |  PD3   |
 *  29             |  PD6   |
 *  30             |  PD9   |
 *  31             |  PA7   |
 *  32             |  PD10  |
 *  33             |  PC1   |
 *  34             |  PC2   |
 *  35             |  PC3   |
 *  36             |  PC4   |
 *  37             |  PC5   |
 *  38             |  PC6   |
 *  39             |  PC7   |
 *  40             |  PC8   |
 *  41             |  PC9   |
 *  42             |  PA19  |
 *  43             |  PA20  |
 *  44             |  PC19  |
 *  45             |  PC18  |
 *  46             |  PC17  |
 *  47             |  PC16  |
 *  48             |  PC15  |
 *  49             |  PC14  |
 *  50             |  PC13  |
 *  51             |  PC12  |
 *  52       NPCS2 |  PB21  |
 *  53             |  PB14  |
 *  54             |  PA16  | "A0"
 *  55             |  PA24  | "A1"
 *  56             |  PA23  | "A2"
 *  57             |  PA22  | "A3"
 *  58       TIOB2 |  PA6   | "A4"
 *  69             |  PA4   | "A5"
 *  60       TIOB1 |  PA3   | "A6"
 *  61       TIOA1 |  PA2   | "A7"
 *  62             |  PB17  | "A8"
 *  63             |  PB18  | "A9"
 *  64             |  PB19  | "A10"
 *  65             |  PB20  | "A11"
 *  66             |  PB15  | "DAC0"
 *  67             |  PB16  | "DAC1"
 *  68             |  PA1   | "CANRX"
 *  69             |  PA0   | "CANTX"
 *  70             |  PA17  | "SDA1"
 *  71             |  PA18  | "SCL1"
 *  72             |  PC30  | LED AMBER "RX"
 *  73             |  PA21  | LED AMBER "TX"
 *  74       MISO  |  PA25  |
 *  75       MOSI  |  PA26  |
 *  76       SCLK  |  PA27  |
 *  77       NPCS0 |  PA28  |
 *  78       NPCS3 |  PB23  | unconnected!

```

# Answer
> 0 votes
As far as I know you can use them as GPIO too (I know for sure for Arduino Uno/Mega etc., I know for STM32, I would be very surprised if it's not possible for Arduino Due.

Other solutions are using shift registers like:

* 74HC595: For adding upto 32 outputs using SPI
* 74HC565: For adding upto 32 inputs using SPI

Or you can use GPIO extenders using either SPI or I2C.

---
Tags: arduino-due, digital
---


# Question
Title: How to make BLE data accessible to a particular app?
I used the BLE example from here.

But any device can read and write to the advertised characteristic. Is there a way to make the data inaccessible to other devices except for my app somehow. What I would really like to do is something like SDP and then connect and exchange data over RFCOMM but it seems impossible to do so in esp32. I have done it using bluez library on Linux but in case of esp32 I found only one library btstack that is impossible to use with esp-idf because of lack of CMakeLists.txt. Is there some way I can achieve what I want?

# Answer
In general terms, you could simply require a client to authenticate first. This would require a bit of a deviation from the example you linked to (which actually only handles reading of the characteristic) to handle multiple connections and their state, but it should be pretty straightforward.

The Arduino BLE library seems to lack sending quite a bit of information via the callbacks, so you just know there's a connect or disconnect or a write to a characteristic, and not which devices did. This means you won't be able to handle multiple connections at the same time, but making sure you reset your authentication state whenever you receive a connect or disconnect should be enough to prevent anyone but your own client from "talking" to your device.
> 1 votes

---
Tags: bluetooth, esp32
---


title: Connect Arduino to LiDAR via RS-232

text:
# Question
Title: Connect Arduino to LiDAR via RS-232
**Edit: We're so close! Update at bottom!** I'm not sure if this is the right place to ask, but since you helped my so much in the past, I thought it's worth a try.

So as I stated in my last question, I'm using my Arduino Leonardo to simulate a GPS Receiver.

The Arduino is now connected to a Velodyne VLP-16 LiDAR

Here's what the Lidar needs:

I wired it like this:

And wrote the following code:

```
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 1;
unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt = 1000000/triggerFreq; //micros

unsigned long i;

float gprmc = 181721.000;

void setup() {
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();
}

void loop() {
  timestamp = micros()-triggerStartTime;
  if (timestamp>= dt*i+200000)
  {
    digitalWrite(12,HIGH);

    i +=1;
    gprmc += 1;
    mySerial.print("$GPRMC,");
    if (gprmc < 100000) mySerial.print(F("0"));
    mySerial.print(gprmc,3);
    mySerial.println(F(",A,4042.695,N,07400.796,W,,,080120,000.0,W*63"));
    Serial.print("$GPRMC,");
    if (gprmc < 100000) Serial.print(F("0"));
    Serial.print(gprmc,3);
    Serial.println(F(",A,4042.695,N,07400.796,W,,,080120,000.0,W*63"));
    digitalWrite(12,LOW);
  }
  else if (timestamp>=dt*i+100000)
  {
    digitalWrite(11,LOW);
  }
  else if (timestamp>=dt*i)
  {
    digitalWrite(11,HIGH);

  }

}

```

Here's the situation now:

* I'm seeing on the board that the messages are being sent (TX LED flashing)
* I'm also seeing that the pulse is sent correctly (flashing LED)
* I don't measure any voltage on the TX output pin (RS232 pin3) (I'm just using my multimeter, but normally it reacts to such short voltage pulses by blinking an LED)
* I do measure such a pulse on RS232 pin4
* The LiDAR doesn't react to my sent messages

Now my question: Do you see an error in my implementation? Is the message sent correctly?

Thank you sooo much for your help! I'm really appreciating it!

Edit: The LiDAR manual says:

> The supported NMEA sentence and syntax are exactly the same as on the wired (serial) GPS interface. Supported sentence delimiter sequences include (HEX 0D0A, the standard), by itself, and by itself.

To be honest I'm not very familiar with these kind of problems so I'm not sure if these delimiters are already being sent?

Edit Nr2: Ok the following situation:

* I'm actually not sure what changed. The code is still the same as above
* The LiDAR now recognizes SOME of the messages (I can only see the position, so I edited the code to change the position a bit every second, and the Lidar updates its position irregularly but approx. all 10 seconds)
* If anyone knows an explanation, I would be very happy to know. Otherwise, I just keep on trying an will keep you updated!

---

So the following code partially works. That means: the LiDAR recognizes **certain** messages... it seems like those are always the same messages (i incremented the position every second, these are the positions):

* 3015.2746
* 3015.2766
* 3015.2971
* 3015.3107
* 3015.3117

I displayed all the times when something was sent, and i could not find any differences between the messages that worked and those that didn't work.

**One more followup:** If I try to increment `pos+=0.0001`, it does not work... it seems like i can only change up to 3 decimals. I don't understand why, since the float uses 4 bytes, so this should be no problem to store?! helpppp

Ok so here is the code for now:

```
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 1;
unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt = 1000000/triggerFreq; //micros
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;

unsigned long i;

int hh = 04;
int mm = 51;
int ss = 00;
float pos = 3015.2307;
bool msg;

void setup() {
  // put your setup code here, to run once:
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();
}

void loop() {
  timestamp = micros()-triggerStartTime;
  if (timestamp>= dt*i+350000)
  {
    pos +=0.001;
    digitalWrite(12,HIGH);
    i +=1;
    if (ss == 59)
    {
      ss=0;
      if (mm==59)
      {
        mm=0;
        hh+=1;
      }
      else mm+=1;
    }
    else ss+=1;

    ts_msg_high = micros();
    mySerial.print("$GPRMC,");
    if (hh<10) mySerial.print(F("0"));
    mySerial.print(hh);
    if (mm<10) mySerial.print(F("0"));
    mySerial.print(mm);
    if (ss<10) mySerial.print(F("0"));
    mySerial.print(ss);
    mySerial.print(".000,A,");
    mySerial.print(pos,4);
    mySerial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");

    // Print Debug Messages
    digitalWrite(12,LOW);
    ts_msg_low=micros();
    Serial.print("PPS at: ");
    Serial.print(ts_pps_high);
    Serial.print("\t PPS low after: ");
    Serial.print(ts_pps_low-ts_pps_high);
    Serial.print("\t MSG high after: ");
    Serial.print(ts_msg_high-ts_pps_high);
    Serial.print("\t MSG low after: ");
    Serial.print(ts_msg_low-ts_pps_high);
    Serial.print("$GPRMC,");
    if (hh<10) Serial.print(F("0"));
    Serial.print(hh);
    if (mm<10) Serial.print(F("0"));
    Serial.print(mm);
    if (ss<10) Serial.print(F("0"));
    Serial.print(ss);
    Serial.print(".000,A,");
    Serial.print(pos,4);
    Serial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
  }
  else if (timestamp>=dt*i+100000)
  {
    digitalWrite(11,LOW);
    if (msg==true)
    {
      msg = false;
      ts_pps_low = micros();
    }

  }
  else if (timestamp>=dt*i)
  {
    digitalWrite(11,HIGH);
    if (msg==false)
    {
      msg = true;
      ts_pps_high = micros();
    }
  }

}

```

You can see my output as well:

```
PPS at: 2001060  PPS low after: 100000   MSG high after: 350016  MSG low after: 427132$GPRMC,045103.000,A,3015.2336,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 3001060  PPS low after: 100004   MSG high after: 350004  MSG low after: 427112$GPRMC,045104.000,A,3015.2346,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 4001056  PPS low after: 100000   MSG high after: 350004  MSG low after: 427116$GPRMC,045105.000,A,3015.2355,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 5001060  PPS low after: 100004   MSG high after: 350004  MSG low after: 427112$GPRMC,045106.000,A,3015.2365,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 6001056  PPS low after: 100004   MSG high after: 350004  MSG low after: 427116$GPRMC,045107.000,A,3015.2375,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 7001060  PPS low after: 100004   MSG high after: 350004  MSG low after: 427120$GPRMC,045108.000,A,3015.2385,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 8001056  PPS low after: 100004   MSG high after: 350020  MSG low after: 427132$GPRMC,045109.000,A,3015.2395,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 9001060  PPS low after: 100000   MSG high after: 350016  MSG low after: 427160$GPRMC,045110.000,A,3015.2404,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 10001052     PPS low after: 100008   MSG high after: 350020  MSG low after: 427164$GPRMC,045111.000,A,3015.2414,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 11001064     PPS low after: 100000   MSG high after: 350020  MSG low after: 427164$GPRMC,045112.000,A,3015.2424,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 12001056     PPS low after: 100008   MSG high after: 350004  MSG low after: 427152$GPRMC,045113.000,A,3015.2434,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 13001056     PPS low after: 99996    MSG high after: 350020  MSG low after: 427164$GPRMC,045114.000,A,3015.2443,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 14001056     PPS low after: 100008   MSG high after: 350008  MSG low after: 427156$GPRMC,045115.000,A,3015.2453,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 15001052     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045116.000,A,3015.2463,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 16001052     PPS low after: 100000   MSG high after: 350016  MSG low after: 427164$GPRMC,045117.000,A,3015.2473,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 17001056     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045118.000,A,3015.2482,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 18001052     PPS low after: 100000   MSG high after: 350016  MSG low after: 427164$GPRMC,045119.000,A,3015.2492,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 19001056     PPS low after: 100004   MSG high after: 350020  MSG low after: 427160$GPRMC,045120.000,A,3015.2502,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 20001060     PPS low after: 100000   MSG high after: 350004  MSG low after: 427148$GPRMC,045121.000,A,3015.2512,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 21001052     PPS low after: 100004   MSG high after: 350020  MSG low after: 427168$GPRMC,045122.000,A,3015.2521,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 22001064     PPS low after: 100004   MSG high after: 350004  MSG low after: 427148$GPRMC,045123.000,A,3015.2531,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 23001052     PPS low after: 100008   MSG high after: 350020  MSG low after: 427172$GPRMC,045124.000,A,3015.2541,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 24001052     PPS low after: 100008   MSG high after: 350024  MSG low after: 427168$GPRMC,045125.000,A,3015.2551,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 25001056     PPS low after: 100000   MSG high after: 350016  MSG low after: 427168$GPRMC,045126.000,A,3015.2561,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 26001052     PPS low after: 100008   MSG high after: 350024  MSG low after: 427160$GPRMC,045127.000,A,3015.2570,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 27001056     PPS low after: 100000   MSG high after: 350020  MSG low after: 427156$GPRMC,045128.000,A,3015.2580,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 28001060     PPS low after: 100008   MSG high after: 350004  MSG low after: 427144$GPRMC,045129.000,A,3015.2590,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 29001056     PPS low after: 100000   MSG high after: 350020  MSG low after: 427156$GPRMC,045130.000,A,3015.2600,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 30001056     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045131.000,A,3015.2609,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 31001056     PPS low after: 100008   MSG high after: 350004  MSG low after: 427148$GPRMC,045132.000,A,3015.2619,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 32001056     PPS low after: 99996    MSG high after: 350012  MSG low after: 427164$GPRMC,045133.000,A,3015.2629,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 33001056     PPS low after: 100008   MSG high after: 350020  MSG low after: 427164$GPRMC,045134.000,A,3015.2639,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 34001056     PPS low after: 100000   MSG high after: 350016  MSG low after: 427164$GPRMC,045135.000,A,3015.2648,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 35001060     PPS low after: 100004   MSG high after: 350000  MSG low after: 427144$GPRMC,045136.000,A,3015.2658,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 36001060     PPS low after: 100000   MSG high after: 350004  MSG low after: 427148$GPRMC,045137.000,A,3015.2668,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 37001060     PPS low after: 100004   MSG high after: 350004  MSG low after: 427144$GPRMC,045138.000,A,3015.2678,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 38001064     PPS low after: 100004   MSG high after: 350004  MSG low after: 427144$GPRMC,045139.000,A,3015.2687,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 39001060     PPS low after: 100008   MSG high after: 350004  MSG low after: 427152$GPRMC,045140.000,A,3015.2697,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 40001052     PPS low after: 100008   MSG high after: 350024  MSG low after: 427160$GPRMC,045141.000,A,3015.2707,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 41001052     PPS low after: 100000   MSG high after: 350016  MSG low after: 427168$GPRMC,045142.000,A,3015.2717,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 42001060     PPS low after: 100004   MSG high after: 350004  MSG low after: 427148$GPRMC,045143.000,A,3015.2727,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 43001056     PPS low after: 100000   MSG high after: 350020  MSG low after: 427164$GPRMC,045144.000,A,3015.2736,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 44001052     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045145.000,A,3015.2746,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 45001064     PPS low after: 100004   MSG high after: 350004  MSG low after: 427144$GPRMC,045146.000,A,3015.2756,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 46001052     PPS low after: 100004   MSG high after: 350020  MSG low after: 427172$GPRMC,045147.000,A,3015.2766,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 47001056     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045148.000,A,3015.2775,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 48001056     PPS low after: 100000   MSG high after: 350016  MSG low after: 427164$GPRMC,045149.000,A,3015.2785,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 49001060     PPS low after: 100004   MSG high after: 350004  MSG low after: 427144$GPRMC,045150.000,A,3015.2795,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 50001052     PPS low after: 100000   MSG high after: 350016  MSG low after: 427160$GPRMC,045151.000,A,3015.2805,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 51001060     PPS low after: 100004   MSG high after: 350004  MSG low after: 427148$GPRMC,045152.000,A,3015.2814,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 52001056     PPS low after: 100000   MSG high after: 350020  MSG low after: 427164$GPRMC,045153.000,A,3015.2824,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 53001064     PPS low after: 100004   MSG high after: 350000  MSG low after: 427144$GPRMC,045154.000,A,3015.2834,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 54001056     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045155.000,A,3015.2844,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 55001060     PPS low after: 100004   MSG high after: 350020  MSG low after: 427172$GPRMC,045156.000,A,3015.2854,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 56001068     PPS low after: 100004   MSG high after: 350000  MSG low after: 427144$GPRMC,045157.000,A,3015.2863,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 57001060     PPS low after: 99996    MSG high after: 350012  MSG low after: 427160$GPRMC,045158.000,A,3015.2873,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 58001064     PPS low after: 100004   MSG high after: 350004  MSG low after: 427148$GPRMC,045159.000,A,3015.2883,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 59001056     PPS low after: 100000   MSG high after: 350024  MSG low after: 427132$GPRMC,045200.000,A,3015.2893,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 60001060     PPS low after: 100004   MSG high after: 350020  MSG low after: 427124$GPRMC,045201.000,A,3015.2902,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 61001064     PPS low after: 100008   MSG high after: 350004  MSG low after: 427116$GPRMC,045202.000,A,3015.2912,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 62001060     PPS low after: 100008   MSG high after: 350008  MSG low after: 427124$GPRMC,045203.000,A,3015.2922,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 63001060     PPS low after: 100012   MSG high after: 350008  MSG low after: 427120$GPRMC,045204.000,A,3015.2932,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 64001052     PPS low after: 100000   MSG high after: 350020  MSG low after: 427136$GPRMC,045205.000,A,3015.2941,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 65001060     PPS low after: 100008   MSG high after: 350004  MSG low after: 427120$GPRMC,045206.000,A,3015.2951,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 66001064     PPS low after: 100000   MSG high after: 349996  MSG low after: 427116$GPRMC,045207.000,A,3015.2961,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 67001060     PPS low after: 100004   MSG high after: 350004  MSG low after: 427120$GPRMC,045208.000,A,3015.2971,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 68001060     PPS low after: 100000   MSG high after: 350004  MSG low after: 427112$GPRMC,045209.000,A,3015.2980,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 69001052     PPS low after: 100004   MSG high after: 350020  MSG low after: 427164$GPRMC,045210.000,A,3015.2990,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 70001064     PPS low after: 100004   MSG high after: 350004  MSG low after: 427136$GPRMC,045211.000,A,3015.3000,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 71001060     PPS low after: 100004   MSG high after: 350004  MSG low after: 427148$GPRMC,045212.000,A,3015.3010,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 72001064     PPS low after: 100004   MSG high after: 350004  MSG low after: 427144$GPRMC,045213.000,A,3015.3020,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 73001056     PPS low after: 100000   MSG high after: 350016  MSG low after: 427164$GPRMC,045214.000,A,3015.3029,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 74001064     PPS low after: 99988    MSG high after: 350004  MSG low after: 427148$GPRMC,045215.000,A,3015.3039,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 75001052     PPS low after: 100000   MSG high after: 350020  MSG low after: 427164$GPRMC,045216.000,A,3015.3049,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 76001060     PPS low after: 100004   MSG high after: 350000  MSG low after: 427144$GPRMC,045217.000,A,3015.3059,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 77001056     PPS low after: 100008   MSG high after: 350004  MSG low after: 427148$GPRMC,045218.000,A,3015.3068,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 78001060     PPS low after: 100008   MSG high after: 350004  MSG low after: 427152$GPRMC,045219.000,A,3015.3078,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 79001052     PPS low after: 100008   MSG high after: 350020  MSG low after: 427164$GPRMC,045220.000,A,3015.3088,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 80001052     PPS low after: 100000   MSG high after: 350016  MSG low after: 427164$GPRMC,045221.000,A,3015.3098,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 81001056     PPS low after: 100008   MSG high after: 350020  MSG low after: 427164$GPRMC,045222.000,A,3015.3107,N,09749.2872,W,0.67,161.46,030913,,,A*7C
PPS at: 82001060     PPS low after: 100000   MSG high after: 350016  MSG low after: 427172$GPRMC,045223.000,A,3015.3117,N,09749.2872,W,0.67,161.46,030913,,,A*7C

```

# Answer
A number of hints to check, though I can only throw vague observations on the error (EDIT: some hints only make sense with an older version of the question):

* You set the SoftwareSerial to pin 7 for RX and pin 6 for TX, but the TX LED of the board is connected to the *hardware* UART, which is used by `Serial`. So the TX LED reacts to your debug messages sent via `Serial.print()` to the PC. The TX and RX pins on your Arduino board are always connected to the hardware UART, which always is managed by `Serial` and cannot be claimed by `SoftwareSerial`.
* The "SoftwareSerial TX pin" of your Arduino (note: the TX pin *you* set via `SoftwareSerial mySerial(7, 6);`) needs to be connected to RX of the GPS module. Remember: If you transmit something via the transmit line of one device, it needs to be received by the receive line of the other device (T stands for transmit, R for receive, and X for that you must cross the lines). (This hint ignores that you've got a RS232 shield, I realized that only later.)
* The docs state that your gprmc record is accepted in either `hhmmss` or `hhmmss.s` format. Yet you send a string with three places after the dot. I'm not sure whether I misinterpret something here.
* If you just add 1 to gprmc every second, you'll end up sending the equivalent of "18 hours, 17 minutes, 61 seconds" after 40 seconds runtime (because the format is expected to be `hhmmss`), which might or might not confuse the GPS chip.
* Is 9600 baud the correct speed for the GPS receiver? Somewhere in the docs should be a hint about that (I'd expect at least 115200 on devices that are less than 20 years old...).
* The pulse line might follow negative logic, i.e. it normally is HIGH and need to be pulled LOW for the pulse. Check the data sheet whether a LOW pulse is needed, in which case you need to swap HIGH and LOW on the pulse line.
* What is pin 12 (msg\_sent) and why do you need it? Its not mentioned in the schematics. I can only glean that it might signal your RS232 shield that the message has been sent to the RS232 shield and the RS232 UART now may empty its buffer, i.e. actually send the message over the wire to the GPS chip. If this is indeed the case, you signal the RS232 shield that the message has been sent before you actually send the message.
* Try it without the RS232 shield? RS232 is just a specification of "serial protocol" that allows for voltage levels of up to 25V plus a few extra signal lines. By the schematic and wiring, I see that the GPS chip does not use any extra lines and expects a signal level of 5V. With SoftwareSerial, you already output "serial protocol" at 5V signal level from your GPIO pins. From afar, it looks like the RS232 shield inserts more potential points of failure into the communication. Have you got a Serial-to-USB converter to actually check the output of your RS232 shield?
* Your delimiters are not sent. Hex 0D0A is simply CRLF, or "carriage return, line feed" or "the standard line break characters in plain text files on DOS and Windows". Which means: The last `mySerial.print()` would need to be changed to `mySerial.println()`, which is just like `mySerial.print()`, only that it adds a line break at the end.
* Maybe it works if you connect the pin labeled `GPS_RXD_CNT` in the schematics with pin 6 of your Arduino while removing any own wiring from TX and RX of your Arduino.
* Floats do not "store 3 decimal places after the decimal point", they store the significant binary places plus the position of the point. This means: if the number of significant places is big, you lose precision at the end. Converted to decimal, a 32-bit float only has a precision of 6-7 decimal places. A number like (decimal) 100000.01 would lose its last 1, yielding 100000.0; this also is true for 1000000.1 (=1000000.0), 10000001000.0 (=10000000000.0) and 0.000010000001 (=0.00001). So if you add 0.1 to 1234567.0, you'll end up with 1234567.0 -- or in the extreme: 1234567000000.0 + 11111.0 = 1234567000000.0. (Numbers off the top of my head, reality might introduce some rounding between decimal and binary representation, this is just to get the point across -- also, your decimal output will not show this exactly, because a binary representation only is precise for fractions of powers of two after the point).

Also, you might want to add some `Serial.println()` calls for each of your `digitalWrite()` calls, outputting something like "pin 11 (PPS) is now HIGH". Then use the Serial Monitor of Arduino IDE (don't forget to set its baud rate to 9600) to check whether the protocol looks right.
> 1 votes

---
Tags: arduino-uno, arduino-leonardo, gps, rs232
---


title: Information about 'Arduino Nano 33 IoT'

text:
# Question
Title: Information about 'Arduino Nano 33 IoT'
blox w-102 is based on esp32\** which (Esp32) can be used as a standalone chip for projects. Here I want to know **how w-102 and samd21g18a are communicating with each other**. If they are communicating then what is the need of doing so?

# Answer
> 2 votes
The Arduino boards with the NINA module: MKR 1010 WiFi, MKR 4000 vidor, Uno WiFi and Nano 33 IoT use the NINA module for WiFi networking with the WiFiNINA library and for BLE with the ArdunioBLE library. Additionally the flash memory of the NINA module will be available as storage.

The NINA module runs a firmware made by Arduino with ESP32 IDF framework.

I wired MKR ZERO with an ESP32 dev board for the WiFiNINA firmware and library according to MKR 1010 WiFi schematics, which is very similar to Nano 33 IoT. The MCUs are connected on SPI pins and UART for communication. The firmware uses one additional pin to signal to SPI master as 'ready' pin. Also io 0 and enable pin of NINA module are wired to put the ESP32 into flashing mode for firmware upgrade over UART.

On MKR 1010 and Nano33 IoT I2C is connected too. Boot MCU have access to on-board I2C sensors and could in theory communicate over I2C. This is currently not used.

The WiFiNINA library uses SPI communication. SAMD is master, NINA is slave.

The ArduinoBLE library communicates over UART. 'Ready' pin is used to switch to BLE mode in firmware at NINA reset.

The firmware uses io 0 as 'heartbeat' signal for the library.

My wiring:

* the orange wire from MKR pin 5 is connected as reset to EN (with a wire under the ESP32 board)
* io 0 of ESP32 is the yellow wire to MKR pin 4
* VSPI pins 5, 18, 19, 23 (I changed 12 to 19 in firmware). white wire on MKR pin 7 and ESP32 pin 19 is CS
* I used 22 as readyPin (originally 33). white wire on MKR pin 6
* I didn't wire I2C and Serial here

# Answer
> 0 votes
The two chips are connected together by both UART and SPI channels. I am unsure, but I think the main communication is performed over SPI and the UART is only used for programming and debugging of the NINA.

---
Tags: esp32, arduino-nano-ble
---


title: Generate number

text:
# Question
Title: Generate number
I wanna make some sketch to generate number to represent sensor value, with range from high (900) to low (670), that number decrease with range between 1-10 and with some delay of switching number with range from 5-15 seconds:

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

    void number(){
      int sensor = 0;                  //sensor variable
      int a = random(0, 10);           //range subtraction sensor value
      int delay = random(5000, 15000); //range delay switching value
      for(sensor = 900; sensor >= 670; sensor -=a){ //iteration sensor value with range 670-900
        Serial.println(sensor);
        delay(delay);}
    }

    void loop() {
    number();
    }

```

with output:

* 900 (delay 7 sec)
* 894 (delay 3 sec)
* 988 (delay 5 sec)
* 979 (delay 9 sec)

The sketch above was work as well, **but i still can't using variable "sensor" result after iteration "for" in void loop**. I hope you can help me, thanks.

# Answer
> 2 votes
```
int sensor = 900;                 //variabel sensor

void setup() {
  Serial.begin(9600);
  while (!Serial);
  randomSeed(analogRead(A0));
}

int number() {
  int a = random(0, 10);          //range pengurang nilai sensor
  int d = random(500, 1500); //range delay perubahan nilai
  if (sensor < 670) {
    sensor = 900;
  }
  sensor -= a;
  delay(d);
  return sensor;
}

void loop() {
  int val = number();
  Serial.println(val);
}

```

I modified the delay for test.

randomSeed ensures different random values at every run

EDIT: a not blocking version which returns the same values for random interval:

```
int sensor = 900;                 //variabel sensor
unsigned long nextChangeMillis = 0;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  randomSeed(analogRead(A0));
}

int number() {

  if (millis() < nextChangeMillis)
    return sensor;

  int a = random(0, 10);          //range pengurang nilai sensor
  int d = random(500, 1500); //range delay perubahan nilai
  if (sensor < 670) {
    sensor = 900;
  }
  sensor -= a;
  nextChangeMillis += d;
  return sensor;
}

void loop() {
  int val = number();
  Serial.println(val);
}

```

---
Tags: arduino-uno, arduino-mega, c++, wires, resistor
---


# Question
Title: Arduino randomly freezes during runtime?
I'm currently trying to create a traffic simulation project on Arduino, where it can change lights, open a gate, and turn on street lamps based on light. If anybody could help me diagnose why my arduino is behaving this way, that'd be extremely appreciated. Here is my code, if it helps you understand.

```
//Libraries Used
#include<Servo.h>

//Variable Declaration
int red1 = 10;
int yellow1 = 9;
int green1 = 8;
int red2 = 13;
int yellow2 = 12;
int green2 = 11;
int debug = 3;
int PIR = 5;

int button1 = 2;
int buttonState = 0;

int light = 0;

unsigned long previousTime = 0;
unsigned long currentTime = 0;
int currentState = 0;

int currentPIR = 0;
int pirState = LOW;

Servo servo;

void setup()
{
  pinMode(red1, OUTPUT);
  pinMode(yellow1, OUTPUT);
  pinMode(green1, OUTPUT);
  pinMode(red2, OUTPUT);
  pinMode(yellow2, OUTPUT);
  pinMode(green2, OUTPUT);
  pinMode(debug, OUTPUT);

  pinMode(PIR, INPUT);

  pinMode(button1, INPUT);

  servo.attach(4);
  servo.write(90);
}

void loop()
{

  currentPIR = digitalRead(PIR);
  if(currentPIR == 1){
    servo.write(180);
  }else{
    servo.write(90);
  }

  buttonState = digitalRead(2);
  light = analogRead(A0);

  if(light > 100){
    digitalWrite(debug, HIGH);
  }else{
    digitalWrite(debug, LOW);
  }

  if(buttonState == HIGH){
    if(currentState == 3){
      digitalWrite(debug, HIGH);
      currentState++;
    }
  }
  //Using millis() instead of delay(), so program doesn't pause completely.
  currentTime = millis();
  changeLights();
}

void changeLights(){
  if(currentState == 0){
    //Red, Green
    digitalWrite(red2, LOW);
    digitalWrite(red1, HIGH);
    digitalWrite(green2, HIGH);
    asyncDelay(4000);
  }
  else if(currentState == 1){
    //Red, Yellow
    digitalWrite(green2, LOW);
    digitalWrite(yellow2, HIGH);
    asyncDelay(2000);
  }
  else if(currentState == 2){
    //Red, Red
    digitalWrite(yellow2, LOW);
    digitalWrite(red2, HIGH);
    asyncDelay(750);
  }
  else if(currentState == 3){
    //Green, Red
    digitalWrite(red1, LOW);
    digitalWrite(green1, HIGH);
    asyncDelay(4000);
  }
  else if(currentState == 4){
    //Yellow, Red
    digitalWrite(green1, LOW);
    digitalWrite(yellow1, HIGH);
    asyncDelay(2000);
  }
  else if(currentState == 5){
    //Red, Red
    digitalWrite(yellow1, LOW);
    digitalWrite(red2, HIGH);
    asyncDelay(750);
  }
}

void asyncDelay(int delayTime){
  if(currentTime - previousTime == delayTime){
    currentState++;
    previousTime = currentTime;
    if(currentState == 6){
      currentState = 0;
    }
  }
}

```

# Answer
> 0 votes
You should replace:

```
if(currentTime - previousTime == delayTime){

```

with

```
if(currentTime - previousTime >= delayTime){

```

There is always a chance that, since you are using a servo which is quite intensive with interrupts, that `millis()` may skip a beat and that statement can never be true.

---
Tags: arduino-uno
---


# Question
Title: How to transmit data from Arduino to Raspberry Pi?
I am planning to build a network with five Arduino Mega devices, each of which will collect data using multiple sensors. Each Arduino will periodically transmit the sensor data to a gateway Raspberry Pi using XBees. As it is the first time I am working with Arduino and Raspberry Pi, I need help with the following:

1. Which protocol to use to transmit data from Arduinos to the Raspberry Pi? Do I have to write code for both Arduino and Raspberry Pi or are there existing solutions that I can use for this purpose?
2. Does MQTT, Node-RED or Node.js have any role in the above?

Thank you for your advice!

A.

# Answer
> 1. Which protocol to use to transmit data from Arduinos to the Raspberry Pi? Do I have to write code for both Arduino and Raspberry Pi or are there existing solutions which I can use for this purpose?
> 2. Does MQTT, Node-RED or Node.js have any role in the above?

I have searched, explored, read and found that MQTT can be used to send and receive data from Arduinos to RaspberryPi as in \[1\] and \[2\]. So, no need to design and develop a new protocol.

MQTT libraries, such as PubSubClient \[3\] are available for Arduino. So Arduino code can use these libraries and no need to write much code either.

Simple and straight!

A.

\[1\] https://funprojects.blog/2018/03/04/arduino-talking-mqtt-to-node-red/

\[2\] https://iotdesignpro.com/projects/interface-arduino-with-node-red-to-send-sensor-data-on-webpage

\[3\] https://www.arduinolibraries.info/libraries/pub-sub-client
> 1 votes

---
Tags: arduino-mega, xbee, raspberrypi, mqtt, node.js
---