title: Arduino random LED on

text:
# Question
Title: Arduino random LED on
I have a project which has two options No. 1 Randomly turn on one LED from a group of 6 LED (Relay Board) No.2 randomly turn on one LED from a group of 2 LED (Relay Board) The selection of the desired option happens with a switch.

I found this code online which is just perfect for 6 LED but I don't know how to add the selection of the options in it, how to do it?

```
int timeShowRandom = 3000;
int timeShowDecision = 6000;
int timeBlink = 100;
int buttonPin = 2;
int buttonPress = false;
int randomNumber;
int previousNo = 0;
int timePassed = 0;

void setup() {
  // Set button pin
  pinMode(buttonPin, INPUT);
  // Set output pins
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
}

void getRandomNo() {
 int rand = random(7,13);
  if (rand == previousNo) {
   getRandomNo();
  } else {
    randomNumber = rand;
    previousNo = randomNumber;
  }
}

void loop() {
 if (digitalRead(buttonPin) == HIGH && buttonPress == false ) {
     buttonPress = true;
  } if (buttonPress == true && timePassed <= timeShowRandom) {
    getRandomNo(); // Get random pin number
    digitalWrite(randomNumber, LOW);
    delay(timeBlink);
    digitalWrite(randomNumber, HIGH);
    delay(timeBlink);
   timePassed = timePassed + (timeBlink * 2);
  } else if(buttonPress == true) {
    digitalWrite(random(7,13), LOW); // Set random pin on
    delay(timeShowDecision); // For x seconds
    buttonPress = false; // Set button to be enabled again
    timePassed = 0;
  }
  else {
    // Reset all output pins
    digitalWrite(10, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
  }
}

```

# Answer
Various suggestions:

Create 2 different arrays of pin numbers: 1 for the first group of relay pins, and the 2nd for the second group of relay pins:

```
byte firstRelayPins[] = [7, 8, 9, 10, 11, 12];
byte secondRelayPins[] = [13, 14]; //Replace values with your relay pins

```

Write a function that returns a random index from one or the other of the arrays based on a bool:

```
byte randomPin(bool useSecondArray) {
    int max;
    int index;
    if useSecondArray {
       return secondRelayPins[random(sizeof(secondRelayPins))]; //Fetch random pin from array
    } else {
       return firstRelayPins[random(sizeof(firstRelayPins))]; //Fetch random pin from array
    }
}

```

Based on the state of your switch, set useSecondArray when you call that function to determine which relay's pin you turn on.

Use the returned value to set the desired relay pin.

In your "turn everything off" code, use the arrays of index pins rather than hard-coded indexes.

You should also refactor your code to use `millis()` rather than using `delay()`. (Search on "Arduino blink without delay" for guidance on how to do that.)

Note that this is a rough outline of what to do. The code above will likely need to be adjusted to fit your needs. Don't expect to be able to copy/paste it into your project.
> 1 votes

---
Tags: arduino-nano, led
---


title: How i convert to Arduino Mega?

text:
# Question
Title: How i convert to Arduino Mega?
i need using OV7670 camera on my arduino mega, and i found this site have tutorial using ov7670 camera, but in this tutorial they use arduino Uno. if i'm using arduino Mega2560, what i need to do? do i have to change their code and pin connection ?

here is the link

https://www.instructables.com/id/OV7670-Arduino-Camera-Sensor-Module-Framecapture-T/?amp\_page=true

# Answer
> 2 votes
**Yes, you will have to change the code to match the Mega pinout**.

Because the program need to run quite fast, and the Arduino functions `digitalRead()` and `digitalWrite()` are dead slow, the author of the program used direct port access for performing the raw IO. For example:

```
    //Wait for vsync it is on pin 3 (counting from 0) portD
    while(!(PIND&8));//wait for high
    while((PIND&8));//wait for low

```

This is testing pin PD3 (8 is 23), which on the Uno is digital 3, but on the Mega is digital 18. The same code could be written in a portable fashion:

```
    //Wait for vsync it is on pin 3 (counting from 0) portD
    while (digitalRead(3) == LOW);   //wait for high
    while (digitalRead(3) == HIGH);  //wait for low

```

but it would probably be too slow.

Note also that here:

```
    UDR0=(PINC&15)|(PIND&240);

```

the program takes advantage of the particular pin mapping of the Uno in order to read 8 inputs with only two port reads (4 bits on port C and 4 bits on port D). You could do even better on the Mega if you use pins A8 through A15 for the data bus, and then read the whole 8-bit word as `PINK`.

There may be some other differences between the Uno and the Mega that need to be taken into account, but the pin mapping is the only one that is obvious to me just by quickly going through the code.

---
Tags: arduino-mega, camera
---


# Question
Title: Communication between three NodeMCUs such that one in in AP mode, second one in AP+STA mode and the third NodeMCU in STA mode
I am able to establish a connection between first and second NodeMCU, but unable to do so for the third nodeMCU. I used the IP address to establish connection. Should I assign a different IP to each nodeMCU so that communication can take place? In the code that I had written, i have taken the same IP for all three NodeMCUs, so communication was possible between 1st nodemcu(in AP mode) and 2nd nodemcu(in STA+AP mode). For the 3rd node mcu the IP taken was different. Can any one suggest what to do next.

# Answer
> 1 votes
The two network interfaces (station and SoftAP) of the middle esp8266 must have different IP address range. If the top esp8266 has SoftAP with 192.168.4.x, set for the SoftAP of the middle esp8266 IP for example 192.168.5.1. Because with same IP address ranges the esp8266 doesn't know to which network do you want to connect a TCP socket or send an UDP message.

---
Tags: arduino-uno, esp8266, nodemcu
---


# Question
Title: Can't Compile .ino using ArduinoJson Library
I am using an ESP32 NodeMCU for which I wrote working software before. This also occurs when I just try to compile without uploading, so no hardware problem. I am using the newest version of **ArduinoJson(6.12.0)** and it is included:

`#include <ArduinoJson.h>`

