# Question
Title: Networking Multiple Arduinos -- Is It "Rocket Science?"
Have a set of Arduinos that need to swap data--for a model rocket launch controller!

How to send 24 bits of info (launch commands) from a "master" Arduino, 12 bits each to two "slave" Arduinos that are 15' to 150' away from the "master.

Each "slave" needs to send 12 bits of info (continuity statii) to the "master."

"Master" \<--- 15' to 115' ---\> "Slave 1" \<--- 10' to 35' --\> "Slave 2"

Seems too long for I2C?

# Answer
The best solution would be to use an RS485 adapter connected to each Arduino via serial port. This is a tried and true solution that is perfect for a setup like this and only costs a few bucks of extra hardware per node.

If you can't use additional hardware, you can also create a poor-man's current loop system like RS485 using normal Arduino pins since they are capable of sourcing and sinking 20mA.

With either of these solutions, you can send however much data as you want as long as you have some kind of minimal protocol to serialize it into a sequence of bits on the wire. To send 12 bits, you might just define a start condition as an idle "0" on the wire for a certain period of time, followed by a "1" start bit, followed by you 12 data bits, followed maybe a parity bit or a checksum, and completed by a "1" stop bit.

Check out how, say RS232 or RS485 serialize bits to get an idea of how this works. If you end up using hardware that only supports sending data in 8 bit chunks, then you could, say, send two bytes per data "packet" where each byte has 6 bits of your data, plus one bit that indicates if ths byte is the first group of 6 bits or the second group, and then one bit of parity for error checking.
> 1 votes

# Answer
I've got I2C to work reliability between Arduinos with different byte sizes. I have copied the test code below. Note that there is separate code for sending and receiving. It may need to be tweaked but contains the basic idea.

One (or more) Arduinos sends to main I2C controller:

**Sender Code:**

```
//sender test

#include <Wire.h>

#include <Wire.h>
#define NUMDATA 4

byte byteData[2 * NUMDATA]; //= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

//test

void setup()
{
  Wire.begin(3);                // join i2c bus with address #3
  Wire.onRequest(requestEvent); // register event
}

void loop()
{
int aData;
  for(int i = 0; i < NUMDATA; i++){
    aData = analogRead(i);

    byteData[i*2 + 1] = ((aData >> 8)  & 0xFF);
    byteData[i*2] = (aData & 0xFF);

   // memcpy((void *)byteData[i*2], (void *) analogRead(i), sizeof(int));
  }

}

void requestEvent()
{
  Wire.write(byteData, 2 * NUMDATA);
}

```

**Receiving Code:**

```
#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for main controller)
  Serial.begin(9600);  // start Serial for output
}

void loop()
{

  getSenderData();

  Serial.println("Hello");
  delay(500);
}

void getSenderData() {
//Gets sensor data for one grid

    //Byte Array to get raw bytes
    byte ICdataAsBytes[8];
    int i = 0;

    Wire.requestFrom(3,8);    // request 6 bytes from sending device #2

    while(Wire.available())    // sender may send less than requested
        ICdataAsBytes[i++] = Wire.read();

    int *tempData =(int*)&ICdataAsBytes;

    for( i = 0; i < 4; i++)
        Serial.println(tempData[i]);

}

```
> 1 votes

---
Tags: arduino-mega
---


# Question
Title: How to call multiple delayed functions using a single millis()
I am working in a project where I need to call more than 1 functions actually 4 functions using a single millis()

Here is the code below.

```
 unsigned long then = 0;

 void loop(){

     unsigned long now = millis();

     if(now-then >=0){

         Serial.println("Function 1 called");

     }else if(now-then>=2000){

         Serial.println("Function 2 called");

     }else if(now-then>=4000){

         Serial.println("Function 3 called");

     }else if(now-then>=6000){

        Serial.println("Function 4 called");

         Serial.println("The end");

         then = now;
     }
 }

```

All the functions above gets run successfully but not in a proper sequence.

The running sequence of the functions seem to be very improper and random.

The 'function 1' gets executed in a proper sequence and timing but rest of the others are making a messy output.

How can I fix it please?

Thanks.

# Answer
> 2 votes
The current structure with multiple if statements and on timestamp variable does only work, if you also check for `millis()-then` being smaller than the next interval. Otherwise the first if statement will always be executed.

I think it gets easier, when you use only one if statement, but put the intervals in an array. In that if statement you can either use a `switch` statement to execute the code for the corresponding interval, or use a function pointer. Somewhat like this (untested):

```
unsigned long then = 0;
unsigned long intervals[4] = {0, 2000, 4000, 6000};
int current_interval_index = 0;

...

void loop(){
    unsigned long now = millis();
    if(now-then >= intervals[current_interval_index]){
        switch(current_interval_index){
            case 0:
                Serial.println("Function 1");
                break;
            case 1:
                Serial.println("Function 2");
                break;
            case 2:
                Serial.println("Function 3");
                break;
            case 3:
                Serial.println("Function 4");
                break;
        }
    then = now;
    current_interval_index = (current_interval_index + 1) % 4; // increment index and wrap it back to zero, if it goes to 4
    }
}

```

That way you can easily extent for more functions and the intervals are conveniently managed in an array. Note, that the intervals add up here. So function 4 executes after 2s+3s+6s = 11s.

# Answer
> 0 votes
your `else` in that set of `if`'s is causing only a single if to be possible to be true at any one time, and once the `now-then` line up, only the first one in the line-up will ever execute. remove the `else` from your if block. treat each if as its own thing. i.e.

```
if(now-then >=0) { /* do thing 1*/ }
if(now-then >=1000) { /* do thing 2*/ }
if(now-then >=2000) { /* do thing 3*/ }
if(now-then >=3000) { /* do thing 4*/ }

```

that way, even if the conditions line up, all the blocks will be checked, and all the `if`'s that resolve true, will execute.

---
Tags: arduino-uno, millis
---


title: Accelerometer Orientation (LIS3DH)

text:
# Question
Title: Accelerometer Orientation (LIS3DH)
Newbie here! I’m trying to make a pocket level using an LIS3DH but I don’t know how to “reset” all the axis to start reading from a certain orientation since my LIS3dh won’t be mounted flat and will change often. Ideally whenever the level starts it would start reading everything at 0 no matter the orientation. I’m sure it’s just math, but it’s way over my head to begin to understand it.

Starting with the absolute basics I’m using the adafruit lib. I can easily get all the readings, and I understand they are acceleration forces. But how do I start them all from 0?

Initially I was thinking to take the very first reading and store it, then add or subtract the new readings from the originals based on if the new numbers are higher or lower than original (subjectively) but that only works in some instances which means that it wasn’t a good solution.

I don’t have specific code to share as I’m using the adafruit LIS3DH example.

Here’s a reading from the sensor of it not flat

`X: -11408 Y: -3152 Z: 10560 X: -6.87 Y: -1.87 Z: 6.27 m/s^2`

And here’s readings closer to a flat surface

`X: -80 Y: 704 Z: 16176 X: -0.02 Y: 0.46 Z: 9.86 m/s^2`

# Answer
> 2 votes
Consider taking on this project in sever steps. Some you might do now and other later if necessary

First, accelerometers do not usually need alignment. But if accuracy and reproducibility is important, a project may benefit from finding any offset a single accelerometer may need and finding any magnitude adjustments between the three accelerometers. Using gravity rotate each accelerometer through their maximum negative and positive values. Use these values to find an offset such that the absolute values are equal for each individual accelerometer. Then select one accelerometer as the bases and find the appropriate coefficients to normalize the other two accelerometers such that the absolute values of all maximums and minimum are equal. As hinted, this is one of the step you can skip until later if necessary. If you need a more thorough explanation you can find it in section 2 of this STMicro document.

To find angles it would be best to consider the classic airplane example where pitch (nose up or down) and roll (rotation around the axis passing through the nose and tail). Here is a good submersible Arduino project to consider. In this project the accelerometer Z axis is pointed down and the X to the side. To find ROLL the author calculates the inverse tangent of the negative of the ratio of acceleration in the X direction over the acceleration in the Z direction.

The pitch calculation is a bit more involved. This can be found by taking the inverse tangent of the acceleration in the Y direction over the square root of the sum of the square of the X plus Y acceleration.

That out of the way, now consider how to zero the angles out. First decide on if you will adjust the roll or the pitch. Let's consider the roll case. Record the current roll angle and subtract it from the current calculated roll angle before displaying it as zero. Now rotate your accelerometer such that you do it around the Y axis (remember, we are only considering the roll case and do not want to change the Y accelerometer's reading!). If you have done the math correctly, the displayed angle will be the difference between when you started and finished your rotation.

All that out of the way, now consider what would happen if you rotated your accelerometer through a roll position where the acceleration in the Z direction falls to zero. Your trigonometric inverse tangent function for roll would go to infinity! In the physical world, where gimbals are used for air and space navigation, this is referred to as Gimbal lock!

What to do about Gimbal lock?! Well, it's a story that starts in 1843 (yeah, that does sound odd doesn't it WRT air and space navigation). In short, if you stop using classical trigonometry to convert acceleration to angle an start using Quaternions you avoid Gimbal lock entirely. Quaternions use complex numbers to describe rotation in 3D space. People who write 3D gaming programs absolutely love how Quaternions simplify their efforts. This is another of those steps you don't have to do. But doing so will make your project all the more robust.

(BTW, this is the STMicro LIS3DH data sheet.)

