title: How can I set a timer?

text:
# Question
Title: How can I set a timer?
I would like to set a stopwatch timer that will determine how long an input is in a certain state before changing. I want to set it so that, depending on the output my code executes one of 2 switch cases. But my trouble comes in on setting a timer. Is there a function I could use? Or a method that somebody knows? The time that the input will be for each case is not fixed so I cannot use a delay.

# Answer
> 1 votes
Even though you are not running an actual (complex) Operating System, you should adhere to common practices. For an Arduino, you should, in many cases, avoid directly controlling the hardware so as to be compatible with as many existing libraries for your particular Arduino platform as possible.

Setting the timer directly (if you are using an official Arduino Uno which contains an Atmel328P processor the processor's timers are covered in section 14 of the Atmel328P Specifications) may cause unexpected results should you use a library which expects the timer to run without being altered.

Instead, consider using the millis() function built into the Arduino IDE. The function returns the current number of milliseconds since the Arduino was powered up. Record this value in your code. Then, if you want to know if One Second has elapsed, get the new value of millis and subtract this saved value from it and see if it is greater than 1000. When that is true, One Second has elapsed.

# Answer
> 1 votes
Use `micros()` (reference page) to obtain a microsecond timestamp, and `millis()` (reference page) to obtain a millisecond timestamp.

Full Disclosure: I link to a library I maintain in my answer below, and I mention a few products (no links) I created with various techniques presented here in order to act as representative examples of when one approach might be preferred over another.

# Example 1: simple linear (synchronous) software timing measurement, including low-resolution (`micros()`) and high-resolution (`timer2.get_count()`)

In the simplest sense, **let's measure how long it takes to set an output pin HIGH and then LOW again:**

```
void setup()
{
    Serial.begin(115200);
    // I'll just leave pin 9 as an input; but uncomment the line below to make it an output
    // pinMode(9, OUTPUT);
}

void loop()
{
    // Measure and print how many microseconds it takes just to set an output pin HIGH and then
    // LOW again.
    uint32_t time_start_us = micros();    // <=== START TIMESTAMP
    digitalWrite(9, HIGH);
    digitalWrite(9, LOW);
    uint32_t time_end_us = micros();      // <=== END TIMESTAMP
    uint32_t time_elapsed_us = time_end_us - time_start_us;
    Serial.print("time_elapsed_us = ");
    Serial.println(time_elapsed_us);
    delay(100);
}

```

The really cool ShowInfo Arduino speed profiling sketch shows that Arduino's `digitalWrite()` function takes about 5us each, so expect the code above to print ~10us. Let's see if that's correct. I ran this on an Arduino Nano and got this output:

```
time_elapsed_us = 8
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 8
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 8
time_elapsed_us = 12
time_elapsed_us = 8
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 12
time_elapsed_us = 8

```

That's weird. Why only `8` or `12` us? Why not `10`? Or `9`? Or something else? Well, it turns out the Arduino `micros()` function only has a resolution of 4us, so it will actually print out either `8` or `12` us since those are multiples of 4 us. To get better resolution you'd have to modify the hardware timer registers, as I've done in my `eRCaGuy_Timer2_Counter` library, which has 0.5us-resolution. Full Disclosure: I wrote and maintain this library. It is free and open source, but I have it on my personal website, which has ads, and I solicit donations for downloads. A fully-functional snippet is also available in code at the bottom of that web-page without downloading anything.

Here is how to do the above code with my library:

```
#include <eRCaGuy_Timer2_Counter.h>

// Convert timer2 clock counts, which are 0.5us each, to us.
float counts_to_us(uint32_t time_counts)
{
    float time_us = (float)time_counts/2.0;
    return time_us;
}

void setup()
{
    Serial.begin(115200);
    // I'll just leave pin 9 as an input; but uncomment the line below to make it an output
    // pinMode(9, OUTPUT);

    // Configure Timer2. This MUST be done before the other Timer2_Counter functions work.
    // Note: since this messes up PWM outputs on pins 3 & 11, as well as interferes with the tone()
    // library (http: arduino.cc/en/reference/tone), you can always revert Timer2 back to normal by
    // calling `timer2.unsetup()`
    timer2.setup();
}

void loop()
{
    // Measure and print how many microseconds it takes just to set an output pin HIGH and then
    // LOW again.
    uint32_t time_start_counts = timer2.get_count();    // <=== START TIMESTAMP
    digitalWrite(9, HIGH);
    digitalWrite(9, LOW);
    uint32_t time_end_counts = timer2.get_count();      // <=== END TIMESTAMP
    uint32_t time_elapsed_counts = time_end_counts - time_start_counts;
    float time_elapsed_us = counts_to_us(time_elapsed_counts);
    Serial.print("time_elapsed_us = ");
    Serial.println(time_elapsed_us);
    delay(100);
}

```

Now look at the output. Here's the more accurate and precise results with my `eRCaGuy_Timer2_Counter` library. Much better! But why those spurious 14.50us values I have marked with `<===`? Why are they off by 4us? I will explain below.

```
time_elapsed_us = 10.00
time_elapsed_us = 10.50
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 14.50  <===
time_elapsed_us = 10.50
time_elapsed_us = 10.50
time_elapsed_us = 10.50
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 14.50  <===
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 10.50
time_elapsed_us = 10.50
time_elapsed_us = 10.50
time_elapsed_us = 10.50
time_elapsed_us = 10.00

```

The tradeoff of doing what Im doing is that you will get a 4us jitter introduced more often. Every time the 8-bit timer2 counter overflows, an ISR (Interrupt Service Routine) is called. This counts overflows to keep track of the 32-bit software timer from an 8-bit hardware counter. Entering this ISR takes about 4us, which means that if you try to grab a timestamp but then the ISR is called, you have to wait 4+us to get that timestamp, so it is off by that much. One of the several Arduino experts I really look up to, Nick Gammon, mentions this here in his Interrupts article where he says, "There is a tweaking figure of 4 µS...". So, this 8-bit counter counts at 1 tick per 0.5us, which means it rolls over every 256 ticks * 0.5us/tick = 128us. So, every 128us you will have at least a 4us delay error introduced if you try to call the `timer2.get_count()` exactly when the ISR is called. If you get really unlucky you may even get this effect twice and be off by as much as 8us. When using the standard `micros()` function, since it rolls over only every 256 ticks * 4us/tick = 1024us, you get this 4us error effect 8x less frequently. That's the tradeoff of getting better resolution: you also get more-frequent 4+us jitter.

And just for kicks, here's a really bad one. Notice the `20.50`us value--off by 10.50us!

```
time_elapsed_us = 15.00 <===
time_elapsed_us = 10.50
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 15.00 <===
time_elapsed_us = 10.50
time_elapsed_us = 10.00
time_elapsed_us = 20.50 <======
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 10.50
time_elapsed_us = 10.00
time_elapsed_us = 10.50
time_elapsed_us = 10.50
time_elapsed_us = 10.00
time_elapsed_us = 10.00
time_elapsed_us = 10.00

```

Using mode filters, median filters, or other filters, these spurious results can be removed, at, of course, the cost of reduced frequency response to the thing being measured (all this means really is it takes multiple measurements to know the true value, just as we need to see with our eyes multiple measurements above to deduce 10.0us seems to be the right answer).

# Example 2: non-blocking (asynchronous) timing measurement of external event

**More-complicated Example: measure how long INPUT pin 9 is HIGH, and print out the HIGH time out each time it goes LOW again.**

In general, use this approach for any and all input events you need to measure at the 100us to ~200us resolution or larger level. You can use this on every single pin at once and get good results with resolutions around that level, depending really just on how long your main loop takes to run each iteration.

```
constexpr uint8_t PIN = 9;

void setup()
{
    Serial.begin(115200);
    pinMode(PIN, INPUT);
}

void loop()
{
    // This will measure how long `SOME_PIN` is HIGH, in microseconds.

    static uint32_t time_start_us = micros();
    bool time_just_acquired = false; // true if a new time value was just measured
    uint32_t time_elapsed_us = 0;

    bool pin_state = digitalRead(PIN);
    static bool pin_state_old = LOW;

    if (pin_state == HIGH && pin_state_old == LOW)
    {
        // The pin just barely went HIGH, so "start the timer" by obtaining a timestamp of the
        // start time
        time_start_us = micros();
        pin_state_old = pin_state; // update
    }
    else if (pin_state == LOW && pin_state_old == HIGH)
    {
        // The pin just barely went LOW, so "stop the timer" by obtaining a timestamp of the
        // end time
        uint32_t time_end_us = micros();
        pin_state_old = pin_state; // update
        time_elapsed_us = time_end_us - time_start_us;
        time_just_acquired = true;
    }

    // In some other place later down the code where you need this value,
    // you can use it like this. Here I just print the value.
    if (time_just_acquired)
    {
        time_just_acquired = false; // reset
        Serial.print("time_elapsed_us = ");
        Serial.println(time_elapsed_us);
    }
}

```

*IMPORTANT: notice in all my examples above I use ONLY UNSIGNED INTEGER variables for timestamps. This is ESSENTIAL. Using **signed** integers for timestamps in the same way I've written them here would be a violation of the C standard because it will produce undefined behavior when you do subtraction which results in underflow, or when the integer has overflow. Using unsigned integers, however, is perfectly valid. Ex: `(uint8_t)0 - (uint8_t)1` = `255`, because it is an unsigned 8-bit integer which safely underflows from its lowest value back around to its highest value. Similarly, `(uint8_t)255 + (uint8_t)1` = `0` because it is an unsigned 8-bit integer which safely overflows from its highest value back around to its lowest value. This is how `time_elapsed_us = time_end_us - time_start_us` works in both of my examples as well. As the 32-bit microsecond counter overflows, which it will every 70 minutes or so, it wraps around back to 0. This means that sometimes `time_end_us` will be SMALLER than `time_start_us`, and you could end up with a measurement like this: `time_elapsed_us = 124 - 4294967295`, which equals `125`.*

# Example 3: use external interrupts to detect changes on pins to measure external events

Use this approach when you need to measure external events at the 4~10us or larger resolution level on 2 pins maximum at a time.

This is a really good approach for measuring external events, but you get only 2 pins per Arduino Uno or Nano or similar that can do it. They are pins 2 or 3. See the table here: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/.

For a demo, see Edgar Bonet's answer here.

# Example 4: use pin change interrupts to measure external events

Use this approach when you need to measure external events at the 4~10us or larger resolution level on \> 2 pins maximum at a time.

These are like external interrupts except you have to manage up to 8 pins in a single interrupt service routine (ISR), instead of only 1 pin per ISR, so they aren't quite as good as "external interrupts". *Every single digital-capable pin on an Arduino Uno or Nano can do this.* I use this approach when reading many PWM signals from a radio control receiver, for instance, but it requires some sophistication and a ring buffer to do it right, as the time in the ISR *must* be minimized or else you get tons of jitter all over the place! That means you just grab the timestamp in the ISR, store it in a ring buffer, and exit. You do NOTHING ELSE! No subtraction, no math, no determining which pin fired, *nothing!* You then process the ring buffer of timestamps and pin states in your main loop to determine which pin changed and do the math to obtain a new time reading on that pin. I used this for passing signals through a fire-shooting battlebots hexacopter that flew on ABC TV. It worked well. It made me happy to see the ISR do its job.

# Example 5: use input capture (on pin 8 *only*) to measure an external event

This is the "golden", or "best" approach. But, you get 1 pin per Arduino Uno or Nano that can do it. Use this approach when you need to measure external events at the 62.5 *nanosecond* or larger resolution level **jitter-free**. There will be NO ISR TIMESTAMP DELAY WHATSOEVER with this approach, which is really cool.

Input Capture is only available on 16-bit timers on the 8-bit AVR microcontrollers such as the ATmega328. Since an Uno or Nano only has 1 16-bit timer, this means they get 1 single input capture pin. It is pin 8. Don't waste this pin for anything else if you need perfect time measurements of external events using input capture. Input capture is the "perfect" way to measure external events since it stores the time count in a hardware register at the moment the event happens, without CPU interaction through an ISR, which, as we know, would cause a delay and 4+us jitter.

I first did this on a commercial product I made which needed to read a single Radio Control receiver PWM pin. It made me happy to see it work right, as it has zero jitter. I'll come back and add a demo (code only, no more mention of the product) if I get a chance. This technique is also *perfect* for reading PPM (Pulse Position Modulation) signals, which are just a bunch of multiplexed Radio Control PWM signals.

# Answer
> 1 votes
Your title is about “setting a timer”, but your actual question is about measuring the length of a pulse. There are two functions provided by the Arduino IDE for this purpose, `pulseIn()` and `pulseInLong()`:

* `pulseIn()` is based on a carefully timed delay loop. It has a resolution of the order of one microsecond, but will not count the time spent servicing interrupt requests. It works best for very short pulses timed with interrupts turned off.
* `pulseInLong()` is based on `micros()`. It has a resolution of 4 µs and will *not* work properly if interrupts are turned off. It works best for longer pulses where its limited resolution and interrupt latency are tolerable.

Both of these are *blocking* functions: they completely block your sketch while they perform the measurement. If you don't want your sketch to be unresponsive during this time, you can write a non-blocking version of `pulseInLong()` using a finite-state machine like this:

```
// Measure the length of a pulse in a non-blocking manner.
// Returns 0 if no measurement is available at the time of the call.
void get_pulse_length() {
    static enum {
        INITIAL_WAIT,    // wait for the first (partial) pulse to end
        BETWEEN_PULSES,  // wait for the pulse to start
        WITHIN_PULSE     // wait for the pulse to end
    } pulse_state = INITIAL_WAIT;
    static uint32_t pulse_start;  // when the current pulse started

    uint8_t pin_state = digitalRead(pulse_pin);
    uint32_t now = micros();
    switch (pulse_state) {
        case INITIAL_WAIT:
            if (pin_state == LOW)
                pulse_state = BETWEEN_PULSES;
            break;
        case BETWEEN_PULSES:
            if (pin_state == HIGH) {
                pulse_start = now;
                pulse_state = WITHIN_PULSE;
            }
            break;
        case WITHIN_PULSE:
            if (pin_state == LOW) {
                pulse_state = BETWEEN_PULSES;
                return now - pulse_start;
            }
            break;
    }
    return 0;
}

```

Note that this measures high pulses. You will have to swap `HIGH` and `LOW` if you want to measure low pulses. You would use it like this:

```
void loop() {
    uint32_t pulse_length = get_pulse_length();
    if (pulse_length) {
        // handle the pulse
    }
}

```

The resolution of the measurement is the execution time of `loop()`, so you have to make sure there is nothing blocking there, and specially no calls to `delay()`. If you need a better resolution from a non-blocking method, you can use interrupts to trigger the measuring process:

```
volatile uint32_t pulse_start, pulse_length;
volatile bool pulse_valid;

void on_rise() {
    pulse_start = micros();
    attachInterrupt(digitalPinToInterrupt(pin), on_fall, FALLING);
}

void on_fall() {
    pulse_length = micros() - pulse_start;
    pulse_valid = true;
    attachInterrupt(digitalPinToInterrupt(pin), on_rise, RISING);
}

uint32_t get_pulse_length()
{
    if (!pulse_valid) return 0;
    noInterrupts();
    uint32_t pulse_length_copy = pulse_length;
    pulse_valid = false;
    interrupts();
    return pulse_length_copy;
}

void setup() {
    attachInterrupt(digitalPinToInterrupt(pin), on_rise, RISING);
}

```

This should give you the resolution of `micros()`, i.e. 4 µs, but occasionally you may get results that are slightly off if interrupts happen to be disabled when the input transitions. If this is unacceptable, the only other options I see is to use a hardware timer with *input capture* capability. You will have to look at the datasheet of your microcontroller to see how it works, and maybe do a Web search for “Arduino input capture”.

---
Tags: timers
---


title: Strange Arduino Serial Behavior

text:
# Question
Title: Strange Arduino Serial Behavior
I have a quirky question today.

I have an Arduino MEGA 2560 with a very simple setup. It's connected to my pc over usb, and has one device connected on its onboard TX/RX2 port group. Whenever I open the COM port on my pc I see a short spike in voltage on the TX2 pin. An analogous behavior happens on even the simplest sketches so I don't think it's the library I'm using to talk to this device.

With the sketch below instead of a short spike in voltage, the TX2 line stays high and when the pc's COM port is opened that TX2 line drops to 0v for maybe a half second.

Not super relevant info about device

```
It's a Noritake GU140X32F-7000 display. The mfg website doesn't list it's model directly but the
info on the 'B' variant, and it's supplied AVR code, work just fine.

MFG Website for this model>> https://noritake-vfd.com/gu140x32f-7000b.aspx
Code Library>> https://www.noritake-elec.com/codeLibrary.php#gu7000

```

Relevant bare-minimum code to see this effect on an oscilloscope connected GRD \<-\> AVR Ground, POS \<-\> Pin16(TX2)

```
void setup() {
  Serial.begin(115200); // Connection to computer
  Serial2.begin(38400); // Connection to TX2 pin 16
  Serial2.write('akjlahsdkjahsdkjlhasdkjhaskldjhaksjhd');
}

uint8_t serialByte = 0;
void loop() {
  if (Serial.available() > 0) {
    serialByte = Serial.read();
  }
}

```

What happens, which I don't want happening, is after I've had the Arduino draw to the Noritake screen, and I open or reopen the COM port from my pc to the Arduino, the screen blanks itself. Doesn't matter if I use PUTTY, python's serial library with

`ser = serial.Serial('COM4', 115200, R timeout=0,parity=serial.PARITY_NONE, rtscts=1)`

or Serial Port Monitor's trial version from https://www.com-port-monitoring.com/ via the send dialog - it happens either way.

Especially weird is I don't see data going over this COM port in the Serial Monitor software when the COM port is opened and yet my oscilloscope (fairly crappy DSO138) catches a spike in voltage happen the moment this serial line is opened from my pc. When I use the Noritake library the TX line is normally low when there's no data, whereas the Arduino built in Serial2 line is normally high until there's data. Then when I connect it goes low for about a half second. The code Noritake uses to communicate over this serial line is a bit odd, not actually using the Serial or Stream built in classes, instead opting to write data manually to this port and only including these two external libraries.

```
#include <avr/pgmspace.h>
#include <util/delay_basic.h>

```

What causes Serial2 to go low when my PC opens the COM port to Serial on my Arduino? What can I do to prevent it from writing to Serial2?

# Answer
As to why this happens: connecting to the Arduino with the built in USB port would wipe the display because the Arduino would reset and re-initiate the display initialization routine. The spike in current was actually the initialization signal. In the bare minimum sketch the signal going high, low, then back high was again due to the Arduino resetting.

The solution I'm going with is just changing how I connect to my Arduino with python by adding `dsrdtr = 1` to my serial declaration. I tested this and my Arduino no longer resets, and uploading sketches is not impacted.

```
# Python 3.7.5
import serial
ser = serial.Serial('COM4', 115200, timeout=0, parity=serial.PARITY_NONE,
                   rtscts=1, dsrdtr = 1)

```
> 2 votes

---
Tags: serial, usb, atmega2560
---


# Question
Title: ESP8266 OTA update with different flash size settings?
I have an ESP8266 in a project. It's specifically this ESP8266 SMT Module - ESP-12F item. It's been working great with OTA, but I realized belatedly that I didn't change the flash settings when I started compiling through the Arduino IDE several versions ago. I had been using the setting "1 MB (FS:64KB OTA:~470KB)", and I've updated OTA over multiple versions with the same basic structure of firmware and using the same server-side set-up.

I can no longer update with that setting because my compiled sketch is now over the OTA size limit. My chip actually has 4 MB, however, so this limit is artificial. I tried changing to "4 MB (FS:2 MB OTA:~1019KB)", and that works under the following test conditions:

1. I compile the "old" program with the 4-MB settings and I re-upload the old program via wired connection.
2. I compile the "new" program that's to come via OTA with those same 4-MB settings.

That's fine for a test, but I already have one of these chips "deployed" in a location where it's hard to access it. I'd like to update that deployed chip OTA while also changing the flash partition. I'm willing to lose any files stored outside of the program itself. So I'd like instead to have:

1. A deployed, OTA-enabled chip with firmware running on the 1-MB partition structure noted above:
2. (Any intermediate step needed)
3. OTA update to new firmware that has been compiled with the 4-MB partition structure.

I'm willing to upload a dummy sketch at "Any intermediate step needed" to work around the current size of the sketch, but, after some experimentation, OTA seems to fail when the partition structure is different regardless of the size of the binary.

That's consistent with #2 in the answer here: esp8266 OTA issue, but that older question took a different direction with the OP and the #2 point there is stated without any detail. I understand that in a broad sense, the prior answer covers my case, but I'm looking for more detail on the specific aspect of the flash partition settings. Especially for these related questions:

* Is there any work-around strategy available to change the flash partitioning between different versions served OTA?
* If no, is the limitation determined by the software in the current OTA framework in the public libraries, or is it somehow fundamental to how the program is laid out in the hardware memory?

In theory at least, it seems like I ought to be able to force the new program to be written OTA at the same location that it would have been written had the old program also had the 4-MB partition. (Again noting that I'm willing to lose any other data in the flash to make this update work.)

# Answer
The basic problem is that when you upload over OTA you don't upload the partition structure.

The ESP32's flash is split into a number of "partitions" or areas. It might look something like:

```
+----+-+-------------+-------------+---------------------+
|BOOT|P|OTA Program 1|OTA Program 2| SPIFFS              |
+----+-+-------------+-------------+---------------------+

```

When you upload over UART you upload all that structure, and that structure can be changed. When you upload over OTA you only upload one of "OTA Program 1" or "OTA Program 2". One of those is active and the other is inactive. You upload to the inactive one and then at the next reboot that becomes the active one. This allows the system to confirm that the program has been written correctly before running it to reduce the chances of bricking a device in the field.

Because of this you can *never* upload anything that doesn't fit into one of the OTA program partitions.

One risky option which you would have to do thorough local testing of first, is to write a program which, when executed, will change the partitioning. You would have to make sure that it runs in the lower OTA partition so that the inactive one is the one that gets both moved and expanded, which may take a little trial and error.

Once that has happened you should be able to upload a larger OTA program into the new, bigger, inactive OTA segment.

But that's only supposition and it's not something I have ever done or heard of anyone doing.
> 3 votes

---
Tags: esp8266, flash, ota, partition
---


title: Wait between UART frames

text:
# Question
Title: Wait between UART frames
I have to reproduce a signal (of 6 UART frames) which have 950 µs delay between each of the frames. Than, a delay of 37ms at the end of those frames.

Everything going right except the delay between each frame...The baud rate is at 9600.

Here is my current code :

```
  Serial1.write(sw_binary_train_1);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_2);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_3);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_4);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_5);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_6);
  delay(37);

```

# Answer
> 1 votes
set delayMicroseconds(1900) do a delay of 950µs between each frames...Strange but works !

# Answer
> 1 votes
It's not strange at all. Serial doesn't block while it sends. When you call write that pushes the byte into the send buffer and that's all. Then the code moves on to the next instruction, the delay(950) and during that time the serial data is actually being sent. It takes about 1 millisecond for that to happen.

This solution works as long as the send buffer doesn't have anything else in it that's slowing you down and as long as you don't change the baud rate. If either of those things happen then you need to recalculate that time.

A better solution would be:

```
  Serial1.write(sw_binary_train_1);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_2);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_3);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_4);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_5);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_6);
  Serial1.flush();
  delay(37);

```

The flush blocks until the send buffer is empty again. That way you don't have to account for that time and all you need the delay for is the time between transmissions.

Even better would be if those things were in an array so you didn't have to keep repeating yourself. Anytime you catch yourself putting numbers on variable names what you really want is an array so that you can use those numbers in the program:

```
for (int i=0; i<6; i++){
  Serial1.write(sw_binary_train[i]);
  Serial1.flush();
  delayMicroseconds(950);
}
delay(37)

```

looks much better.

---
Tags: uart
---


# Question
Title: How can I get my LCD display to display Chinese and Japanese characters?
I'm making a project that requires me to display Chinese and Japanese characters on an LCD. However, the 16x2 LCD display I have does not seem to support displaying Chinese and Japanese characters.

If I do something like `lcd.print("おはよう世界");` or `lcd.print("简体中文测试");`, it seems to display just a bunch of jumbled random characters (which I am assuming have their character values add up to the values of the characters in the code).

How can I get my LCD to display Chinese and Japanese characters?

Or, if there's no way to do it without buying a new one that supports it, where can I buy one?

# Answer
> 1 votes
Displaying Kanji or Chinese characters is way beyond the ability of an LCD that displays 5 pixel by 7 pixel characters.

To understand the limitations, take a piece of graph paper and draw out a set of 5x7 rectangles. See if you can define ANY recognizable Japanese or Chinese characters on your graph paper.

Maybe a couple of characters? (Then again, maybe not.)

You need a display with a lot more resolution, like an OLED graphics display. You are also struggling against a microcontroller that doesn't have support for Unicode. It's just not up to the job. You'd be much better off with a Raspberry Pi and a screen like a smart-phone color LCD screen. Install Linux and you can have native support for Unicode.

As others have pointed out, hiragana or katakana would be more practical, and there are some low-res LCDs that support those characters.

# Answer
> 0 votes
Your LCD uses a single byte for the character to display, so there are \< 256 characters possible. 8 of them are userdefineable, the others are predefined in the LCD-ROM.

The Arduino IDE uses utf-8 code, which takes more than a single byte for all non-ascii characters like in your "おはよう世界".

Even if the character set contains the ones you want to display, you need an escape sequence to have them properly in your print statement.

---
Tags: lcd, display
---


# Question
Title: What exactly does the return type do in a function?
something I've never understood and still don't is, what does the return type do specifically? Everyone in tutorials just say that void returns nothing and int returns int, etc. But what does that mean? Where is it returning to? I can't seem to understand what everyone's talking about when they discuss functions.

# Answer
> 4 votes
It returns it to whatever the function is being assigned to.

Take the function:

```
int plus(int a, int b) {
    return a + b;
}

```

That function takes two integers, adds them together, and "returns" them *as an integer*.

You can then do:

```
int c = plus(3, 4);

```

and `c` will be handed the value `7` by the function.

Equally you can do:

```
Serial.println(plus(3, 4));

```

And the `Serial.println()` function will be handed the value `7` for printing.

The type of the return defines the kind of data that *can* be returned.

Oh, and `void` doesn't mean "returns nothing", but means "doesn't return anything" - which means you can't assign it to anything since there's nothing returned to assign.

# Answer
> 1 votes
The reason is that a function is evaluated just as any other expression would be. Every expression - \`(x\**x - 3\*x + 5), for instance - has a value and a type (unless the type is void, then it has no value, or not a defined one), and that includes functions. The compiler needs to know the type of every element of the expression in order to know how to use that element in an operation (arithmetic or other kinds). Sometimes a value has to be converted from one type to another to combined with another element or assign to a variable, and knowing the type of each element is the only the compiler knows how to accomplish this.

Here is an example:

`float squareroot(float x);` could declare a function that takes a floating point number and returns its square root as a floating point number. If you assign that value to an integral of variable, the compiler needs to see that the functions does not return an integer but a float, so it includes the appropriate code to convert the float to an integer (by truncating the fractional part, in this case).

If the function could be written without declaring its return value type, the compiler would be unable to make the conversion, or even to know whether one will be needed.

---
Tags: programming, arduino-ide, c++, electronics
---


title: MPU6050 Problem with NodeMCU

text:
# Question
Title: MPU6050 Problem with NodeMCU
I am using MPU6050 as a part of IMU of my drone, and I wrote this program for Arduino Nano to fetch the orientation of the MPU6050 module in 3D space. And that works perfectly fine, but when I uploaded this exact code to a NodeMCU, the output started getting increased only, i.e., whenever there's any change of orientation of the module, the output, instead of showing the specific orientation, gets increased on and on. Can you please help me out with interfacing the MPU6050 with my NodeMCU. I am providing the program underneath.

```
#include <Wire.h>
const int MPU = 0x68; // MPU6050 I2C address

char status;                // Declaring all the necessary variables
double T, P;
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll_sensor, pitch_sensor, yaw_sensor;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        // end the transmission
  calculate_IMU_error();  // Call this function if you need to get the IMU error values for your module
  delay(20);
}
void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14, true); // Read 6 registers total, each axis value is stored in 2 registers

  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value

  // Calculating roll_sensor and pitch_sensor from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * (180 / PI)) - AccErrorX;
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * (180 / PI)) - AccErrorY;

  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 14, true); // Read 4 registers total, each axis value is stored in 2 registers

  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;

  // Correct the outputs with the calculated error values
  GyroX = GyroX - GyroErrorX;
  GyroY = GyroY - GyroErrorY;
  GyroZ = GyroZ - GyroErrorZ;

  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + (GyroX * elapsedTime); // deg/s * s = deg
  gyroAngleY = gyroAngleY + (GyroY * elapsedTime);
  yaw_sensor =  yaw_sensor + (GyroZ * elapsedTime);

  // Complementary filter - combine acceleromter and gyro angle values
  roll_sensor = (0.94 * gyroAngleX) + (0.06 * accAngleX);
  pitch_sensor = (0.94 * gyroAngleY) + (0.06 * accAngleY);

  // Print the values on the serial monitor
  Serial.print("                   roll_GY: "); Serial.print(roll_sensor);
  Serial.print("         pitch_GY: "); Serial.print(pitch_sensor);
  Serial.print("         yaw_GY: "); Serial.print(yaw_sensor);
  Serial.println();

}
void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 300 times
  while (c < 300) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * (180 / PI)));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * (180 / PI)));
    c++ ;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 300;
  AccErrorY = AccErrorY / 300;
  c = 0;
  // Read gyro values 300 times
  while (c < 300) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);

    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();

    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }

  //Divide the sum by 300 to get the error value
  GyroErrorX = GyroErrorX / 300;
  GyroErrorY = GyroErrorY / 300;
  GyroErrorZ = GyroErrorZ / 300;
}

