# Question
Title: How to use capactive touch on Adafruit board in Arduino mode?
I have a Trinket M0 which has three pins capable of capacitive touch, A0, A3, and A4. When using CircuitPython on these boards you can use the CapTouch Library. But as far as I can tell this does not exist for use in Arduino mode. Does anyone know how to get these pins to pick up capacitive touch? I've tried the Adafruit\_FreeTouch library, but with zero documentation, it's not very user friendly. I thought I had it working with two pins, but whenever both pins detect capacity, the capacity is divided between them, so both pins report about the same capacity.

Any help would be greatly appreciated.

This question does seem like a duplicated of Built-in capacitive touch detection with SAMD21 development board (Arduino Zero Compatible) but there was never a solution.

Thanks!

# Answer
> 5 votes
Example code for capacitive touch on Trinket M0. Note: make sure to install the Adafruit FreeTouch library.

```
// touch - Capacitive touch demo using FreeTouch. Trinket M0 version.
// Note: the pin silkscreened 1 is Analog Pin 0.

#include "Adafruit_FreeTouch.h"

Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);

void setup()
{
  // Initialize A0 as a touch sensor
  if (! qt_1.begin())
    Serial.println("Failed to begin qt on pin A0");
}

void loop()
{
  int counter, result = 0;
  counter = millis();
  result = qt_1.measure();
  Serial.print("QT 1: "); Serial.print(result);
  Serial.print(" (");  Serial.print(millis() - counter); Serial.println(" ms)");
  Serial.println("\n*************************************");
  delay(200);
}

```

Information about the parameters for the constructor can be found at: https://forums.adafruit.com/viewtopic.php?f=8&p=610501 and are paraphrased below incase the link goes dead.

The parameters for the constructor are:

p - The input pin connected to the sensor.

t - How much to oversample the input. One of the following:

```
OVERSAMPLE_1
OVERSAMPLE_2
OVERSAMPLE_4
OVERSAMPLE_8
OVERSAMPLE_16
OVERSAMPLE_32
OVERSAMPLE_64

```

Oversampling is a process of taking several measurements, finding the average, and reporting that instead of the actual readings. It's way of reducing noise, but also improves the accuracy of the measurement. The average value of noise is zero (if it wasn't, it would be a source of free energy), so the more readings you add together, the closer the noise error in the measurements approaches zero.

There's another side-effect of adding noise to measurements though: it dithers the sensor output around the real input value. If I have a window comparator that only measures "below 1v" and "above 2v", and feed it a signal at 1.1v plus a couple of volts of noise, I can expect to see about ten "below 1v" outputs for every one "above 2v" output. The noise pushes the signals above and below the thresholds, but vanishes if I take the average of a large enough sample. Statistically, getting a 10:1 improvement in resolution like that would take about 64 readings to make the noise error small enough to ignore.

Oversampling takes longer though, so there's always a tradeoff between how much you can do and how long the signal will remain stable.

r - The value of the resistor that will discharge the touch pad. One of the following:

```
RESISTOR_0
RESISTOR_20K
RESISTOR_50K
RESISTOR_100K

```

f - Frequency mode. One of the following:

```
FREQ_MODE_NONE
FREQ_MODE_HOP
FREQ_MODE_SPREAD
FREQ_MODE_SPREAD_MEDIAN

```

For systems that take repeated measurements, there's one kind of noise that doesn't average to zero: noise that occurs at the same frequency as the sampling rate. There are all sorts of videos that show the effect of a camera being in sync with the thing it's recording.. this one is especially nice: https://www.youtube.com/watch?v=uENITui5\_jU

For capacitive sensors, things like induced signal from fluorescent lights can create noise, and if the lamp frequency is just slightly off of your sampling frequency, the touch system will think it looks like a series of touches.

(If you have an oscilloscope, hold the tip of a probe between your fingers and put your hand within a foot or so of a fluorescent light.)

One way to prevent that is to change the sampling frequency. You can shift it up and down in a predictable pattern, hop from one frequency to another, or add some random jitter. Atmel's QTouch library supports all those options, but 'NONE' (fixed frequency readings) is the simplest.

---
Tags: adafruit
---


title: 3.3V to 5V PWM level shift

text:
# Question
Title: 3.3V to 5V PWM level shift
I need to shift a PWM signal from a ESP32 (3.3V) to receiver that supports 5V. The signal is at maximum of 400Hz. Can this shifter do the job ?

# Answer
That should work, but it's overkill. Those devices are made for bidirectional signaling. You should be able to use a single transistor that is driven to saturation at 3.3V. A Suitable "logic level" MOSFET with a 3.3 gate voltage should do the trick.

And, as Chris L said in his answer, you may be able to drive an input on a 5V Arduino directly with 3.3V. That's a high enough voltage to be read as a logic level 1.
> 1 votes

---
Tags: pwm, esp32, voltage-level, drone
---


# Question
Title: What else is consuming Data Segment reported by avr-size?
I am facing a low memory available problem in arduino. I am compiling a big sketch for arduino mega 2560.

Analysing a .elf file, the avr-size tool gives:

```
text    data     bss     dec     hex filename
68524   4392    2560   75476   126d4 C:\Users\LEAN...

```

And the avr-nm (avr-nm doc) shows only variables with t, T, b, d and B. The following is how the command is executed (the output is being saved in a file called test.txt).

```
   avr-nm -a -td -C -l --size-sort -r x.elf >> test.txt

```

Then, I perform a sum to confirm the avr-size result using this Python script:

```
f = open("test.txt", "r")
lines = f.readlines()
f.close()

su = 0
dsum = 0
bsum = 0
tsum = 0
gsum = 0
for line in lines:
    #print(line, end="")
    s = line.split()
    try:
        val = int(s[0])
        su = su + val
        if(s[1].lower() == 'b'):
            bsum = bsum + val
        if(s[1].lower() == 'd'):
            print(line)
            dsum = dsum + val
        if(s[1].lower() == 't'):
            tsum = tsum + val
        if(s[1].lower() == 'g'):
            gsum = gsum + val
    except:
        print("ERR: ",s[0])
print("\n\nSIZE: ", su)
print("SIZE d/D: ", dsum)
print("SIZE b/B: ", bsum)
print("SIZE t/T: ", tsum)
print("SIZE g/G: ", gsum)

```

and the sum result of each var type is:

```
SIZE:  71015
SIZE d/D:  135
SIZE b/B:  2560
SIZE t/T:  68320
SIZE g/G:  0

```

The question: Here d/D sums is 135 bytes. So, why the data segment reported by avr-size is 4392 bytes? how to find out what is occupying this space?

Best Regards.

**EDIT**

It must be a Joke!

I have a lot of like this in the code:

```
Serial.print("QTDE REG: ");

```

Just changing for this:

```
Serial.print(F("QTDE REG: "));

```

I have reduced by 10 the .data size!

So, in this way `Serial.print("QTDE REG: ");` "QTDE REG: " is stored as a global variable?? I thought the compiler would save locally.

**EDIT 2**

I have an advance running `avr-objdump -s -j .data x.elf` as suggested by Edgar below. Now I see that all my string literals are in data! For example:

```
void myFunction(){
    ...
    sprintf(buf, "{\"name\":\"Intervalo de Registros\",\"value\":\"%d\", \"unit\":\"C\"},", (int)settings.treg);
    ...
}

```

`avr-objdump -s -j .data x.elf` shows:

```
 800660 2c007b22 6e616d65 223a2249 6e746572  ,.{"name":"Inter
 800670 76616c6f 20646520 52656769 7374726f  valo de Registro
 800680 73222c22 76616c75 65223a22 2564222c  s","value":"%d",
 800690 2022756e 6974223a 2243227d 2c007b22   "unit":"C"},.{"

```

**EDIT 3**

As commented, all string literals are saved in the (SRAM). So, the problem is, I have a lot of strings literals spread across different functions. How to save this amount of SRAM? Note that using F() for sprintf gives compilation error.

Is there any way to put the literal in stack (release memory when function returns) and not in the global area? Is F() the only solution?

**============ SOLUTION ============**

For now, I have found this solution: use `sprintf_P` with `PSTR(...)` in the same way of `F(...)`:

```
sprintf_P(buf, PSTR("{\"name\":\"Intervalo de Registros\",\"value\":\"%d\", \"unit\":\"C\"},"), (int)settings.treg);

```

I will test more...

Thanks for all clarification!

Best Regards!

# Answer
> 2 votes
Most of the missing data section is probably made of string literals. When you write something like

```
Serial.println("Hello, World!");

```

the string `"Hello, World!"` is implemented by the compiler as an *anonymous* array of characters, and the address of this array is provided to the `println()` method. Since the array is anonymous, it doesn't show up in the output of `avr-nm`. You can check that this is the case by looking at the actual contents of the section:

```
avr-objdump -s -j .data x.elf

```

And you can avoid this by wrapping the strings in the `F()` macro:

```
Serial.println(F("Hello, World!"));

```

This has the effect of keeping the string in flash, and passing the *flash address* to the `println()` method. Note that this is actually a different, overloaded method, that knows how to retrieve the character data from flash.

---

**Edit**: Adding some clarifications.

All this complexity about flash vs. RAM storage comes from the fact that the AVR uses a Harvard architecture, where RAM and flash are in different address spaces, accessed through different memory buses using different machine instructions. Unlike C, the C++ language has no notion of address spaces, and the compiler simply assumes that any pointer to function holds a flash address, whereas any pointer to data holds a RAM address.

Per the rules of the language, a string literal has the type `const char *`, and a function that should be able to accept a string literal should take a `const char *` parameter. Since these are pointers to data, when you dereference them the compiler emits the machine instructions that are appropriate for reading RAM. This is why the compiler puts all string literals in the .data section of the flash: at program startup, the C runtime copies them to the .data section of the RAM, making them accessible to those machine instructions.

The current solution to avoid this useless copy involves a bunch of preprocessor macros like `F()`, `PSTR()`, `PROGMEM`, `pgm_read_byte()`... that expand to compiler extensions or inline assembly. These allow you to pass around the flash addresses of string literals disguised as regular data pointers. These pointers should never be dereferenced with the regular operators of the language (`*` and `[]`), but only through the `pgm_read_*()` macros. And they should only be given to functions that do expect these kind of pointers, like `sprintf_P()` or `Print::println(const __FlashStringHelper *)`, which is the `println()` that gets invoked when using the `F()` macro.

> Is there any way to put the literal in stack

Yes, there is, but it has to be done explicitly:

```
PROGMEM const char greeting[] = "Hello, World!";

void say_hello() {
    char stack_copy[strlen_P(greeting)+1];
    strcpy_P(stack_copy, greeting);
    Serial.println(stack_copy);
}

```

As you have already noticed, it is preferable to not put the strings in RAM at all, and instead use functions like `sprintf_P` that expect flash-based strings. However, if you need to use a library function that expects a RAM-based string, you can use this trick to avoid permanently committing it to RAM.

---
Tags: memory-usage, data-type, avr-toolchain
---


# Question
Title: Serial broken into two shorter shorter strings
I'm trying to do a serial read:

```
    if (Serial.available() > 0) {
  int inputValue = Serial.read();
  Serial.println();
  Serial.println("I got this:");
  Serial.print(inputValue, BIN);
}

```