---
Tags: arduino-uno, arduino-mega, accelerometer
---


# Question
Title: Why ATMEGA328P U-TH doesn't answer to USBasp but work fine with Arduino as ISP?
I ordered ATMEGA328P AU from China recent but I got "ATMEGA328P U-TH". which seem super problematic. I try to use USBasp to burn bootloader but it fail and show error message as shown.

```
avrdude: error: program enable: target doesn't answer. 1
avrdude: initialization failed, rc=-1
     Double check connections and try again, or use -F to override
     this check.

```

which I believed many people face same situation as mine. Then I accidentally found the solution by using Arduino as ISP which successfully birn bootloader. After that I can use USBasp to upload sketch or burn bootloader. I don't understand what happen here. Note: I solder ATMEGA328P U-TH in SMD package to Arduino UNO clone.

# Answer
> -1 votes
If you want to upload a sketch via any other interface than ISP, the atmega needs a bootloader.

The bootloader basically is a piece of software which is stored in a dedicated flash section, the "bootloader section". Code stored in this bootloader section has the special ability to write to parts of flash memory where the actual program is stored (this is called the "application section"). In general, a program can not overwrite its own flash section, so the bootloader and the application need to be stored in different sections/partitions.

In principle, a bootloader can do whatever a normal sketch could do: toggle pins, access eeprom, read UART/I2C/etc... and as it can also write to the "application section", you can make it read data from any interface and transfer it to the application section. This is what happens if you upload code via USBasp (Arduinos have a USB-to-UART converter on board). But of course, this requires that a bootloader is installed.

`avrdude: error: program enable: target doesn't answer. 1` \- this might sound misleading, what it actually means is, that the **bootloader** doesn't answer. That makes sense, as the device doesn't have a bootloader.

When there is no bootloader, the only way to upload code is to use ISP, which doesn't need any software to function. It's a hardware functionality that Atmel implements in silicon. A code upload via ISP works in (almost) any case.

---
Tags: atmega328, arduinoisp, usbasp
---


# Question
Title: Converting ESP32 SPI code to Arduino for MAX6921 IV-18 driver board
I purchased a IV-18 VFD tube driver module, which came with some example code for an ESP32 board. The driver module has a 20 output MAX6921 serial chip to drive the vacuum tube. I want to use this driver module with an Arduino Uno and then eventually a Raspberry Pi.

I think I have a very rough understanding of the electronics and demo code, but cannot seem to get my SPI calls to work. Rather than trying to translate the demo code in its entirety, my first goal is to just get one segment to light up.

**Quick background**

The IV18 tube has 9 grids. The first grid has only a dot and a dash, but the remaining 8 grid have 7 segments and a decimal point.

To light a segment, you provide power to the segment pins / decimal point and to the grid for that segment. To display several numbers, you have to quickly cycle through lighting each of the grid positions and the relevant segments for that position. If you cycle through this fast enough, the human eye sees the whole grid with numbers (persistence of vision).

What I have tried

So far, I have made the connections from the Arduino Uno to the driver board

```
Driver GND   - Uno GND
Driver 5V    - Uno +5V
Driver Din   - Uno digital pin 11 / MOSI
Driver CLK   - Uno digital pin 13 / SCK
Driver LOAD  - Uno digital pin 2
Driver BLANK - Uno digital pin 3
Driver Dout  - Not connected

```

The example code has hex codes which I believe are then translated to a 24 bit buffer (although only 17 bits are required) to send via SPI to set the MAX6921 outputs HIGH or LOW.

I think the bits required are as follows:

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| G7 | G6 | G5 | G4 | G3 | G2 | G1 | G0 | SEG\_G | SEG\_F | SEG\_E | SEG\_D | SEG\_C | SEG\_B | SEG\_A | SIGN |  |  |  |  |  |  |  | DP |

So to light the number 8 in the righthand most grid, I assumed I'd need the 8th bit high (grid) and bits 9,10,11,12,13,14 and 15 for the 7 semens for the "8".

In my setup function, I call `SPI.begin` and then `SPI.transfer` with what I assumed was the matching binary data (from right to left, I think because of the bit order LSB/MSB?):

`SPI.transfer(0b000000000111111110000000);`