```

# Answer
> 0 votes
I see that you are reading 16-bit integers from the IMU like this:

```
// doesn't work on 32-bit systems
void loop() {
    ...
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
    ...
    GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // ...
    GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
    GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
    ....
}

```

While all too often I am forced to use "#ifdef" to set up platform-specific code for each platform, in this case I'm pretty sure it's possibly to write cross-platform compatible code that will work on both platforms; perhaps something more like this:

```
// warning: untested, but I think it should work
int16_t wire_read_16(){
    int16_t value = (Wire.read() << 8 | Wire.read());
    return value;
}

void loop() {
    ...
    AccX = (wire_read_16()) * (1.0f / 16384.0f); // X-axis value
    AccY = (wire_read_16()) * (1.0f / 16384.0f); // Y-axis value
    AccZ = (wire_read_16()) * (1.0f / 16384.0f); // Z-axis value
    ...
    GyroX = (wire_read_16()) * (1.0f / 131.0f); // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
    GyroY = (wire_read_16()) * (1.0f / 131.0f);
    GyroZ = (wire_read_16()) * (1.0f / 131.0f);
    ....
}

```

I see that onehorse is apparently having exactly the same problem at "integer type definitions on Teensy 3.1"

It sounds like maybe you've stumbled over a quirk of the C programming language where "int" varies from system to system. (See Ido Gendel, "The problem with ints"). The "int" in some systems (such as the ATmega based Arduinos) is a 16-bit integer. The "int" in some other systems (such as the ARM based Arduinos, perhaps including NodeMCU) is a 32-bit integer. ( inttypes vs Arduino defined integral types ; "Arduino reference: int" ) In yet other systems, "int" is a variety of other sizes.

For example, when your IMU is trying to send you a "-2", it sends 0xFFFE. When the nano puts that into its "int" which is a 16-bit integer, it then later properly interprets that as meaning "-2". I suspect what's happening is that when the other system puts that value into its "int" which is a 32-bit integer, that somehow ends up containing 0x0000FFFE which means +65534, but what *should* have happened is "sign extension" so that 32-bit integer ends up containing 0xFFFFFFFE which means "-2". By sticking that value into an intermediate "int16\_t" variable, we're explicitly telling the compiler that it's a signed 16-bit integer, so later when that compiler sticks it into a 32-bit integer it sign-extends properly.

The C compiler (correctly) handles an int divided by a float by converting both values to floats (and sign extending properly), and then dividing. Likewise with an int divided by a double.

---
Tags: arduino-nano, nodemcu, mpu6050, imu, drone
---


# Question
Title: Can you access the EEPROM of an ATtiny with Arduino Code?
I'm attempting to reduce the amount of RAM being used by my program by writing some values to the EEPROM of my micro controller. I'm currently programming on the ATtiny85 which has 512 Bytes of EEPROM. According to the documentation this is how you write to EEPROM:

```
#include <EEPROM.h>