However, it seems that what I receive is always 6 bits first and then followed by 4 bits. I'm really confused. I used a different board just to be sure that it's not just a problem with the board. Could it be the serial monitor I'm using? I'm using the Arduino serial. This is an example of the output:

```
21:31:02.021 ->
21:31:02.021 -> I got this:
21:31:02.021 -> 110101
21:31:02.021 -> I got this:
21:31:02.021 -> 1010

```

Can anyone shine a light as to what is happening here?

# Answer
I guess you are sending `5` and have the line ending set to newline only. Then everything is correct and as expected. You see 2 bytes, that are transmitted. `Serial.print()` will cut out the leading zeros of the byte, so all other digits before that are just zero.

The first byte is the character `5` encoded in ASCII (53 is the decimal representation of the ASCII value here). The second byte is the newline character `\n`, which marks the end of a line or the end of the data message (depending on the interpretation of the data). If you don't want to send the newline character, select Nothing for the line ending (My Arduino IDE is in German, so I don't know, what exactly is the term in the english version here, but you need to set it for not using any line ending).

As it seems, that you don't know that currently: When you write a number into the serial monitor, you are not sending the direct binary value of that number. You are sending the ASCII representation of the individual digits. ASCII is a system, where the values of a byte represent a character. That includes decimal digits, the alphabet and some special characters. So when you type "255", you are not sending `0b11111111` (1 byte with all bits set --\> decimal 255), you are sending 3 bytes with the ASCII byte value for the characters `2`, `5` and `5`. You can read the byte values for all the characters in tables, just by googling for "ASCII" and looking at the images found.
> 1 votes

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


title: Computer doesn´t recognize MKR1010

text:
# Question
Title: Computer doesn´t recognize MKR1010
I´m learning how to use the Arduino MKR1010. When I wrote a program for controlling LEDs and to read a BMP280 sensor with a web aplication, and I uploaded the program to the board, suddenly the computer did not recognice the board.

The power LED of the board works, but I can't access the board with my computer, and I can't see in the COM ports list, and neither as a "unrecognised device" to reinstall the drivers.

I have tried with a few others USB cables and with another computer, but I still have the same problem. I have also tried to press the reset button reset and I still have the same result. What can I do to make my board work?

# Answer
The MKR board connects to computer over native USB support of the MCU. The handling of the USB is done by Arduino core functions linked at build to your sketch.

A consequence of using the native USB port is, if your sketch has a problem, it influences the USB communication. In this case you can activate the bootloader to handle the USB port and the upload. It is done by **double clicking the reset button on board**.

This applies to other SAMD boards (Zero, M0) and to AVR boards with native USB port (Leonardo, Micro) too.
> 0 votes

---
Tags: usb, mkr1010
---


# Question
Title: I can't run shell commands on Linux through AVR sketch (Arduino Yun)
I'm a little confused with some Process.h methods. I'm trying to run the command "nc 192.168.1.15 9911" to the Linux processor through a sketch. The appropriate netcat listener is waiting on another computer. Arduino Yun is on the same network with thie computer via WiFi.

When I execute this command through SSH connection on Arduino Yun it works fine, but I can't figure out how it's done through a sketch.

This is my code:

```
#include <Process.h>

Process p;

void setup() {
   Bridge.begin();
   Serial.begin(9600);
   delay(2000);
   p.begin("nc");
   p.addParameter("192.168.1.15 9911");
   p.run();
   //while (!p.running()) {};

 }

 void loop() {
    if (p.available() > 0) {
    Serial.println("test");
 }
}

```

This code doesn't seem to work, p.available() nerver executes even if I send data packets. I also tried **p.runShellCommand("nc 192.168.1.15 9911");** with no luck.

It seems that the commands never reach the Linux command line.

Any insights?

# Answer
There's a few things wrong with your program, some more obvious than others.

First, you have to put each parameter to your shell command in a separate `addParameter()` call. Otherwise it treats all the parameters as a single parameter and tries to connect you to an address of `192.168.1.15 9911` instead of to port 9911 of address 192.168.1.15.

Secondly you should use `runAsynchronously()` instead of `run()` otherwise your sketch blocks at that point until `nc` terminates. If that never happens then your sketch never gets to the point where it can read the data.

Here is an adaption of your sketch that works for me:

```
#include <Process.h>

Process p;

void setup() {
    Bridge.begin();
    Console.begin();
    p.begin("nc");
    p.addParameter("192.168.1.15");
    p.addParameter("9911");
    p.runAsynchronously();
}

void loop() {
    static uint32_t ts = millis();

    if (millis() - ts > 1000) {
        Console.println(millis());
        ts = millis();
    }

    if (p.running()) {
        while (p.available()) {
            Console.write(p.read());
        }
    } else {
        Console.println("Restarting process");
        delay(100);
        p.begin("nc");
        p.addParameter("192.168.1.15");
        p.addParameter("9911");
        p.runAsynchronously();
    }
}

```

It also re-runs `nc` if / when it terminates. There's also a "heartbeat" printing of millis() so that you can see the sketch is running. It uses the console, not Serial, for its output, so SSH in to the Yun and `telnet localhost 6571` to view the output.
> 0 votes

---
Tags: arduino-uno, arduino-yun, linux, networking, tcpip
---


# Question
Title: What are the traditional ways to optimize program memory usage?
While doing big projects using Arduino boards (Uno, Atmega328P MCU). I used to get warnings like this

```
Sketch uses 13764 bytes (44%) of program storage space. Maximum is 30720 bytes.
Global variables use 1681 bytes (82%) of dynamic memory, leaving 367 bytes for local variables. Maximum is 2048 bytes.

Low memory available, stability problems may occur.

```
* What are the generally practiced methods for the optimization program memory usage?
* Is there any difference in memory usage if the variable is declared globally or locally.
* Will it matter what the control statement/selection statements are (like `if`, `switch` )
* Usage of Serial monitor. `Serial.print()`
* ......

> Low memory available, stability problems may occur.

How bad are these warnings?

Before marking it duplicate, I have referred the following. But it wasn't satisfactory
Most memory efficient way to program
What are safe memory usage limits?

# Answer
> 18 votes
> What are the generally practiced methods for the optimization program memory usage?

First, note you are searching for ways to lower SRAM memory. This contains global (variable) memory and heap space (dynamic memory + stack memory).