This lights the first grid (the one after the degree and minus sign) but not what I want - I see some segments in the leftmost grid (the full grid, not the grid with the dot and minus) but these light in a different pattern each time (varies each time I reset or re-upload which I think is to be expected as I'm pushing data to the MAX6921 each time).

**This is my code so far**

```
#include "SPI.h"

#define DISP_CLK 13   // White - SPI SCK
#define DISP_DATA 11  // Yellow - SPI MOSI
#define DISP_LOAD 2   // Blue
#define DISP_BLANK 3  // Green

void setup() {
  Serial.begin(9600);
  Serial.println("IV18 Test");

  SPI.begin();

  pinMode(DISP_BLANK, OUTPUT);
  digitalWrite(DISP_BLANK, LOW);

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

  SPI.transfer(0b000000000111111110000000);
}

void loop() {

}

```

I'm pretty sure the two fundamental things I have wrong here are the bits of data to send and then the correct use of the SPI.

Can someone please help me to understand the ESP32 code properly, and ideally help me get the correct data to send via SPI so that I can light up the segments & grid positions that I expect to.

# Answer
So it turns out that I got a few things wrong.

UPDATE: Working code is now on my GitHub if anyone is interested.

Firstly, I misunderstood the example code and made a mess of the bits to send to the MAX6921. To work out the correct mapping, I went and probed each pin of the IV-18 and noted the connection to the pins / outputs of the MAX6921 which gave me this table:

| BIT | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| IV-18 | G9 | G8 | G7 | G6 | G5 | G4 | G3 | G2 | G1 | A | B | C | D | E | F | G | DP |  |  |  |  |  |  |  |
| MAX6921 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |  |  |  |  |  |  |  |

Note that the MAX6921 value is the OUTPUT number and not the PIN number

This then gave me the correct order for each bit to send, as noted in the top row of the table.

The next mistake was trying to send all 24 bits in one go. Instead, I broke each byte into a separate `SPI.transfer()` call which finally let me display the segments in the grid position that I expected.

For example, to display "HELLO", my loop function has this:

```
void loop() {
  //             XXXXXXXDP                 GFEDCBA1                  23456789
  SPI.transfer(0b00000000); SPI.transfer(0b11101100); SPI.transfer(0b10000000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b11110010); SPI.transfer(0b01000000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b01110000); SPI.transfer(0b00100000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b01110000); SPI.transfer(0b00010000); delay(1);
  SPI.transfer(0b00000001); SPI.transfer(0b01111110); SPI.transfer(0b00001000); delay(1);
}

```

I have setup TIMER1 to use instead of the loop/delay code, so hopefully I can finish converting the rest of the example code to Arduino.
> 2 votes

---
Tags: arduino-uno, esp32, spi
---


# Question
Title: How to show the distance in decimal use sensor TF-Luna Lidar or more specific value
I want to ask about TF-Lunar Lidar, I've written code to know the distance in cm by reading the array data, right now I need some help about how to read the data so it can be showing the more specific value (float or in decimal) Or do you guys know what is the speed of the waves transmitted and captured by the lidar sensor, so that I can calculate it in a more specific form, such as using the method of calculating the distance on the Hc-srf04 sensor I also have used this format to read the distance in mm, but It never works (image about array data)

# Answer
> 0 votes
> so if i inputting the duration of the light travel from trigger to echo, i can find the distance?. will it work?

That's the basic working principle, but you cannot do that with an Arduino. Light is too fast, resulting in incredibly small travel times. You need specialized hardware for that. And thats, what a Lidar sensor (or other Time Of Flight sensor) are.

---

The TF-Lunar Lidar sensor supports different output formats. The distance in cm is just the default. There is also the format, that you showed in your question (9 byte mm), which gives you the distance in mm. The manual of the TF-Lunar also explains how to change the used output format (look at page 22: "5.Output format setting ID\_OUTPUT\_FORMAT=0x05"). How exactly this is done depends on your actual code and the used communication interface (Serial or I2C).

---
Tags: arduino-uno, arduino-nano
---


# Question
Title: Display upTime using `millis()` - Arduino Uno
I want to use the following function to display MCU's uptime, but after several hours I get error.

```
void uptime(char *ret_clk)
{
  byte days = 0;
  byte hours = 0;
  byte minutes = 0;
  byte seconds = 0;

  int sec2minutes = 60;
  int sec2hours = (sec2minutes * 60);
  int sec2days = (sec2hours * 24);

  unsigned long time_delta = millis() / 1000UL;

  days = (int)(time_delta / sec2days);
  hours = (int)((time_delta - days * sec2days) / sec2hours);
  minutes = (int)((time_delta - days * sec2days - hours * sec2hours) / sec2minutes);
  seconds = (int)(time_delta - days * sec2days - hours * sec2hours - minutes * sec2minutes);

  sprintf(ret_clk, "%01dd %02d:%02d:%02d", days, hours, minutes, seconds);
}

```

after 2:55 hours I got a correct answer : `0d 02:55:27`

also after 4 hours, a correct answer : `0d 04:06:44`

but roughly after 12 hours i get an error: `1d 02:01:27`

and after roughly 20 hours I get : `2d 23:74:26`

What is wrong in `uptime` ?

# Answer
> 1 votes
On an 8-bit Arduino an `int` can only hold values in the range -32768 to +32767. One day's worth of seconds is 86400, which is far outside that range.

You should replace your `sec2...` variables with literals, maybe `#define`d - and don't forget to force the length for longer values:

```
#define SEC2MINUTES 60
#define SEC2HOURS 3600
#define SEC2DAYS 86400UL

```

# Answer
> 3 votes
The millis function increments rapidly, hence it easily exceeds the maximum value of int - -32768 to +32767.

So, use unsigned long data types for millis and other stuff that's large.

4 billion and some change is the max value that unsigned long data types can store, hence no overflowing till about 49 days.

---
Tags: millis
---


# Question
Title: Why is this extremely simple code not working?
I have a problem with a for loop, and `Serial.print("Its Working")` does not appear. Seems simple, I've done it before, now for whatever reason, its not working anymore

```
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

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

  for (int x = 0; x > 10; x++) {

    Serial.println("Its Working");
    delay(1000);
  }
}

```

# Answer
The problem is:

```
for (int x = 0; x > 10; x++) {

```

That can be rewritten, in pseudo code, as:

* X is zero
* While X is greater than 10:
    + Increment X

You see the problem? X is zero. It's not greater than 10, so it never increments.

I *assume* you actually wanted:

```
for (int x = 0; x < 10; x++) {

```

Also be aware that your `for` loop will be run over and over again, so you will never see it finish. You should add

```
Serial.println("Loop done");

```

at the end so you know it's finished.
> 6 votes

---
Tags: esp8266, nodemcu, loop
---


# Question
Title: Arduino , python , pyfirmata , standard firmata
Is there a way to change arduino analog reference to EXTERNAL IN PYTHON using pyfirmata or any other library ? Necessary Links : https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/

My sensor has a 3.3 volt operating voltage , my arduino has a 5 volt operating voltage. As such in arduino using C++ and arduino module the scaling can be done using analogReference(External) and providing reference voltage to analog read?

IS there any equivalent to this in python, pyfirmata ?

# Answer
No, not as far as I know. The firmata protocol does not include a command to set the analog reference. However, you can of course modify the firmata firmware to your liking. In the simplest case, just add the appropriate command to the `setup()` function of the main .ino.
> 1 votes

---
Tags: arduino-mega, uart, python, adc, analogreference
---


# Question
Title: Raspberry Pi 3B+ BLE communication to Arduino Nano 33 IOT
I have an Arduino Nano 33 IOT and it uses BLE. I want it to talk to my Pi 3B+ and send all of its sensor data. I cannot figure out a way to do it using Python for the Pi and ArduinoBLE library for my Nano IoT. Is it possible?

# Answer
For completeness, it appears an appropriate Python library can be installed with:

```
pip3 install adafruit-circuitpython-ble

```

The test code, used with the Arduino code 'Echo' from the ArduinoHardwareBLE library is below. This was updated to let you choose the name of the device (here, MY\_BLE) rather than any random device that has UART capability. It also allows you to send a small file from a few lines, with a "#" denoting a comment (first character in the line). ESC and a return quits the program.

```
# Connect to an "eval()" service over BLE UART.

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

ble = BLERadio()

uart_connection = None

def send_stuff(s):
    uart_service.write(s.encode("utf-8"))
    uart_service.write(b'\n')
    readline=uart_service.readline().decode("utf-8")
    while(len(readline)>0):
        print(readline)
        readline=uart_service.readline().decode("utf-8")

while True:

    if not uart_connection:
        print("Trying to connect...")
        print("ESC then RETURN to exit.")
        for adv in ble.start_scan(ProvideServicesAdvertisement):
            if UARTService in adv.services:
                regular_name = adv.complete_name
                if(regular_name=='MY_BLE'):
                    uart_connection = ble.connect(adv)
                    print("Connected")
                    # for some reason, we have to read a line...
                    uart_service = uart_connection[UARTService]
                    print(uart_service.readline().decode("utf-8"))
                    break
        ble.stop_scan()

    if uart_connection and uart_connection.connected:
        uart_service = uart_connection[UARTService]
        while uart_connection.connected:
            s = input("Prompt: ")
            if(len(s)>0):
                if(ord(s[0])==27):
                    print("done.")
                    exit()
                else:

                    # Check if "!" character is used; if so, send contents of a file
                    if(s[0]=="!"):
                        print("sending commands")
                        count=0
                        file1=open('commands.txt','r')
                        Lines=file1.readlines()
                        for line in Lines:
                            count=count+1
                            tmp=line.strip()
                            if(len(tmp)>0):
                                if(tmp[0]=='#'):
                                    print("comment:" + tmp)
                                else:
                                    print("Line{}: {}".format(count, tmp))
                                    send_stuff(tmp)

                    else:
                        send_stuff(s)

```
> 1 votes

---
Tags: arduino-nano, bluetooth, raspberrypi, iot, ble
---


title: Serial communication of strings

text:
# Question
Title: Serial communication of strings
I used this simple code to understand the basics of serial communication. This achieves simple communication between the computer and arduino:

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

void loop() {
  if(Serial.available()>0)  //check for any data received
  {
      receive_buffer = Serial.readString();  //read received data
      Serial.print("received data is: ");
      Serial.println(receive_buffer);        //display received data
  }

}

```

This works. Now, my next idea was to try communicating between two arduinos. I used this code for the reciever arduino.

The sender arduino contains a motor fitted with an encoder, and using the ppr value I calculate the rpm of the motor. The code for rpm works perfectly. I now want to communicate this data to the receiver.

**Wiring**: (RX,TX) of sender connected to (TX,RX) of receiver, and `GND` is made common.

Now, on arduino.cc, it says that Serial.write() can have String as an input. So, I tried typecasting the rpm value (which was int), into a String, and then send that string to the receiver through Serial.write().

```
float ppr=512.0;
int encpin=3;
volatile long pulsecount=0;
float revs;
float rps;
int rpm;

extern volatile unsigned long timer0_millis;

void setup()
{
  pinMode(encpin,INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(encpin),function,RISING);
                                        //when pulse is detected
                                           //interrupt triggered,
                                           //function callled
}
//increments pulse by one
void function(){
  pulsecount+=1;
}

void loop()
{
 revs= pulsecount/ppr ;
 if(millis()>=1000)
  {
    rps= revs;
    rpm=rps*60;
    pulsecount=0; //resets pulsecount

    String strrpm= (String)rpm;

    //Serial.println(rpm);
    Serial.write(strrpm);

   // Serial.println("string rpm");
    //Serial.println(strrpm);

    noInterrupts ();  //resests millis() to 0
    timer0_millis = 0;
    interrupts ();
  }
}

```

However, I get an error:

```
43:24: error: no matching function for call to 'HardwareSerial::write(String&)'

```

The issue is not with typecasting. I tried to simply print strrpm and it worked fine. When tried Serial.write() with a different and simple string, i.e `Serial.write("abcdef");` , it still gave the same error.

**How then should I should I send my strrpm (string rpm) value to the receiver?**

# Answer
> 1 votes
`Serial.write()` is meant for sending binary data. So if you want to send a string with it, you need to provide a c-string, not the Arduino implementation of the `String` class. That's done easily with a member function of that class:

```
Serial.write(strrpm.c_str());

```

That compiles successfully for me.

Though you should not do it like this. The `String` class is generally bad on small microcontrollers, especially on the AVR microcontrollers with little memory (like Uno, Nano, Mega, ...), because it causes memory fragmentation (see Majenkos "The Evils of Arduino Strings").

Instead you should just use the corresponding `print()` functions of the `Serial` class. They are made for sending human readable strings. No need to first build up a `String` object. Just do

```
Serial.println(rpm);

```

And it will do the string conversion itself without using the `String` class.

---

Besides that I have some notes on your code:

* The way you use `millis()` is a bit weird. There is no need to actually reset the `millis()` value itself. Normally you would hold a timestamp in a variable and then only calculate the difference between `millis()` and the timestamp. That is also overflow safe. Like this

```
  unsigned long timestamp = 0;

  ...
  if(millis()-timestamp >= 1000){
      ...
      timestamp+=1000;
  }

```

That doesn't use an extern variable, it is not resetting the `millis()` counter (which might mess with other things too, that rely on it) and is somewhat the standard way to do it.
* You are using an atomic section for resetting the `millis()` counter, but not for accessing `pulsecount`. That is actually the place, where you absolutely need this. `pulsecount` is of type `long`, so it will need many instructions to do the calculation for `revs`. The your interrupt service routine can easily mess with the data in that moment, resulting in garbled data. Move the calculation into the if statement and use an atomic section like with the `millis()` counter to read it into a local variable then you can do the calculations. That will keep the time, where interrupts are turned off very short. You can also - instead of turning all interrupts off - just detach the pin interrupt for that time, so that other things are not affected. Like this code:

```
  void loop(){
      if(millis()-timestamp > 1000){
           // deactivate our pin interrupt, so it cannot mess with the data
           detachInterrupt(digitalPinToInterrupt(encpin));
           // copy pulsecount to local variable for further calculation
           long local_pulsecount = pulsecount;
           // reactivate our pin interrupt
           attachInterrupt(digitalPinToInterrupt(encpin),function,RISING);
           // Do calculation and print the value
           ...
           timestamp += 1000;
       }
   }

```

---
Tags: serial, debugging
---


title: Arduino Yún causing power suge warning

text:
# Question
Title: Arduino Yún causing power suge warning
Recently I got an Arduino Yún board that sends out a power surge error message everytime I connect it to my laptop through the USB cable. I tried two Arduino Leonardo and one Arduino Uno and there wasn't any problem with them or the USB port. Am I missing something or is the board faulty already?

# Answer
> 1 votes
Use a USB tester to test the current consumption, it should be \< 500ma

I recommend using a USB that has power of its own, eg. monitor USB

# Answer
> 0 votes
Yún boards are more powerful boards than your average Arduino. Probably too powerful for your little laptop's USB ports. Use a powered hub or an external power supply to run the board.

---
Tags: arduino-yun
---


# Question
Title: How to remove any previous program from Arduino?
I have a Arduino UNO and I want to remove the previously uploaded code....how to do that?

# Answer
Just upload a new one. I frequently "blank" an arduino when I'm done with it by uploading "Blink.ino" from the examples included with the IDE. (The only reason I've had to remove old code is to avoid an issue where I might later wire up the Arduino in a way that is dangerously incompatible with the old code running on it.)
> 4 votes

# Answer
Replacing your sketch with another doesn't actually "remove" the previous one. Is that really necessary? If you're trying to prevent the first one from executing, replacing it, as already suggested by @Juraj, is a simple and proper solution.

If you need to prevent anyone ever being able to read any part of the previous one, you'd need to load another sketch at least as large as the previous one so it over-writes all of it, or create and run a modified "bootloader" program that erases the parts of flash you wish to obscure.

(Your question doesn't address your reason for wanting to "remove" the sketch. I'm adding this for completeness; not because I think it's likely.)
> 2 votes

# Answer
I got it. just upload blank code that is written when you start arduino ide.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: How to increase sensitivity of Capacitive Touch Switch?
I am working with `Capacitive Touch Sense` technology.In that I am using `TTP224` Touch detector IC. I am getting good sensitivity when I am using Touch pad without putting any non electric material over it and able to switch ON/OFF connected led.But when I put any non electric material like `Acrylic Sheet` of `2mm` thickness I am not able to get any signal through pad or not able to ON/OFF connected led.

So, How can I increase sensitivity of Touch pad?

I have bought TTP224 module from here.

And what can be the alternatives for `TTP224`???

# Answer
According to the datasheet (if you can name it that):

> The capacitance Cs0~Cs3 can be used to adjust the sensitivity. The value of Cs0~Cs3 use smaller, then the sensitivity will be better. The sensitivity adjustment must according to the practical application on PCB. The range of Cs0~Cs3 value are 0~50pF.

So, reduce the capacitances Cs0 to Cs3 and you will get better sensitivity.
> 2 votes

# Answer
Sometimes things just \****. In my case, where 0.5 mm more of gap make the TTP223 unable to work, because I designed such a small pad. My solution? Remove the paint in the PCB, put a lot of solder in to make the pad taller. Work like a charm.
> 2 votes

# Answer
remove all c3 to c10 capacitors of 22pf. This will increase sensitivity and will sense through 5 mm sheet also .
> 2 votes

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


title: Trouble initializing a struct array

text:
# Question
Title: Trouble initializing a struct array
The goal for this is to create a struct that includes a name, ID, fileName, and a boolean, then create an array of that structs. Here's what I came up with:

```
struct Amiibo
{
  char *aName{};
  char *ID{};
  char *AudioFileName{};
  bool alreadyPlayed{false};
};

Amiibo amii[20] = {

      {"Mario","A5005B00","MARIO",false},                     //0
      {"Meta Knight","A5 00 02 00","MK"},                     //1
      {"Inkling", "A5 00 05 00","INK"},                       //2
      {"Donkey Kong","A5 00 01 00","DK"},                     //3
      {"Lucas","A5 00 0A 00","LUCAS"},                        //4
      {"Duck Hunt", "A5 00 08 00","DUCKH"},                   //5
      {"Ocarina of Time Link","A5 00 01 00","OOTL"},          //6
      {"Breath of The Wild Link","random","BOTWL"},           //7
      {"8-bit Link","random","8BITL"},                        //8
      {"Toon Link","random","TOONL"},                         //9
      {"Mr. Game and Watch","random","GANDW"},                //10
      {"Falco","random","FALCO"},                             //11
      {"King Dedede","random","DEDEDE"},                      //12
      {"Mewtwo","random","MEWTWO"},                           //13
      {"Captain Falcon","random","CAPF"},                     //14
      {"ROB","random","ROB"},                                 //15
      {"PAC-MAN","random","PACMAN"},                          //16
      {"Cloud","random","CLOUD"},                             //17
      {"Ness","random","NESS"},                               //18
      {"Ryu","random","RYU"}                                  //19

};

```

This gives me the following error:

> error: could not convert '{"Mario", "A5005B00", "MARIO", false}' from '' to 'Amiibo'

And the same error for all the other elements of the array. I tried changing amii\[20\] to a pointer using \*amii\[20\]. That got me this error:

> braces around scalar intializer for type "Amiibo"

I'm not sure what to make of that, since I'm fairly certain this isn't scalar type.

I'd really just like to make a struct array so I can cycle through these at random using a random seed. It shouldn't be that difficult, yet I'm running up against a wall. I'd appreciate any advice you all have to give. Thanks.

# Answer
> 1 votes
If you use default values in struct declaration, you have to define also constructors for setting specific elements:

```
struct Amiibo
{
  const char *aName{};
  const char *ID{};
  const char *AudioFileName{};
  bool alreadyPlayed{false};

  Amiibo() = default;  // default implementation for default constructor

  Amiibo(const char* name, const char* id, const char * audio)  // constructor with three c strings as parameters
  : aName{ name }
  , ID{ id }
  , AudioFileName{ audio }
  { ; }
};

Amiibo amii[] = {
      {"Mario","A5005B00","MARIO"},                           //0
      {"Meta Knight","A5 00 02 00","MK"},                     //1
      {"Inkling", "A5 00 05 00","INK"},                       //2
      {"Donkey Kong","A5 00 01 00","DK"},                     //3
      {"Lucas","A5 00 0A 00","LUCAS"},                        //4
      {"Duck Hunt", "A5 00 08 00","DUCKH"},                   //5
      {"Ocarina of Time Link","A5 00 01 00","OOTL"},          //6
      {"Breath of The Wild Link","random","BOTWL"},           //7
      {"8-bit Link","random","8BITL"},                        //8
      {"Toon Link","random","TOONL"},                         //9
      {"Mr. Game and Watch","random","GANDW"},                //10
      {"Falco","random","FALCO"},                             //11
      {"King Dedede","random","DEDEDE"},                      //12
      {"Mewtwo","random","MEWTWO"},                           //13
      {"Captain Falcon","random","CAPF"},                     //14
      {"ROB","random","ROB"},                                 //15
      {"PAC-MAN","random","PACMAN"},                          //16
      {"Cloud","random","CLOUD"},                             //17
      {"Ness","random","NESS"},                               //18
      {"Ryu","random","RYU"}                                  //19
};

```

Btw on the older AVRs all those strings will resides also in memory

---
Tags: arduino-uno, array, struct
---


# Question
Title: how to run 2 different servo (continuous rotation and regular servo) in parallel, not run one after other?
I need to control 2 servos in parallel, whereas one is of continuous rotation and another is of regular positioning control (angle) on arduino IDE. I tried but it works one after another, not parallel. How can I do that, please suggest. Thanks.

# Answer
I am proposing one answer

https://wokwi.com/arduino/projects/297646292038844936

Here, we are not using the delay function. We are using the `millis()` Based on your actual application, you can control individual servo accordingly.

Here is the Arduino simulation: https://wokwi.com/arduino/projects/297646292038844936

```
/* Sweep
  by BARRAGAN <http://barraganstudio.com>
  This example code is in the public domain.

  modified 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo2;  // create servo object to control a servo

// twelve servo objects can be created on most boards
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 15;           // interval at which to blink (milliseconds)

int pos = 0;    // variable to store the servo position
int pos2 = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo2.attach(10);  // attaches the servo on pin 9 to the servo object

}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    pos = pos + 1;
    if (pos > 180) {
      pos = 0;
    }                      // waits 15ms for the servo to reach the position

    myservo2.write(pos2);              // tell servo to go to position in variable 'pos'
    pos2 = pos2 + 1;
    if (pos2 > 90) {
      pos2 = 0;
    }

  }

}

```
> 4 votes

# Answer
The angel of two Servomotors should be same ? If yes, Try this for 180 deg. Servos : You can connect signal pin of ech servo to a specific PWM pin of Arduino like pin number '9' in this example It's just for test but you can change this how you want to

I hope it will work you, Good luck

```
#include <Servo.h>

Servo myservo;

int PWMpin = 9;  // change this for your circuit configuration

int a = 0;

void setup() {
  myservo.attach(9);
  myservo.write(0);  // set servo to mid-point
}
void loop() {
  for (int i = 0; i < 180; i++) {
   myservo.write(i);
    delay(10);
  If (i == 180) {
    analogWrite(PWMpin, a);
    }
  }
}

```
> 2 votes

# Answer
As i know, there is no way for a single arduino or any other microcontrollers to command on pins in exactly same time and it's because of microcontrollers nature. When you have to command 2 outputs Microcontroller will be act like this :

Command 1 .... To pin number 9 Command 2 .... To pin number 10

and for example if your microcontroller, like arduino or others do each command in one complete clock cycle and your clock frequency will be 16 MHz, so each cycle's time period is 62.5 nano-seconds.

So your microcontroller will do your command in first clock cycle and do the second command in next clock cycle, In the other words, command 2 will do 62.5 nano-second after command one (if each those commands takes just one clock cycle) but in normal 16 MHz arduino boards it takes much much more time to do commands like this and it was just an example to understand it's principle, and because of this reason i suggest you to connect both servomotors into same output PWM pin if you are using two standard servomotors; But the main issue is different angle limitations of your servomotors and it's impossible to control them when you want one of them to rotate 360 deg. and the other must rotate 180 deg. . If you connect those signal pin to a same output, you have two options with two issuse. First, if you command to the output pin to turn 360 deg. , All things will be good but when your output pin command for angles more than 180 deg. , The little servo will stop. Second, if you limit your rotation to 180 deg., You will not be able to rotate 360 deg. Your bigger servomotor.

I hope my description will be useful and face you by your complete pattern of what's going on in this project's issue
> 2 votes

---
Tags: servo
---


# Question
Title: How can i change by esp8266 baudrate, as I accidentally changed the baudrate to something else(which I dont remember)?
```
//In order to connect,

SoftwareSerial esp8266(2,3);

// the TX pin of esp8266 is connected to pin 3 of
// arduino uno and RX pin is connected to 2
// we need to pass baud rate to begin function

void setup()
{
  Serial.begin(115200);
  esp8266.begin(???); // what should i do in order to make it work?
}

```

What should i do in order to make it work?

# Answer
I encountered a similar situation where I accidentally set the baudrate to 8000 with the AT commands.

Thankfully I remembered the baud rate I set, so I used PuttY to create a serial communication with the port with the weird 8000 baud rate and changed the baud rate back to 9600.

The method can be found here: http://flower-platform.com/2015/12/16/esp8266-with-at-commands-connect-from-pc-with-putty/

The AT command I used to change the baud rate: `AT+UART_DEF=9600,8,1,0,0`
> 1 votes

---
Tags: arduino-uno, esp8266, baud-rate
---


# Question
Title: How to change the resolution of DS18B20?
I'm using DS18B20 sensor with this library, the 750ms delay is causing problem in timer part of my code. the code below is from DallasTemperature.cpp:

```
// returns number of milliseconds to wait till conversion is complete (based on IC datasheet)
int16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution) {

    switch (bitResolution) {
    case 9:
        return 94;
    case 10:
        return 188;
    case 11:
        return 375;
    default:
        return 750;
    }

```

I'm reading the temperature like this:

```
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS A0
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {}

void loop () {
    float currentTemp = sensors.getTempCByIndex(0);
    sensors.requestTemperatures();
}

```

*sensor is not connected in parasite mode, and there is only one sensor.*

How can i change the resolution from 12 to 9 bit?

# Answer
> 1 votes
Simple:

```
sensors.setResolution(9);

```

It normally defaults to 9, but then probes the connected device to find the maximum resolution it supports and sets it to that. This would normally be done in `sensors.begin()` which you omitted from your snippet above. If you don't have that it will be on 9 bit anyway, and also the bus probably won't work regardless.

# Answer
> 1 votes
Seems to work better:

```
sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);

```

---
Tags: temperature-sensor
---


title: eval() function for Arduino?

text:
# Question
Title: eval() function for Arduino?
I plan to do the following:

```
void setup(){
  String term = "12 + (2 * 5)";
  int result = eval(term); // eval function (from Python)
  Serial.println(result); // expecting 22
}

```

However there is no eval function. Are there any alternatives?

# Answer
> 5 votes
TinyExpr does what you want, and more.

> TinyExpr is a very small recursive descent parser and evaluation engine for math expressions. It's handy when you want to add the ability to evaluation math expressions at runtime without adding a bunch of cruft to you project.
>
> In addition to the standard math operators and precedence, TinyExpr also supports the standard C math functions and runtime binding of variables.

# Your example

You'd just need to save `tinyexpr.h` and `tinyexpr.c` next to your Sketch.

```
#include "tinyexpr.h"

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

void loop() {
  char term[] = "12 + (2 * 5)";
  Serial.println(term);
  int error;
  double result = te_interp(term, &error);
  if (error){
    Serial.println("Problem with expression.");
  } else {
    Serial.printf(" = %.10g\n", result);
  }
  delay(1000);
}

```

It outputs:

```
12 + (2 * 5)
 = 22

```

Since `term` is known at compile-time, this example is not very useful, and it simply outputs `22` in an endless loop.

# Basic interactive console

If you use the input from `Serial`, you can write a very basic interactive console. A `String` has been used for conciseness, but this example could be rewritten with cstrings:

```
#include "tinyexpr.h"

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

void loop() {
  if (Serial.available() > 0) {
    String expression = Serial.readStringUntil('\n');
    Serial.print("> ");
    Serial.println(expression);

    int error;
    double result = te_interp(expression.c_str(), &error);

    if (error) {
      Serial.print(" ");
      for (int i = 0; i < error; i++) {
        Serial.print(" ");
      }
      Serial.println("↑");
      Serial.println("I didn't understand this part.");
    } else {
      Serial.printf(" = %.10g\n", result);
    }
  }

  delay(50);
}

```

TinyExpr knows the order of operations, and it understands many other mathematical expressions:

```
> 12 + 2 * 5
 = 22
> 3^5
 = 243
> exp(7)
 = 1096.633158
> (1 + sqrt(5)) / 2
 = 1.618033989
> 1 + 2 * 3 + 4 * 5
 = 27
> sin(pi/2)
 = 1
> sin(pi/3)
 = 0.8660254038

```

If there's a syntax error somewhere, `error` tells you the position of the first encountered error:

```
> 3 +
      ↑
I didn't understand this part.
> sin() * 5
      ↑
I didn't understand this part.
> 3 / (4 + 5 * 7
                ↑
I didn't understand this part.

```

# Answer
> 1 votes
No, there are no alternatives. You need to parse the string and perform the operations yourself.

Personally I prefer to use RPN since it is so much easier to parse. Your string could be re-written then as:

```
2,5,*,12,+

```

Tokenise on `,` and look to see if it's a number (push on a stack) or an operator (pop operands off stack, do operation, push result on stack).

# Answer
> 0 votes
I Googled and the news isn't good. There isn't an off the shelf function that does this in C/C++. There are plenty of links to algorithms that you could implement. But would you have the memory to do it on an Arduino?

So, looking at the problem for a different perspective why don't you run python on the Arduino? There is a version called pymite which runs on a mega.

---
Tags: string, mathematics
---


title: Connect ESP32 via MQTT

text:
# Question
Title: Connect ESP32 via MQTT
For a project I am working on, I need to connect my ESP32 board to another server via MQTT protocol. I am using the Mosquitto MQTT Broker and it is presently on my laptop. Following is the test code I am using, which I'll build around this program.

```

#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "*****";              //WiFi Name
const char* password = "********";      //WiFi Password
const char* server= "***.***.**.***";    //RPi or Machine IP on which the broker is

WiFiClient espClient;
PubSubClient client(espClient);

int setup_WiFi(){
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Attempting MQTT connection...");
  client.connect("esp32");
  if (client.connect("esp32")){
      Serial.println("connected");
    }
    else {
      Serial.print("failed, rc=");
      Serial.println(client.state());
    }
    return 0;
}

int reconnect() {
  unsigned long startAttemptTime = millis();
  while (!client.connected())
  {
    Serial.println("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("esp32")){                 //if (client.connect("esp32", MQTT_USER, MQTT_PASS)) {
      Serial.println("connected");
    }
    else {
      Serial.print("failed, rc=");
      Serial.println(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
  return 0;
}

int send_mqtt(){
  setup_WiFi();
  char sss[15]="Hello World";
   if (!client.connected()){
    reconnect();
  }
  client.publish("esp32/test", sss);    //send message
  WiFi.disconnect(true);
  Serial.println("Sent");
  return 0;
}
void setup() {
  Serial.begin(115200);
  client.setServer(server, 1883);   //mqtt server details
  setup_WiFi();
  reconnect();
  send_mqtt();
}

void loop() {
  send_mqtt();
  delay(10000);     //Wait 10 secs before next transmission
}

```

I tried connection but got this error

> Attempting MQTT connection...failed, rc= -2

What am I doing wrong? Any changes I need to make to the .conf file about which I don't know? Guide me. Thank You in advance

# Answer
> 1 votes
The code in your sketch is unlikely to be the problem. It works fine for me after I enter the IP addresses and password for my network.

According to the pubSubClient API documentation, the `rc = -2` code returned by `client.state()` is due to the network connection having failed. As your code has already checked that it is connected to WiFi before trying to contact the MQTT broker, it is probably the communication between the two devices that is the issue, not the WiFi connection itself. Things to check:

1. Are both devices are on the same network, and do they have a route to contact each other? From the laptop running the MQTT broker, try running `ping XXX.XXX.XXX.XXX` (replacing the XXXs with the IP address reported by the ESP32), and check you get a response. You might wish to comment out line 67 of your code so it doesn't disconnect from WiFi after every attempt at sending a message, otherwise you will see lots of lost packets.
2. Have you got the right IP address for the MQTT broker in your sketch? It should be the IP address for your laptop, not the loopback address, `127.0.0.1`.
3. Can you use another device on the same network to connect to the MQTT server? (e.g. a cellphone running a MQTT dashboard app, or MQTT Explorer in Windows)
4. Is Mosquitto configured to listen out for remote connections? If you are running v2 of Mosquitto, you have to deliberately configure it to accept incoming connections, otherwise it will only listen to the `localhost` interface. You would also have to either set up an authentication mechanism or explicitly configure it to allow anonymous connections. This might be why you can connect from the laptop running the broker, but not from other devices.
5. On the MQTT server, can you see any connection attempts in Mosquitto's log file (`/var/log/mosquitto/mosquitto.log`)? There might be some error messages that give you further clues.

---
Tags: esp32, iot, mqtt
---


# Question
Title: How to send a message to my phone that my Arduino system is on when turning on my Arduino
i have installed a GSM shield on the Arduino to create security alarm system using PIR SENSOR when ever there motion I will receive a call to my phone. but i want to add also a line of code which can make my system send me a txt message stating that my system is turned on so i can make sure that when ever i turn my system on i can doule check by getting a message that says that system is turned on successfully i dont know how to start doing that. this is the code i did:

```
int PIR = 6;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(96000);
 pinMode (PIR , INPUT );
}

void loop() {
  // put your main code here, to run repeatedly:
if (digitalRead (PIR == HIGH)){
  Serial.println("thief detected");
  delay (200);
  Serial.println ("ATD+0197263315;");
  delay(1000);
  Serial.println("ATH");
  delay(1000);

  }
  else digitalWrite (PIR, LOW );

}

```

# Answer
> 1 votes
You can send an SMS using the Arduino GSM library. Here is a bare bones sketch that sends one pre-set SMS when it starts up, based on this tutorial:

```
#include <GSM.h>

#define PINNUMBER "1234"
#define REMOTENUMBER "07123456789"
#define TXTMESSAGE "System started!"

GSM gsmAccess;
GSM_SMS sms;

void setup() {
  boolean notConnected = true;

  while (notConnected) {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
      notConnected = false;
    } else {
      delay(1000);
    }
  }

  sms.beginSMS(REMOTENUM);
  sms.print(TXTMESSAGE);
  sms.endSMS();
}

void loop() {
}

```

If you can't or don't want to use the GSM library, it should also be possible to send an SMS by using the SoftwareSerial library to control your GSM shield using AT codes. Here's a tutorial on this approach, which is lighter weight but might be more fiddly to get working, especially if you need a PIN for your SIM card.

---
Tags: arduino-uno, programming, sensors, c++, gsm
---


# Question
Title: Im trying to map a joystick to a servo but need the servo to be at 0 when the joystick is in nerural. And up to 180 when joy is forward or back
Im trying to map a joystick to a servo but need the servo to be at 0 when the joystick is in nerural. And up to +180 when joy is forward or back.

I just cant seem to figure out the mapping or setup for the code for this part. I remember seeing it done before but my google skils are failing me and i cant seem to find it again. Thanks

# Answer
> 2 votes
Try this one although, the others answered you properly :

```
#include <Servo.h>
Servo myservo;
int potpin = 1;
int val;

void setup () {
    myservo.attach(9);
}

void loop () {
    val = analogRead(potpin);
    val = map(val, 0, 1023, 0, 360);
    myservo.write(val);
    delay(20);
}

```

Connect the signal wire of your Servomotor to PWM pin number 9 of Arduino Connect the output of your joystick to A1 pin of your arduino

Actually i'm not sure about one of that lines and i forgot the correct form, if didn't work, change this line :

```
val = map(val, 0, 1023, 0, 360);

```

To this :

```
val = map(val, 0, 1023, -180, 180);

```

I think both of them works

Good luck

# Answer
> 1 votes
You can use the `map` function, see Arduino Map Function.

So in your case, assuming a `value` of 0..1023 coming from an analog pin, where 0 needs to be mapped to -180 and 1023 to +180, you get

```
int mappedValue = map(value, 0, 1023, -180, 180);

```

(note I assume you mean -180 when backwards, +180 when forwards).

**UPDATE**

It seems value 0 (backward) needs to be mapped to 180, 512 (neutral) to 0, and 1023 (forward) to 180 (again).

For this you need two maps depending on the value:

```
int mappedValue = 0;
if (value < 512) // Backwards
{
    mappedValue = map(value, 0, 511, 180, 0);
}
else // Forward
{
    mappedValue = map(value, 512, 1023, 0, 180);
}

```

---
Tags: servo, joystick
---


# Question
Title: How to make ultrasonic and light sensors detect whether a person moving in or out
I am trying to make a circuit that will be used for turning on a light whenever there are 1 or more people in a room. I need to add to a variable counter when someone enters and subtract when someone leaves. However, I do not know how to use the ultrasonic sensor for this purpose. What can I do?

# Answer
> 0 votes
See this tutorial on the Arduino Projecthub, that project was already made. Here is a tutorial how to use a Ultrasonic sensor.

---
Tags: variables, photoresistor, ultrasonics
---


# Question
Title: ESP8266 Arduino Json object array deserialisation into struct
I'm trying to de serialize an array of JSON objects into a struct. Following the instructions given by the Arduino JSON assistant, I managed to produce this helper function:

```
void JsonPreprocessor(const char* buf)
{
  StaticJsonDocument<96> filter;

  JsonObject filter_ResponseData_Metros_0 = filter["ResponseData"]["Metros"].createNestedObject();
  filter_ResponseData_Metros_0["Destination"] = true;
  filter_ResponseData_Metros_0["ExpectedDateTime"] = true;
  filter_ResponseData_Metros_0["Deviations"] = true;

  StaticJsonDocument<512> doc;

  DeserializationError error = deserializeJson(doc, buf, DeserializationOption::Filter(filter));

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  JsonArray ResponseData_Metros = doc["ResponseData"]["Metros"];
  for (int i = 0; i < MAX_ELEMENTS; i++)
  {
    strcpy(dep_arr[i].destination, ResponseData_Metros[i]["Destination"]);
    strcpy(dep_arr[i].destination, ResponseData_Metros[i]["ExpectedDateTime"]);
  }
}

```

The function writes into an array of structs declared like this:

```
struct Departure {
   char* destination;
   char* departure;
   int  deviation;
} depart;

struct Departure dep_arr[MAX_ELEMENTS];

```

And the JSON passed as a constant character array to the preprocessor function. Uploading and running this function keeps crashing my ESP8266 without any debug output. Without posting the whole json object, which is long enough as is without the filters, My object array in JSON looks similar to this after filtering:

```
{
  "ResponseData": {
    "Metros": [
      {
        "Destination": "Destination_1",
        "ExpectedDateTime": "2021-04-29T05:15:30",
        "Deviations": 1
      },
      {
        "Destination": "Destination_2",
        "ExpectedDateTime": "2021-04-29T05:21:30"
      },
      {
        "Destination": "Destination_2",
        "ExpectedDateTime": "2021-04-29T05:30:30"
      },
      {
        "Destination": "Destination_1",
        "ExpectedDateTime": "2021-04-29T05:36:30"
      },
      etc...
    ]
  }
}

```

In my test code I've defined my MAX\_ELEMENTS macro to be 3.

I'm at a complete loss due to not having any debug output. I'm using ArduinoJson6 and my code is written and compiled on Arduino IDE 2.0.0-beta.5

# Answer
No memory is allocated for the strings. You should declare your struct like so:

```
struct Departure {
   char destination[32];
   char departure[32];
   int  deviation;
} depart;

```

This assumes the max length for both strings is 31 characters.

Then, pass the max size to `strlcpy()`:

```
strlcpy(dep_arr[i].destination, ResponseData_Metros[i]["Destination"], 32);
strlcpy(dep_arr[i].destination, ResponseData_Metros[i]["ExpectedDateTime"], 32);

```

If your strings are **very** long, you can use a `String` instead of `char[]`.

See the example JsonConfigFile.ino, it shows all of this.
> 2 votes

---
Tags: esp8266, json, espressif, esp
---


title: Servo not moving

text:
# Question
Title: Servo not moving
I have connected my servomotor (MG996R) to my L293D motor shield, which is connected to an Arduino Uno R3 Board.

I use 4x AA 1.2V NiMH batteries to power the shield, and a regular 9V battery to power the Arduino separately. I've removed the jumper wire on the shield.

I've tried uploading all the example codes I could find, multiple times, yet none of them work. The servomotor simply doesn't move at all.

Is there anyway I could see if my servomotor is broken ? Maybe the wiring is wrong, but I don't think so. Orange is for signal, Red is for + and Brown is for GND.

Could someone help troubleshoot the problem ? Thanks !

PS : here is the example code I use

```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

```

# Answer
You have two problems Both of them is related to your power supply :

* 1st, max. Voltage requirement for your servomotor is 6 volts, not 9 volts
* 2nd، your batteries are weaker than servo's need. Your servomotor need 2.5 Amps. In the max. Torque.

So, over-voltage and not enough current is your fault (According to 996R servomotor datasheet). Change your power supply by suitable one
> 1 votes

---
Tags: arduino-uno, motor, servo, arduino-motor-shield
---


# Question
Title: Error Downloading http://downloads.arduino.cc/packages/packages_index.json
I managed to update the library but getting error "Error Downloading http://downloads.arduino.cc/packages/packages\_index.json" when updating the *Board Manager*. I switched the proxy to no proxy instead of automatic. Anyone can help me?

# Answer
The URL is wrong, and should read:

```
https://downloads.arduino.cc/packages/package_index.json

```

Note that "package\_index" is in the singular, not the plural.

Check what you have in the "Additional Boards Manager URLs:" section of Preferences.
> 0 votes

# Answer
I had the same issue and the fix that worked for me is to directing the jvm to use the Windows Certificate Store instead of the ancient cacerts file that comes with java 1.8. This may also help people behind a Cisco Umbrella filter.

One does this by adding the following lines to "C:\Program Files (x86)\Arduino\arduino.l4j.ini" (note, you will need to open a text editor as an administrator, then open the file in question, in order to edit it):

```
-Djavax.net.ssl.trustStore=NUL
-Djavax.net.ssl.trustStoreType=Windows-ROOT

```

I found this answer here
> 0 votes

---
Tags: library
---


title: Is my BMA421 locked up?

text:
# Question
Title: Is my BMA421 locked up?
I have been trying to set up the BMA421 motion sensor in a nrf52 based smart watch, using the datasheet for the BMA423, which has the same interface. I had got the sensor working well with the original source code, but I was trying to set it up myself. It is connected via I2C, address 0x18.

I made some mistakes in my original code. I was trying to initialise the chip with a 6Kb byte stream (as in the original source), in chunks of 64 bytes. I didn't resend the register at the start of each data chunk, so ended up writing bytes to random registers.

Unfortunately, I have managed to get the sensor into an unrecoverable state - it now returns 0xFF to all reads, and doesn't respond to a soft-reset code (register 0x7E=0xB6). Even exhausting the watch battery to power cycle the chip doesn't seem to help.

I have found someone with a similar issue on the Borsch Sensortec forum, so I am hoping that a complete battery discharge works.

Does anyone have any other suggestions?

# Answer
> 0 votes
The BMA421 was not locked. An erroneous write to the wrong register had switched it to the (non-existant) SPI interface. The solution was to power cycle the sensor.

---
Tags: i2c, accelerometer, nrf52
---


title: How to set 60 min beeper?

text:
# Question
Title: How to set 60 min beeper?
I am trying to make a device that will register latency and number of shocks for passive avoidance behavior in drosophila. My device has two buttons green and red. I press green when I put a fruit fly into the test tube. When drosophila enters the shock compartment I press the red button to give electric shock through Grass stimulator. My Arduino registers latencies or elapsed time from pressing green button and subsequent presses red button and the number of shocks (presses of the red button). This part works just fine, however, I want to have a 60 sec beeper as the test runs only 1 min. This part does not work. The beeper counts 60 seconds from the starting of the device, not from the press of the green button. I am not sure what I am doing wrong.

Here is the code:

```

#include <LiquidCrystal.h>

/*
  Super-basic stopwatch using millis();
*/

unsigned long start, finished, elapsed;
unsigned long startTime;
unsigned long endTime;
unsigned long duration;
byte timerRunning;
int switchPin = 3;              // switch is connected to pin 3
int val;                        // variable for reading the pin status
int buttonState;                // variable to hold the button state
int buttonPresses = 0;          // how many times the button has been pressed
const int buz = 13;
unsigned long delayStart = 0; // the time the delay started
//bool timerRunning = false; // true if still waiting for delay to finish
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd (9, 8, 7, 6, 5, 4);

void setup()
{
  lcd.begin(16, 2);
  //lcd.setCursor (0,0);
  //lcd.print("resetting");
  lcd.setCursor (3,1);
  lcd.print("resseting");
  delay(3000);
  lcd.clear();
  lcd.setCursor (0,0);
  lcd.print ("Latency= ");
lcd.setCursor (0,1);
lcd.print ("Shocks= ");
  Serial.begin(9600);
  pinMode(2, INPUT); // start button
  pinMode (2, INPUT_PULLUP);
  pinMode (buz,OUTPUT);
  pinMode(switchPin, INPUT);    // Set the switch pin as input
  digitalWrite(buz, LOW); // turn buz off
  delayStart = millis();   // start delay
  //delayRunning = true; // not finished yet
  buttonState = digitalRead(switchPin);   // read the initial state
  Serial.println("Press 'Green' for Start/Reset, 'Red' for Shocks");
}

void displayResult()
{
  float h,m,s,ms;
  unsigned long over;
  elapsed=finished-start;
  h=int(elapsed/3600000);
  over=elapsed%3600000;
  m=int(over/60000);
  over=over%60000;
  s=int(over/1000);
  ms=over%1000;
  Serial.print("Elapsed time: ");
  Serial.println(elapsed);
  Serial.print("Latency: ");
  Serial.print(m,0);
  Serial.print("m ");
  Serial.print(s,0);
  Serial.print("s ");
  Serial.print(ms,0);
  Serial.println("ms");
  Serial.print("Shocks: ");
  Serial.print(buttonPresses);
  Serial.println(" time(s)");
  lcd.setCursor (8,0);
  lcd.print(m,0);
  lcd.print("m");
  lcd.print(s,0);
  lcd.print("s");
  lcd.print(ms,0);
  lcd.setCursor (7,1);
  lcd.print(buttonPresses);

}

void loop()

    {float h,m,s,ms;

  if (digitalRead(2) == HIGH);{ // button pressed & timer not running already
  start=millis();
  lcd.setCursor (7,1);
  lcd.print("           ");
  buttonPresses=0;
  lcd.print(buttonPresses);
    Serial.println("Started");
    lcd.setCursor (8,0);
    lcd.print("           ");
    lcd.print("Start...");
  lcd.print(buttonPresses);
  lcd.setCursor (8,0);
    lcd.noBlink();

  delay(300);

  // Turn on the blinking cursor:

  lcd.blink();
    delay(200); // for debounce

  }

  if (digitalRead(3)==HIGH)
  { lcd.noBlink();
  lcd.setCursor (9,0);
   lcd.print("        ");
    finished=millis();
    delay(200); // for debounce
    buttonPresses++;
    displayResult();
    delay(200);}

    if (timerRunning && ((millis() - delayStart) >= 60000)) {
    //timerRunning = false; // // prevent this code being run more then once
    digitalWrite(buz, HIGH); // turn buz on
   // tone(buz, 1000); // Send 1KHz sound signal...
  delay(1000);        // ...for 1 sec
  noTone(buz);     // Stop sound...
  delay(1000);        // ...for 1sec
    Serial.println("Turned buz on");
    lcd.setCursor (10,1);
    lcd.print("1min");
  }}

```

# Answer
> 1 votes
The best place to start, is with the `BlinkWithoutDelay` example in the IDE.

Once you master that concept, you may be tempted to start several different timers. With enough timers, your code will start to look like a bowl of spaghetti.

Next, you could build a generic function which would help to reduce the "spaghetti code".

I would favour an OOP approach.

```
// Sketch uses 910 bytes (2%) of program storage space.
// Global variables use 18 bytes (0%) of dynamic memory.
// Arduino Uno, IDE 1.8.9
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

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

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

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

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

};