void setup() {
  EEPROM.write(0, 1);
  EEPROM.write(1, 0);
  EEPROM.write(2, 3);
  EEPROM.write(3, 2);
  EEPROM.write(4, 1);

}

```

For some reason this isn't working for me and I can't seem to find the error. Am I programming this wrong or can the EEPROM of the ATtiny simply NOT be accessed with Arduino Code?

Here is the Datasheet: http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85\_Datasheet-Summary.pdf

Here is the second sketch I'm using to test the EEPROM:

```
    #include <EEPROM.h>

void setup() {
  EEPROM.write(0, 1);
  EEPROM.write(1, 0);
  EEPROM.write(2, A3);
  EEPROM.write(3, A2);
  EEPROM.write(4, A1);

byte CLK = EEPROM.read(0);

}

void loop() {

  if(CLK == 1)
  {
    for(int i = 0; i < 3; i++)
    {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
    }
    exit(0);
  }
  else
  {
    for(int i = 0; i < 100; i++)
    {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
    }
    exit(0);
  }

  exit(0);

}

```

# Answer
> 10 votes
The Arduino EEPROM library is compatible with the ATTiny range of AVR microcontrollers as the library itself is built on the standard Atmel AVR avr/eeprom.h 'library' so it is compatible with all the AVR microcontrollers.

The EEPROM also doesn't take to being written or read to often as EEPROM can wear very quickly. Reading though does not cause much damage though.

Also note that using `exit(0);` **will stop the ATTiny from doing anything else** after it is called so I hope your intention is to only run the loop once, if not this would account for either not seeing anything or it only ever running the blinking cycle once.

To answer your follow up question. Yes you can run one sketch to set you values in EEPROM and then use another sketch to read those. That us usually the point of EEPROM it is a memory type that "keeps its value while there is no power".

Also you need to make sure the ATTiny is set to preserve EEPROM during upload with the ISP, this is done with the fuse settings. You need to look for a tutorial on fuse calculators for the AVRs. To set the `EESAVE` you need to set the High fuse to `0xD7`, you can change this in the `boards.txt` file. Here is a fuse calculator.

If the code that is on your question at the moment is being used you won't be seeing anything as it needs the pins to be set with `pinMode`. That's a note for others that see this.

Next what you can do is run a basic test code which blinks the LED without anything else going on.

Basically:

```
void setup(){

 pinMode(0, OUTPUT);

}