* Avoid memory gaps, by not using dynamic memory (with free/malloc/new).
* Avoid using the `String` class.
* Avoid global memory in SRAM by using `PROGMEM`, `F(..)` if possible.
* Use the smallest variable size (e.g. `uint8_t` instead of `int`).
* Store arrays of booleans into bits (8 booleans per byte).
* Use bit flags if applicable.
* Use some compressed type of memory internally (affects performance), e.g. if you have many 6 bit values to store, store them not in separate bytes but use 6 bytes for 8 times 6 bit values).
* Avoid passing arrays by value.
* Avoid a deep call stack with many (big) variables. Note this affects your design, so use it as a last resort.
* If you need a calculatable table, calculate each value instead of storing it as a table.
* Do not use longer arrays than needed, and think about reasonable maximum array sizes otherwise (see hcheung's comment below).
* (this is not a complete list).

> Is there any difference in memory usage if the variable is declared globally or locally.

Yes, local variables are added to the stack, but are removed after the function ends, global variables stay (but are only created once). Note that variables on the stack (and also dynamic memory) are NOT taken into account in the memory calculated in the warning message during compiling.

> Will it matter what the control statement/selection statements are (like if, switch )

No, this will only affect the program memory.

> Usage of Serial monitor. Serial.print()

Probably yes, the serial monitor probably reserves (quite?) some memory as a buffer.

> Low memory available, stability problems may occur. How bad are these warnings?

How bad it is, depends on how much memory is used which is not calculated, which is dynamic memory, and stack memory.

You can calculate it manually (which can be quite cumbersome for a big program), you can also use the GitHub library for this:

Arduino MemoryFree

If you know how much heap memory you use worst case, than add it to the calculated global variables memory. If this is less than your maximum available SRAM memory, you are safe.

# Answer
> 7 votes
I just want to add a single bullet to Michel Keijzers’ excellent answer:

* think about every single item you are storing in memory and ask yourself the question: do I really need to keep this in RAM?

It may sound silly to state what many would consider obvious, but we have seen here many instances of novices who do not take this into consideration. As a simple example, consider this function that averages 500 analog readings:

```
int averageAnalogReading()
{
    // First take and store the readings.
    int readings[500];
    for (int i = 0; i < 500; i++)
        readings[i] = analogRead(inputPin);

    // Then compute the average.
    long sum = 0;
    for (int i = 0; i < 500; i++)
        sum += readings[i];
    return sum / 500;
}

```

Storing all those readings is completely useless, as you can just update the sum on the fly:

```
int averageAnalogReading()
{
    long sum = 0;
    for (int i = 0; i < 500; i++)
        sum += analogRead(inputPin);
    return sum / 500;
}

```

For the same reason, if you need some kind of running average to smooth data, you should consider using an exponentially-weighted running average, which can be incrementally updated without storing the readings.

# Answer
> 4 votes
> What are the generally practiced methods for the optimization program memory usage?

(nb. as per Edgar's comment I emphasise that this is about using PROGMEM more efficiently.)

* ### If you can replace code with a table whose size is ≤ the lines of code, do it.

+ Instead of using a sequence of ifs, find a way to collapse the procedure into a table
    + Use tables of function pointers if it makes sense
    + Sometimes you can come up with a mini-language that is much more dense than AVR instructions, for example encoding robot logic into 16 commands, and then you can pack two commands *per byte*. This could collapse your memory usage 50-fold.
* Use functions instead of repeated code—this may sound obvious but there are often subtle ways of rewriting code (but bear in mind that function calls have overhead)
* Use hash tables rather than tables with big gaps
* Use fixed point rather than floating point (e.g. you can take a byte and interpret its value as ranging from 0.00 to 2.55, instead of using a 4-byte float)

> Is there any difference in memory usage if the variable is declared globally or locally.

Let's talk about the stack.

```
void A() {
    byte a[600];
    ...
}
void B() {
    byte b[400];
    ...
}
void loop() {
    byte xxx[1000];
    ...
}

```

This program will firstly use at least 1000 bytes of RAM all the time. There is no real difference compared to declaring xxx globally. But then what is critical is which function calls which.

If loop() calls A(), and then loop() calls B(), the program will not use more than 1600 at any time. However, if A() *calls* B(), or vice versa, the program will use 2000. To illustrate:

```
loop() [1000]
  └──── A() [1600]
  │    [1000]
  └──── B() [1400]
  └──── A() [1600]
  └──── B() [1400]

```

versus

```
loop() [1000]
  └──── A() [1600]
        └──── B() [2000]
  │    [1000]
  └──── A() [1600]
        └──── B() [2000]

```

> Will it matter what the control statement/selection statements are (like if, switch )

Not much difference for a small number of cases. Otherwise it depends on your code. The best way is to just try both and see which is better. But:

`switch`es usually use jump tables which are quite compact if you cover nearly every case in a range (0,1,2,3,4,..,100). `if`s usually use a sequence of instructions, which take up more bytes and cycles than a jump table entry, but it makes more sense if you don't have a consecutive stretch of cases.

> Usage of Serial monitor. Serial.print()

I don't believe that makes a lick of difference. Serial buffers are tiny (say 64 bytes, or 128 for a bigger board) and I believe they are allocated whether or not you use Serial.

Of course "literal strings like this" and char\[\] buffers consume memory. You can comment them out (or use `#ifdef`s) when you don't need them.

# Answer
> 1 votes
Since you asked for **traditional ways**, I am going to raise a traditional method. In this case, more than 50 years old.

Generate and analyze a listing.

Methodology:

1. Compile all the code with debugging turned on (add `-g`).
2. Link the code with debugging turned on, producing an ELF executable. Do NOT convert to an image loadable on the arduino.
3. use `objdump` to make a listing. My usage of this read:

```
( avr-objdump --headers --source --disassemble --syms program.elf ; \
  avr-objdump --full-contents --section=.final_progmem program.elf ) > program.lst

```

Your usage may vary based on what you prefer to see.

The point of this is that this allows you to see exactly what is using every byte of your memory.

You may want to play around with different optimizations, until you understand what you are seeing. `-O0` produces the most comprehensible disassembly, while `-Os` makes the smallest.

One tip based on having done this: The Arduino libraries are designed for generality, not speed and memory efficiency.

---
Tags: programming, memory-usage, code-optimization
---


# Question
Title: Digital Pin won't ground when set to LOW
My friend and I are repurposing an old rc car for a project. When we connect the dc motors to 5V and ground, the motors spin. However, when we power the motors from 5v and ground it in the digital output pin set to LOW, nothing happens. The identical circuit works in tinkercad. We are using a nano, but have tried an uno and mega as well.

# Answer
**Never directly connect a motor to an Arduino IO pin**

You *will* destroy the Arduino.

An Arduino cannot source (or sink in your case) enough current to drive a motor, and if the motor did manage to turn the huge amounts of EMI it generates would literally blast holes in the silicon inside the chip.

You *must* use a motor driver of some form. If you only want one direction that driver can be a single NPN Bipolar transistor or N-channel MOSFET. If you need it to change direction then an H-bridge is what you want.
> 1 votes

---
Tags: motor, digitalwrite
---


# Question
Title: What does display.setSegments(&segto, 1, 1); do?
I am using a TM1637 display for my Arduino Uno. The goal was to just light up one point of the colon in the middle - what seems to be kind of impossible to accomplish. During research I stumbled over the following snippet, which I dont fully understand:

```
  uint8_t segto;
  int value = 1244;
  segto = 0x80 | display.encodeDigit((value/100)%10);
  display.setSegments(&segto, 1, 1);

```

Ok line 1 seems to declare s.th. like a char, an unsigned 8bit integer. Line 2 should be clear. Line 3: The pipe symbol seems to do a kind of addition - never seen this before. The rest here is also not clear to me - why these strange calculation to pass a value (here 2) to .encodeDigit() ? Finally line 4: Why is the adress of 'segto' passed to the function instead of just the value?

This all ends up showing a "2:" on the display. I got the snippet from this 'manual': https://robojax.com/learn/arduino/robojax-TM1637\_display\_manual.pdf

Maybe s.o. can help to light things up a bit

# Answer
> 0 votes
Let's take the hardest line first. We'll start from the "inside" outwards.

```
segto = 0x80 | display.encodeDigit((value/100)%10);

```

The innermost bit is:

```
value/100

```

That gives you 12 from 1244.

Then there's modulus 10.

```
12%10

```

That gives you 2 (divide by 10 and return the remainder - 12/10 = 1.2, or 1 remainder 2)

That is then passed through a function that calculates what segments need to be turned on to represent the digit 2. Let's say that's `00110111` in binary, where each bit represents a segment to display.

To that you want to add the colon, which is in the most significant bit's place. So you set that bit. That's done with the `OR` operator, which in C is `|`. `0x80` is `10000000` in binary.

OR the two values together:

```
00110111
10000000
========
10110111

```

That value is then assigned to the `segto` variable.

I am not familiar with that library, but I would assume that the `setSegments` function is expecting an array of segment settings, a number of digits to apply it to, and maybe a digit offset in the display (at a guess).

In C there is no real difference between using a 1 element array and using a variable and taking its address.

You could just as well have used:

```
uint8_t segto[1];
int value = 1244;
segto[0] = 0x80 | display.encodeDigit((value/100)%10);
display.setSegments(segto, 1, 1);

```

If you were doing more than one digit you'd be wanting to use an array anyway.

---
Tags: arduino-uno, display, variables, memory
---


# Question
Title: if I add a .cpp file, Serial becomes unusable
I am using the mega 2560. When I just use .ino and .h files, if I use Serial, it works fine, without even using:

```
#include <SoftwareSerial.h>

```

However, when I add a .cpp file I start getting 2 errors, one is solved by adding the aforementioned include, the second one, after adding it, is :

```
'Serial' was not declared in this scope

```

I know I can declare it manually and use the RX/TX pins, but I would like to be able to use the default Serial so that I don't have to occupy more pins. Especially since it works file w/o the .cpp file. Can anyone explain to me why this happens? Is it because I specify a C++ file so the compiler changes?

# Answer
> 3 votes
A CPP file isn't an Arduino file. It doesn't know about anything Arduino-esque unless you tell it about it.

The simplest way is to just add, at the top of the file:

```
#include <Arduino.h>

```

---
Tags: arduino-mega, c++, softwareserial
---


title: Power Arduino and LED strip

text:
# Question
Title: Power Arduino and LED strip
I saw this question about powering Arduino and LED strip. So, I searched for a 5v 4a power supply and foud this one.

How does that adapter provide power for both Arduino and LED strip? I thought I might need DC barrel Plug to alligator clips but I'm not sure as this is the first time I use an external power supply to power multiple components.

So what do I need to make that wall adapter able to power both Arduino and LED strip?

# Answer
> 0 votes
I assume, that your problem is how to connect everything to the power supply.

You have some different options, depending on your requirements. The linked adaptor (barrel plug to alligator clips) doesn't seem to fit the barrel plug of the power supply. So you cannot use that. Especially it seems, that both are the male part of the connection. For every plug connection you need a male and a female part of the same connector type (much like your power outlet on the wall is a female part, while the power plug on your supply is a male part; in terms of plug systems).

* The best way (especially, when you want to not only experiment, but also use it as a fixed product) would be to solder the wires. For this you need a soldering iron, soldering tin and something to clean the iron (sponge for soldering irons for example).

+ You can buy a barrel jack, solder wires to it and connect them to the Arduinos 5V pin, ground and to the LED strips power lines in parallel (from + pin of the supply one wire each to 5V Arduino and + pin of the LED strip, from - pin of the supply one wire each to ground of Arduino and - pin of the LED strip). Then you can still disconnect the power supply from your project.
    + If you don't want to buy a barrel jack and you don't need to disconnect the power supply from your project, you can splice up the cable of the power supply (only the LOW VOLTAGE PART!!!). You can use nail scissors, if you don't have other tools for it. Cut off the plug by cutting the cable a few cm before it. Then cut the plastic between the 2 connected parts of the cable for a few cm, so that you get the 2 individual cables (+ and -). Use the scissors to carefully cut the outer plastic around the cables and remove about 1cm of it, so that you now have 2 cable ends with the bare cable core free. Twist each end, so that it each little copper strand stays in the cable shape. Then solder the cable ends. Now you can take another wire/cable to solder the connections from the two ends to the described parts. Be sure to isolate the connections at the cable (in the best case with shrinking pipes, otherwise you can also use tape).
* If you don't want to solder, you can search for fitting connectors for every part. There are breadboard power adaptors, which should work with this power supply. They have pins on them, that you can not only use with breadboards, but you can also connect jumper wires to them. There also exist such adaptors for typical LED stripes, though that depends on the type of strip, that you have. When looking for jumper wires, you should make sure, that they are capable of conducting enough current. The Arduino does not need much current, thus standard jumper wires will be sufficient. But the LEDs can draw much more current, so that the standard jumper wires will start to smolder and catch on fire. Then you need some with a bigger wire diameter.
* You can also use alligator clips, but in my experience, they only work for rather specific cases. The connection, that they make, is fragile and can be easily disturbed. They are slipping and rotating easily. When connecting the LED strip, you might easily connect + and - together and destroy the power supply. Also it is almost impossible with most of them to connect to a standard 0.1 inch pin (which are used on the Uno and Nano), without also connecting other pins. Unless you break out these pins with something else (like jumper cables), that is not a good choice.

---

You can now choose yourself, which way to go. If you plan to do more with Arduino and electronics, I would suggest, that you buy a soldering iron and the needed supplies. You will need it and they only cost a few bucks, if you just buy a simple one (back then I got one for 15€/$, which also had a temperature control, so you can also get it cheaper). If you don't want to buy it, but still want to solder, you could look for a maker space near your location.

I would go for soldering here, because you are very much limiting yourself, when you choose to do not. Then you need to buy fitting parts, which is more difficult.

> how do I know what the ground is and the 5v?

For the power supply you can see it on the label. There you will find the following sign:

It means, that the outer shell of the connector is ground (`-`) and the inner pin is 5V (`+`). With cables there are 2 possibilities:

* Often the wires inside a cable each have an own isolating plastic shell around them, which is color coded. Black is normally ground, while red is 5V/+.
* When having a 2 wire cable, the cable is often designed as coaxial cable (which reduces noise on the signal). In that case you have one inner wire, which has it's own isolating plastic shell, and the outer wire, which is laid around the inner wire without any further isolation. The outer wire is normally ground.

When using an extra cable for connecting 2 parts, make sure to use the same wires on both sides (for example the red wire for 5V on both sides).

To be sure, you can check the voltage on the wires with a multimeter (also a very useful tool), when the cable is connected. A multimeter has a positive and a negative lead, which are marked as red and black respectively. When you connect the multimeter to the wires and it shows a positive voltage, you have found the correct association of the wires with their voltage (5V or ground).

# Answer
> 0 votes
You can feed 5V directly into the 5V pin of the Arduino as ChrisL says. However, that bypasses the protection circuits built into the Arduino. If you ever forget to disconnect the 5V and plug a USB cable into your Arduino then you risk damaging it, since both your external power supply and the USB port will be feeding 5V into the 5V line.

What I decided to do is to cut the end off of USB cable and connect that to my 5V power supply. On almost all USB cables, the +5V wire is red and the ground wire is black. You'd just solder red to +5V and black to ground, then plug the USB cable into your Arduino. Then when you need to connect the Arduino to your computer, you disconnect the USB power cable and plug in a USB data cable. It's impossible to feed power from both sources at once.

If you're going to be doing much tinkering with Arduinos and electronics you should get a decent soldering iron and an auto-ranging multimeter. You can use the multimeter to figure out which wires are which. (See chrisl's on how to use a multimeter to find positive and negative power connections.

Another issue you may face is voltage droop on your power supply as your LED strip turns groups of LEDs on and off. If you draw near the max current from your power supply then there will likely be fluctuations in the power supply voltage as the LEDs turn on and off.

What are the max current requirements for your LED strip? You don't want to draw too close to the full output of your power supply or you might get fluctionations in voltage that could cause your Arduino to malfunction. If you use a power supply with something like 25% extra capacity (Say your LED strip draws 4A and you use a 5A power supply instead) you should be ok.

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


# Question
Title: GPS date and time not displaying correctly in Arduino Uno,NEO6M GPS module
I am learning how the Arduino and GPS module work so I can apply it to another project. My components are an Arduino Uno, NEO-6M GPS module, and a Adafruit 1.8" TFT display.

The code did not work as expected. It does display "waiting for sats".

However, it still displays the generic time and date, 1-1-1970 and 12:00:00 AM, for a while until the local time adisplays.

Plus the updated code takes a lot longer to display the time

Here is the code so far. What I would like it to do is:

1. Display "waiting for sats"
2. continue when a successful GPS signal is received
3. adjust GPS time & date to local
4. display date and time

Eventually this will be the basis for a Speed and GPS trackker for my RC vehicles. Any help is greatly appreciated.

```
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <TimeLib.h>

#define cs   10
#define dc   8
#define rst  9

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);

static const int RXPin = 2, TXPin = 3; //GPS communication

// Change this value to suit your Time Zone
const int UTC_offset = -4;   // Eastern Australia Time is 10

static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

time_t prevDisplay = 0; // Count for when time last displayed

void setup()
{

  Serial.begin(9600);  //set baud rate for serial monitor
     ss.begin(GPSBaud);  //set baud rate for GPS

   tft.initR(INITR_BLACKTAB);     //correct INITR for my display

  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(20, 58);
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
  tft.println("GPS Date & Time");
  tft.print("        Monitor");
  delay(3000);
  tft.fillScreen(ST7735_BLACK);
}

void loop()
{

  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN,ST7735_BLACK);

     if (ss.available() < 1)
{
       gps.encode(ss.read());
 }

        GPS_Timezone_Adjust();  // Call Time Adjust Function

}

void GPS_Timezone_Adjust(){
  while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {

      int Year = gps.date.year();
      byte Month = gps.date.month();
      byte Day = gps.date.day();
      byte Hour = gps.time.hour();
      byte Minute = gps.time.minute();
      byte Second = gps.time.second();

//Hour = hourFormat12();
        // Set Time from GPS data string
        setTime(Hour, Minute, Second, Day, Month, Year);
        // Calc current Time Zone time by offset value
        adjustTime(UTC_offset * SECS_PER_HOUR);

    }
  }

  if (timeStatus()!= timeNotSet) {
  if (now() != prevDisplay) {
      prevDisplay = now();
      ClockDisplay();
    }
 }
}

void ClockDisplay(){
    tft.setCursor(5, 8);

    tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
    tft.print("Date:   ");
    tft.setTextColor(ST7735_CYAN,ST7735_BLACK);

      if(month() < 10){
        tft.print("0");
        }
      tft.print(month());

      tft.print("-");

      if(day() < 10){
        tft.print("0");
        }
      tft.print(day());

      tft.print("-");

      tft.print(year());

    tft.setCursor(4, 30);
    tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
    tft.print("Time:   ");
    tft.setTextColor(ST7735_CYAN,ST7735_BLACK);

      if(hourFormat12() < 10){
        tft.print("0");
        }
    tft.print(hourFormat12());
    tft.print(":");

      if(minute() < 10){
        tft.print("0");
        }
    tft.print(minute());
    tft.print(":");

      if(second() < 10){
        tft.print("0");
        }
    tft.print(second());

    if (isAM()) {
    tft.println(" AM ");
    } else {
    tft.println(" PM ");
    }

    tft.setCursor(5,50);
    tft.setTextColor(ST7735_WHITE,ST7735_RED);
    tft.println("RAW GPS DATE & TIME");

    tft.setCursor(5,58);
    tft.print(gps.date.month());
    tft.print("-");
    tft.print(gps.date.day());
    tft.print("-");
    tft.print(gps.date.year());

    tft.setCursor(5,66);
    tft.print(gps.time.hour());
    tft.print(":");
    tft.print(gps.time.minute());
    tft.print(":");
    tft.print(gps.time.second());

  smartDelay(400);
  }
    // deadline for a good recption
      static void smartDelay(unsigned long ms)
  {
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

```

# Answer
> 1 votes
> Display "waiting for sats" ... continue when a successful GPS signal is received

You are (or the Arduino library you are using is) using the time.h library which starts on January 1st, 1970. If no adjustments are made, time.h will report January 1st, 1970.

You are not (or the Arduino library you are using is not) waiting for a "good GPS signal" indication from the GPS module before displaying the time.

> adjust GPS time & date to local

If you are using time.h you (or the Arduino library you are using) should set a time-zone offset instead of correcting the time by hand. This will take advantage of the time.h library utilities which take care of troublesome cases like calculating a time & date which crosses midnight with respect to UTC (aka GMT).

> display date and time

The time.h library stores the date / time as the number of seconds since January 1st, 1970. So when displaying the current time, use time.h function calls to convert this counter to the current local time.

Hints / Suggestions:

* The GPS module is a radio receiver. It works best when the view of the sky is unobstructed by buildings, trees, hills or bad weather. Such obstructions results in slow lock times or no lock at all. The more satellites the GPS module can see the better.
* The GPS module is a computer in and of its self. The computer will analyze messages form satellites several times before it is ready to report location and time data. If possible, leave the GPS module powered up even if the Arduino is not. This should likely reduce or eliminate the delay the GPS module needs before reporting location and time.

---

Added later...

@Tvr4 brings up a good point. While time.h is more ubiquitous (used almost everywhere in C programming), in the Arduino paradigm, the built in Arduino time library is often used. For more, this is discussed in this stackoverflow question / answer. If you want to dive into the Arduino time library, the code is in this github repository. Also, you should find more help with this time libaray in the readme file displayed on that web page.

# Answer
> 0 votes
I'm guessing that the GPS module doesn't receive a time reading until it acquires a GPS lock. That can take many seconds.

You haven't posted your code so we can't tell how you're handling the time reading.

I would suggest checking for the midnight 1970 time (which is the UNIX "epoch time") and handling that with special-case code. If you're reading the time as a numeric value it is almost certainly 0.

---
Tags: arduino-uno, softwareserial, spi, adafruit, tinygps
---


# Question
Title: Cannot send any UDP packets from ESP8266 Wemos D1
I am attempting to send sensor data from a battery-powered device using UDP. The goal is to send a datagram immediately after the wifi station awakes from sleep then immediately go back to sleep after writing the datagram to a given IP address or hostname.

I can send data to Thingspeak's API using their library so I know the device works, but when attempting to use the WiFiUDP library to send a datagram to an IP address on the same LAN I see nothing happen. My device is getting on the wifi and the `udp.endPacket()` command is returning successful, but I am not receiving the packets on the server. I know the server works because I can use `nc` to send UDP packets from other machines on the LAN.

Here is my sketch with the irrelevant bits redacted.

```
// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html
#include <ESP8266WiFi.h>
// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/udp-examples.html
#include <WiFiUdp.h>

// Create udp class instance
WiFiUDP udp;

void setup() {
  Serial.begin(115200);
  Serial.print("Connecting to WiFi");
  WiFi.mode(WIFI_STA);
  WiFi.hostname(hostname);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.print("SSID:\t");
  Serial.println(WiFi.SSID());

  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());

  Serial.print("Gateway:\t");
  Serial.println(WiFi.gatewayIP());

  uint8_t buffer[50] = "hello world";
  char message[] = "hello world 2";

  IPAddress staticIP(192, 168, 1, 118);
  udp.beginPacket(staticIP, 3381);
  udp.write(buffer, 11);
  //udp.write(message);
  udp.endPacket();

  // Calculate required sleep time and go to sleep
  long sleepTime = measurementInterval - millis(); // in milliseconds
  if (sleepTime < 100) sleepTime = 100; // set minimum sleep of 0.1 second
  Serial.print ("Going to sleep now for ");
  Serial.print((float)sleepTime / 1000, 3);
  Serial.println (" seconds.");
  Serial.print ("Time going to sleep=");
  Serial.print ((float)millis() / 1000, 3);
  ESP.deepSleep(sleepTime * 5000); // convert to microseconds
}

```

And my node server just to be complete here:

```
const dgram = require('dgram')
const server = dgram.createSocket('udp4')

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`)
  server.close()
})