// Make a copy of the object to work with.
MillisTimer SixtySecondTimer(60000);

void setup(){

  // Call this function from a button click
  // to start the 60 second timer.
  SixtySecondTimer.Start();

  // Timer complete indicator.
  pinMode(LED_BUILTIN, OUTPUT);

}

void loop(){

  // Call the update function as fast as possible.
  if(SixtySecondTimer.Update()){
    digitalWrite(LED_BUILTIN, HIGH);
    SixtySecondTimer.Stop();
  }

}

```

---
Tags: arduino-uno, timers
---


# Question
Title: if(Serial.available()>0) VS while(Serial.available()>0)
What's the low level difference between `if(Serial.available() > 0)` and `while(Serial.available() > 0)`? On what conditions would you choose one over the other?

I was testing my codes on 4 daisy chained 74HC595 shift registers controlling multiple LEDs. The code takes in a number from the serial monitor and displays it out in binary via the LEDs. Here is the code below that worked:

```
#define latchPin 8  //ST_CP pin of 74HC595
#define clockPin 9  //SH_CP pin of 74HC595
#define dataPin 7   //DS pin of 74HC595

//number of 74HC595 in daisy chain
#define numOfDaisyChainReg 4

byte registerVal[numOfDaisyChainReg];

void setup() {
    Serial.begin(115200);
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
}