void loop(){

 digitalWrite(0, HIGH);
 delay(1000);
 digitalWrite(0, LOW);
 delay(1000);

}

```

Below is the code you have written, it works I have it running in front of me. I have commented it and changed a few things to make it work as intended, although the intention is not clear.

```
#include <EEPROM.h>

byte CLK = 0; //This is a global variable with an initial value

void setup() {
  // put your setup code here, to run once:

  EEPROM.write(0, 1); //set the pin to D1
  delay(5);

  //read from EEPROM address 0
  //this sets the value of the global variable CLK
  CLK = EEPROM.read(0); //place this inside a function

  //just to give an example...
  byte PIN = CLK;   //PIN variable is a local variable

  pinMode(PIN ,OUTPUT); //using that local variable

}

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

  // Note: the below if() will always be true as the value
  // of CLK is never change and shouldn't be changed as
  // it will change the pin number of the output

  if (CLK == 1) {
    for (int a = 0; a < 3; a++) {
      digitalWrite(CLK, HIGH);  //this uses the global variable
      delay(1000);
      digitalWrite(CLK, LOW);
      delay(1000);
    }
    //putting exit(0); will actually stop the program
    //remove it
//    exit(0);
  }
  else {
    for (int a = 0; a < 100; a++) {
      digitalWrite(0, HIGH);  //this has a predefined pin no.
      delay(500);
      digitalWrite(0, LOW);   //this has a predefined pin no.
      delay(500);
    }
    //putting exit(0); will actually stop the program
    //remove it
//    exit(0);
  }
}

```

# Answer
> 1 votes
When you upload a new sketch with the default settings, the EEPROM will be cleared.

"The -e option instructs avrdude to perform a chip-erase before programming; this is almost always necessary before programming the flash."

If you're using the Arduino IDE, the -e option is enabled by default. This is probably why it's not working for you.

See also the question Is there a way to preserve EEPROM contents in AVR Atmega when burning a new firmware to flash with avrdude?

# Answer
> 0 votes
Not sure if things have changed so significantly since the question was asked originally but I'll answer using the Atmel AVR libraries.

Don't assign the EEPROM value to a variable as then you are wasting precious SRAM again. EEPROM has unlimited read cycles.

I can't find any current references to `EEPROM.read()` as a Macro or function in the Arduino IDE. Instead there is the AVR EEPROM library which uses `eeprom_read_byte()` as shown below.

```
#include  <avr/eeprom.h>

// the setup routine runs once when you press reset:
void setup() {
/* The "131" value is used to prevent damaging excess EEPROM writes on every restart.
   If you want to try setting a different GPIO pin for LED blink change the test value in
   both the read and following write to EEPROM address 511 */

    if (eeprom_read_byte((uint8_t*)511) != 131) {
       eeprom_write_byte((uint8_t*)511,131);
// Store the GPIO pin number in EEPROM address 1
       eeprom_write_byte((uint8_t*)1,1);
    };
// initialize the digital pin as an output.
    pinMode(eeprom_read_byte((uint8_t*)1), OUTPUT); // LED pin value stored in EEPROM address 1
}

// the loop routine runs over and over again forever:

void loop() {
    digitalWrite(eeprom_read_byte((uint8_t*)1), HIGH);
    delay(1000);               // wait for a second
    digitalWrite(eeprom_read_byte((uint8_t*)1), LOW);

    delay(1000);               // wait for a second
}

```

# Answer
> 0 votes
It is now very common to read from EEPROM in an ATTiny, particularly an OSCCAL value. It has also been the case for some embedded devices to perform a superfluous write and read back to external EEPROM during POST. Every boot.

```
> ---snip---
>     current tick:1 sec
>     EEPROM Init...
>     Write EE_TEST ==0x7cf u8EEData1=0xaa
>     Read EE_TEST ==0x7cf u8EEData1=0xaa
>     [EEPROM 24c16 found!]
>     EEPROM: Data valid
>     Restore Configuration from EEPROM to Device...
>     Show MY MAC Address(from 24c16): (0x00:92:58:01:45:4d)
>     _24c16_eeprom_word_read: EE_DHCPEN: (01)
> --- end snip ---

```

In addition, available cores include options to suppress EEPROM erase in programming, this is fuseable.

In ancient times AVRDUDE would write flash counts to the four bytes terminated by E2END. (the -y option).

You need to include the header. You can check, peek and poke, the contents with a sketch or by using avrdude in terminal mode (-t) with "dump ee".

And yes, it is normal for Arduino work to have a dedicated temporary sketch to load EEPROM data. So SRAM (or FLASH) does not matter, there is a lot of FLASH compared to EEPROM.

Keep it simple and test your results. Depending upon the library or core, it is best to avoid crossing page boundaries as addressing may wrap around to the beginning of the page due to 6 bit truncation as for I2C external EEPROM. Don't trust, verify.

---
Tags: attiny, memory-usage, eeprom, memory
---


# Question
Title: Running Arduino with 2 outputs and 2 inputs
Totally new to Arduino, 3 weeks old!

I am doing a project with 2 inputs (2 x ultrasonic sensors) and 2 outputs (buzzer and send SMS)

The code to run the buzzer and sms works perfectly individually. For the buzzer, it will stop buzzing after approx 5 seconds.

I would love them to run **concurrently** but it didn't work as planned when I upload the code on the board.

I've read on forums to use **millis / blinkwithoutdelay** but am unsure how I can incorporate those functions on my mode as the examples posted online are different from my project.

The following is the code I have created.

Would appreciate if I can get some help from the experienced folks here.

```
#define TRIG A0 //Module pins
#define ECHO A1
#define TRIG1 A2 //Module pins
#define ECHO1 A3
#define Buzzerpin 13

int ctn = 0;

void setup() {
  Serial.begin(9600); // Serial monitoring
  pinMode(TRIG, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO, INPUT_PULLUP);
  pinMode(TRIG1, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO1, INPUT_PULLUP);
  pinMode(Buzzerpin, OUTPUT);
}

void loop() {

  digitalWrite(TRIG, LOW); // Set the trigger pin to low for 2uS
  delayMicroseconds(2);

  digitalWrite(TRIG, HIGH); // Send a 10uS high to trigger ranging according to specs
  delayMicroseconds(20);

  digitalWrite(TRIG, LOW); // Send pin low again
  delayMicroseconds(2);

  digitalWrite(TRIG1, LOW); // Set the trigger pin to low for 2uS. Give a short LOW pulse beforehand to ensure a clean HIGH pulse
  delayMicroseconds(2);

  digitalWrite(TRIG1, HIGH); // Send a 10uS high to trigger ranging according to specs
  delayMicroseconds(20);

  digitalWrite(TRIG1, LOW); // Send pin low again
  delayMicroseconds(2);

  int distance = pulseIn(ECHO, HIGH, 26000); // Read in times pulse
  int distance1 = pulseIn(ECHO1, HIGH, 26000); // Read in times pulse
  distance = distance/58;
  distance1 = distance1/58;

  if (distance < 25) {
    Serial.print("\r");
    delay(1000);
    Serial.print("AT+CMGF=1\r");
    delay(1000);
    /*Replace XXXXXXXXXX to 10 digit mobile number & ZZ to 2 digit country code*/
    Serial.print("AT+CMGS=\"+YYXXXX\"\r"); // YY is the country code XXX is the number
    delay(1000); //
    //The text of the message to be sent.
    Serial.print("HELLO There");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);
  }
  else {}

  if (distance1 < 25 && ctn < 150) {
    ctn += 1;
    digitalWrite(Buzzerpin, HIGH);
  }
  else {
    digitalWrite(Buzzerpin, LOW);
  }

  if (distance1 > 25 && ctn >= 150) {
    ctn = 0;
    digitalWrite(Buzzerpin, HIGH);
  }
}