The only Function where I use the Library (I'm not good at C/C++, so maybe there is an error):

```
int DeserializeJson(char *json, int *pin, int *pinmode, int *timeInMilliseconds){

  StaticJsonDocument<1024> doc;
  DeserializationError error = deserializeJson(doc,json);

  if (error) {

    Serial.println("Parsing failed");
    return -1;
  }

  memcpy(&pin, doc["Pin"], sizeof( doc["Pin"]));
  memcpy(&pinmode, doc["Mode"], sizeof( doc["Mode"]));
  memcpy(&timeInMilliseconds, doc["TimeInMilliseconds"], sizeof( doc["TimeInMilliseconds"]));

  return 0;
}

```

This is the error I'm getting (at least a part of it):

```
In file included from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Array/ArrayIterator.hpp:8:0,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Array/ArrayRef.hpp:8,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.hpp:17,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.h:9,

                 from C:\Users\error404\source\repos\IOT\esp32\esp32.ino:1:

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp: In instantiation of 'typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type ArduinoJson6120_000001::VariantRef::as() const [with T = const void*; typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type = const void*]':

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Object/MemberProxy.hpp:70:52:   required from 'typename ArduinoJson6120_000001::VariantAs<T>::type ArduinoJson6120_000001::MemberProxy<TParent, TStringRef>::as() const [with TValue = const void*; TObject = ArduinoJson6120_000001::JsonDocument&; TStringRef = const char*; typename ArduinoJson6120_000001::VariantAs<T>::type = const void*]'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Operators/VariantCasts.hpp:16:35:   required from 'ArduinoJson6120_000001::VariantCasts<TImpl>::operator T() const [with T = const void*; TImpl = ArduinoJson6120_000001::MemberProxy<ArduinoJson6120_000001::JsonDocument&, const char*>]'

C:\Users\error404\source\repos\IOT\esp32\esp32.ino:70:47:   required from here

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp:240:24: error: no matching function for call to 'variantAs(ArduinoJson6120_000001::VariantData* const&)'

     return variantAs<T>(_data);

                        ^

In file included from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Operators/VariantOr.hpp:9:0,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Operators/VariantOperators.hpp:9,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp:12,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Array/ArrayIterator.hpp:8,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Array/ArrayRef.hpp:8,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.hpp:17,

                 from C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson.h:9,

                 from C:\Users\error404\source\repos\IOT\esp32\esp32.ino:1:

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp:55:59: note: candidate: template<class T> typename ArduinoJson6120_000001::enable_if<ArduinoJson6120_000001::is_integral<T>::value, T>::type ArduinoJson6120_000001::variantAs(const ArduinoJson6120_000001::VariantData*)

 inline typename enable_if<is_integral<T>::value, T>::type variantAs(

                                                           ^

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp:55:59: note:   template argument deduction/substitution failed:

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp: In substitution of 'template<class T> typename ArduinoJson6120_000001::enable_if<ArduinoJson6120_000001::is_integral<T>::value, T>::type ArduinoJson6120_000001::variantAs(const ArduinoJson6120_000001::VariantData*) [with T = const void*]':

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp:240:24:   required from 'typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type ArduinoJson6120_000001::VariantRef::as() const [with T = const void*; typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type = const void*]'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Object/MemberProxy.hpp:70:52:   required from 'typename ArduinoJson6120_000001::VariantAs<T>::type ArduinoJson6120_000001::MemberProxy<TParent, TStringRef>::as() const [with TValue = const void*; TObject = ArduinoJson6120_000001::JsonDocument&; TStringRef = const char*; typename ArduinoJson6120_000001::VariantAs<T>::type = const void*]'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Operators/VariantCasts.hpp:16:35:   required from 'ArduinoJson6120_000001::VariantCasts<TImpl>::operator T() const [with T = const void*; TImpl = ArduinoJson6120_000001::MemberProxy<ArduinoJson6120_000001::JsonDocument&, const char*>]'

C:\Users\error404\source\repos\IOT\esp32\esp32.ino:70:47:   required from here

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp:55:59: error: no type named 'type' in 'struct ArduinoJson6120_000001::enable_if<false, const void*>'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp: In instantiation of 'typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type ArduinoJson6120_000001::VariantRef::as() const [with T = const void*; typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type = const void*]':

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Object/MemberProxy.hpp:70:52:   required from 'typename ArduinoJson6120_000001::VariantAs<T>::type ArduinoJson6120_000001::MemberProxy<TParent, TStringRef>::as() const [with TValue = const void*; TObject = ArduinoJson6120_000001::JsonDocument&; TStringRef = const char*; typename ArduinoJson6120_000001::VariantAs<T>::type = const void*]'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Operators/VariantCasts.hpp:16:35:   required from 'ArduinoJson6120_000001::VariantCasts<TImpl>::operator T() const [with T = const void*; TImpl = ArduinoJson6120_000001::MemberProxy<ArduinoJson6120_000001::JsonDocument&, const char*>]'

C:\Users\error404\source\repos\IOT\esp32\esp32.ino:70:47:   required from here

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp:61:61: note: candidate: template<class T> typename ArduinoJson6120_000001::enable_if<ArduinoJson6120_000001::is_same<T, bool>::value, T>::type ArduinoJson6120_000001::variantAs(const ArduinoJson6120_000001::VariantData*)

 inline typename enable_if<is_same<T, bool>::value, T>::type variantAs(

                                                             ^

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp:61:61: note:   template argument deduction/substitution failed:

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp: In substitution of 'template<class T> typename ArduinoJson6120_000001::enable_if<ArduinoJson6120_000001::is_same<T, bool>::value, T>::type ArduinoJson6120_000001::variantAs(const ArduinoJson6120_000001::VariantData*) [with T = const void*]':

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp:240:24:   required from 'typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type ArduinoJson6120_000001::VariantRef::as() const [with T = const void*; typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::VariantRef>::value)), typename ArduinoJson6120_000001::VariantAs<T>::type>::type = const void*]'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Object/MemberProxy.hpp:70:52:   required from 'typename ArduinoJson6120_000001::VariantAs<T>::type ArduinoJson6120_000001::MemberProxy<TParent, TStringRef>::as() const [with TValue = const void*; TObject = ArduinoJson6120_000001::JsonDocument&; TStringRef = const char*; typename ArduinoJson6120_000001::VariantAs<T>::type = const void*]'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Operators/VariantCasts.hpp:16:35:   required from 'ArduinoJson6120_000001::VariantCasts<TImpl>::operator T() const [with T = const void*; TImpl = ArduinoJson6120_000001::MemberProxy<ArduinoJson6120_000001::JsonDocument&, const char*>]'

C:\Users\error404\source\repos\IOT\esp32\esp32.ino:70:47:   required from here

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantAs.hpp:61:61: error: no type named 'type' in 'struct ArduinoJson6120_000001::enable_if<false, const void*>'

C:\Users\error404\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Variant/VariantRef.hpp: In instantiation of 'typename ArduinoJson6120_000001::enable_if<(((! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ArrayRef>::value) && (! ArduinoJson6120_000001::is_same<T, ArduinoJson6120_000001::ObjectRef>::value)) && (! ArduinoJson6120_000001::is_same<T,

exit status 1
Fehler beim Kompilieren für das Board ESP32 Dev Module.

```

# Answer
In its own way, the compiler tries to say "I don't know how to convert `doc["Pin"]` to a `const void*`".

Indeed, ArduinoJson doesn't support conversion to `const void*`; it supports conversion to `const char*`, but that doesn't make sense here. Instead, you want to convert `doc["Pin"]` to an integer and assign it to the variable passed by the caller of `DeserializeJson()`.

The solution is to use the assignment operator instead of `memcpy()`:

```
*pin = doc["Pin"];
*pinmode = doc['Mode"];
*timeInMilliseconds = doc["TimeInMilliseconds"];

```
> 1 votes

---
Tags: arduino-ide, c++, c, esp32, json
---


# Question
Title: Changing preferences.txt to 4-space tabs, how to AutoFormat existing code?
Title says it all really, but to elaborate, in my `preferences.txt` file, I've changed the `editor.tabs.size` variable to `4`, which works wonderfully, and now produces 4-space tabs as do my other IDEs for all the languages I write in.

However, I was told that using the `Tools->AutoFormat` feature would update all lines in my previously-written sketches that had the standard 2-space tabs with the new 4-space tab layout.

This isn't so. Whether I `CTRL-a` to select all and run the Auto Format function, or whether I leave everything de-selected, nothing happens.

Should auto-format "fix" the 'incorrect' indenting to the new style? If so, what am I missing?

I'm currently on Arduino IDE 1.8.5 on Linux Mint, if that makes a difference.

# Answer
The auto formatter (astyle) uses a separate configuration to the editor (crazy, I know, but that's the Arduino mentality for you...).

It uses a separate configuration, which is in the `lib` folder of your Arduino program, called `formatter.conf`.

* Copy that file to the same location as `preferences.txt` so it doesn't get overwritten when you upgrade the IDE.
* Edit the file and change `indent=spaces=2` to `indent=spaces=4`

The auto format should now be the same as the editor format.
> 3 votes

---
Tags: arduino-ide
---


# Question
Title: How to produce a .o file from code using Arduino IDE (primarily for LGPL3 compliance)
I spent a great deal of time looking for any posts regarding this and came up empty.

The reason I needed to do this is that I am working on some proprietary code that will be released in an embedded device, but makes use of an LGPL 3.0 licensed library which requires (4.d.0) that I release "corresponding application code in a form ... permit the user to recombine or relink the application with a modified version of the library."

Since the application is on an embedded device, the "corresponding application code" works out to the pre-link .o file which is normally well hidden in the Arduino process.

# Answer
> 2 votes
To extract the .o produced during compilation in the Arduino IDE, do the following:

1. Go to the Arduino-\>Preferences menu item. This will open a preferences window.
2. In the preferences window find the line that says "Show verbose output during" and make sure that compilation is checked. (you can leave upload on or off as you prefer).
3. Click "OK" to close the preferences window.
4. Compile (or compile and upload) your Sketch.

You will get lots of extra output. In the white text, you will either see messages about files being compiled or about "using previously compiled file". In either case, there will be a path provided which will indicate where your Sketch was compiled. On my Mac environment this is `/var/folders/<long random string>/T/arduino_build_<number>/sketch/<sketch_name>.ino.cpp.o`

The line where your sketch is compiled is very long, but the path is also visible in most of the library lines and you can just work down into `.../sketch/...` instead of `.../library/...` instead of scrolling so far to the right on the exactly correct line.

To find the exact line where your sketch is compiled, look for the line directly below a line which simply says "Compiling sketch..."

I know this is rather basic (now that I know how to do it), but it took quite a bit of digging to find it and I figured others might want an answer that's searchable.

---
Tags: arduino-ide
---


title: Powering SIM800L

text:
# Question
Title: Powering SIM800L
With peak consumption at 2A, the SIM800L needs much more current than can be supplied by an Arduino or NodeMCU.

What is the best strategy to power this module, considering that you have access to a 100-240V outlet?

# Answer
> 2 votes
I had to design a board for a customer with a built in LTE modem module (similar to a SIM800), and the power circuitry was something that required special consideration.

One requirement of the board was that the modem should be able to be powered on and off to save power, but that powering it on shouldn't ever cause the rest of the board to brownout.

To this end a separate 5V power circuit was built with a "soft start" facility built in. This was always on, and fed into a number of capacitors to act as a reservoir. From them the power went via a large P-channel MOSFET to switch the power on to the LTE module when needed. The capacitors provided the extra inrush current the LTE module demanded at powerup, and the soft start of the power supply limited the initial inrush current of charging the capacitors.

The power supply also had a "power good" output on it which was monitored to know when the output voltage had risen to an acceptable level (and hence the capacitors were charged) and the LTE module was able to be safely enabled.

The basic circuit was:

simulate this circuit – Schematic created using CircuitLab

That is a somewhat overkill probably for your situation though, but you should understand how it's done in the "real world" in a proper device. However for experimental / prototyping with an Arduino where you aren't wanting to turn the modem on and off, and aren't too worried about the odd brownout, and bulkiness isn't of as much of a concern, then simply using two suitably sized external power supplies is adequate. One small one to power the MCU (Arduino), and one larger one to power the modem.

simulate this circuit

Because the power supplies themselves should have plenty of capacitance, and they are separately powered from a low impedance source (the mains power) there should be no interference between the modem and the MCU.

# Answer
> 1 votes
The cleanest solution is to use separate power supplies for your MCU and your other high power devices. Get a 2.5A supply for the SIM800L, and a more modest supply for the Arduino/NodeMCU.

If you use the same power supply for both, you should use a bigger power supply than your max current needs to minimize "droop" as the load changes. You might also need to add filtering capacitors to the 5V rails of each device fed by the power supply.

## EDIT

I've used this 2A power supply in my projects before: https://www.amazon.com/gp/product/B01G6ZJ6DY/ref=ppx\_yo\_dt\_b\_asin\_title\_o00\_s00?ie=UTF8&psc=1

You could use one of those for your SIM800L, and a 0.5A supply for the Arduino (A USB power supply would be fine.) Just be sure to tie the ground lines of the separate power supplies together.

# Answer
> 1 votes
I am usually using 12V/1000 mA adapter source to power Arduino and adjustable step-down/buck converter which powers GPS and similar modules. Advantage of this is that these converters usually have big capacitors on input and output, so you do not have to use additional auxiliary capacitors.

---
Tags: power
---


# Question
Title: Serial.availableForWrite versus Serial.flush
Is there a difference between the following two line codes?

> > while (Serial.availableForWrite \<= 0) {}

versus

> > Serial.flush()

Thanks!

# Answer
> 4 votes
The line

```
while (Serial.availableForWrite() <= 0) {}

```

waits until the serial output buffer is **not full**. Whereas

```
Serial.flush();

```

waits until the serial output buffer is **empty**.

# Answer
> 2 votes
https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/

> `availableForWrite` Get the number of bytes (characters) available for writing in the serial buffer without blocking the write operation

Write operations on Arduino streams wait if they can't write the data to output. You can use the count returned by `availableForWrite` to avoid this blocking.

https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/

> `flush` Waits for the transmission of outgoing serial data to complete.

One use of `flush()` is to wait until the data are sent away before putting the MCU into sleep mode.

---
Tags: serial, arduino-due, softwareserial, serial-data, matlab
---


title: CNY70 from 3.3v instead of 5v?

text:
# Question
Title: CNY70 from 3.3v instead of 5v?
I would like to use a CNY70 with arduino that is not 5v but 3.3v powered. On the web there most tutorials use 5v and 200 + 10k resistors (e.g. here and here). So as far as I understand for 3.3v I would have to use lower ones.

Can someone explain how those 200 or 10k were calculated? How could I use CNY70 with 3.3v (if it's possible at all) ?

# Answer
The CNY70 is just an IR LED and IR Phototransistor. You can treat the IR LED (emitter) portion of it just like any LED and size the resistor appropriately.

The receiver is just a phototransistor which can operate at anything from about 1V up to 32V with no need to adjust anything. The resistor used there is merely a pullup resistor. You can think of the receiver as a button. When enough IR light falls on it it turns "on".

On an Arduino you could even get away without the pullup resistor and use an input in `INPUT_PULLUP` mode.
> 1 votes

---
Tags: arduino-pro-mini
---


# Question
Title: How to calculate illuminance from the output of a TCS34725 color sensor?
I am using Arduino UNO with the sensor with the following programm.

```
#include <Wire.h>

// TCS34725 I2C address is 0x29(41)
#define Addr 0x29

void setup()
{
  // Initialise I2C communication as MASTER
  Wire.begin();
  // Initialise Serial Communication, set baud rate = 9600
  Serial.begin(9600);

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select Wait Time register
  Wire.write(0x83);
  // Set wait time = 2.4 ms
  Wire.write(0xFF);
  // Stop I2C Transmission
  Wire.endTransmission();

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select Atime register
  Wire.write(0x81);
  // Atime = 700 ms, max count = 65536
  Wire.write(0x00);
  // Stop I2C Transmission on the device
  Wire.endTransmission();

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select control register
  Wire.write(0x8F);
  // AGAIN = 1x
  Wire.write(0x00);
  // Stop I2C Transmission
  Wire.endTransmission();

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select enable register
  Wire.write(0x80);
  // Power ON, RGBC enable, wait time disable
  Wire.write(0x03);
  // Stop I2C Transmission
  Wire.endTransmission();
  delay(800);
}

void loop()
{
  unsigned int data[8];

  // Start I2C Transmission on the device
  Wire.beginTransmission(Addr);
  // Select data register
  Wire.write(0x94);
  // Stop I2C Transmission on the device
  Wire.endTransmission();

  // Request 8 byte of data from the device
  Wire.requestFrom(Addr, 8);

  // Read 8 bytes of data
  // cData lsb, cData msb, red lsb, red msb, green lsb, green msb, blue lsb, blue msb
  if (Wire.available() == 8)
  {
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
    data[6] = Wire.read();
    data[7] = Wire.read();
  }

  // Convert the data
  float cData = (data[1] * 256.0) + data[0];
  float red = (data[3] * 256.0) + data[2];
  float green = (data[5] * 256.0) + data[4];
  float blue = (data[7] * 256.0) + data[6];

  // Calculate the final lux
  float luminance = (-0.32466 * red) + (1.57837 * green) + (-0.73191 * blue);

  // Output data to serial monitor
  Serial.print("Red color Luminance   : ");
  Serial.print(red);
  Serial.println(" lux");
  Serial.print("Green color Luminance : ");
  Serial.print(green);
  Serial.println(" lux");
  Serial.print("Blue color Luminance  : ");
  Serial.print(blue);
  Serial.println(" lux");
  Serial.print("IR Luminance          : ");
  Serial.print(cData);
  Serial.println(" lux");
  Serial.print("Ambient Light Luminance : ");
  Serial.print(luminance);
  Serial.println(" lux");
  delay(500);
}

```

Is the output really in lux or is it counts? If it's counts, how can I calculate the illuminance in lux?

# Answer
> 1 votes
The output of this program is a very wild guess at what the illuminance may be. I would definitely no trust it. It uses the same formula as the function `Adafruit_TCS34725::calculateLux()`, from the Adafruit TCS34725 driver. Googling for the numeric coefficients, I found that the likely source of this formula is the application note Calculating Color Temperature and Illuminance using the TAOS TCS3414CS Digital Color Sensor. That application note seems serious, but it addresses a *different model* of sensor from the one you have. It also gives a formula that does not depend on the gain nor the integration time (maybe that's not adjustable on the TCS3414CS), which makes absolutely no sense if you have a TCS34725. I found an issue filed against the Adafruit driver that shows the formulas used in the library are grossly wrong when compared against a high-quality lux- and color-meter.

I suggest you try implementing the illuminance formula given in the application note DN40 – Lux and CCT Calculations using ams Color Sensors. This documents gives a generic formula with specific coefficient matching different color sensor models, and it does give coefficients specific for the TCS3472 family. Adafruit did use this document to implement a color temperature calculation (function `Adafruit_TCS34725::calculateColorTemperature_dn40()`), but they failed to use it for the illuminance calculation.

# Answer
> 0 votes
In the chip's datasheet on page 8 in the chapter "RGBC Operation" (emphasis by me):

> The RGBC engine contains RGBC gain control (AGAIN) and four integrating analog-to-digital converters (ADC)for the RGBC photodiodes. The RGBC integration time (ATIME) impacts both the resolution and the sensitivityof the RGBC reading. Integration of all four channels occurs simultaneously and upon completion of theconversion cycle, the results are transferred to the color data registers. **This data is also referred to as channelcount.**

So, if you read the values from the data registers, you get simple count values, which were determined by the ADCs connected to the channels. To get a value in lux, you need to calculate that yourself.

Adafruit has a library for their breakout board with this chip. In their tutorial it seems, that the library outputs a value in lux. Maybe you can also use this library, or you can check, how they are converting the values from the sensor to lux values.

---
Tags: arduino-uno
---


# Question
Title: ESP32 cam board and waking from deep sleep
I am getting an error that the sd card cant be mounted when the ESP32 comes out of deep sleep. The board is coded to wake up on a timer from deep sleep and mount the sd card and take a picture. My question is how can I get the SD card to mount properly? I am providing 3volts to the board and I think the same error happens when 5volts is applied. Here is the code:

```
/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-take-photo-save-microsd-card

  IMPORTANT!!!
   - Select Board "ESP32 Wrover Module"
   - Select the Partion Scheme "Huge APP (3MB No OTA)
   - GPIO 0 must be connected to GND to upload a sketch
   - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "fd_forward.h"
#include "fr_forward.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "dl_lib.h"
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memo
// define the number of bytes you want to access
#define EEPROM_SIZE 1

RTC_DATA_ATTR int bootCount = 0;
// Pin definition for CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

int pictureNumber = 0;

#define uS_TO_S_FACTOR 1000000

#define TIME_TO_SLEEP  60

void setup() {

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

  Serial.begin(115200);

  Serial.setDebugOutput(true);
  //Serial.println();

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  //pinMode(4, INPUT);
  //digitalWrite(4, LOW);

  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  Serial.println("Starting SD Card");
  delay(2000);
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    //return;
  }

  uint8_t cardType = SD_MMC.cardType();
  if(cardType == CARD_NONE){
    Serial.println("No SD Card attached");
    return;
  }

  camera_fb_t * fb = NULL;

  // Take Picture with Camera
  fb = esp_camera_fb_get();
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;

  // Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";

  fs::FS &fs = SD_MMC;
  Serial.printf("Picture file name: %s\n", path.c_str());

  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  }
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
    EEPROM.write(0, pictureNumber);
    EEPROM.commit();
  }
  file.close();
  delay(2000);
  // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_en(GPIO_NUM_4);

  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

  Serial.println("Going to sleep now");

  delay(2000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {

}

```

also here is the board I am using

Here is output of the error:

```
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:9232
load:0x40080400,len:6400
entry 0x400806a8
Starting SD Card
E (4147) sdmmc_sd: sdmmc_check_scr: send_scr returned 0xffffffff
SD Card Mount Failed
No SD Card attached

```

Here is a diagram of the pins used by the SD card and Camera. Although I have nothing hooked up to them currently

# Answer
You need to initialize SD\_MMC to 1 bit mode (by default 4 bit mode) this way the microsd is slow, but you free up 3 pins, GPIO4 too. I had this problem to write on SD when used GPIO4 to switch on/off the flash led.

`if (!SD_MMC.begin("/sdcard", true)) { // 1 bit mode
 Serial.println("SD Card Mount Failed !!!");
 return;
}
YOUR CODE HERE ...`

After this I can use GPIO12 as pullup input (tested on my sketch), when it goes to GND the camera will take the frame and save it to microsd (and even send it over TCP socket to Android device and my PC that save to storage memory and show it :D).

GPIO16 don't worked here, it work just one time, then remains LOW and can't be reused.

Note that I do not use sleep function, just check in the loop() the state of GPIO12 to trigger a camera shot.
> 1 votes

# Answer
The code I posted forces GPIO4 to hold its value in this line:

rtc\_gpio\_hold\_en(GPIO\_NUM\_4);

This pin is used for SD card interface. I needed to un-hold it after deep sleep wakeup if I wanted to use the pin again.
> 0 votes

---
Tags: sd-card, esp32
---


# Question
Title: Arduino MKR 1010 WiFi as BLE central/client
I'm trying to use my new Arduino MKR 1010 WiFi as a Bluetooth Low Energy **central**/**client**, however I could only find information on how to use it as a *peripheral/server* (for example with the ArduinoBLE library, which only supports peripheral mode).

Is this possible? Maybe with a different library or firmware for the integrated NINA-W102 chip?

# Answer
In case this thread turns up in a search, the ArduinoBLE library now includes central and peripheral support.
> 1 votes

---
Tags: bluetooth, mkr1010, ble
---


title: Serial Module Echoing a `0x00`

text:
# Question
Title: Serial Module Echoing a `0x00`
I am having a problem with a MAXIM Serial module (Config A) with a simple repeating code from COM port. When sending a character (`k`:`0x6b`) I receive a (`0x00`) echo.

Without the module and just connecting the arduinos crossing the TX/RX cables, I do not have any echo.

The echo persists, disregarding of:

* The speed (from 38400 to 2000000 bps),
* Using or not the high speed options (2.3MOhm for 250000bps) of the MAXIM,
* Using or not 120 ohm terminal resistors,
* Both grounds are 0V, connecting them has no effect,
* Removing the `A` (red) `B` (green) Serial Bus Cables (???). Message not send in this case, as expected (!).

What could be the problem?

**Devices**:

* Two Arduino Mega 2560,
* Two MAX3292, one for each arduino,
* AWG24 Cable, shorter than 7 in each.

**Config A**: With Module (`00` echo), Half Duplex (f.19 p.13).

**Config B**: Without Module (No echo), only crossed cables

Code:

```
long rate=38400;
void setup() {
    Serial.begin(rate); while (!Serial);
    Serial1.begin(rate); while (!Serial1);
    pinMode(22,OUTPUT);
    pinMode(23,OUTPUT);
}
char s;
void loop() {
    if (Serial.available()) {
        digitalWrite(22,1);
        digitalWrite(23,1);
        s=Serial.read();
        Serial1.write(s);
        Serial1.flush();
        digitalWrite(23,0);
        digitalWrite(22,0);
    }
    if (Serial1.available()){
        s=Serial1.read();
        Serial.write(s);
    }
}

```

Execution: Four `k` sent, `0x00` echoes received. After this, four `k` send from other arduino, received successfully.

**Epilogue.**

Actually, the problem was a resistor at the RO output, not shown in the diagram ("The problem is in the code you didn't post").

It was a voltage divider for a 5V3.3 conversion in the Arduino Due case, useless in the Arduino Mega, but still there.

Theorizing a reason, that resistor caused a spike at the output (?), thus forcing the module to interpret it as another byte, an empty one (?).

After removing the resistors, it worked perfectly. Now I migrated this back into Arduino Due, but with a diode plus a pull up resistor as a 5V3.3 converter.

# Answer
> 1 votes
Check your wiring! My guess is the twisted pair (A-B swap).

I've checked your code, it seems right. Please note that /RE and DE were designed that way so you can simply connect them and control with only one pin.

I don't have the exact same hardware, I had MAX485 and Arduino Nano at hand. Nano only has one hardware serial, so I've used the SoftwareSerial library instead. I've connected them, adjusted your code to my setup, and it worked. Here it is in case it helps to troubleshoot your issue. I've also optimized your version a little bit (but it worked before so the bug is somewhere else).

```
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 4); // RX, TX

const int dir_pin=9;
const int dir_transmit=1;
const int dir_receive=0;
long rate=38400;

void setup() {
    Serial.begin(rate); while (!Serial);
    mySerial.begin(rate); while (!mySerial);
    pinMode(dir_pin,OUTPUT);
}
char s;
void loop() {
    if (Serial.available()) {
        digitalWrite(dir_pin,dir_transmit);
        while(Serial.available())
        {
          s=Serial.read();
          mySerial.write(s);
        }
        mySerial.flush();
        digitalWrite(dir_pin,dir_receive);
    }
    while (mySerial.available()){
        s=mySerial.read();
        Serial.write(s);
    }
}

```

---
Tags: serial, rs485
---


# Question
Title: Arduino UNO Low-Power Consumption (Multiple Ultra-Sonic Sensors)
I've read post that it's possible to connect multiple Ultra-Sonic Sensors to one Arduino. But I have a few questions:

1. If I use Arduino Uno, what is the maximum number of Ultra Sonic Sensors that I can connect one Arduino UNO?
2. Is there any option to power Arduino UNO in some kind of low-power mode so I can achieve power autonomy for at least 90 days.(I'm referring to battey life, or solar powered solutions)
3. Can Arduino UNO work on the low/high temperatures (e.g. -20 / +50 Celsius degrees), and what is the known work temperature range?
4. How to secure jumpers/cables to work on extreme temperatures (e.g. -20 / +50 Celsius degrees)

Thanks in advance :D

# Answer
> 2 votes
1. You did not specified, what kind of ultrasonic sensor you want to use so I assume use of "standard" ultrasonic Arduino modules (like hc-sr04), which need 4 pin (VCC, GND, TRIGGER and ECHO). Since Arduino Uno has got 20 IO pins (6 analog and 14 digital), you can use 10 pins as outputs for TRIG signals and 10 as inputs for ECHO signals and thus connect up to 10 ultrasonic modules to one Arduino Uno.
2. In general, Arduino Uno is not designed for low-power applications. If you want more specific answer, you should ask more specific question...
3. Working temperature of Arduino Uno is -40 to 85 °C.
4. One of the options is using a terminal shield with screw terminals, e.g something like this.

---
Tags: arduino-uno
---


# Question
Title: Translating WS2812-LED-Strip-IDs when cutting up a strip to multiple parallel ones
Lets say i have 1 meter of WS2812 Strip at 60 LEDs per meter. Now i cut the strip up in to 6 single strips but keep the wiring the same and lay them out in parallel. So it would look something like this

1 | 11 | 21 ...

2 | 12 | 22 ...

3 | 13 | 23 ...

...

10 | 20 | 30 ...

Is there any library that would allow me to easily translate this? If i for example want to work with rows, turn a certain row in a certain color, treat certain sub-strips as if they were an individual one, etc etc... I'm sure i can't be the first one who had this problem?

# Answer
> 1 votes
No, there is no library.

It's just simple maths.

If all your strips are the same, then you just multiply the strip number by the number of LEDs per strip, and add the number of the LED you want in that strip.

So, assuming 10 LEDs per strip:

```
lednumber = 10 * strip + led;

```

You can make a little macro to do it for you if you like:

```
#define STRIP2LED(S, L) (((S) * 10) + (L))

```

Then you can use such things as:

```
// Set all LEDs on strip 3 to red
for (uint8_t i = 0; i< 10; i++) {
    leds[STRIP2LED(3, i)] = CRGB::Red;
}

```

---
Tags: neopixel, ws2812
---


title: Communicate between 3 nodeMCU

text:
# Question
Title: Communicate between 3 nodeMCU
How should I verify the communication between three node MCUs where one behaves as server and the other two as clients such that data of each node mcu is obtained on all three?

# Answer
> 0 votes
communication between 3 nodemcu can be done instead don`t assume one nodemcu as server other two as client. Mqtt is a message protocol which is used to transfer messages. Connect all the three nodemcu`s in the same network and host a mqtt server separately in the same network. Mqtt has to flexibility to send data from one nodemcu to other nodemcus which are in the same network. Publish and subscribe method can be used to get data or post data.

Go through this link

http://mqtt.org/

---
Tags: nodemcu
---


# Question
Title: "expected primary-expression before '.' token" in debug code
I'm making some code for school, and is adding debug code to it. When compiling, I get the error as written in the title. This is the code in question:

```
#define DEBUG 1

#ifdef DEBUG
#define Serial.println(x) DEBUG_PRINT(x)
#else
#define DEBUG_PRINT(x)
#endif

```

And the code in my void setup, which has Serial.begin:

```
#ifdef DEBUG
Serial.begin(9600);
DEBUG_PRINT("Asteroid");
#endif

```

What am I getting wrong? I get the feeling it's my define text, but I'm unsure.

Thank you for your time Gaarden

# Answer
In short: you have your macro backwards.

Macros are not formed as "Take this set of commands and call it X" but "Make this macro X and have it equate to this set of commands".

Where you have:

```
#define Serial.println(x) DEBUG_PRINT(x)

```

it should instead read:

```
#define DEBUG_PRINT(x) Serial.println(x)

```

When you call it, because the macro doesn't contain a semi-colon in it, you need to specify the semi-colon as if you were calling a function:

```
DEBUG_PRINT("Aardvark");

```

You can omit the semi-colon only if you have a semi-colon in your macro:

```
#define DEBUG_PRINT(x) Serial.println(x);

```

and then:

```
DEBUG_PRINT("Aardvark")

```

By doing it that way your "empty" macro now does become truly empty when used. Without the semi-colon in the macro you would have to use:

```
DEBUG_PRINT("Aardvark");

```

Which for the empty variant would end up as:

```
;

```

Not always desirable, and can cause some problems.

So by adding the semi-colon into the macro you can omit it from the usage of the macro, and your empty variant now becomes:

```

```
> 2 votes

# Answer
You defined the pre-processor macro the wrong way around.
Think it is like an assign statement. You come up with a name and assign something to it.

`#define SHORT_NAME(ARG) some_real_function_that_has_an_awkward_long_name(ARG)`

See the manual of your favourite compiler GCC for reference.
It is always a good idea to do that when using features you haven't used before. Sometimes it can be enlighting.
> 1 votes

---
Tags: arduino-uno, debugging, software, debug
---


# Question
Title: I2C communication problem with two slaves (atlas scientific) and one Nano (official)
I'm working on a project using an arduino Nano (official) and two peripherals from Atlas Scientific (pH and DO) communicating via i2c. Everthing works fine when i use a usb alimentation connected to the PC or to a 5V adaptater (typically a phone charger).

I want to use a 12V battery and a 12V DC 1.5A adaptater to power up my system, the problem is that it works fine for a moment (30 to 40 seconds) and then the pH start having problem with the communication and the led becomes red and the TX/RX leds from the arduino (which are connected to nothing start going crazy. I use 4.7k pull up resistors and an L7805ACV voltage regulator to go from 12 to 5V.

Attach, a part of the system schematics.

If you have any clue, starting to be new idealess

EDIT : Here is the part of the program concerning the i2c communication :

```
#include "Wire.h"

/*********************************************************************************************************
 *                                               Address
 *********************************************************************************************************
 */
int pH_address = 99;
int DO_address = 97;

/*********************************************************************************************************
 *                                         i2C CONFIGURATION
 *********************************************************************************************************
 */

byte received_from_computer = 0;
char sensor_data[20];
byte in_char_sensor = 0;
byte j = 0;
byte code = 0;
int time_ = 850;

void setup()
{
  Wire.begin();
}
void loop()
{
  pH = Get_i2C(pH_address);
  delay(200);
  DO = Get_i2C(DO_address);
  delay(200);
}

/**********************************************************************************************************
 *                                                  i2C
 * ********************************************************************************************************
 */

float Get_i2C(int address)
{
  char computerdata = 'R';
  Wire.beginTransmission(address);
  Wire.write(computerdata);
  Wire.endTransmission();

  delay(time_);

  Wire.requestFrom(address, 16, 1);
  code = Wire.read();
  while (Wire.available())
  {
    in_char_sensor = Wire.read();
    sensor_data[j] = in_char_sensor;
    j += 1;
    if (in_char_sensor == 0)
    {
      j = 0;
      break;
    }
  }
  return atof(sensor_data);
}

```

# Answer
Two ideas.

1: Count your grounds. If you count more than 1 you have a problem. Your system should have a single ground, so ANY connection on every component labeled GND should be connected to ground.

The reason multiple grounds are a problem is that your signals (other than differential signals) are measured relative to ground, so if two components have different ideas of what "ground" is they start to disagree about what constitutes a 1 and a 0.

2: Scope your power supply. Check that your 5V supply is still providing 5V. It's possible (although unlikely) that the L7805ACV can't supply enough current and your system is browning out. If possible have a look with an oscilloscope to check for noise on the 5V supply.

Your boards should already have decoupling capacators, but adding another won't hurt, so also try adding a 0.1uf cap between 5V and GND to eliminate any noise.
> 1 votes

---
Tags: arduino-nano, i2c
---


# Question
Title: Number of digits setting for serial printing the sensor output value
I am getting fan motor rpm as 3200. But if I get the data as 50, I should get the value like 0050. How can I do this?

I can do it like checking the value for single digit(0-9), double digit (10-99), and triple digit (100-999) and four digit(1000-9999). I need to fix digit size and send it through serial. Is there any other way for this?

# Answer
> 3 votes
You can use the C function `sprintf`:

```
char text[5];
sprintf(text, "%04d", number);
Serial.println(text);

```

The leading 0 in 04d will add zero's for the length (4) is met, so 1 will become 0001, 10 will become 0010, 100 will become 0100 and 1000 will stay 1000.

# Answer
> 3 votes
Three if statements look a bit simplistic, but are much better in code size than `sprintf`, if that's the only usage for sprintf.

```
 if (number < 1000) Serial.write('0');
 if (number < 100) Serial.write('0');
 if (number < 10) Serial.write('0');
 Serial.println(number);

```

Saves about 1.5kB Flash, compiled with Arduino 1.8.9 for an Uno

---
Tags: arduino-uno, serial, data
---


# Question
Title: In Nrf24lO1 pa+Lna,is there any indication led light?
How do I know that my \**Nrf24lO1 pa+Lna \** is working or not? For that any separate led is there for on ?

# Answer
> 0 votes
There is no led.

But you can use the isChipConnected function in the RF24 library

---
Tags: nrf24l01+
---


# Question
Title: ESP8266 still connects to wifi even after flashed with empty sketch
So, my wifi is a hotspot password protected. I was developing a program until I decided to comment the ssid and passwords from it, to prevent the ESP from connecting to the internet. But then it still connected. After some debugging, I decided to upload an empty sketch. It still connects to the hotspot!

What is going on?! How does it still know my SSID and password when loaded with an empty sketch!?

# Answer
> 4 votes
The Espressif esp8266 SDK remembers the SSID and password on flash to start connecting immediately after boot. The WiFi channel is stored in the RTC memory (cleared on power down)

You can control this with WiFi.persistent() and WiFi.setAutoConnect().

---
Tags: esp8266
---


# Question
Title: Do comments occupy space in compiled C++ sketch? Arduino / NodeMCU
I tend to leave old code around as comments until I am sure that my current version is stable. Just the way I like working. I am concerned that I may be unnecessarily bloating up my sketches.

Do comments occupy space in an Arduino IDE compiled C++ sketch for Arduino (Nano, Uno)? Is it correct to suppose that the behavior would be the same for NodeMCU?

# Answer
The C/C++ processor (which processes only the #define & #include statements) is the first stage of the compilation process. It runs before the compiler does and strips out everything that isn't code. The compiler will never see your comments.
> 3 votes

# Answer
No. Comments don’t take up any space.
> 1 votes

---
Tags: arduino-uno, arduino-ide, arduino-nano, c++, nodemcu
---


# Question
Title: Alternative to delay() when using Ticker in ESP8622
When using the Ticker library on the ESP8266 you can't use the `delay()` function because Ticker functions are using the underlying timer. The original Arduino library says that you can use a Ticker as delay, but in the ESP8266 implementation things work differently. You "attach()" a callback function and specify the period.

**How can I generate a delay that doesn't require the underlying timer?**

(BTW, where is the documentation for the ESP8266 Ticker library? The repository has no documentation nor comments on the functions.)

# Answer
> 2 votes
use the ticker callback to increment a value. this value can be used as millis() substitute. actually the "millis" is made that way.

write a simple function to give you a delay. **this code assumes the callback function is interrupt/event driven like a systick timer in ARMs.**

```
uint32_t ticks;

void callbackFunc()
{
   ticks++;
}

void myDelay(uint32_t del)
{
   uint32_t tempTime = ticks;
   while (ticks < tempTime + del);
}

```

---
Tags: esp8266
---


# Question
Title: Using a Force Sensing Resistor and time input
So the code below measures how much force is exerted on the FSR. I would like to know what would I have to change in this code so that it can record for how long the FSR is being pressed for. So instead of "What force is exerted on the FSR?", I want to ask "How long is the FSR being pressed for?"

Any help will be most appreciated

```
#include<SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial bluetooth_port(0, 1); //ports for Rx and Tx
int flexSensorPin; // The flex sensor for pin 0

void setup()
{

  Serial.begin(9600); // Start the serial transmission
}

void loop()
{

  flexSensorPin = analogRead(A0); // Flex sensor pin
  Serial.print(flexSensorPin);
  Serial.println("EOL");

  delay(100);

}

```

# Answer
> 1 votes
Use the analog comparator implemented in AVRs. this function, monitors two analog levels and generates interrupts if one of them goes higher or lower than the other as set. use this interrupt to record/stop counting. on AIN connects to FSR, and the other to a potentiometer to define a threshold. here are some links to get you going.

http://www.gammon.com.au/forum/?id=11916 https://github.com/tardate/LittleArduinoProjects/tree/master/playground/AnalogComparator

---
Tags: sensors, time
---


# Question
Title: How can one reset Arduino Nano from NodeMCU?
If one connects the `RESET` pin on an Arduino Nano to a digital pin on a NodeMCU, will the NodeMCU be able to reset the Nano by setting said pin to `LOW`?

# Answer
> 2 votes
Yes, you can reset a 5 V Arduino with esp8266. I did it many times. The esp8266 doesn't have a problem with pull-up level current at 5 V.

On my picture io 0 of the esp-12F is wired to reset pin of Nano. The esp-12F runs WiFiLink firmware which can OTA upload sketch to ATmega328p and of course before flashing it must reset the ATmega.

# Answer
> 1 votes
Yes - grounding the reset pin over-rides the pullup resistor on the Atmega 328's reset pin. You may not be able to prevent the NodeMCU from resetting the Nano when it (NodeMCU) is reset, if that matters.

# Answer
> 1 votes
yes it can.

and to make this answer a little longer...

1. you don't need a level shifter as the pins are 5v tolerant. pullups aren't a problem
2. you may use an optocoupler for isolation :)

---
Tags: arduino-nano, nodemcu
---


# Question
Title: NRF24L01+ changing configuration after startListening
I have been trying to get two Arduino UNO talk to each other via NRF24L01's with TMRH20's NRF24 library. I tried many tutorials and examples and none of them worked. Most of them prints some error messages that's due to `radio.write` returning `false`.

After some troubleshooting I saw something weird. I set up the configuration (e.g. data rate) and when I call `startListening` it seems to be changed back.

This code:

```
void setup() {

    Serial.begin(9600);
    printf_begin();

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.printDetails();
    Serial.println();

    radio.startListening();
    radio.printDetails();
}

```

Outputs:

```
STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xe7e7e7e7e7 0x4141417852
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xe7e7e7e7e7
RX_PW_P0-6   = 0x00 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x03
RF_CH        = 0x4c
RF_SETUP     = 0x27
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 250KBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_MAX

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xe7e7e7e7e7
RX_PW_P0-6   = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x03
RF_CH        = 0x02
RF_SETUP     = 0x0f
CONFIG       = 0x08
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 2MBPS
Model        = nRF24L01+
CRC Length   = 8 bits
PA Power     = PA_MAX

```

You can see that the address was set up correctly *before* `startListening` (`0x4141417852`) but *after* it reverted back to what I assume is the default value (`0xc2c2c2c2c2`). Data rate has also changed.

## Is this normal?

The other Arduino UNO doesn't have `startListening` or `stopListening`, but if I print the configuration after `openWritingPipe` I see the correct configuration.

# Answer
> 2 votes
The first thing that comes to my mind is that you are powering the nrf24L01 directly from the 3V3 pin of your Arduino Uno. **DO NOT do this.**

The 3V3 pin does not provide enough current for the nrf24L01. This renders the module completely unstable. You can:

* Use a decent capacitor across the VCC and GND on the module. (But I do not recommend going for that solution)
* Use a separate 3V3 power source that is capable of handling the current spikes of the nrf24L01. But don't forget to connect its ground to the Ardino Uno aswell.
* Use a power module that powers the nrf24L01 from Arduino Unos 5V rail.

---
Tags: arduino-uno, nrf24l01+
---


title: SD card readline reading batched lines?

text:
# Question
Title: SD card readline reading batched lines?
So, I am trying to transmit float data, over UART, from my Arduino to another machine. The log of this data is really large, so I am forced to put it on an SD card, and read it into the Arduino line-by-line, then transmit that single line.

The issue is that my code seems to be "grabbing" ~65 lines (or more) at a time, transmitting them over UART, then stopping (or crashing) the Arduino.

My log looks like this (a small snippet of the several thousands of lines):

```
14.71927
14.71795
14.71787
14.71787
14.71787
14.71799
14.7175
14.71836
14.71746
14.71787
14.71923
14.71878
14.7184
14.71791
14.71893
14.7184
14.71746
14.71799
14.71746
14.71795
14.71874
14.71795
14.71878
14.71836
14.71881
14.72235
14.72781
14.72872
14.72917
14.72826
14.73188
14.73278
14.73595
14.73783
14.74227
14.74231
14.74363
14.74683
14.7495
14.75492
14.75899
14.76396
14.76807
14.77033
14.77161
14.77262
14.77978
14.78524
14.7884
14.78746
14.79695
14.80238
14.80652
14.80648
14.81055
14.81191
14.81865
14.82234
14.82095
14.81733
14.8286
14.82908
14.82999
14.82682
14.83673

```

And my code looks like this (I know it says 4Hz, but is at 1Hz, but that was to help "see" the "batch" grabbing and printing):

```
// Define our LED pins
#define greenLED    6
#define redLED      5

// Define our serial BAUD rate
#define BAUDrate    9600

// To read data from the SD card
#include <SD.h>

// To print data to an LCD panel
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd( 0x3F, 16, 2 );

void setup(){
    // Set LED pins as outputs
    pinMode( greenLED, OUTPUT );
    pinMode( redLED, OUTPUT );

    // LED output at start: GREEN = ON, RED = OFF
    digitalWrite( greenLED, HIGH );
    digitalWrite( redLED, LOW );

    // Begin wired comms with MSP board
    Serial.begin( BAUDrate );

    // Begin reading data from SD card
    SD.begin( 4 );                      // Need pin #4 for SD card bit-shifting
    File dataLog;                       // Store our data from the SD card
    dataLog = SD.open( "DATA.TXT", FILE_READ );
    String data = dataLog.readStringUntil( "\n" ); // Prime our data

    int i = 0;

    while( data != "" ){
        i++;
        Serial.print( i );
        Serial.print( "\t" );

        Serial.println( data );         // Send our data to MSP board
        lcdUpdate( data );              // Print our sent data to the LCD screen

        delay( 1000 );                   // Wait 1/4 of a second (4 Hz)

        data = dataLog.readStringUntil( "\n" );    // Reprime our data
    }

    // Close our data log to avoid corrupting SD card contents upon restart
    dataLog.close();

    // Switch our LEDs since we're finished streaming our data
    digitalWrite( greenLED, LOW );
    digitalWrite( redLED, HIGH );
}

void loop(){
}

// Prints the current data being sent over UART to an LCD screen
void lcdUpdate( String ourData ){
    lcd.setCursor( 0, 0 );
    lcd.print( " Sending data:  " );
    lcd.setCursor( 0, 1 );
    lcd.print( "    " );
    lcd.print( ourData );
    lcd.print( "    " );
}

```

Again, I want it to grab a single line, print it to the serial terminal, print it to the LCD, then grab a second line and repeat. I'm not able to test the LCD (since I don't have one with me at the moment), but the serial terminal is giving me problems, so I'm assuming the LCD won't work, either.

I'm getting something, as a Serial Terminal output, along the lines of:

```
1       14.71927
14.71795
14.71787
14.71787
14.71787
14.71799
14.7175
14.71836
14.71746
14.71787
14.71923
14.71878
14.7184
14.71791
14.71893
14.7184
14.71746
14.71799
14.71746
14.71795
14.71874
14.71795
14.71878
14.71836
14.71881
14.72235
14.72781
14.72872
14.72917
14.72826
14.73188
14.73278
14.73595
14.73783
14.74227
14.74231
14.74363
14.74683
14.7495
14.75492
14.75899
14.76396
14.76807
14.77033
14.77161
14.77262
14.77978
14.78524
14.7884
14.78746
14.79695
14.80238
14.80652
14.80648
14.81055
14.81191
14.81865
14.82234
14.82095
14.81733
14.8286
14.82908
14.82999
14.82682
14.83

```

It seems to want to stop somewhere between the 65th and 69th element, randomly. I'm assuming that it's running out of buffer space, since it's grabbing everything from the SD card, instead of a single line, one at a time.

This has become more evident with my `i = 0` line, and that it isn't iterating for every line, just the once for the ~65 lines.

Am I reading the data in incorrectly, or am I parsing things incorrectly, or is what I'm trying to do simply not possible?

# Answer
> 1 votes
Arduino's reference doesn't help with your readStringUntil call (see SD's documentation), but assuming it's the same as Stream's, it needs a character, not a string as a terminator.

Your output shows that your Arduino tried to read a line, but there were no line endings found - probably because of the '' vs. "". That's why your output starts with a 1 (i's value), and there no other line numbers after that, even though in your output clearly shows newlines.

---
Tags: sd-card, datalogging, serial-data
---


title: Sound Recognition

text:
# Question
Title: Sound Recognition
I'm looking to recognize a particular sound using arduino uno.

I need to recognize a clap sequence to trigger a relay.

Having given it some thought i need it to be continuous listening mode with out any trigger such as a button press. The background will be quiet.

Is the arduino uno powerful enough to do this and how will i get stated on this? Any help is appreciated.

Note i need to do this entirely onthe Uno itself and not on PC like How do I listen for a sound that matches a pre-recorded sound?

I am thinking i will prerecord the sound and compare with a live sample, is this feasible?

# Answer
If it's just a clap sound and the background is quiet, then really all you'd need is to sense how loud the sound is. This can be done using an analog comparator interrupt (this is present on the chip itself but not on the Arduino library). If all the uno is doing is measuring the sound and maybe setting an output pin when it's loud, then just poll the analogs attached to your microphone and trigger the condition when the output is loud enough. You'd probably need to amplify the microphone if you haven't already, but yes, the uno can handle that.

Edit: if it's a clapping *sequence*, then it can still do it. Again, just measure the time between loud and quiet, don't worry about what the sound is (that is, you don't need to worry about exactly recording and analyzing the sound, you just need to know when it's loud and when it's quiet)
> 2 votes

# Answer
Adding to Michaels answer above which only works for some cases (and it wont work perfectly even with a sequence of claps). To make it work in more cases you would need to store more information about the clap noise- as Michael points out in his comment above "properly identify" the clap- to make the identification more accurate. There are various ways to do this- you could compare it with live recording as you wrote in your question. I suggest tyou try neural networks to do such a comparision I. I would say you would need a two layer neural network with say a sample of different claps for training it-(its probably quicker to train it not with arduino). Here is a library for neural networks for arduino

http://robotics.hobbizine.com/arduinoann.html

that you may use. Or you can implement you own neural network. Its well known that sound recognition can be used to analyse sounds.

The built in ADC of Arduino can probably be used to record and good enough for something like a clap in your case-though it cant be used for high quality sound recordings.
> 2 votes

# Answer
I have not tested it but there is an example for the ArduinoSound library which especially detects claps.

https://github.com/arduino-libraries/ArduinoSound/tree/master/examples/ClapDetector

```
/*
 This example reads audio data from an Invensense's ICS43432 I2S microphone
 breakout board, and uses the input to detect clapping sounds. An LED is
 togggled when a clapp is detected.

 Circuit:
 * Arduino/Genuino Zero, MKRZero or MKR1000 board
 * ICS43432:
   * GND connected GND
   * 3.3V connected 3.3V (Zero) or VCC (MKR1000, MKRZero)
   * WS connected to pin 0 (Zero) or pin 3 (MKR1000, MKRZero)
   * CLK connected to pin 1 (Zero) or pin 2 (MKR1000, MKRZero)
   * SD connected to pin 9 (Zero) or pin A6 (MKR1000, MKRZero)

 created 18 November 2016
 by Sandeep Mistry
 */

#include <ArduinoSound.h>

// the LED pin to use as output
const int ledPin = LED_BUILTIN;

// the amplitude threshold for a clap to be detected
const int amplitudeDeltaThreshold = 100000000;

// create an amplitude analyzer to be used with the I2S input
AmplitudeAnalyzer amplitudeAnalyzer;

// variable to keep track of last amplitude
int lastAmplitude = 0;

void setup() {
  // setup the serial
  Serial.begin(9600);

  // configure the LED pin as an output
  pinMode(ledPin, OUTPUT);

  // setup the I2S audio input for 44.1 kHz with 32-bits per sample
  if (!AudioInI2S.begin(44100, 32)) {
    Serial.println("Failed to initialize I2S input!");
    while (1); // do nothing
  }

  // configure the I2S input as the input for the amplitude analyzer
  if (!amplitudeAnalyzer.input(AudioInI2S)) {
    Serial.println("Failed to set amplitude analyzer input!");
    while (1); // do nothing
  }
}

void loop() {
  // check if a new analysis is available
  if (amplitudeAnalyzer.available()) {
    // read the new amplitude
    int amplitude = amplitudeAnalyzer.read();

    // find the difference between the new amplitude and the last
    int delta = amplitude - lastAmplitude;

    // check if the difference is larger than the threshold
    if (delta > amplitudeDeltaThreshold) {
      // a clap was detected
      Serial.println("clap detected");

      // toggle the LED
      digitalWrite(ledPin, !digitalRead(ledPin));

      // delay a bit to debounce
      delay(100);
    }

    // update the last amplitude with the new amplitude
    lastAmplitude = amplitude;
  }
}

```
> 0 votes

---
Tags: arduino-uno, sound
---


# Question
Title: EEPROM: managing address mapping between firmware versions
Is there a common way to handle changes in the mapping between eeprom addresses and variables between firmware versions? It's not about the eeprom memory to survive the update, but to be(come) compatible with future sketches with a possibly different set of variables.

To make it clearer consider the following fictional scenario:

A coffee machine has been programmed to measure `water_temperature` and the firmware is supposed to stop heating within a `temperature_hysteresis` below `set_temperature`. `set_temperature` is a persistent parameter that has been individually optimized be the user and must therefore survive any firmware update. As a configuration parameter also `temperature_hysteresis` is stored in the eeprom. Now the manufacturer decides to update his machine with a PID-controller, making the parameter `temperature_hysteresis` obsolete while he introduces some new parameters for the controller's gains (`pid_gains`). How can he manage that the firmware keeps values that haven't been touched by the update (like `set_temperature`) while the additional parameter `pid_gains` is added.

I assume that obsolete parameters should be removed as there could be more updates with new parameters in the future. That's why simply incrementing the eeprom address and ignoring deprecated addresses probably won't work.

On the other hand, when re-using old addresses I wonder how a fragmentation of the eeprom can be avoided. I came up with the idea of putting all configuration data into a json in the eeprom and to handle the problem a layer above by parsing the json for configuration data. But anyhow, that feels so wrong and might be too complicate.

Does anyone have experience with this kind of problem and knows how this routine is commonly implemented?

# Answer
> 1 votes
There's lots of ways you could handle this.

Two thoughts right off the top of my head:

1. Have a "Version" identifier in the EEPROM.

The firmware then needs to know the EEPROM layout of all versions up to the current one. It can then read the EEPROM from the old version and write back a new format for the current version.

2. Have each entry in the EEPROM tagged with a "meaning".

This is not too different to your JSON idea (which you are right is horrible), but instead of lots of words you just use a simple number to identify the meaning of the value it is associated with. Assuming that each stored value is an 8-bit byte (though it doesn't have to be), you could allocate "1" as "set\_temperature", "2" as "temperature\_hysteresis", "3" as "pid\_gains", etc, Then the EEPROM might contain the bytes `1,96,2,5` and the firmware would know that the second byte is the `set_temperature` because it has a 1 in the first byte.

You can think of it as a "key / value" pair, but both the key and the value are just numbers.

To find the `temperature_hysteresis` you just scan through all the even EEPROM entries until you find `2`, then read the next entry. If you don't find a `2` then you use the default value.

Your firmware can then choose to either update an existing cell that is tagged with the right type (scan for type, update next cell), or it could erase all the values and replace them with just the ones it cares about - the choice is yours.

Any values that your firmware no longer cares about will be ignored, and potentially erased.

---
Tags: esp32, eeprom, firmware
---


title: Timer 1 Arduino - Create 2 Timers

text:
# Question
Title: Timer 1 Arduino - Create 2 Timers
I’m trying to output 2 separate frequencies using 2 output pins from an Arduino using the Timer 1 library. A snippet of the code is show below.

```
void setup()
{
 Serial.begin(9600);
 pinMode(button,INPUT_PULLUP);
 pinMode(button2,INPUT_PULLUP);
 pinMode(sig_out, OUTPUT);
 pinMode(sig_out2, OUTPUT);
Timer1.initialize(1000);
Timer1.pwm(sig_out,512,period);
Timer1.pwm(sig_out2,512,period2);
}

```

The issue is the way I’ve wrote this makes sense as I’ve initialised 2 outputs and 2 inputs but the ‘period’ is getting overwritten as there’s 1 timer and I’m not sure how to stop this. I was thinking about storing them in variables (like 'T1=' 'T2=') but it would still use the same timer.

I just wanted to know if there’s a way to use 2 timers so the Arduino outputs the frequencies separately.

# Answer
The Timer1 library only supports... Timer 1! So you only have one hardware timer available. If you are using an Arduino Uno or anything similar, you have a couple of other timers. However, unlike Timer 1, which is a 16-bit timer, the others are 8-bit only. This means they are very limited in the range and precision of the frequencies they can generate. If you have an Arduino Mega, then you have a few other 16-bit timers available. You may want to search for a library called Timer3, which should work just like Timer1, while using the 16-bit Timer 3.

If you don't find any suitable library, you may still be able to generate your two signals using only Timer 1. Here is the trick:

* set both PWM outputs to “toggle on compare match”
* enable both compare match interrupts
* in each of these ISRs, advance the compare match register by half a period of the corresponding signal.

For doing this you will need to dig into the low-level details of how a timer actually works. I recommend you start by reading the Timers and counters tutorial by Nick Gammon. Take the time to read and study this. It's not a topic you will be able to master in just a couple of hours.
> 1 votes

---
Tags: frequency, serial
---


# Question
Title: When GPS can't see satellites, how can I continue to tick off a smooth-ish time?
I'm getting 10 updates/sec from my GPS unit (The MTK3339 used in the Adafruit breakout board), and using it to update a clock display. This works well enough, though there's one minor problem that I'd like to solve and one major one that I have to solve.

The minor issue first; I don't get an update *every* 100ms. I get one *roughly* every 100ms... plus or minus about 20-30ms. If a late and an early update arrive back-to-back right when the display goes from n to n+1 seconds, it's noticeable that it's not ticking at a regular cadence. It's not fatal, but the arythmic stutter of it is deeply painful to watch.

The major issue is - what do I do when the GPS can't find a signal? Maybe the device is driving through a tunnel for a minute or there's some other sky obstruction. I still want the clock to update in a best-guess sort of way.

You can't just update the seconds display and then, 1000 (arduino-measured) milliseconds later, update the clock if a new message hasn't arrived. 1000 real-world milliseconds can be anywhere from 700 - 1400ms measured by an arduino, depending on the board and the quality of the crystal. Worse yet, the discrepancy is far from consistent within a single crystal. Seeing the processor speed up and slow down by several percent over the course of a few minutes isn't uncommon.

So what I'd like is a mechanism that will constantly smooth the received (GPS) time to give a best-estimate of current actual time. I'm okay with it being a second or two off (at most) from real time, as long as the cadence feels like actual seconds, and a loss of GPS for a few minutes can be quickly corrected when the signal is re-acquired.

I'm somewhat aware of (strikethrough)DIP(/strikethrough) PID methods, but I'm not sure how to apply them here. It seems that someone must have solved the problem for the sake of syncing internet time, so I shouldn't be reinventing a solution.

# Answer
What you want, namely something to “*smooth the received (GPS) time*”, is called a GPS disciplined oscillator. Obviously, you are not after the high accuracy of commercial GPSDOs, but the working principle of what you are describing is essentially the same.

> what do I do when the GPS can't find a signal?

In GPSDO lingo, this is called the “holdover” state. At this point you rely solely on your local oscillator (here, `millis()` or `micros()`), and steer it to correct for is natural drift, as determined while the GPS reception was good. Or you can go fancy, measure the chip temperature, and apply a temperature compensation.

> I'm somewhat aware of DIP methods, but I'm not sure how to apply them here

I guess you mean “PID”.

You apply this to the *phase* of the oscillator. If the local oscillator is ahead of the GPS (positive phase error), you lower its frequency. For example, you could increment the seconds count every 1,000,100 microseconds (as measured by `micros()`), instead of every 1,000,000. This will make your clock a little bit slow, and resynchronize it with the GPS. Conversely, if your clock is behind the GPS, you slightly increase its frequency to make it run faster.

In other words, the *error value* of your PID is the phase error of your clock, and the *control variable* is the frequency adjustment. By applying the PID technique this way, you are building what is known as a phase-locked loop, or PLL. This is the standard way of implementing a GPSDO.

> It seems that someone must have solved the problem for the sake of syncing internet time

Sure, but NTP implementations can be quite complex, as they have to deal with multiple servers having different round-trip delays and different levels of trust. I am not aware of any Arduino library that does anything similar. You may search for “time synchronization” or “PLL”. If you don't find any, you can pick a PID library and apply it to your oscillator.

A couple of final remarks:

1. You wrote “*speed up and slow down by several percent over the course of a few minutes isn't uncommon*”. This shows there is something *awfully wrong* with either your Arduino or your code. Over a few minutes, you expect frequency variations of the order of *one part per million* on an Arduino clocked off a ceramic resonator, and a few *parts per billion* if yours is clocked off a crystal. See this experimental study on the stability of an Arduino clock. This stability problem is the very first thing you should investigate and fix.
2. Many GPS modules have the option to give you a 1PPS (one pulse per second) signal. If you can use this signal, you may get a quite accurate measurement of your phase error. Relying on the NMEA sentences will give you lots of jitter, which you would then have to compensate for by setting the time constant of the PLL to a very long value.
> 2 votes

# Answer
An accuracy of 700-1400 ms seems like a big issue on your side. Usually it's like +- 10-20 ms. Are you able to provide your code? Or at least important parts of it? Is it possible that you used the delay function?

If so, you should definitely read into the millis function, and how to use it as a timer. This will significantly improve the "accuracy". Because upon calling the delay function, the chip not only waits a given amount of seconds. The chip also calls the yield function. This one is mostly used to make sure that all background work is done before continuing.

What also might me a problem is every type of modification of the chip clock. I've seen some code where people modify the frequency of the PWM-signal. This also affects the clock in every other way.
> 0 votes

# Answer
> You can't just update the seconds display and then, 1000 (arduino-measured) milliseconds later, update the clock if a new message hasn't arrived.

Why not? I'd do just that:

* Maintain an in-memory clock
* Update whenever a GPS message arrives
* Every 1000ms (by millis), tick the clock if a message hadn't arrived, and in any case, update the display.

Something like:

```
SimpleTimer Timers;
unsigned long MyClock_sec = 0;
bool clockIsTicked = false;

void setup()
{
   Timers.setInterval(10L,  GpsCallback);     // if msg, upd MyClock & set flag
   Timers.setInterval(1000, DisplayCallback); // if no flag, ++MyClock; upd display
}

void loop(){
   Timers.run();
}

void GpsCallback(void){
   // if gps message {
   //    MyClock = <<GPS_TIME>>;
   //    ++clockIsTicked;
   // }
}

void DisplayCallback(void){
   if( !clockIsTicked )
      ++MyClock;

   // update the display
   clockIsTicked = false;
}

```

(Not compiled or tested - consider it a pseudo-code outline).
> 0 votes

---
Tags: gps, time, timing
---


# Question
Title: Why do I get avrdude: stk500v2_ReceiveMessage(): timeout error when uploading to Arduino Mega?
I have an Arduino Mega clone and I haven't used it for a while. I remember it not working so when I plugged it in and tried uploading the code to it and sure enough it didn't work. So I plugged in an Uno and it worked. The Mega is a 2560 Atmel. Here's my code:

```
#define distanceForward A0
#define distanceLeft A1
#define distanceRight A2
#define distanceRightAngle A3
#define distanceLeftAngle A4
#define distanceBack A5
int talk = 2;

void setup() {
  Serial.begin(9600);
  pinMode(talk, OUTPUT);
  pinMode(distanceForward, INPUT);
  // /\ Ir distance sensor pin for input signal to arduino, Front Facing
  pinMode(distanceLeftAngle, INPUT);
  // /\ Ir distance sensor pin for input signal to arduino, Left Angle
  pinMode(distanceRightAngle, INPUT);
  // /\ Ir distance sensor pin for input signal to arduino, Right Angle
  pinMode(distanceLeft, INPUT);
  // /\ Ir distance sensor pin for input signal to arduino, Left
  pinMode(distanceRight, INPUT);
  // /\ Ir distance sensor pin for input signal to arduino, Right
  pinMode(distanceBack, INPUT);
  // /\ Ir distance sensor pin for input signal to arduino, back
}

void hall_roam() {
  Serial.write("forward");
  if (analogRead(distanceLeftAngle) < 30) {
    Serial.write("right");
    if (analogRead(distanceLeftAngle) > 30) {
      Serial.write("forward");
    }
    if (analogRead(distanceRightAngle) < 30) {
      Serial.write("left");
      if (analogRead(distanceRightAngle) < 30) {
        Serial.write("forward");
      }
      if (analogRead(distanceForward) < 60) {
        Serial.write("stop");
        if ((analogRead(distanceLeft) < 60) && (analogRead(distanceRight) < 60)) {
          Serial.write("left");
          if (analogRead(distanceForward) > 60) {
            Serial.write("stop");
          }
        }
      }
      if ((analogRead(distanceLeft) > 60) && (analogRead(distanceRight) > 60)) {
        Serial.write("left");
        if (analogRead(distanceForward) > 60) {
          Serial.write("stop");
        }
      }
      if ((analogRead(distanceLeft) > 60) && (analogRead(distanceRight) < 60)) {
        Serial.write("left");
        if (analogRead(distanceForward) > 60) {
          Serial.write("stop");
        }
      }
      if ((analogRead(distanceLeft) > 60) && (analogRead(distanceRight) < 60)) {
        Serial.write("left");
        if (analogRead(distanceForward) > 60) {
          Serial.write("stop");
        }
      }
      if ((analogRead(distanceLeft) < 60) && (analogRead(distanceRight) > 60)) {
        Serial.write("right");
        if (analogRead(distanceForward) > 60) {
          Serial.write("stop");
        }
      } else {
        Serial.write("forward");
      }
    }
  }
}

void roam() {
  Serial.write("forward");
  if (analogRead(distanceForward) < 60) {
    Serial.write("stop");
    Serial.write("left");
    if (analogRead(distanceForward) > 60) {
      Serial.write("stop");
      Serial.write("forward");
    }
  }
}

void talkbb8() {
  pinMode(talk, HIGH);
  pinMode(talk, LOW);
}

void chill() {
  Serial.write("stop");
  talkbb8();
}

void loop() {
  if ((analogRead(distanceLeft) < 60) && (analogRead(distanceRight) < 60)) {
    hall_roam();
  } else if ((analogRead(distanceForward) < 60) && (analogRead(distanceBack) < 60)) {
    Serial.write("left");
    if ((analogRead(distanceLeft) < 60) && (analogRead(distanceRight) < 60)) {
      Serial.write("stop");
      hall_roam();
    }
  } else {
    roam();
  }
}

```

If there's a bracket out of place or something it's probably nothing. I'm talking about the characters. Is there anything in the characters that would screw up the upload like the three "!!!" problem I heard about or something like that. It's possible that the USB chip in it isn't recognized by my iMac. If so how do I fix that?

# Answer
The error message basically means that the programmer is unable to contact the `boot-loader` on the device. The code you're trying to upload has no bearing on the problem.

There could be one of the four possible reason behind it. They are:

1. Wrong Port Selected:

If `TX/RX` led is not blinking, then you may have selected wrong port. If one of both of them are blinking then, you aren't using the wrong port. It might be worth checking again though, sometimes USB COM devices install on strange port numbers.
2. Board is not in `Bootloader` Mode:

The `Arduino Mega` is not executing the `bootloader` for some reason. If the programmer is not resetting the micro before attempting to connect, this might be the reason. Try to reset the board (press and release the button) while the programmer is attempting to connect. Sometimes software that runs in a tight loop will prevent the `bootloader` from connecting. Barring that, the fuses might have gotten messed up or the code erased. You would need to reflash the bootloader and proper fuses, again, see the appropriate info page for your device.
3. Arduino Mega 2560 only: ATmega8U/16U software

Might not be working and would need reprogramming. See the Programming section on the info page, you will need the firmware and Atmel-compatible DFU (device firmware update) software on your computer to`reflash` the target.
4. Hardware damage:

There could be hardware damage to the board, AVR(s), or FTDI chip. Time to buy another board.

You can check this answer.
> 4 votes

# Answer
I tried all the solutions listed on this page:

* changed ports,
* checked correct port on Arduino IDE,
* restarted,
* reconnected,
* bought a new arduino mega,
* etc.

Nothing worked.

Finally gave up and used the web version of the Arduino IDE and it worked just fine.
> 1 votes

# Answer
If you have a timeout issue please ensure the crystal used on board is 16 Mhz.

change

mega.menu.cpu.atmega2560.upload.protocol=wiring To:

mega.menu.cpu.atmega2560.upload.protocol=stk500v2

Thank you! Solved my problem!
> 1 votes

# Answer
I had the same issues on MAC OSX El Capitan (older iMAC) using IDE 1.8.x and of course JAVA performed an update. I regressed the Arduino AVR drivers to 1.6.21 (as instructed online) and this did not resolve the Timeout errors.

I gave up and used IDE 1.8.9 on my OSX MB Pro, and it worked flawlessly.

I think that Java versions and IDE drivers were the issue.
> 0 votes

# Answer
If you have a timeout issue please ensure the crystal used on board is 16 Mhz.

change

```
mega.menu.cpu.atmega2560.upload.protocol=wiring

```

To:

```
mega.menu.cpu.atmega2560.upload.protocol=stk500v2

```

I had this problem after changing crystal value and changing parameters solved the above problem.
> -1 votes

---
Tags: arduino-mega, usb, bootloader
---


# Question
Title: How to make procedures triggered remotely
I am installing lights in a model train and there are multiple prototypical lighting procedures that need to be activated. The lights are connected as follows: Headlight Top - Pin 1 Headlight Bottom - Pin 2 Front Right Marker - Pin 3 Front Left Marker - Pin 4 Rear Right Marker - Pin 5 Rear Left Marker - Pin 6 Rear Left Headlight - Pin 7 Rear Right Headlight - Pin 8 Front Right Ditch Light - Pin 9 Front Left Ditch Light - Pin 10

I would like to simply address a forward procedure which would turn on pins 1, 2, 3, 4, 5, 6, 9, and 10. This is the lighting configuration when the loco is shifted into the forward gear. For reverse, pins 3, 4, 5, 6, 7, and 8 would be activated. There will be a few others too but those are the primary procedures. Is there a way I could set up a variable which names all those pins at once? Or is there some other way I could name a forwards or backwards lighting procedure with a single short name such as "Procedure 2"? I am using Arduino IDE.

# Answer
> 1 votes
perhaps an array and a loop? (dont have the Arduino IDE atm, so sorry about any typos)

```
int lights[] = {1, 2, 3, 4, 5, 9, 10};
int count = 7;//because there are 7 items in the array
//

main(){
    for (int i = 0; i < count; i++){
         digitalWrite(lights[i], HIGH);
         delay(1000);
    }
}

```

EDIT: still no IDE, but here is a little more depth.

forward(true) = forward lights on

forward(false) = forward lights off

reverse(true) = reverse lights on

reverse(false) = reverse lights off

```
void forward(bool state){
    int lights[] = {1, 2, 3, 4, 5, 6, 9, 10};
    int count = sizeof(lights) / sizeof(lights[0]);

    for (int i = 0; i < count; i++){
        switch (state){

            case true: //turn on
                digitalWrite(lights[i], HIGH);
                break;

            case false: //turn off
                digitalWrite(lights[i], LOW);
                break;
        }
        //delay(1000); //optional delay between lights?
    }
}

void reverse(bool state){
    int lights[] = {3, 4, 5, 6, 7, 8};
    int count = sizeof(lights) / sizeof(lights[0]);

    for (int i = 0; i < count; i++){
        switch (state){

            case true: //turn on
                digitalWrite(lights[i], HIGH);
                break;

            case false: //turn off
                digitalWrite(lights[i], LOW);
                break;
        }
        //delay(1000); //optional delay between lights?
    }
}

```

# Answer
> 0 votes
> I would like to simply address a forward procedure which would turn on pins 1, 2, 3, 4, 5, 6, 9, and 10.

And what about pins 7 and 8? You didn't say what to do with them in the forward procedure. Should they be turned off? Should they stay in whatever state they were before? I know it is kind of obvious to you, but it doesn't hurt being specific, for the benefit of those lacking the required background. Lacking a complete specification, we are left to making assumptions.

kei, in his answer, assumed that any pin you did not mention should be left alone, in whatever state it was before. In this answer I will instead assume that you want to *always* control the 10 pins, turning each of them either on or off.

With this assumption, the obvious solution is to have, for each procedure, an array of 10 “states” (either `HIGH` or `LOW`), and loop through the array setting each pin to its appropriate state:

```
for (int i = 0; i < LED_COUNT; i++)
    digitalWrite(led_pins[i], pattern[i]);

```

Here, `pattern[i]` is the state associated to `led_pin[i]` in this specific procedure. Now, since all these pins are consecutive, you don't need the `led_pins` array, and you can replace `led_pins[i]` by `i + FIRST_LED_PIN` (i.e. `i+1`).

This way you can implement as many procedures as you want, each one being defined as a simple 10-number array. I would add a *single function* to activate any procedure. This function would take as an argument a pointer to the light pattern you want to apply:

```
const uint8_t FIRST_LED_PIN = 1;
const int LED_COUNT = 10;
const uint8_t formward_pattern[LED_COUNT] = {
    HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW,  LOW,  HIGH, HIGH
};
const uint8_t reverse_pattern[LED_COUNT] = {
    LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW,  LOW
};

void set_led_pattern(const uint8_t *pattern)
{
    for (int i = 0; i < LED_COUNT; i++)
        digitalWrite(i + FIRST_LED_PIN, pattern[i]);
}

```

With this in place, you can set the light pattern of the forward procedure by issuing the single statement:

```
set_led_pattern(formward_pattern);

```

and for the reverse procedure:

```
set_led_pattern(reverse_pattern);

```

---
Tags: led, variables
---


title: Arduino ESP8266 communication

text:
# Question
Title: Arduino ESP8266 communication
I saw two peculiar things while googling this subjects.

1. Sometimes Tx and Rx are connected directly despite the fact, that it works on different voltages, sometimes resistor dividor is used, sometimes it goes through resistor. Why no consensus? What are differences?
2. Why contributors are so stubborn to use software UART? Is there any reason I can't understand, that should stop me from using built in UART?

# Answer
> 3 votes
> Sometimes Tx and Rx are connected directly despite the fact, that it works on different voltages, sometimes resistor dividor is used, sometimes it goes through resistor. Why no consensus? What are differences?

There is some uncertainty as to whether the ESP8266 has 5V tolerant inputs or not. This uncertainty stems from differences in an early Chinese datasheet translated by the community, and the current English datasheet. It's better to err on the side of caution though and translate your 5V signal from the Arduino to a 3.3V one with either a proper logic level translator or a resistive divider (note that the latter can limit the maximum baud rate you can use).

You can read more here:

> Why contributors are so stubborn to use software UART? Is there any reason I can't understand, that should stop me from using built in UART?

Bad information begets bad information. People copy poor quality examples and tutorials and pass that bad knowledge on to others1.

Many Arduino boards only have one hardware UART port, and that is shared with the USB connection to the PC. It is hard to reliably use that UART for other serial communication, since doing so will break your ability to upload code while your hardware is connected. So it's simpler in that case to use SoftwareSerial (or one of the better implementations).

However, I would never advocate using SoftwareSerial unless you *absolutely have to*. It barely functions at 115200 baud (one of the common default ESP8266 baud rates). If you have a convenient hardware UART then really you *must* use it, for the sake of your sanity if nothing else.

---

1: Even worse though are the examples where people use SoftwareSerial to communicate over the pins of a hardware UART... that's just plain stupid...

---
Tags: esp8266, voltage-level, uart
---