void loop() {

  while (Serial.available() > 0) {

    uint32_t num = Serial.parseInt();
    Serial.print(num, DEC);
    Serial.print(" : ");
    Serial.println(num, BIN);

    //breaks the recieved int into 4 unsigned bytes
    //and assigns the byte value into the "registerVal" array
    for (uint8_t a = 0; a < numOfDaisyChainReg; a++) {
      registerVal[a] = (num >> (numOfDaisyChainReg - (a + 1)) * 8) & 0xFF;
      Serial.print("registerVal["); Serial.print(a); Serial.print("] = ");
      Serial.println(registerVal[a], BIN);
    }

    //writes the 4 bytes into the shift register
    digitalWrite(latchPin, LOW);
    for (uint8_t x = 0; x < numOfDaisyChainReg; x++) {
      shiftOut(dataPin, clockPin, MSBFIRST, registerVal[x]);
    }
    digitalWrite(latchPin, HIGH);

  }

}

```

Originally, I had `if(Serial.available() > 0)` and that didn't work as no LEDs lit up despite everything else in the code working as it was expected. Switching to `while(Serial.available() > 0)` solved that problem. Anyone have any idea why that's the case?

# Answer
> 4 votes
I figured out why `while(Serial.available()>0)` and `if(Serial.available() > 0)` would or would NOT work in terms of my shift register code. It has to do with the serial monitor **line feed and carriage return setting**! If it isn't set to no line ending, it will either not register the input number or reset it back to zero right after the input is read. Learned to always check the line return option in the serial monitor! With this solved, the original question is nothing more than a general `if` vs `while` statement; which I already know the answer.

**Thanks to everyone who contributed to this question!** It did help me understand a lot more about `Serial.available()` in general. @jsotola gave a really good article. Combined with this YouTube video, it makes a lot more sense now.

# Answer
> 0 votes
Some implementations of the Arduino core have features that need `loop()` to exit regularly. Although it's not often used, the `serialEvent()` is an example of one such thing, at least in the AVR Arduino core.

The ESP8266 Arduino core appears to do some task scheduling when `loop()` exits, among other things.

For your particular use case, it may make no difference at all, probably doesn't. It *may* not even generate different code once compiled. If you were doing something where you could not afford to exit `loop()`, run other stuff and re-enter `loop()` to run your code for a second pass, then there might be a performance reason to use your own while loop inside `loop()`. In your code as it currently is, the eventual blocking on `Serial` writes will end up limiting the execution to the same speed.

---
Tags: serial, shift-register
---


# Question
Title: How to fix memory-leak code in ESP8266/NodeMCU caused by string concenation?
I have following code in loop() in NodeMCU.

This part is before setup():

```
String serial_data_read = "";   // for incoming serial string data
String serial_data = "";   // for incoming serial string data