```

# Answer
First thing: you should call `pulseIn()` right after sending the TRIG pulse. If you wait too much, you will miss the start of the echo pulse. For instance, here:

```
int distance = pulseIn(ECHO, HIGH, 26000);
int distance1 = pulseIn(ECHO1, HIGH, 26000);

```

the second `pulseIn()` is starting too late, because of the time taken by the first one.

Next, the general approach for doing things is a non-blocking fashion (and thus being able to handle concurrent tasks) is to program each task in the form of a finite state machine. Combine this with the timing technique used in the “Blink without delay” Arduino tutorial if you need time-triggered actions.

Here I would use one state machine for sending the SMS and another one for the buzzer. The first one is the most complex:

**Edit**: I expanded on how I designed this state machine.

In a canonical finite state machine implementation, each action is associated with a state transition. We then have a transition for each command sent to the GSM module, and we can label the states according to which commands have already been sent, like this:

SENT\_NOTHING → SENT\_CR → SENT\_CMGF → SENT\_CMGS → SENT\_MSG → SENT\_ALL.

All of the above transitions send a string to the GSM module. The first one (SENT\_NOTHING → SENT\_CR) is triggered by the distance detected being less than 25 cm. The following ones are time-triggered one second after the previous one. We have to add one final transition (SENT\_ALL → SENT\_NOTHING) that performs no action but lets the system “forget” it has sent an SMS and thus makes it ready to send a new one. This transition would also be time-triggered, after a potentially long delay (how often would the user like to receive those reminders?). In the code below, this last delay is one second, which I believe is too short, but matches the last `delay(1000)` in the code you posted. The implementation would be like this:

```
static enum {
  SENT_NOTHING, SENT_CR, SENT_CMGF, SENT_CMGS, SENT_MSG, SENT_ALL
} sms_state = SENT_NOTHING;
static uint32_t time_last_command_sent;
uint32_t now = millis();
switch (sms_state) {
  case SENT_NOTHING:
    if (distance < 25) {
      Serial.print("\r");
      time_last_command_sent = now;
      sms_state = SENT_CR;
    }
    break;
  case SENT_CR:
    if (now - time_last_command_sent >= 1000) {
      Serial.print("AT+CMGF=1\r");
      time_last_command_sent = now;
      sms_state = SENT_CMGF;
    }
    break;
  case SENT_CMGF:
    if (now - time_last_command_sent >= 1000) {
      Serial.print("AT+CMGS=\"+YYXXXX\"\r");
      time_last_command_sent = now;
      sms_state = SENT_CMGS;
    }
    break;
  // and so on for the cases SENT_CMGS and SENT_MSG...
  case SENT_ALL:
    if (now - time_last_command_sent >= 1000) {
      sms_state = SENT_NOTHING;  // forget we sent an SMS
    }
    break;
}

```

I have an issue with this implementation though: it is overly repetitive, as the cases SENT\_CR, SENT\_CMGF, SENT\_CMGS and SENT\_MSG are essentially copies of the same code. In order to make the code dryer, I prefer merging them into a single state, and splitting the state information into two variables: `sms_state` and `commands_sent`. The new possible values for `sms_state` are now:

* SMS\_READY: the code is ready to send the message as soon as it is required by the detected distance.
* SMS\_SENDING: it has started to send the commands to the GSM module, but is not done yet.
* SMS\_DONE: the SMS has been sent, but no other one will be sent until some time has elapsed, after which it will transition to SMS\_READY.

The mapping to the “full” machine states is then:

```
 full state    │ sms_state   commands_sent
───────────────┼───────────────────────────
 SENT_NOTHING  │ SMS_READY         0
 SENT_CR       │ SMS_SENDING       1
 SENT_CMGF     │ SMS_SENDING       2
 SENT_CMGS     │ SMS_SENDING       3
 SENT_MSG      │ SMS_SENDING       4
 SENT_ALL      │ SMS_DONE          5

```

It could be argued that `sms_state` is redundant, as all the state information is contained in `commands_sent`. I still wanted to keep `sms_state` in order to easily `switch` on it. This is not the only possible approach though, and it would be perfectly sensible to write something like

```
if (commands_sent == 0) {
  // handle the case SMS_READY
} else if (commands_sent < command_count) {
  // handle the case SMS_SENDING
} else {
  // handle the case SMS_DONE
}

```

For the buzzer, there are only two states: BUZZER\_OFF and BUZZER\_ON. The transitions are conditioned by the measured distance and, for the ON → OFF transition, also by the time it has been ON.

Here is my tentative, untested implementation of this approach:

```
#define TRIG A0 //Module pins
#define ECHO A1
#define TRIG1 A2 //Module pins
#define ECHO1 A3
#define Buzzerpin 13

// Commands to be sent to the GSM module.
const int command_count = 5;
const char * const commands[command_count] = {
  "\r",
  "AT+CMGF=1\r",
  "AT+CMGS=\"+YYXXXX\"\r",
  "HELLO There",
  "\x1a"
};

void setup() {
  Serial.begin(9600);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT_PULLUP);
  pinMode(TRIG1, OUTPUT);
  pinMode(ECHO1, INPUT_PULLUP);
  pinMode(Buzzerpin, OUTPUT);
}

void loop() {
  // Measure both distances.
  digitalWrite(TRIG, LOW);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(20);
  digitalWrite(TRIG, LOW);
  int distance = pulseIn(ECHO, HIGH, 26000) / 58;
  digitalWrite(TRIG1, HIGH);
  delayMicroseconds(20);
  digitalWrite(TRIG1, LOW);
  int distance1 = pulseIn(ECHO1, HIGH, 26000) / 58;

  // Timing for both state machines.
  uint32_t now = millis();

  // Send the SMS.
  static enum {SMS_READY, SMS_SENDING, SMS_DONE} sms_state;
  static uint32_t time_last_command_sent;
  static int commands_sent = 0;
  switch (sms_state) {
    case SMS_READY:
      if (distance < 25) {
        Serial.print(commands[commands_sent++]);
        time_last_command_sent = now;
        sms_state = SMS_SENDING;
      }
      break;
    case SMS_SENDING:
      if (now - time_last_command_sent >= 1000) {
        Serial.print(commands[commands_sent++]);
        time_last_command_sent = now;
        if (commands_sent >= command_count) {
          sms_state = SMS_DONE;
        }
      }
      break;
    case SMS_DONE:
      if (now - time_last_command_sent >= 1000) {
        commands_sent = 0;
        sms_state = SMS_READY;
      }
      break;
  }

  // Drive the buzzer.
  static enum {BUZZER_OFF, BUZZER_ON} buzzer_state;
  static uint32_t time_buzzer_started;
  if (buzzer_state == BUZZER_OFF && distance1 < 25) {
    digitalWrite(Buzzerpin, HIGH);
    buzzer_state = BUZZER_ON;
    time_buzzer_started = now;
  } else if (buzzer_state == BUZZER_ON && distance1 >= 25
             && now - time_buzzer_started >= 2000) {
    digitalWrite(Buzzerpin, LOW);
    buzzer_state = BUZZER_OFF;
  }
}

```
> 4 votes

# Answer
Using the blinkwithoutdelay approach is not incorporating functions, it is a coding style.

The idea is that you write your loop code to pass through without any delays, or with only very tiny delays. On each pass through the loop, you see how much time has passed, and if it's been 5 seconds since you started the buzzer, you turn off the buzzer.

You can probably get away with the microsecond delays that you use in your ultrasonic sensor code. Those delays are so small that they will only cause **very** short pauses in your app.

The `delay(1000)` calls in your loop are not going to work. Each one of those causes EVERYTHING to stop for a full second. You won't check the ultrasonic sensor, you won't change the buzzer state, you won't do ANYTHING, for 5 seconds, once you enter the body of that `if` statement. Those delay calls have to go.
> 0 votes

---
Tags: millis
---


# Question
Title: Is it required to delete variables before going to sleep?
This tutorial shows how to put the arduino to sleep and use a watchdog to wake up at intervals:

https://youtu.be/urLSDi7SD8M

I been studding c++ and as I am getting better I am instantiating objects with the `new` keyword. I have learned that if you create something with the `new` keyword you are responsible for deleting it from memory when you no longer needed. But I do not know if this applies when you put arduino to sleep.

**Anyways my question is in the comments of the code:**

```
Foo * someObject;

void setup()
{
    someObject = new Foo(arg1, arg2, ..); // crete an instance of someObject
   // init pins etc..
}

void loop()
{
     if(button1Pressed())
     {

          // **** DO I HAVE TO DELETE OBJECTS BEFORE GOING TO SLEEP? Do I need this line? ****
          delete someObject;

          gotToSleepAndWakeUpIn4Seconds() ;  // places arduino in sleep mode and wakes up again in 4 seconds

          int x = 0; // this line never executes arduino is on sleep mode and will wake up again in 4 seconds
     }

     // more code
     if(something)
        someObject->executeFunction1();

     // etc...
     // ....
}

```

# Answer
> 3 votes
You have probably learnt that objects created with `new` are stored in the heap, while globals are stored in the .data and .bss sections, and locals on the stack¹. This distinction, however, only exists in the software. At the hardware level, .data, .bss, heap and stack are just arbitrary portions of the RAM.

Think of what would happen if the RAM was erased, or somehow corrupted, when the microcontroller sleeps. Not only would that affect the heap-based objects, but also every variable in the program. And even the return address from the call to `gotToSleepAndWakeUpIn4Seconds()` would be lost, so the CPU would not know where to resume execution when it wakes up. The only reasonable thing to do at wakeup would then be to restart the program from scratch. And this is actually what happens when you reset the microcontroller².

But a sleep is not a reset. The contents of the RAM is preserved while sleeping. This means that the *whole state* of the program is preserved: locals, globals and heap-based objects. No need to delete and re-create stuff.

As a side note, if you can allocate memory statically, this is usually better than dynamic allocation, ans you avoid the risk of heap fragmentation:

```
Foo someObject(arg1, arg2, ..);  // static global instance