server.on('message', (msg, rinfo) => {
  console.log(`got message from ${rinfo.address}:${rinfo.port} - ${msg}`)
})

server.on('listening', () => {
  const address = server.address()
  console.log(`server listening ${address.address}:${address.port}`)
})

server.bind(3381)

```

I've also tried adding delays between each function to no avail.

# Answer
Per the esp8266 subreddit, you need to add a sufficient `delay()` of 50-100 milliseconds (not microseconds) before going to sleep as none of the udp functions are blocking.
> 0 votes

---
Tags: esp8266, arduino-ide, wifi, sketch
---


# Question
Title: Is it possible to get which pin generated interrupt?
I wrote some code that handles rotary encoder using an interrupt, but I would like to get which pin generated the interrupt, so I'll be able to handle many interrupts in a single method.

Something like:

```
void ISREncoders()
{
  int pin = GetCurentInterruptPin(); // <============= this
  int dataPin = dataPins[pin];
  int data = DigitalRead(dataPin);
  if(data == HIGH)
  {
    encoders[pin] += 1;
  }
  else
  {
    encoders[pin] -= 1;
  }
}

```

Is it anyhow possible?

---

As mentioned in the answer this is not possible. Still, after peeking some encoder libraries that use interrupt found out that they do the following:

The Encoder class contains several static ISR methods hard coded.

As you create new objects it increments an internal counter and sets proper ISR method on the interrupt.

This is for sure the best solution available, but this is not at all scalable, for instance if you have an imaginary board with thousand pins that handle thousands encoders you will have to hard code each ISR method.

# Answer
It is not possible to know which interrupt caused the ISR to be called. The INTFx flag gets cleared when the interrupt routine is called, so you lose that information (which is a shame).

The closest you could do is to have a separate ISR for each pin which just calls the common routine with a parameter to say which ISR it was executed via. That will add some extra latency though as it has to make an extra function call, but that can be somewhat mitigated by having the common function marked as `always_inline`, which means the compiler will duplicate it and place it within the code where it's being called from. This reduces latency but increases code size.

```
static ISREncoder(uint8_t pin) __attribute__ ((always_inline)) {
    // Do stuff with the `pin` variable
}

void ISR0() { ISREncoder(2); }
void ISR1() { ISREncoder(3); }

```
> 2 votes

---
Tags: interrupt, rotary-encoder
---


# Question
Title: Controlling an MCP41HV31 Digital Potentiometer
I need to control a 10kOhm digital potentiometer in rheostat mode in 256 steps. I found an Arduino tutorial, which works with an MCP41010 (I added a viper resistance according to the datasheet). This works fine - I can send values from 0 to 255 to the CS pin an the resistance between output pin A and B changes from 0 to 10kOhm. The problem is, that my application requires 16V to go through this resistance, which the MCP41010 can't handle.

I tried to go with a MCP41HVX1 high voltage digital potentiometer (which I soldered on a TSSOP-to-DIP Breakout board) and assumed it would work the same way. Turns out it doesn't... My connections are:

Arduino nano -\> MCP41HVX1

* 10 -\> CS
* 11 -\> SDI
* 13 -\> SCK
* 5V -\> VL
* GND -\> DGND

With the MCP41010 I connect a 115Ohm viper resistor between output pin A and wiper terminal and measure resistance between output pin A and B (pink connectors). I noticed, that the MCP41HVX1 has a different description for the rheostat modus but I can't get that to work either.

This is my circuit that works with the MCP41010

And here is the respective code (which sets the MCP41010 to 255 i.e. 10kOhm)

```
#include <SPI.h>
byte address = 0x11;
int CS= 10;