```

This part is in loop():

```
if ((last_weight_time < millis() - 1000)) {
   last_weight_time = millis();
   serial_data_read = "";
   Serial.print("P");
   while(Serial.available()) {
      character = Serial.read();
      serial_data_read.concat(character);
   }
   serial_data = serial_data_read;
}

```

I don't understand C programming that much, but I think it has something to do with memory leaking and eventually running out of memory. It runs for around 20 minutes and then just stops. When I manually restart NodeMCU it runs again fine.

I would be very grateful for any help, how to rewrite my code so it doesn't leak memory. Thank you very much.

# Answer
To write code that will not cause memory leak, you need to understand of where and what caused the memory leak first. The memory leak in this particular case is caused by the line

```
serial_data_read.concat(character);

```

When you instantiate a String object with `String serial_data_read = ""`, Arduino String class create a memory allocation using dynamic memory allocation in the heap, and since your initialised it with "", it therefore create a minimum size of allocation. This is all good if you know how to the dynamic memory is created and how it going to be used.

The problem started when you start doing String concatenation with the line `serial_data_read.concat(character)`, the original allocation for your global variable `serial_data_read` is no longer have enough space for the concatenated variable, so it create a temporary variable in the heap and do the concatenation, and then eventually put the result back to this newly allocated memory for `serial_data_read` on the heap, leaving a hole at the heap for the original `serial_data_read` variable (and the temp variable).

What make this worst is that this is happening for ~~each iteration~~ every 16 iterations(see Edgar Bonet's comment below) of the while loop. Theoretically the old `serial_data_read` prior the concatenation should be free-up at some point (e.g. if your while loop is within a function, the part of the heap might be free-up at the exit of the function), it however does not necessary be the case because your newly created `serial_data_read` stay on top of piles of to-be-free-up memory that blocking the free up(think of a piece of cheese with a lot of holes on it), so the heap memory get less and less at each iteration.

**Short term fix - do not do String concatenation in a loop**

String class is not always evil if you know what's going on and how to use it. One of the quick fix for your problem is simply do not do String concatenation within a loop. And if you are using it within a function, keep it local. This will minimise the heap fragmentation.

```
if ((last_weight_time < millis() - 1000)) {
   last_weight_time = millis();
   if (Serial.available() > 0) {
      String serial_data_read = Serial.readStringUntil('\n');
   }
}