void loop()
{
    // Some code, then,

    if (something)
        someObject.executeFunction1();
}

```

Notes:
¹ As an optimization, locals of the *current* stack frame may be in CPU registers, but this doesn't change the conclusion.
² On AVR, a warm reset doesn't loose the RAM, but it is then reinitialized by the C runtime. A cold reset (power-cycle) does loose the RAM.

---
Tags: c++, memory-usage
---


# Question
Title: Arduino Nano - How to add multiple sensors? Lithium battery requirements? LED requirements?
I am new to arduino and need help with a couple projects I am working on. One involves the use of 2 sensors - one pulse sensor, and one vibration sensor. Both need to be plugged into the "5v" pin but there seems to be only one. Is there a way I could split the pins to add multiple sensors? Will data be taken in simultaneously, and be cross compared with each other for code execution? I dont want to use breadboaard and want to wire directly to chip.

Also, I need to wire up a rechargeable lithium battery to both projects, I have a 3.7v 1000 Mah lithium battery and a charging port, but do I need more? Ive seen battery regulators, and other parts people recommend, but I want to make sure it will work with just those 2 parts.

I also need to wire a multicolor LED to the board, but do I need any resistors? I see them often for others people projects, but I do not have any and am wondering if I need them.

Thanks if you can answer any of these questions. Totally new to EE

# Answer
This is an addition to the answer of Thomas Weller.

> Also, I need to wire up a rechargeable lithium battery to both projects, I have a 3.7v 1000 Mah lithium battery and a charging port, but do I need more? Ive seen battery regulators, and other parts people recommend, but I want to make sure it will work with just those 2 parts.

I guess with "charging port" you simply mean a plug, where you can connect a power supply to charge the Li battery. Then the answer is: No, you cannot do it with only the battery and the plug. Lithium batteries are rechargeable, yes, but there is much to consider for charging. You must never ever overcharge the battery or discharge it beyond a certain point. Otherwise the battery gets broken (the result can be between simply holding less and less or no power, to the battery exploding).

Also you need to know the battery level to accurately charge or turn of the device, when the battery is empty. Lithium batteries mostly don't change their voltage enough between the full and empty states. Thus Li battery devices have a circuit, that measures, how much power is coming in (while recharging) and how much power is taken out (for powering a device), to determine the current battery level.

At your stage you cannot build that yourself, and also I wouldn't recommend that to anyone. You can by Li battery charger/regulator boards, which will do all that for you, and they are not expensive. There are also microcontroller boards, that incorporate that support for Li batteries.
> 0 votes

# Answer
**For the 5v pin:** If you wire 2 sensors to the 5v pin, it will not effect sensor readings of either sensors, and should return separate sensor values regardless of whether or not they are both wired to the 5v pin.

In order to wire both sensors to 1 5v pin, without involving a breadboard you have 2 options:

1. wire both sensor pins, and the 5v pin onto a custom pin header PCB that connects 3 or more pin headers together
2. Strip 3 jumper wires and solder them together (2 for the sensors and 1 for the 5v pin)

**For the lithium batteries:** It says on their website: that the operating voltage is 5v, So your battery voltage needs to be at least that. It might be a good idea to get 2 (store.arduino.cc)

**For the LEDs:** If it is a standard LED, it should be able to withstand voltages of 3.3v or under. Thus the resistor is only absolutely essential for higher voltages. However, it is recommended to use a resistor even with voltages of 3.3v or below, because low resistance could shorten the lifespan of the LED
> 1 votes

# Answer
Warning: unexperienced experiments even with low voltage may result in dangerous situations. E.g. a typical 10 Ohm resistor on 5 V may get so hot that it starts burning. Make yourself familiar with basic electronics, ideally with the help of someone else who can explain it to you. That person should especially explain the safety instructions first.

> Both need to be plugged into the "5v" pin but there seems to be only one.

5 Volts means that this is a voltage source. In an ideal voltage source, you can basically plug in as many components as you like.

A real world voltage source will have a power limit. So you need to find datasheets of all components: the Arduino and the sensors. You can then read how much power the Arduino can provide and you can read how much power the sensors need.

As long as the Arduino can provide more power than the sensors need, that's ok. If it can't stuff will become more complicated, since you'll need another 5 V source and find a way to connect them safely.

> Is there a way I could split the pins to add multiple sensors?

One does not split pins, one connects additional wires to a pin.

> Will data be taken in simultaneously, and be cross compared with each other for code execution?

The 5V pin is only a voltage source. It will not provide or receive data. You'll need another pin or even multiple other pins to send and receive data.

Sometimes you can only have one device per pin (like a digital out pin), sometimes you can have multiple devices on a few pins (like I²C, SPI, 1Wire).

Typically, you would define what you need and then buy the components so you can build it. This requires a bit of knowledge, so watch some tutorials or introduction videos first.

> I dont want to use breadboaard and want to wire directly to chip.

Sorry to be that direct, but at your level of understanding, that's probably not a good idea. Build it on a breadboard first and once it works as intended, make it a soldered circuit.

> I need to wire up a rechargeable lithium battery to both projects, I have a 3.7v 1000 Mah lithium battery and a charging port, but do I need more?

As you said your components need 5 V, a 3.7 V battery will not help you at all.

You also need to be careful with the terms: a Mah is something totally different than a mAh. Don't confuse other people by mixing Mega (millions) with milli (1/1000).

Other than that, again, read the data sheets, find out how much current each component needs and sum it up. Then divide the 1000 mAh by the value you found, e.g. 100 mA and you'll get 10 h. That's how long it will last. Maybe it's good for your purpose, maybe not. How should we know that?

> I want to make sure it will work with just those 2 parts.

That's great. Just consider all the aspects written in the data sheets of the components and it'll be fine.

> I also need to wire a multicolor LED to the board, but do I need any resistors?

Yes. Read the data sheet of the multicolor LED and build a voltage dividor according to the values you find.

> Totally new to EE

That's probably true. Maybe you want to start at the beginning and not jump into such a complex project. Get some resistors, measure voltages, measure currents. Make an LED light up. Learn about Ohms law, you'll need it very often. Once you got familiar with the basic stuff, come back to this project.

Honestly, I think you'll destroy components if you start with "a couple of projects".
> 0 votes

# Answer
A multicolor LED as in an RGB LED?

To power and LED you will need current limiting resistors.

For an RGB LED you'll need 3, one each for the red, green, and blue channels. You'll need to do some math to figure out what resistance values you need. You need to know the supply voltage (5V) the voltage drop of the LED, and the current to supply to the LED.

Here is a link to an LED resistor calculator: https://ohmslawcalculator.com/led-resistor-calculator

The formula is R = (source\_voltage - LED\_voltage\_drop) / LED\_current

So if you have a 20 mA LED with a 1.3V voltage drop, and you are powering it from 5V (all fairly common values) you'd get:

(5-1.3)/0.02 = 185 Ω.

Then you would round up to the nearest resistor value.

You can safely use a higher resistance value than what you calculate. That will cause the LED to be dimmer. If you use a lower resistance you risk burning out the LED, or even burning out your Arduino.

For 20% resistors, that would be a 220Ω resistor. (The percent is a tolerance value. 20% resistors can have their actual resistance vary by as much as 20% from one to the next. You can get resistors in 20%, 10%, 5%, 2%, 1% tolerances, and even lower. The lower the tolerance value, the more they cost, and the more resistors you need to have all the possible values.

Don't use that value however. Look up the voltage drop and current for your LED and plug them into the above formula.

If you want to vary the apparent color of an RGB LED through software you can hook each color channel to a different PWM output pin on your Arduino. You then set each color channel to a different "duty cycle" to vary the brightness of that color.
> 0 votes

---
Tags: arduino-nano
---


# Question
Title: Wemos D1 mini and JSN-SR04T-2.0: Type of power supply affects the sensor readings
Pretty similar to what is described here I have the strange problem that my sensor readings are affected by the type of power supply I use.

Whenever I connect my D1 mini through USB with laptop everything works fine. The readings make sense and are quite accurate. But as soon as I disconnect it from the laptop and use a USB power supply (I tested different ones) the readings do not make sense anymore.

I also tried to apply the sketch to a NodeMCU board. The results are the same. So I assume it has something to do with either the sensor or the ESP 12E.

Any suggestions?

# Answer
> -1 votes
Try a different supply or computer, it sounds like that one has a lot of ripple and or noise on it. Not all USB power supplies are clean and some do not have much filtering.

---
Tags: esp8266, power
---


# Question
Title: digital input pins on arduino nano with standard firmata and pyfirmata are always 'None'
I have connected pin D2 on my arduino nano to high, and tried it out with an arduino c program and it works. However, when I load standard firmata onto the the controller from the arduino IDE and try the following python program:

```
import pyfirmata

board = pyfirmata.Arduino('/dev/ttyUSB0')

for x in range(2,14):
    print("%s %s" % (x, board.get_pin("d:%s:i" % x).read()))

```

I get this:

```
$ venv/bin/python test.py
2 None
3 None
4 None
5 None
6 None
7 None
8 None
9 None
10 None
11 None
12 None
13 None

```

I can write digital pins with fermata and pyfirmata, but I can't *read*.

I have also tried this:

```
import pyfirmata

board.digital[2].mode = pyfirmata.INPUT
board.digital[3].mode = pyfirmata.INPUT

for x in range(2,14):
    print("%s %s" % (x, board.digital[x].read()))

```

and other combinations, and always get None

(disconnecting the wire in the picture doesn't change anything either)

---

I have also just repeated the experiment with an arduino uno and get the same result

---

so I guess my questions are:

* Can anybody spot anything obvious that I am doing wrong?
* Can anybody confirm that pyfirmata input ever works?
* What did you do that I am not doing?

# Answer
"None" indicates that there is no data to be found by read() because the incoming serial stream has never been serviced. Launch an Iterator to start a new Python thread that services the serial port in the background.

```
it = pyfirmata.util.Iterator(board)
it.start()

```
> 1 votes

---
Tags: arduino-nano, pins, firmata
---


# Question
Title: How to Set RTC in ES32 using NTP server?
I am working on ESP32 And want to set RTC from the NTP server. How can I get epoch value I have done this thing on CC3200 launchpad and used an NTP server library to obtain epoch value.

# Answer
this snippet from setup() sets on esp32 the NTP for internal RTC and uses epoch seconds to set time to TimeLib library.

```
  configTime(gmtOffset_sec, daylightOffset_sec, "pool.ntp.org");
  time_t now = time(nullptr);
  while (now < SECS_YR_2000) {
    delay(100);
    now = time(nullptr);
  }
  setTime(now);