void setup()
{
  pinMode (CS, OUTPUT);
  SPI.begin();
}

void loop()
{
  digitalPotWrite(255, CS);

}

int digitalPotWrite(int value, char Port)
{
  digitalWrite(Port, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(Port, HIGH);
}

```

Has anyone ever done this or has a clue what's going on?

# Answer
I realize that this thread is old. I am providing an answer for anyone else who may end up here like I did a while back looking to solve this.

I have created an Arduino library on Github (https://github.com/gregsrabian/MCP41HVX1) which allows for control of this family of chips. The README.md within the github project documents all of the APIs and also provides the wiring diagram. There are also example sketches included.

I have created an article on Instructables (https://www.instructables.com/id/MCP41HVX1-Digital-Potentiometer-for-Arduino/) that provides a step by step on how to control this family of chips. There is also an explanation on how to solder the TSSOP chip.
> 2 votes

# Answer
One thing I discovered, after coming back to the internet multiple times for clues, is that that SHDN pin on the MCP41HVX1 has to be tied HIGH.

If not, you can try incrementing, decrementing, or writing values to your heart's content and the thing is not going to budge.

I tied SHDN to the VL level via a 10k resistor and I can write and increment without problems.

I think it should have been flagged in the datasheet though, in the Pinout Description table.
> 0 votes

---
Tags: digital, potentiometer
---


title: How to send a number as a byte?

text:
# Question
Title: How to send a number as a byte?
I want to send a number between 0 and 120 as a byte over Serial port. I'm working on a project that involves sending ultrasonic sensor readings over Bluetooth to an Android. I would like to send the entire reading as a byte and I think this can be done because an signed byte ranges from -128 to 127. However, the byte received in my Android app doesn't show the correct sensor reading. Here's the relevant code snippet:

```
  while (true){
      //ultrasonic sensor sends out signal
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      pinMode(echoPin, INPUT);
      duration = pulseIn(echoPin, HIGH);

      cm = (duration / 2) / 29.1;   // Divide by 29.1 or multiply by 0.0343
      inches = (duration / 2) / 74; // Divide by 74 or multiply by 0.0135
      // max range is 156 inches, but our app will only display up to 100 inches
      inches = min(127, inches);
      Serial.print(inches, BIN);
      delay(50);

```

In my Android app written in Java I read the value like this:

```
b = (byte) inputStream.read();

```

For example, if `inches` is 100 and I send that over Serial port, how can I expect to get the same reading in my Android app?

# Answer
The problem is the BIN in your print statement. Everything is ALWAYS binary. The BIN means to break that binary up into ascii digits 0 and 1. So if you send

`Serial.print(21, BIN);`

then the print function takes 21 as a binary number, 00010101 and then sends those binary digits as ascii. So what goes out on the wire is 8 separate bytes, it goes 48, 48, 48, 49, 48, 49, 48, 49 as 48 and 49 are the ascii codes for 0 and 1.

What you want to do is just to send the raw byte. So use Serial.write instead. The print functions convert things to ascii representations but the write function just sends the raw bytes out. So if you write:

```
Serial.write(inches);

```

Assuming that inches is a byte type variable then it just sends the raw byte out.
> 1 votes

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


title: Arduino using delay in I2C receiveEvent

text:
# Question
Title: Arduino using delay in I2C receiveEvent
I have read before that you can't use delay() inside I2C receiveEvent because it is an ISR.

What I want to do is as follows: I have a servo connected to my Arduino Uno and I want to control that using an I2C signal. Since I want to decrease the speed of the servo, I was previously using a loop with delay inside, which doesn't work when the function is called by I2C.

This is the code that I used before to control the servo:

```
void setServo(bool status) {
    if (status) {
        for (int pos = 0; pos <= 180; pos += 5) {
            servo.write(pos);
            delay(50);
            Serial.println(pos);
        }
    } else {
        for (int pos = 180; pos >= 0; pos -= 5) {
            wasteFlapServo.write(pos);
            delay(50);
            Serial.println(pos);
        }
    }
    servoStatus = status;
}

```

How could I still control the speed of the servo even if I use I2C? Thanks for your help.

Kind regards, Moritz

# Answer
> 2 votes
The general way of doing long things triggered by an ISR is to simply set a flag insode the ISR, which then gets checked inside `void loop()`.

```
volatile byte flag = 0;

void loop(){
    if(flag){
        // Do something here
        flag = 0; // reset the flag
    }
}

void receiveEvent(int howMany){
    flag = 1; // set flag, if correct data was received
}

```

Here keep the following in mind:

* The `loop()` needs to run fast to react fast. Long delays are doing other long stuff there will impact the responsiveness of the code. Depending on your plans for the exact behavior, the usage of `delay()` is generally not good. You should look into the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It is worth learning that rather early.
* `flag` mus be declared volatile, to tell the compiler, that is may change at any time. Otherwise it might optimize the variable away.
* `flag` is of type `byte` here. It is imprtant, that this flag only has a single byte, because reading and writing of a single byte cannot be interrupted. Multi-byte variables get read or written in multiple COU cycles, thus it would be possible, that the interrupt writes parts of the variable, while you are reading it in the main code. That would lead to garbled data. By using a single byte, you avoid using critical sections for keeping the reading in main code save. For a flag thats way simpler.

---
Tags: arduino-uno, i2c, interrupt, servo, isr
---


# Question
Title: nRF24L01 - Measuring distance using time elapsed
For school usage, my team and I are working on a wristband that will alert the user if they are too close to another wristband (for social distancing). The problem is measuring distance using radio waves. Since I cannot use signal strength, I'm thinking about calculating distance from time taken to transfer some data and velocity (which will be around the speed of light). I discarded the idea of using ultrasound because it is too easily interfered with by other obstacles.

My plan is along the lines of this:

* Sensor 1 and 2 are synchronised to a clock.
* Both will run a "stopwatch", and the time values should be exactly the same at the same time.
* Sensor 1 sends out a message to Sensor 2. The message contains the time at which the transmission started.
* Sensor 2 receives the message, immediately records the time of reception, and calculates the time taken for data to travel
* d = v/t
* Vice-versa

If the distance is smaller than the radius, a warning is triggered in the form of a vibration motor.

Limitations include clock speed; I intend on using a Seeeduino XIAO, an Arduino-compatible board. The clock speed is max. 48MHz, meaning that the smallest increments it can measure is 20.82 nanoseconds. I also calculated that it would take 13.33 nanoseconds to travel two metres (the former distance to keep in public). Hence, with the clock speed available to me, I can only measure 3m and beyond.

Assuming I was happy with this distance, would I be able to do this using one single Arduino sketch? I know that Arduino programs can only run one at a time. Would a constant background clock/stopwatch be too complex? Could you give me any other pointers?

# Answer
> 1 votes
Speed-of-light-delay measurements are not practical for the use-case you propose. As Majenko suggests in his comment, you'd need EXTREMELY accurate time measurement, as well as high speed radio-frequency signal processing. Any measurements you do through software will be far too inaccurate as a result of the software timing.

Apple's iBeacons (which are based on BLE) offer immediate, near, medium, and far distance readings that are based on signal strength. You should be able to achieve something similar with your own wristbands using BLE. The different distance thresholds would have some slop to them, but it should be possible to get decent results.

---
Tags: arduino-nano, sketch, nrf24l01+
---


title: ATTINY85 - RF Transmitter (RH ASK)

text:
# Question
Title: ATTINY85 - RF Transmitter (RH ASK)
I am working on a small RF sensor powered by a battery. I used the code from Mr K. (https://arduino.stackexchange.com/a/55516/65870) as base and adapted it to the RH Ask protocol:

```
#define F_CPU 8000000  // This is used by delay.h library

#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <util/crc16.h>

#define LED_PIN           0

#define TX_PIN            4 //3
#define TX_BAUDRATE       2000
#define TX_MILLIINTERVAL  (1000UL/TX_BAUDRATE)
#define TX_MICROINTERVAL  (1000000UL/TX_BAUDRATE)
#define TX_MAXLEN         12
#define RFRepetitions 3
byte RollingCounter = 0;

// Define sensor IDs (for MQTT)
#define SensorIDMoisture 6

// Define moisture sensor variables
#define MoistureSensorPinA    A1
#define MoistureSensorPinD    10
#define MoisturePowerOutPin   1
#define RFPowerPin            3 //4

inline void led(const bool onOff) { digitalWrite(LED_PIN, onOff ? HIGH : LOW); }
inline void tx(const bool onOff) { digitalWrite(TX_PIN, onOff ? HIGH : LOW); }

const uint8_t header[8] = { 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x38, 0x2C };
const uint8_t conv4to6[16] = { 0x0D, 0x0E, 0x13, 0x15, 0x16, 0x19, 0x1A, 0x1C,
                               0x23, 0x25, 0x26, 0x29, 0x2A, 0x2C, 0x32, 0x34 };

// Watchdog timer
#ifndef cbi
  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// Important: Sleep time equals the wdt_length setting multiplied by the wdt_loops_max
#define wdt_loops_max 225
#define wdt_length 9 // 9 = 8 seconds

volatile int wdt_loops = wdt_loops_max; // Start with maximum value in order to have a measurement when powering on the system

void rawSend(const uint8_t * p, uint8_t len) {
  while (len--) {
    const uint8_t val = *p++;
    for (uint8_t mask = 1; mask != 0x40; mask <<= 1) {
      tx(val & mask);
      delayMicroseconds(TX_MICROINTERVAL);

//      _delay_ms(TX_MILLIINTERVAL);
    }
  }
}

void send(const uint8_t * buf, const uint8_t len) {
  #define RH_ASK_HEADER_LEN 4
  //  First create the payload ...
  static uint8_t payload[(TX_MAXLEN+3+RH_ASK_HEADER_LEN)*2];
  uint8_t * p = payload;
  uint16_t crc = 0xFFFF;
  uint8_t v = len + 3 + RH_ASK_HEADER_LEN;
  crc = _crc_ccitt_update(crc, v);
  *p++ = conv4to6[v >> 4];
  *p++ = conv4to6[v & 0x0F];

  uint8_t _txHeaderTo = 0xff;
  uint8_t _txHeaderFrom = 0xff;
  uint8_t _txHeaderId = 0;
  uint8_t _txHeaderFlags = 0;

    // Encode the headers
    crc = _crc_ccitt_update(crc, _txHeaderTo);
    *p++ = conv4to6[_txHeaderTo >> 4];
    *p++ = conv4to6[_txHeaderTo & 0xf];
    crc = _crc_ccitt_update(crc, _txHeaderFrom);
    *p++ = conv4to6[_txHeaderFrom >> 4];
    *p++ = conv4to6[_txHeaderFrom & 0xf];
    crc = _crc_ccitt_update(crc, _txHeaderId);
    *p++ = conv4to6[_txHeaderId >> 4];
    *p++ = conv4to6[_txHeaderId & 0xf];
    crc = _crc_ccitt_update(crc, _txHeaderFlags);
    *p++ = conv4to6[_txHeaderFlags >> 4];
    *p++ = conv4to6[_txHeaderFlags & 0xf];

  for (uint8_t l = len; l--;) {
    v = *buf++;
    crc = _crc_ccitt_update(crc, v);
    *p++ = conv4to6[v >> 4];
    *p++ = conv4to6[v & 0x0F];
  }
  crc = ~crc;
  v = (uint8_t)crc;
  *p++ = conv4to6[v >> 4];
  *p++ = conv4to6[v & 0x0F];
  v = (uint8_t)(crc >> 8);
  *p++ = conv4to6[v >> 4];
  *p++ = conv4to6[v & 0x0F];

  //  Now transmit the header and the payload ...
  rawSend(header, sizeof(header));
  rawSend(payload, (len + 3 + RH_ASK_HEADER_LEN)*2);
  tx(false);

  //Serial.print("CRC: ");Serial.println(crc);
}

ISR(WDT_vect)
{
  wdt_loops++;
}

// Sleep
void system_sleep() {
  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();

  sleep_mode();                        // System sleeps here

  sleep_disable();                     // System continues execution here when watchdog timed out
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
}

// Setup for Watchdog
void setup_watchdog(int ii) {
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
//  pinMode(LEDPin, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  led(false);

  // Initialize moisture sensor
  pinMode(MoistureSensorPinD, INPUT);

  // RF sensor initialization
  //driver.init();

  setup_watchdog(wdt_length); // approximately 8 seconds sleep

}/*--(end setup )---*/

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  if(wdt_loops >= wdt_loops_max)
  {
    //digitalWrite(LEDPin, HIGH);
    led(true);

    wdt_loops = 0;
    moisture_measurement();

    led(false);
  }
  system_sleep();

}/* --(end main loop )-- */

void moisture_measurement()
{
  // Activate sensor
  analogWrite(MoisturePowerOutPin,255);
  analogWrite(RFPowerPin,255);
  _delay_ms(150);

  // Turn On RF transmitter

  float MoistureMedian   = 0;
 // float sensorValue;
  for(int i = 0;i<=100;i++)
  {
    float sensorValue = analogRead(MoistureSensorPinA);
//    moisture_percentage = ( 100 - ( (sensorValue/1023.00) * 100 ) );
//    moistureSensorSum += moisture_percentage;

    MoistureMedian += ( 1 - ( (sensorValue/1023.00) * 1 ) );
    //delay(1);
    _delay_ms(1);
  }

  // Read digital values
  bool digitalValue = digitalRead(MoistureSensorPinD);

  // Switch off sensor
  analogWrite(MoisturePowerOutPin,0);

  // Transmit value
  TransmitSensorValue(SensorIDMoisture,MoistureMedian);

  _delay_ms(150);
  // Turn Off RF transmitter
  analogWrite(RFPowerPin,0);

}

void MessageEncrypt(int adressIn, int parameterIn, float payloadIn, byte pByteArray[])
{
  pByteArray[0] = (byte)adressIn;

  byte * payloadBArray = (byte *)&payloadIn;
  pByteArray[1] = payloadBArray[0];
  pByteArray[2] = payloadBArray[1];
  pByteArray[3] = payloadBArray[2];
  pByteArray[4] = payloadBArray[3];

  RollingCounter = RollingCounter + 1;
  if(RollingCounter > 2)
    RollingCounter = 0;

  pByteArray[5] = RollingCounter;
}

//CRC-8 - based on the CRC8 formulas by Dallas/Maxim
//code released under the therms of the GNU GPL 3.0 license
byte CRC8(const byte *data, byte len) {
  byte crc = 0x00;
  while (len--) {
    byte extract = *data++;
    for (byte tempI = 8; tempI; tempI--) {
      byte sum = (crc ^ extract) & 0x01;
      crc >>= 1;
      if (sum) {
        crc ^= 0x8C;
      }
      extract >>= 1;
    }
  }

  return crc;
}

void TransmitSensorValue(int SensorID, float SensorValue)
{
  byte MessageOut[6];
  MessageEncrypt(SensorID, 1, SensorValue, MessageOut);

    for(int i=0;i<RFRepetitions;i++)
    {
      send((const uint8_t *)&MessageOut, sizeof(MessageOut));
    }
}

```

The code runs like a dream as long as I use 2000 as baudrate. As soon as I use another baudrate (500 or 1000) my test receiver does not receive any messages.

Any ideas what is going wrong here?

Thanks :)

# Answer
I found the problem. I used 2 2032 battery to power the attiny85. The internal clock of the chip is not precise enough when running at 6V. To solve the issue I removed 1 battery. The alternative would be to set the baudrate of the transmitter and receiver to different values (I had to set the receiver to 520 bdps to receive the messages from the transmitter with 500 bdps).

Maybe somebody can reuse my code for his project.
> 1 votes

---
Tags: rf, attiny85
---


title: How to convert RGB values to Intensity

text:
# Question
Title: How to convert RGB values to Intensity
I made an arduino color sensor with tcs3200 and arduino uno. I have coded the arduino to find the RGB values when I place the color paper below the sensor. How can I derive the intensity using the RGB values.

# Answer
I remember a formula that calculated luminance (perceived brightness) using simple weights applied to the red, green, and blue values in a light source.

This formula allows for the fact that the human eye is most sensitive to green light and least sensitive to blue light.

The Wiki article on HSV/HSL has these different weightings for R,G, and B. (In all of the following, `Y'` is the computed brightness value.)

```
Y' = 0.2989 • R + 0.5870 • G + 0.1140 • B
Y' = 0.2120 • R + 0.7010 • G + 0.0870 • B
Y' = 0.2126 • R + 0.7152 • G + 0.0722 • B
Y' = 0.2627 • R + 0.6780 • G + 0.0593 • B

```

All of them weigh green more than the other 2. I didn't read the article closely enough to understand the different weightings of the different formulas. Perhaps they convert colors using different color models like Adobe RGB and sRGB.

See the link at https://en.wikipedia.org/wiki/HSL\_and\_HSV for more information.
> 2 votes

# Answer
There is no simple way to have a formula from the RGB values to intensity. Also, there is intensity that can be measured with an intensity meter/sensor, but what people (humans, or each individual) consider more intensity (perceived intensity) is not fully related.

However, some things I found when I had a similar problem:

* Typically a LED value of 0 is OFF, 1 is shining a little and 255 a lot. However, the difference in (perceived) intensity between value 1 and 10 is much higher than between e.g. 100 and 255.
* Also, each LED color has a different intensity, e.g. red seems more bright than blue or green, with the same R, G or B value for the DMX lights I have, as can be read from the remarks from Duncan C and Majenko below, red is less bright than others.
* Also, it depends on the physical device probably (it could have an internal algorithm to convert an RGB value to some power driven to the LED(s)).

What you can do is measure for each value and color the intensity with an intensity meter or sensor. Or, in case you are more interested in the perceived intensity, manually check two LEDs with values to and create your own intensity algorithm.

I ended up having 3 arrays (for R, G, B), having for each value from 0-255 an 'intensity' value. I did it partly by measuring, partly by manually checking.
> 1 votes

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


# Question
Title: Why is there a need of use delay() after using Serial.flush() in the program
This code is a part of a long code for understanding serial communication and the functions related to it.

```
char buffer[18];
int red, green, blue;
int RedPin = 11;
int GreenPin = 10;
int BluePin = 9;

void setup()
{
Serial.begin(9600);
Serial.flush();
pinMode(RedPin, OUTPUT);
pinMode(GreenPin, OUTPUT);
pinMode(BluePin, OUTPUT);
}

void loop()
{
if (Serial.available() > 0) {
int index=0;
delay(100); // let the buffer fill up
int numChar = Serial.available();
if (numChar>15) {
numChar=15;
}
while (numChar--) {
buffer[index++] = Serial.read();
}
splitString(buffer);
}
}

```

In void setup(), Serial.flush() is used. On internet, I have read that it flush out any character present in a serial line. After calling it we can be sure that all the data has been sent before moving on to the next line of the program.

In void loop(), in the first if condition, delay(100) ensures to fill the buffer. Basically, buffer is the place in memory where the received serial data is stored prior to processing.

The question is that is there any need of using delay(100), if we call the Serial.flush() initially because it ensures that all the serial data has been transmitted (as in serial transmission one bit is transmitted at a time)? Does it takes further time to store the transmitted data in the memory (buffer) and does this is the reason to use delay(100)? Please clarify why delay(100) is used after calling Serial.flush(), I am confused.

# Answer
> 2 votes
The Serial.flush() is doing nothing. It delays until all bytes have been sent out of the UART. Since nothing has been sent it's not got anything to wait *for*.

The delay after the `available` call is very bad practice. It's a really really bad way of dealing with serial reading.

You should read this for a better understanding of serial communication.

---
Tags: serial, programming, arduino-ide
---


# Question
Title: Connect two SD cards to one Arduino board and copy from one to another
I'm trying to connect 2 SD cards to an Arduino Uno board.

1. My first question is: Is it possible to connect two SD cards to one Arduino simultaneously?
2. The second question is: If it is possible to connect 2 SD cards, How can I copy card 1 data to card 2

My project goal is to copy data from one peripheral memory to another peripheral memory when an external interrupt occurs.
Can anyone help me please ?

# Answer
You can't do it with your **Arduino-Uno** (and usual SD libraries).

SD cards are organized in 512 byte "sectors". You need at least one sector for the file system itself and one sector for the data. If you try to have two files open simultaneously, all your 2048 bytes RAM are required for the SD buffers and you can't return from the file open() call any more.
> 1 votes

---
Tags: arduino-uno, interrupt, sd-card, memory
---


# Question
Title: Arduino Micro: 69 is supposed to show up when I press 1 on the keypad, however some weird number (15 in this case) is showing up
```
// **I AM ALSO GETTING WEIRD CLUELESS DELAYS WHEN I PRESS BUTTONS ON THE MODE MENU**

/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 0.70
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

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

int timeV, thrustV, massV, gravityV;

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

bool keyDetect = false;
bool menuKeyDetect = false;
bool goHomeDetect = false;

bool countDownDetect = false;
bool countDownOutput = false;
bool twrCalDetect = false;

String timeValue, thrustValue, massValue, gravityValue;

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();

  Startup();

  timeV = constrain(timeV, 15, 120);
}

void loop() {
  PressKey();

  if (menuKeyDetect == true) {
    PressMenuKey();
  }

  if (goHomeDetect == true) {
    GoHome();
  }

  if (countDownDetect == true) {
    CountDownSequence();
  }

  if (countDownOutput == true) {
    CountDownOutputSequence();
  }
}

// Pages & Sections
void Startup() {
  lcd.print("Jeb's Launch");

  lcd.setCursor(0, 1);
  lcd.print("Control System");

  delay(3000);

  lcd.clear();
  lcd.print("Alpha Build 0.70");

  lcd.setCursor(0, 1);
  lcd.print(" STUDIO HORIZON");

  delay(3000);

  lcd.clear();
  lcd.print("Welcome, Kerman");

  lcd.setCursor(0, 1);
  lcd.print("Press any key...");

  keyDetect = true;
}

void ModeMenu() {
  menuKeyDetect = true;

  lcd.clear();
  lcd.print("1. Countdown");

  lcd.setCursor(0, 1);
  lcd.print("2. TWR");
}

void CountDown() {
  lcd.print("Time (sec): ");

  lcd.setCursor(0, 1);
  lcd.print("# to continue...");

  goHomeDetect = true;
  countDownDetect = true;
}

void TwrCal() {
  lcd.print("Thrust: ");

  lcd.setCursor(0, 1);
  lcd.print("# to continue...");

  goHomeDetect = true;
}

// Actions & Behaviours
void PressKey() {
  char key = keypad.getKey();
  if (key) {
    Serial.println(key);
    if (keyDetect == true) {
      lcd.clear();
      ModeMenu();
      keyDetect = false;
    }
  }
}

void PressMenuKey() {
  char key = keypad.getKey();
  if (key == '1') {
    Serial.println(key);
    if (menuKeyDetect == true) {
      lcd.clear();
      CountDown();
      menuKeyDetect = false;
    }
  } else if (key == '2') {
    Serial.println(key);
    if (menuKeyDetect == true) {
      lcd.clear();
      TwrCal();
      menuKeyDetect = false;
    }
  }
}

void GoHome() {
  char key = keypad.getKey();
  if (key == '*') {
    lcd.clear();
    ModeMenu();
  }
}

void CountDownSequence() {
  char key = keypad.getKey();

  if (key == '0') {
    timeV = timeV + 0;
  }

  if (key == '1') {
    timeV = 69;
  }

  countDownDetect = false;
  countDownOutput = true;
}

void CountDownOutputSequence() {
    lcd.setCursor(13, 0);
    Serial.println(timeV);
    lcd.print(timeV);
}

```

# Answer
> 0 votes
According to the documentation, the `getKey()` function is *non blocking*. This means it does *not* wait for a key to be pressed: it instead returns immediately whether a key has been pressed or not. If no key has been pressed (i.e. most of the time), it returns a NUL character, which has the numeric value zero and evaluates to `false` in a boolean context. Hence the idiom:

```
char key = keypad.getKey();
if (key) {  // if a key has actually been pressed
    // handle it
}

```

The `CountDownSequence()` function fails to account for this:

```
void CountDownSequence() {
  char key = keypad.getKey();  // no check for NUL

  if (key == '0') {
    timeV = timeV + 0;  // this has no effect at all
  }

  if (key == '1') {
    timeV = 69;  // this is what you would expect to be executed
  }

  countDownDetect = false;  // these two lines tell the rest of the
  countDownOutput = true;   // program that we are done.
}

```

Since `key` will almost certainly be `'\0'`, the program will move to the next step without ever initializing `timeV`.

As a side note, I recommend you try to rewrite your program as a finite state machine. A single `state` variable would make it less confusing and easier to understand than the current collections of booleans.

---

**Edit**: Expanding on the idea of the finite state machine. I tried an implementation of your concept based on it.

For handling a menu system, where the user can navigate through several on-screen “pages”, the most obvious first approach is to have one state per page displayed. For this program, these states could be:

* `MENU`, which offers the choice to move to either of the following two pages
* `SET_COUNT` allows the user to set the countdown duration
* `TWR` allows him to compute the thrust/weight ratio
* `COUNT_DOWN` actually runs the countdown timer

In the following, I added an extra *transitional* state called `START` that comes right before `MENU`. This is not required, and its only purpose is to avoid code repetition by having a single transition (`START``MENU`) responsible for actually drawing the menu.

When implementing a finite state machine, my first recommendation would be to start by drawing a state diagram like this:

In this diagram, each transition is labeled with the event that triggers it. The events are key presses, save for “finished” which means that the countdown is done. The state diagram can become significantly more complex than this as you add new functionality. It is, however, a very good way of *designing* your system from the point of view of user interaction.

Once you are happy with the state diagram, the coding is just a matter of translating it to a `switch`/`case` construct, with one `case` per state. Here is my take at it:

```
/*
   Jebediah's Launch Control System for Kerbal Space Program
   Alpha Build 0.70
   An Open-Source Project by John Seong
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

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

byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6};

Keypad keypad=Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Show a two-line message on the LCD.
void lcdShow(const char *line0, const char *line1) {
  lcd.clear();
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcdShow("Jeb's Launch", "Control System");
  delay(3000);
  lcdShow("Alpha Build 0.70", " STUDIO HORIZON");
  delay(3000);
  lcdShow("Welcome, Kerman", "Press any key...");
  while (!keypad.getKey()) ;  // wait for key press
}

void loop() {
  static enum {START, MENU, SET_COUNT, COUNT_DOWN, TWR} state = START;
  static uint32_t last_second;  // millis() value on last full second
  static int count;             // countdown value

  char key = keypad.getKey();

  switch (state) {
    case START:  // transitional state
      lcdShow("1. Countdown", "2. TWR");
      state = MENU;
      /* fallthrough */
    case MENU:
      if (key == '1') {  // Countdown
        lcdShow("Enter time", "seconds: ");
        count = 0;
        state = SET_COUNT;
      } else if (key == '2') {  // TWR
        lcdShow("Thrust:", "# to continue...");
        state = TWR;
      }
      break;
    case SET_COUNT:
      if (key >= '0' && key <= '9' && count <= 99) {
        lcd.print(key);
        count = 10 * count + (key - '0');
      } else if (key == '#') {
        lcdShow("Take off in", "     seconds");
        // Force a refresh on entering COUNT_DOWN:
        last_second = millis() - 1000;
        count++;
        state = COUNT_DOWN;
      } else if (key == '*') {
        state = START;
      }
      break;
    case COUNT_DOWN:
      if (millis() - last_second >= 1000) {
        last_second += 1000;
        count--;
        if (count == 0) {
          Serial.println("Take off!");
        } else if (count < 0) {
          state = START;
          break;
        }
        lcd.setCursor(1, 1);
        lcd.print(count<10 ? "  " : count<100 ? " " : "");  // pad
        lcd.print(count);
      } else if (key == '*') {
        state = START;
      }
      break;
    case TWR:
      if (key == '*' || key == '#') {
        state = START;
      }
      break;
  }
}

```

Note the comment “fallthrough” between `START` and `MENU`. This indicates that the lack of `break` at this place is intended: the processing of the `MENU` case will follow right after the processing of the `START` case, in the same loop iteration. The purpose of the fall through is to not loose the current key press, if any. If this is not important, you could put a regular `break` here and defer the handling of `MENU` to the next loop iteration.

Note also that the key presses are checked with tests of the form `if (key == SOME_VALUE)`, which means there is no need for an extra `if (key)` to test whether there was an actual key press.

---
Tags: arduino-micro
---


# Question
Title: How do you remove an item from array arduino?
Is there a way that can change `{3, 5, 3, 6}` to `{3, 5, 6}` with a function? I checked all the arduino forums but they don't give the answer i need (just delete 1 item from an array with a function like `delete(myArray, 2)`).

# Answer
> 3 votes
There is no such concept in C. Arrays are a fixed size and that size can never be changed. You can't "delete" an entry. You can replace one with something else, and you can introduce the concept of a variable that says how many entries the array has, but you can't delete one.

So you *could*:

* Keep a count of how many entries are in the array
* Shuffle down all the entries one space so the unused one is at the end
* Decrement the count of entries

So in your example `{3, 5, 3, 6}` becomes `{3, 5, 6, 6}` and your "count" holds `3` to say the first three entries are valid and to ignore the last.

Alternatively you can introduce the concept of "end of array". C strings do this with the NULL character (0). Anything before that character is valid, and anything from that character onwards is ignored. So say you nominated the value -1 to be "end of array" you could have, after again shuffling down the values: `{3, 5, 6, -1}`.

You could also have `-1` (or whatever you chose) indicating an "invalid" entry, so your array would be `{3, 5, -1, 6}` and you would ignore the `-1` entry in your code.

# Answer
> 0 votes
In C++, arrays are fixed-length data structures. There is no way you could remove an item. You could replace it with an invalid item, though.

---
Tags: arduino-ide, array, functions
---


# Question
Title: Any limitation on array size in Arduino Mega 2560?
I am writing an Arduino code with 3 arrays.

Two of those are *double* and other one is *int*. Further first two arrays have nearly 420 elements **for each**. Now I noticed that with more that 89 elements on 3rd array the program stall, and stuck executing. But with 89 or less number of element it runs with out an issue.

What would be the issue?

# Answer
A Mega has 8 KB of memory.

You are using:

* double (same as float on an Arduino, see double) , 4 bytes * 420 elements * 2 arrays = 3,360 bytes
* int (2 bytes) * 89 = 178 bytes

In total this is 3,538 bytes

This is about 50%, so I'm unsure what the 'rest' is. You can take a look at the other related question that may show some answers (like using dynamic memory, memory gaps, or local/stack variables): What are the traditional ways to optimize program memory usage?
> 0 votes

---
Tags: arduino-ide, c++, array, memory-usage, data-type
---


title: ESP8266 CCLOCK Odd behavior

text:
# Question
Title: ESP8266 CCLOCK Odd behavior
I'm trying to write some extremely fast code for the ESP8266, so I'm trying to figure out how to time things. I've discovered `CCLOCK`, a register that reflects the number of clock cycles since startup. (https://github.com/esp8266/Arduino/issues/4632#issuecomment-380632906, and other references.) In testing it out, though, I've encountered some weird behavior. Consider the following code:

```
static inline volatile uint32_t asm_ccount(void) {
    uint32_t r;
    asm volatile ("rsr %0, ccount" : "=r"(r));
    return r;
}

char outgoingPacket[4];

...

void loop() {

  // ... some stuff ...

  uint32_t startTime = asm_ccount();
  uint32_t stopTime = asm_ccount();
  uint32_t elapsed = stopTime-startTime;

  outgoingPacket[0] = (elapsed >> 24) & 0xff;
  outgoingPacket[1] = (elapsed >> 16) & 0xff;
  outgoingPacket[2] = (elapsed >> 8) & 0xff;
  outgoingPacket[3] = elapsed & 0xff;
  Udp.beginPacket(targetUdpIp, targetUdpPort);
  Udp.write(outgoingPacket, 4);
  Udp.endPacket();
}

```

(On my computer, I have basically the following Java code running to receive these messages:)

```
    while (true) {
      DatagramPacket packet = new DatagramPacket(buf, buf.length);
      socket.receive(packet);

      byte[] data = packet.getData();
      StringBuilder sb1 = new StringBuilder();
      StringBuilder sb2 = new StringBuilder();
      for (int i = 0; i < packet.getLength(); i++) {
        sb1.append(String.format("%8s", Integer.toString(((int) data[i]) & 0xFF, 2)).replace(' ', '0'));
        sb2.append(String.format("%2s", Integer.toString(((int) data[i]) & 0xFF, 16)).replace(' ', '0'));
      }
      System.out.println(sb1 + " " + Integer.parseInt(sb2.toString(), 16));
    }

```

(Yes, it's a little hacky, I know, but the results have seemed correct.)

Now, most of the time, the output looks like

```
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000000000001 1

```

But about 5 times in 77000, I'll get lines like

```
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000000110101000 424
00000000000000000000000000000001 1
00000000000000000000000000000001 1
...
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000010010100001 1185
00000000000000000000000000000001 1
00000000000000000000000000000001 1
...
00000000000000000000000000000001 1
00000000000000000000000000000001 1
00000000000000000000010001001100 1100
00000000000000000000000000000001 1
00000000000000000000000000000001 1

```

I ran the code for 1 minute 4 seconds, and got 3 counts of 424, 1 of 1100, and 1 of 1185. It seems particularly odd that 424 would show up three times.

Given that, as far as I understand, the relevant lines of code (the two calls to `asm_ccount`) would have been compiled to a given set of instructions, I'd have expected it to take exactly the same number of cycles every time.

Why is this not happening?

Is it interrupts? Something something caching? Does that register not actually work as claimed or as I understand? Have I done something dumb in the transmission or logging code? Something else?

# Answer
> 1 votes
You've got interrupts running and interrupting your code. Those take some cycles to run.

---
Tags: esp8266, timing, assembly
---


# Question
Title: Arduino Yun receives UDP packets but prints them with gibberish
Arduino Yun is set to receive UDP packets. It receives those data with some gibberish.

How is all set up: Arduino Yun (acts as a server) is connected through Ethernet to a PC which is (through WiFi) connected to the router. Another PC (acts as client), is also connected to the router (through Wifi).

Client uses netcat to connect to Arduino Yun. I write something and press enter. The packets are received by the Arduino Yun with some gibberish. For example, I write "test" and press enter, but this is what I receive on the Arduino Yun:

Sometimes gibberish characters are different, but always exist. This is what Wireshark monitors when I send the "test" packet (with netcat) to my Arduino Yun:

It shows that indeed I send only "test", so the gibberish is created on the Arduino side, I suppose.

This is my sketch (not the entire code, but the important part):

```
void loop() {
  int udp_received = Udp.parsePacket();
  if (udp_received) {
    char udp_buffer[16];
    udp_buffer[15] = '\0';
    Udp.read(udp_buffer, 15);
    Serial.println(udp_buffer);
  }
}

```

I use BridgeUdp.h Any insights appreciated.

# Answer
You are receiving a small packet of about 5 or 6 characters (depending on your line ending). That is being received into a 16 byte buffer which has contents unknown. So the first 5 or 6 bytes of the array have valid data in it. The rest is whatever was already in there.

You need to use the return value of `Udp.parsePacket()` to tell you how many of the bytes in your buffer are actually valid received bytes and only print those.

The simplest way:

```
Serial.write(udp_buffer, udp_received);

```
> 1 votes

# Answer
You send only 5 or 6 characters "test\r\n". the rest is random memory content.

The return value of parsePacket should be the count of received characters, but the implementation in BridgeUdp is wrong and returns always 1 on success.

You you can use `BridgeUdp.available()` to get the count.

```
void loop() {
  if (Udp.parsePacket()) {
    int udp_received = Udp.available();
    char udp_buffer[16];
    Udp.read(udp_buffer, udp_received);
    udp_buffer[udp_received] = '\0';
    Serial.println(udp_buffer);
  }
}

```
> 1 votes

---
Tags: serial, communication, ethernet, arduino-yun
---


# Question
Title: Running hardware interrupt function on NodeMCU ESP8266, Exception(0) after four iterations, can't disarm interupt function
I've been trying to test the stability and consistency of hardware interrupts on my NodeMCU ESP8266. I'm using the Arduino IDE. This sketch should not require any external circuitry and I think, but am not certain that the problem is a value overflowing somewhere. **QUESTION 1: Can anyone point out where the problem that's causing Exception(0)?**

The hw\_timer\_\* functions are documented in the ESP8266 NONOS SDK reference pdf. The hw\_timer\_\* declarations where not found by the Arduino IDE after I set it up with the board manager url here, so I copied hw\_timer.h and hw\_timer.c from the Expressif github repo into the same folder as my .ino file. The interrupt functions run now, but after four iterations, I get the exception & a stack dump and then the board reboots with this rst message:

```
 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

```

The code of my sketch is here. You shouldn't need any pins or anything. **EDIT:** I added `volatile` before the 3 vars referenced in interrupt and in the other fns.

```
#include "user_interface.h";
#include "hw_timer.h";
#include "hw_timer.c";

// interrupt interval used for my hw_timer
#define timerInterval 100

// the number of cycle count samples we collect before analyzing
#define totalSamples 500

volatile uint32_t cycleSamples[totalSamples];
volatile uint16_t cycleSampleCount = 0;

// calculate min/max/mean
uint32_t elapsedCycles; // the number of cycles elapsing between two samples
float elapsedSum = 0; // cycles are large numbers...just in case we exceed 2^32 we use a float
uint32_t elapsedMax = 0;
uint32_t elapsedMin = 0xFFFFFFFF;
uint32_t elapsedCount = 0;
float elapsedMean;

// for std dev calculation
float diffSumSquared = 0;
float variance = 0;
float stdDev = 0;

// set to true by the timer fn when it has gathered the samples
volatile bool analyzeSamples = false;

// The hardware timer callback function must NOT be defined with ICACHE_FLASH_ATTR.
// Interrupt callback functions must be in IRAM, because the flash may be in the middle
// of other operations when they occur. Do this by adding the ICACHE_RAM_ATTR attribute
// on the function definition
// @see https://arduino-esp8266.readthedocs.io/en/latest/reference.html#interrupts
ICACHE_RAM_ATTR void my_timer_callback(void) {

  if (analyzeSamples) {
    // if this fn has collected all the samples, we have to skip this until it’s finished analyzing them
    // and resets this
    return;
  }

  if (cycleSampleCount >= totalSamples) {
    // we can't disable this timer
    analyzeSamples = true;
    return;
  }

  // take a peek at the cycles counter to check timing accuracy
  cycleSamples[cycleSampleCount] = ESP.getCycleCount();
  cycleSampleCount++;

}

void setup() {

  Serial.begin(115200);

  for(uint8_t i=5; i>0; i--) {
    Serial.printf("counting %d\n", i);
    delay(1000);
  }

  // START THE SAMPLE TIMER USING HARDWARE INTERRUPTS
  // use NMI_SOURCE for highest priority and quickest/most accurate timing
  hw_timer_init(NMI_SOURCE, 1);
  hw_timer_set_func(my_timer_callback);

  // If NM is used as the ISR source for auto-loading the timer, parameter val of hw_timer_arm can not be less than 100
  hw_timer_arm(timerInterval);

}

void loop() {
  // TODO we need to do something nondeterministic here to see if it fucks up timing of interrupts

  if (analyzeSamples) {

    // this doesn’t work to try and disable the interrupt fn
    // hw_timer_set_func(0);
    // nor does this
    //hw_timer_arm(0);

    Serial.println("Sampling complete, analyzing...");

    elapsedSum = 0; // cycles are large numbers...just in case we exceed 2^32 we use a float
    elapsedMax = 0;
    elapsedMin = 0xFFFFFFFF;
    elapsedCount = 0;

    // we loop from the 1th (i.e, the second) item
    for(uint32_t i = 1; i<totalSamples; i++) {
      elapsedCycles = cycleSamples[i] - cycleSamples[i-1];
      Serial.printf("%d %d\n", i, elapsedCycles);
      elapsedSum += (float)elapsedCycles;
      elapsedMax = max(elapsedMax, elapsedCycles);
      elapsedMin = min(elapsedMin, elapsedCycles);

      elapsedCount++;
    }
    // calculate mean
    elapsedMean = elapsedSum / (float)elapsedCount;
    Serial.print("Average elapsed cycles: ");
    Serial.println(elapsedMean);
    // report min/max
    Serial.print("Elapsed cycles max: ");
    Serial.println(elapsedMax);
    Serial.print("Elapsed cycles min: ");
    Serial.println(elapsedMin);

    // calculate the variance/std dev
    diffSumSquared = 0;
    for(uint32_t i = 1; i<totalSamples; i++) {
      elapsedCycles = cycleSamples[i] - cycleSamples[i-1];
      diffSumSquared +=  sq(elapsedCycles - elapsedMean);
    }
    variance = diffSumSquared / elapsedCount;
    Serial.print("Variance: ");
    Serial.println(variance);
    stdDev = sqrt(variance);
    Serial.print("Std Dev: ");
    Serial.println(stdDev);

    // reset the samples to zero and let's try again
    Serial.println("Gonna reset...");

    ets_intr_lock( ); //close interrupt
    for(uint32_t i = 0; i<totalSamples; i++) {
      cycleSamples[i] = 0;
    }
    cycleSampleCount = 0;
    analyzeSamples = false;
    interrupts();
    ets_intr_unlock(); //open interrupt
    system_soft_wdt_restart();

    Serial.println("Reset complete.");

//    stopStopStop = true;

  } else {
    Serial.println("not yet!");
  }
  Serial.println("sleeping 1...");
  delay(1000); // sleep 1000ms

}

```

This brings me to **QUESTION 2: How do you disarm/cancel a hw\_timer?** As you can see in this code, I've tried setting the FN to zero and/or null and I've also tried setting hw\_timer\_arm(0).

The exception and stack dump seem to consistently happen after the `sleep 1...` debug message which corresponds to the end of the loop() function. Some typical debug output:

```
// useful and happy output above right up to this point
497 8000
498 8000
499 8000
Average elapsed cycles: 8000.00
Elapsed cycles max: 8263
Elapsed cycles min: 7738
Variance: 396.13
Std Dev: 19.90
Gonna reset...
Reset complete.
sleeping 1...

Exception (0):
epc1=0x40201030 epc2=0x00000000 epc3=0x400043a3 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3ffedf20 end: 3fffffb0 offset: 0190
3ffee0b0:  00000000 00000000 00000000 4010480d
3ffee0c0:  40105513 00000000 00000000 00000000
3ffee0d0:  00000010 00000000 00000000 40000f68
3ffee0e0:  00000004 00000000 40000f58 00000000
3ffee0f0:  60000200 3fffeed0 00000002 7c097c08
// giant stack dump continues....

```

Any help would be much appreciated.

# Answer
So these docs say that RST cause 4 is **watchdog reset**. Evidently arduino has a watchdog timer to check and make sure that your program isn't stuck in an infinite loop. Therea are some tips in that link on how to avoid this reset. Generally speaking, you need to make sure your loop doesn't spend too much time doing any one thing or handling too many interrupts or it might start to get overwhelmed and then the arduino code can't get around to all the housekeeping it has to do.

Regarding the disabling of a hardware timer function, I posted an issue on the ESP8266 github repo and someone offered what looks like a helpful response, which I have not tested. They suggest:

> Call hw\_timer\_init with second argument = 0; then in your ISR call hw\_timer\_arm() if you want to keep it going and do not call it if you want to "disarm."
> 1 votes

---
Tags: esp8266, arduino-ide, nodemcu, interrupt, hardware
---