```

BTW, you can add `ESP.getFreeHeap()` in your loop() to check if there is still memory leak.

**Long term fix - Don't use String class**

For a better fix, and especially for some one new to the programming or C/C++, do not use String class and learn how to use ***c string and array***. Here is the version without using String class.

```
length = 80;
char buffer[length] = {0};
if ((last_weight_time < millis() - 1000)) {
   last_weight_time = millis();
   while(Serial.available()) {
      Serial.readBytesUntil('\n', buffer, length);
   }
}

```

**Other resources to learn about**

https://www.cplusplus.com/reference/cstring/ all the functions for c string and array manipulation to replace Arduino String class.

https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
> 3 votes

# Answer
The short answer is, don't use the String class at all. You need to read up on using C strings (which are simply null-terminated arrays of characters. There are C library functions for manipulating C strings. ~~You'll want to avoid printf, scanf, and related functions, as the library that supports those is quite large~~

The basic idea is to use statically allocated C strings as buffers. Figure out the largest number of characters you need to store, and create a static array of characters at least one character larger (for the terminating null) and use that to collect the output you are building.
> 1 votes

# Answer
SafeString is a great way to go.. only one instance of each SafeString can ever exist, and u can declare the length of each SafeString..
> 0 votes

---
Tags: esp8266, nodemcu, string, memory
---


# Question
Title: Multiple variable shared between threads?
I got 4 threads running on ESP32 (dual core):

* 1 thread running on 1st core which is related to the WiFi.
* 1 thread running on 2nd core which is related to the touchscreen.
* 1 thread running on 2nd core which is related to the display.
* 1 thread running on 2nd core which is related to the sensors.

Some of the threads execute almost instantly, while for instance the one handling the sensors can take a few seconds per interaction, and no blocking should occur meanwhile for the rest of the threads.

Anyway, with the growing of the program, a lot of variables started to be involved in data transfers between the cores, and since the whole thing is about to be redone, I have the following questions, to clear the things up for myself, since I found quite a lot of confusing, even contradictory information in examples and explanations on the internet:

* Is the "**volatile**" keyword really sufficient for exchange of data between threads (no ISR)?
* Should "**volatile**" always be between "**noInterrupts**()" and "**interrupts**()", even when there is no ISR function?
* What approaches should be used when exchanging a lot of variables between the threads (currently about 40 variables, but the number will probably grow)?
* Is **xQueueSend / xQueueReceive** blocking in case it is put all around the threads with different variables?

# Answer
> 2 votes
> Is the "volatile" keyword really sufficient for exchange of data between threads (no ISR)?

No - "volatile" just tells the compiler that the variable may change value due to something other than the immediate code being generated and informs the code-generator not to rely on the value remaining static when it would otherwise expect so. When copying the value to a register for instance, it would normally expect that register value to continue to represent the value of the variable in memory but if the variable is volatile, that assumption doesn't hold. This would be used to indicate that an ISR might change it at any time; that the variable is an input register and may be changed from the outside at any time; or that another thread may change it, again, at any time (assuming pre-emptive multi-threading or multi-tasking).

```
Should "volatile" always be between "noInterrupts()" and "interrupts()", even when there is no ISR function?