```

The ESP32 examples library in IDE examples folder has example SimpleTime.
> 1 votes

---
Tags: wifi, esp32, web-server, time, rtc
---


title: Holding buttons (keyboard)

text:
# Question
Title: Holding buttons (keyboard)
I made a wireless keyboard, but I just need 4 button for my project: left control, left shift, F1, F2. The problem: When I hold button - it acts like many key presses and releases, but I need, that when I press & hold button - it also acts like I press & hold it.

Could you please help me?

Here is source code:

Transfer\_e5.ino: https://www.paste.org/108039

Receiver\_e5.ino: https://www.paste.org/108040

Or 1 rar package: https://easyupload.io/o3c5sp

Thank you

Or I can put them just here, if you wish.

Receiver:

```
#include <Keyboard.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7); // (ce,cs)
RF24Network network(radio);

const uint16_t this_node = 00;
const uint16_t other_node = 03;

unsigned int laser_state=0;
const unsigned long my_interval = 500;
unsigned long last_sent;
unsigned int income=0;

void setup(void)
{
  Serial.begin(115200);
  pinMode(9,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);

  pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
}

void loop(void){
  digitalWrite(4,LOW);
  network.update();

  if ( network.available() ) {
    RF24NetworkHeader header;
    network.read(header,&income,sizeof(income));

    if(income==10){
      Serial.println("f1");
      Keyboard.press(KEY_F1);
      income=0;
    }

    if(income==11){
      Serial.println("f2");
      Keyboard.press(KEY_F2);
      income=0;
    }

    if(income==12){
      Serial.println("ctrl");
      Keyboard.press(KEY_LEFT_CTRL);
      income=0;
    }

    if(income==13){
      Serial.println("shift");
      Keyboard.press(KEY_LEFT_SHIFT);
      income=0;
    }

    Keyboard.releaseAll();
  }

  unsigned long now = millis();

  if ( now - last_sent >= my_interval  )
  {
//    Serial.print("pin ");
//    Serial.println(digitalRead(9));
    last_sent = now;
    laser_state = digitalRead(9);

    RF24NetworkHeader header(other_node);
    bool ok = network.write(header,&laser_state,sizeof(laser_state));
  }
}

```

Transfer

```
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7);
RF24Network network(radio);

const uint16_t this_node = 03;
const uint16_t other_node = 00;

unsigned int laser_state=0;
const unsigned long interval = 5;
unsigned long last_sent;

unsigned int b1=1;
unsigned int b2=1;
unsigned int b3=1;
unsigned int b4=1;

unsigned int d1=10;
unsigned int d2=11;
unsigned int d3=12;
unsigned int d4=13;

//TR1
int btn1 = 3;
int btn2 = 4;
int btn3 = 5;
int btn4 = 6;

void setup(void)
{
//  Serial.begin(9600);
  pinMode(btn1,INPUT_PULLUP);
  pinMode(btn2,INPUT_PULLUP);
  pinMode(btn3,INPUT_PULLUP);
  pinMode(btn4,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);
}

void loop(void){
  network.update();

  unsigned long now = millis();

  if ( now - last_sent >= interval  )
  {
    last_sent = now;

    b1 = digitalRead(btn1);
    b2 = digitalRead(btn2);
    b3 = digitalRead(btn3);
    b4 = digitalRead(btn4);

    if(b1==0){
//      Serial.println("F1");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d1,sizeof(d1));
    }

    if(b2==0){
//      Serial.println("F2");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d2,sizeof(d2));
    }

     if(b3==0){
//      Serial.println("Ctrl");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d3,sizeof(d3));
    }

    if(b4==0){
//      Serial.println("Shift");
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,&d4,sizeof(d4));
    }
  }
}

```

# Answer
> 2 votes
The root problem is that you send each several ms new key event and on receiver each time you get this event, you call `Keyboard.press` and right away `Keyboard.release`. So, it behaves as several key press-releases.

At sender side you should send 2 types of events:

1. Key pressed (and which button)
2. Key released (and which button)

At receiver side you should

1. When you receive "press" event, call `Keyboard.press`, and don't call `Keyboard.release`
2. When you receive "release" event, call `Keyboard.release`

**Edit: I've made changes to your source code, please, try it**

Transfer

```
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7);
RF24Network network(radio);

const uint16_t this_node = 03;
const uint16_t other_node = 00;

unsigned int laser_state=0;
const unsigned long interval = 5;
unsigned long last_sent;

unsigned int b1=1;
unsigned int b2=1;
unsigned int b3=1;
unsigned int b4=1;

unsigned int d1=10;
unsigned int d2=11;
unsigned int d3=12;
unsigned int d4=13;

//TR1
int btn1 = 3;
int btn2 = 4;
int btn3 = 5;
int btn4 = 6;

void setup(void)
{
//  Serial.begin(9600);
  pinMode(btn1,INPUT_PULLUP);
  pinMode(btn2,INPUT_PULLUP);
  pinMode(btn3,INPUT_PULLUP);
  pinMode(btn4,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);
}

void loop(void){
  network.update();

  unsigned long now = millis();

  if (now - last_sent >= interval)
  {
    last_sent = now;

    auto newB1 = digitalRead(btn1);
    auto newB2 = digitalRead(btn2);
    auto newB3 = digitalRead(btn3);
    auto newB4 = digitalRead(btn4);

    unsigned int packet[2];

    if(newB1 != b1){
//      Serial.println("F1");
      packet[0] = d1;
      packet[1] = newB1;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

    if(newB2 != b2){
//      Serial.println("F2");
      packet[0] = d2;
      packet[1] = newB2;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

     if(newB3 != b3){
//      Serial.println("Ctrl");
      packet[0] = d3;
      packet[1] = newB3;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

    if(newB4 != b4){
//      Serial.println("Shift");
      packet[0] = d4;
      packet[1] = newB4;
      RF24NetworkHeader header(other_node);
      bool ok = network.write(header,packet,sizeof(packet));
    }

    b1 = newB1;
    b2 = newB2;
    b3 = newB3;
    b4 = newB4;
  }
}

```

Receiver

```
#include <Keyboard.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,7); // (ce,cs)
RF24Network network(radio);

const uint16_t this_node = 00;
const uint16_t other_node = 03;

unsigned int laser_state=0;
const unsigned long my_interval = 500;
unsigned long last_sent;

void setup(void)
{
  Serial.begin(115200);
  pinMode(9,INPUT_PULLUP);

  SPI.begin();
  radio.begin();
  network.begin(90,this_node);

  pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
}

void loop(void){
  digitalWrite(4,LOW);
  network.update();

  unsigned int income[2] = {0, 0};

  if ( network.available() ) {
    RF24NetworkHeader header;
    network.read(header,&income,sizeof(income));

    auto keyCode = income[0];
    auto keyPress = !income[1];

    if(keyCode == 10){
      Serial.println("f1");

      if (keyPress) {
        Keyboard.press(KEY_F1);
      } else {
        Keyboard.release(KEY_F1);
      }
    }

    if(keyCode == 11){
      Serial.println("f2");

      if (keyPress) {
        Keyboard.press(KEY_F2);
      } else {
        Keyboard.release(KEY_F2);
      }
    }

    if(keyCode == 12){
      Serial.println("ctrl");

      if (keyPress) {
        Keyboard.press(KEY_LEFT_CTRL);
      } else {
        Keyboard.release(KEY_LEFT_CTRL);
      }
    }

    if(keyCode == 13){
      Serial.println("shift");

      if (keyPress) {
        Keyboard.press(KEY_LEFT_SHIFT);
      } else {
        Keyboard.release(KEY_LEFT_SHIFT);
      }
    }

    keyCode = 0;
  }

  unsigned long now = millis();

  if ( now - last_sent >= my_interval  )
  {
//    Serial.print("pin ");
//    Serial.println(digitalRead(9));
    last_sent = now;
    laser_state = digitalRead(9);

    RF24NetworkHeader header(other_node);
    bool ok = network.write(header,&laser_state,sizeof(laser_state));
  }
}

```

---
Tags: keyboard
---


# Question
Title: DFRobot GPS init error [Arduino Uno, SIM808]
i have problem with initialization DFRobot SIM808 actually when i try to recieve gps data by SoftwareSerial only it does works (i mean examples based on sending and reading command to and from serial's), and recieve data but very long string of data and i need only **Latitude** and **Longitude** and i think using DFRobot will be the easiest way to extract the data i need. So the simple test program like this one is not working:

```
    /*
### Get GPS data
1. This example is used to test SIM808 GPS/GPRS/GSM Shield's reading GPS data.
2. Open the SIM808_GetGPS example or copy these code to your project
3. Download and dial the function switch to Arduino
4. open serial helper
4. Place it outside, waiting for a few minutes and then it will send GPS data to serial

create on 2016/09/23, version: 1.0
by jason

*/
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX    7
#define PIN_RX    8
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

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

  //******** Initialize sim808 module *************
  while(!sim808.init()) {
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }

  //************* Turn on the GPS power************
  if( sim808.attachGPS())
      Serial.println("Open the GPS power success");
  else
      Serial.println("Open the GPS power failure");

}

void loop() {
   //************** Get GPS data *******************
   if (sim808.getGPS()) {
    Serial.print(sim808.GPSdata.year);
    Serial.print("/");
    Serial.print(sim808.GPSdata.month);
    Serial.print("/");
    Serial.print(sim808.GPSdata.day);
    Serial.print(" ");
    Serial.print(sim808.GPSdata.hour);
    Serial.print(":");
    Serial.print(sim808.GPSdata.minute);
    Serial.print(":");
    Serial.print(sim808.GPSdata.second);
    Serial.print(":");
    Serial.println(sim808.GPSdata.centisecond);
    Serial.print("latitude :");
    Serial.println(sim808.GPSdata.lat);
    Serial.print("longitude :");
    Serial.println(sim808.GPSdata.lon);
    Serial.print("speed_kph :");
    Serial.println(sim808.GPSdata.speed_kph);
    Serial.print("heading :");
    Serial.println(sim808.GPSdata.heading);
    Serial.println();

    //************* Turn off the GPS power ************
    sim808.detachGPS();
  }

}

```

# Answer
> 1 votes
{Original answer by Onuralp Arslan}

gps function of sim808 does not require sim card you only need 9v source with enough current and 1575.42 mHz gps antenna use this code it will help

```
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define PIN_RX 11
#define PIN_TX 10
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

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

//************* Turn on the GPS power************
if( sim808.attachGPS())
Serial.println("Open the GPS power success");
else
Serial.println("Open the GPS power failure");

}

void loop() {
//************** Get GPS data *******************
if (sim808.getGPS()) {
Serial.print(sim808.GPSdata.year);
Serial.print("/");
Serial.print(sim808.GPSdata.month);
Serial.print("/");
Serial.print(sim808.GPSdata.day);
Serial.print(" ");
Serial.print(sim808.GPSdata.hour);
Serial.print(":");
Serial.print(sim808.GPSdata.minute);
Serial.print(":");
Serial.print(sim808.GPSdata.second);
Serial.print(":");
Serial.println(sim808.GPSdata.centisecond);

Serial.print("latitude :");
Serial.println(sim808.GPSdata.lat,6);

sim808.latitudeConverToDMS();
Serial.print("latitude :");
Serial.print(sim808.latDMS.degrees);
Serial.print("\^");
Serial.print(sim808.latDMS.minutes);
Serial.print("\'");
Serial.print(sim808.latDMS.seconeds,6);
Serial.println("\"");
Serial.print("longitude :");
Serial.println(sim808.GPSdata.lon,6);
sim808.LongitudeConverToDMS();
Serial.print("longitude :");
Serial.print(sim808.longDMS.degrees);
Serial.print("\^");
Serial.print(sim808.longDMS.minutes);
Serial.print("\'");
Serial.print(sim808.longDMS.seconeds,6);
Serial.println("\"");

Serial.print("speed_kph :");
Serial.println(sim808.GPSdata.speed_kph);
Serial.print("heading :");
Serial.println(sim808.GPSdata.heading);

//************* Turn off the GPS power ************
sim808.detachGPS();
}

}

```

try this, worked for me without sim card connect rx of sim808 to arduino 11 tx to 10 and connect grounds of arduino and sim808

# Answer
> 0 votes
We had the same error in the code. But we managed to solve it! You have to insert the SIM CARD to work. We do not know why, but it works!

---
Tags: arduino-uno, communication, gps
---


title: Serial port usage in code

text:
# Question
Title: Serial port usage in code
I want to write a function that defines a serial port based on a flag but I'm not sure it's possible.

For example:

```
void writeToSerial(bool useSerial1)
{
   SerialPortClass serialPortObject; // Is there some way of defining a generic Serial port object and reusing it below?

   if (useSerial1)
   {
      serialPortObject = Serial1;
   }
   else
   {
      serialPortObject = Serial2;
   }

   serialPortObject.write("test123");
}

```

# Answer
> 2 votes
According to sources at `c:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial*` (on Windows platform), you can use pointer to `Stream` class (because `Serial`s are inherited from `Stream`).

So, your function could look like this:

```
void writeToSerial(bool useSerial1)
{
   Stream* serialPortObject;

   if (useSerial1)
   {
      serialPortObject = &Serial1;
   }
   else
   {
      serialPortObject = &Serial2;
   }

   serialPortObject->write("test123");
}

```

# Answer
> 1 votes
This is not a proper answer, but rather a suggestion to reconsider your approach. The code posted in the question is obviously just a simplified example, and printing “test123” is likely not your final goal. I assume what you really want to do is print out some information about some variables. You can then collect these variables into a data structure (a C++ object) and make `writeToSerial()` a method of this object. The object can the be printed like so:

```
myDataStructure::writeToSerial(true);   // printed to Serial1
myDataStructure::writeToSerial(false);  // printed to Serial2

```

In this case, what I suggest is to instead explicitly `print()` (or `println()`) the object to the relevant serial port, like this:

```
Serial1.print(myDataStructure);
Serial2.print(myDataStructure);

```

This makes the code self-explanatory, and easier to maintain.

Obviously, you cannot just print arbitrary objects this way, as `Serial1` and `Serial2` would have no idea about how to serialize them. But the thing is, you can teach them! Make your class derive from `Printable`, implement the virtual `printTo()` method, and you will be able to print it to any serial port, LCD, or whatever understands `print()`:

```
class MyDataStructure : public Printable {
public:
    size_t printTo(Print& p) const {
        return p.print("test123");
    }
};

MyDataStructure someData;

void setup() {
    Serial1.begin(9600);
    Serial2.begin(9600);
    Serial1.println(someData);
    Serial2.println(someData);
}

void loop(){}

```

See the answer to Is it possible to print a custom object by passing it to Serial.print()? for an example with actual data in the object.

---
Tags: serial, c++
---


# Question
Title: I2C comunication, ESP->Nano on endTransmission no ACK fron nano
i am trying to communicate between ESP(master) and arduino nano(slave). This is only a prototype and all works fine. But i want to add multiple arduinos and therefor i need to detect if the arduino is connected.

I use the return function from wire.endTransmission as shown in i2c scanner to detect devices. But it doesnt work.

On the arduino i have this program:

```
#include <Wire.h>

const int16_t I2C_SLAVE = 0x22; // 0x22 = 34 cize izba 3(30)

void setup() {
  Wire.begin(I2C_SLAVE);

}

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

}