```

No - volatile just describes an attribute about the variable over time

> What approaches should be used when exchanging a lot of variables between the threads

Use a semaphore here. A thread that wants access to one of - or the collection of - shared variables asks for the semaphore. The RTOS either returns it immediately, or (because another thread already holds it) suspends the task until it becomes available, and returns it then. The thread holding the semaphore may access the variables (or whatever shared resource this semaphore controls), then returns the semaphore on completion. Semaphores are usually built in to the RTOS.

(As I'm not familiar with your particular RTOS, I'll leave your fourth question for someone who is).

---
Tags: esp32
---


# Question
Title: Blink LED with different on off times just once with millis
So Im having trouble trying to figure this out. My project needs a valve to stay shut and when an event is triggered, 3 seconds into that event the valve opens for 2 seconds, then remain shut till it's triggered again. I was just treating it like an LED in the code. I was trying to code it to jump from one if-statement to the next with the appropriate delays but it doesn't work the way i thought it would. Any help would be great. Thanks

<pre><code>//the event does ventGo0 = true;

 if(((millis() - previousVenting) > offoffDuration)&&(ventGo0==true)){
        previousVenting1 = millis();
        ventGo1=true;
        ventGo0=false;
       }

     if(((millis() - previousVenting1) > onDuration)&&(ventGo1==true)){
       digitalWrite(ventPin, HIGH);
       previousVenting2 = millis();
       ventGo2=true;
       ventGo1=false;
     }

       if(((millis() - previousVenting2) > offDuration)&&(ventGo2==true)){
         digitalWrite(ventPin, LOW);
         ventGo2=false;
       }

      ```
</code></pre>

# Answer
> 1 votes
You could use two `millis()` based timers.

```
// Sketch uses 1066 bytes (3%) of program storage space.
// Global variables use 27 bytes (1%) of dynamic memory.
// Arduino Uno, IDE 1.8.9
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

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

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

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

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

    byte IsActive(){
      return m_timerActive;
    }

};

// Make copies of the object to work with.
MillisTimer TwoSecondTimer(2000);
MillisTimer ThreeSecondTimer(3000);

void setup(){

  // Call this function when an event is triggered.
  ThreeSecondTimer.ReStart();

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

}

void loop(){

  // Call the update function as fast as possible.
  if(ThreeSecondTimer.Update()){
    digitalWrite(LED_BUILTIN, HIGH);
    ThreeSecondTimer.Stop();
    TwoSecondTimer.ReStart();
  }

  // Call the update function as fast as possible.
  if(TwoSecondTimer.Update() && !ThreeSecondTimer.IsActive()){
    digitalWrite(LED_BUILTIN, LOW);
    TwoSecondTimer.Stop();
  }

}

```

---
Tags: millis
---