```

on the ESP i am trying this:

```
Wire.beginTransmission(I2C_adress[adress]);
int error = Wire.endTransmission();

Serial.println(error);

```

**It returns only 2 (received NACK on transmit of address) Why? When i have other code on the slave (with onRecive and onRequest all works and comunicates)**

Thank you.

# Answer
I'm a fool, I tried to detect other devices in the setup function before the `Wire.begin(PIN_SDA, PIN_SCL, I2C_MASTER);` I Found it only because of you. The rubber duck. I started to write the program down to post it here and bingo. That was the reason why the master had the "NACK" answer. The master was not started yet.

Thank you
> 1 votes

---
Tags: esp8266, arduino-nano, i2c, esp32, esp
---


title: Using a template inside a class

text:
# Question
Title: Using a template inside a class
I'm trying to use a template function, but I get an error

```
home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: sketch/emptyCode.ino.cpp.o: in function `startIOTservices()':
/home/guy/Documents/git/Arduino/HomePi/emptyCode/emptyCode.ino:37: undefined reference to `void myTest::funcOne<bool>(bool)'
/home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: sketch/emptyCode.ino.cpp.o: in function `setup':
/home/guy/Documents/git/Arduino/HomePi/emptyCode/emptyCode.ino:70: undefined reference to `void myTest::funcOne<bool>(bool)'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

```

inside `.cpp` file:

```
myTest::myTest()
{
        Serial.println("start");
}

template <class T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

```

inside `.h` file:

```
class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

```

and calling it from `.ino` file:

`testA.funcOne(true);`

What am I doing wrong ?

*EDIT 1*:

complete .h .cpp files - which originaly belongs to `myJSON` library which are deleted in this snip

```
#ifndef myJSON_h
#define myJSON_h

#include "Arduino.h"
#include <ArduinoJson.h>
#include "FS.h"

#define DOC_SIZE 1000

class myJSON
{
};

class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

#endif

```

.cpp file

```
#include "Arduino.h"
#include "myJSON.h"
#include "FS.h"
#include <ArduinoJson.h>

#define LOG_LENGTH 4

myJSON::myJSON(char *filename, bool useserial)
{
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

myTest::myTest()
{
        Serial.println("start");
}

// template <typename T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

```

# Answer
> 2 votes
move the template method definiton to .h or define it in class. it is not a real function, only a prescription for functions. Like this:

```
class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

template <class T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

```

or this

```
class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg)
    {
            Serial.println(arg);
    }
};

```

---
Tags: class
---


# Question
Title: Problem with STM32 and SDFat lib on other SPI port
I am using STM32F103C8 and I am triing to compile a code with SDFat library. The problem is I need to use the second channel of the SPI1 (pins PB5,PB4,PB3, PA15):

I found out that is possible to use SDFat lib and include SPIClass inside its constructor. Then I could use this code:

```
SPIClass SPI_1(PB5,PB4,PB3, PA15);
SdFat sd(&SPI_1);

```

The problem is this compliation error:

```
no matching function for call to 'SdFat::SdFat(SPIClass*)'

```

Do you have any idea how to solve this error or how to work with SD card on different pins?

Here is source code of this library: https://github.com/greiman/SdFat/blob/master/src/SdFat.h

# Answer
> 1 votes
Ok, I found out that the sdFat library is not supported on stm32 bluepill (sd card HAL peripherals are not enabled), so I decided to use basic Arduino SD library (it uses SPI commands, not HAL).

Also I have to change pins (from SPI1\_1 to SPI1\_2) in variant.h and PeripheralPins.c files of bluepill board. - And finally it works (SPI1\_2).

---
Tags: spi, sd-card, stm32
---


# Question
Title: Arduino split comma separated serial stream
I'm trying to read serial data into Arduino.

I usually use a Serial to USB cable to connect to the hardware and is sending data like

```
33,Z,35.0,F,1073741.824,I,0.0,0x68
33,Z,35.0,F,1073741.824,I,0.0,0x68
33,Z,35.0,F,1073741.824,I,0.0,0x68

```

At 38400 bound rate.

I have been reading this post Splitting a comma separated string through serial (Arduino) https://www.arduino.cc/reference/en/language/functions/communication/serial/print/

I have tried to write something my own but none return readable data.

Any tips please?

# Answer
> 2 votes
The reference article, that you linked to, is about sending data over Serial, not about reading.

You can use the `strtok()` function, which can split a character buffer into tokens based on a delimiting character (the comma in your case).

First you have a buffer, where your Serial message in saved (I'm not covering the actual receiving/reading of the Serial data here, because there are tons of tutorials on the web):

```
char buffer[] = "1,2.3,4,0x56";

```

Then you can get the first token:

```
char *token1 = strtok(buffer, ",");

```

`token1` is a pointer to the start of the token. `strtok()` replaces the found delimiter (which you specify with the second parameter) with a null character. That means, that `token1` points to a null terminated C string with only the first token in it (Keep in mind that the buffer is changed with that, so it does not make any sense to try printing `buffer` after you used `strtok()`). Note, that this does not create a new buffer. It simply points to a specific place inside `buffer`.

You could also directly process it, for example convert it to an integer:

```
int token1_value = atoi(strtok(buffer, ",");

```

To get the next token, you simply again call `strtok()`, but now you provide `NULL` instead of `buffer` in the first parameter. That tells `strtok()`, that you still want to process the same buffer from the last execution.

```
float token2_value = atof(strtok(NULL, ",");

```

You can now do this, until no token is left unprocessed in the `buffer`. In that case `strtok()` returns `NULL`.

```
char *token = strtok(NULL, ",");
while(token != NULL){
    Serial.println(token);
    token = strtok(NULL, ",");
}

```

Have a look at the C++ reference for `strtok()`. It also includes an online editor, where you can run the provided example and play with it.

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