# Question
Title: Arduino Mega reading same information that it's sending out via serial
So I have an Arduino Mega and I'm attempting serial communication with another device, and I ran into this weird issue.

Let's say I use Serial1.write to send out hex A-F. If I read on that same port (Serial1, print out what I read on Serial0), **with NO wires plugged in the serial port**, I get a mirror of what I'm sending out in my read function. I've tested this theory on multiple serial ports, as well as different Megas.

How is this interference happening? Do I have an incorrect understanding of the serial buffers? What can I do to stop it? It's causing interference in communicating with my external device.

Here is a super short program to test this theory.

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

void loop()
{
  char test[15];
  for (int i = 0; i < 15; i++)
    test[i] = i;

  for (int i = 0; i < 15; i++)
     Serial1.write(test[i]);

  while(Serial1.available() > 0 )
   {
    byte c = Serial1.read();
    Serial.print(' ');
    Serial.print(c, HEX);
  }
}

```

**UPDATE:** I came back the next day with my O-scope and the yellow line is the TX and the blue line is the RX. I was not getting the crosstalk anymore in the Serial port, but on the scope shows the RX line was only being effected about 250mV in perfect unison to the TX. I tried connecting everything back up the same way but I was not able to replicate the issue. Somehow whatever I had going on when I posted this was causing the RX line to be affected great enough for the Mega to pick up on it over serial. For now I'm just blaming it on escaped aliens from Area 51 :)

# Answer
> 4 votes
I ran a slightly modified version of your test code on a Mega 2560 and got no echo at all; Unless I totally misunderstood your problem description, there must be something else going on. Here's the code I ran:

```
char test[15];

void setup()
{
    Serial.begin(9600);
    Serial1.begin(115200);
    for (int i = 0; i < 15; i++)
    {
        //Serial.print(i);
        test[i] = i;
        Serial.print(test[i],HEX);
    }
    Serial.println();

    for (size_t j = 0; j < 15; j++)
    {
        Serial.print("test["); Serial.print(j);
        Serial.print("] = ");Serial.println(test[j],HEX);
    }
}

void loop()
{
    for (int i = 0; i < 15; i++)
    {
        Serial1.write(test[i]);
    }

    Serial.println(Serial1.available());

    while (Serial1.available() > 0)
    {
        byte c = Serial1.read();
        Serial.print(' ');
        Serial.print(c, HEX);
    }
}

```

And here's a bit of the output seen on Serial0:

```
Opening port
Port open
VMDPV_1|1_�Se�
0123456789ABCDE
test[0] = 0
test[1] = 1
test[2] = 2
test[3] = 3
test[4] = 4
test[5] = 5
test[6] = 6
test[7] = 7
test[8] = 8
test[9] = 9
test[10] = A
test[11] = B
test[12] = C
test[13] = D
test[14] = E
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

```

As you can see, the Serial1 read buffer was always empty.

Did I misunderstand something you said?

---
Tags: serial, arduino-mega, uart
---


# Question
Title: Is it possible to use WiFi and Bluetooth / BLE in the same ESP32 project?
@Majenko's answer works like a charm. I did have to make some changes as follows:

Per Majenko, you need to change the Tools \> Partition scheme. I used "No OTA (Large APP) as he suggested and it is now working.

However, the Partition Scheme option under Tools was not available for either of my devices (Huzzah32 or NodeMCU-32s). I changed my board type (Tools \> Board) to "ESP32 Dev Module" and several additional options appeared under Tools, including Partition Scheme.

**Original Question:** I am not able to use both the WiFi.h and BLE libraries at the same time. Even the most minimal projects run out of memory during compile. Am I doing something wrong? I get identical results with both an Adafruit Huzzah32 and a NodeMCU-32S.

Does anyone know of a workaround, or barring that a suggested alternate board? A Raspberry pi zero W seems like overkill and the power consumption is ugly, so I don't want to do that unless I really have to.

```
#include <WiFi.h>
#include <BLEDevice.h>

void setup() {
  WiFi.mode(WIFI_MODE_STA);             // use a WiFi function
  BLEDevice::init("Minimal BLE WiFi");  // use a BLE function
}

void loop() { }

```

The error I get is

> Arduino: 1.8.9 (Mac OS X), Board: "NodeMCU-32S, 80MHz, 921600"
>
> Build options changed, rebuilding all **Sketch uses 1443898 bytes (110%) of program storage space. Maximum is 1310720 bytes.**
>
> Global variables use 60208 bytes (18%) of dynamic memory, leaving 267472 bytes for local variables. Maximum is 327680 bytes. **Sketch too big**; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it. Error compiling for board NodeMCU-32S.

# Answer
Yes. Select a partition scheme that gives you more room. For example "No OTA (Large APP)" gives you 3MB of program space.
> 1 votes

---
Tags: arduino-ide, wifi, bluetooth, esp32, memory
---


# Question
Title: Arduino IDE monitor multiple USB ports simultaneously
Is it possible to monitor multiple USB ports simultaneously in Arduino IDE while running only ONE instance of the IDE?

If not, which solutions come alternatively to mind?

# Answer
> 2 votes
If you are only interested in monitoring the output, a simply python script can be run to monitor the port. This sample takes an input of the port number(assuming they get named ttyUSB1, ttyUSB2, ect... Or you can modify it to be a hard coded port. Also make sure the baud rate matches with what your arduino is running (115200 in the example)

You can then run this script in two separate terminals, one for each port

```
#!/usr/bin/env python3

import serial
import sys

if len(sys.argv)<2:
    print("Please give serial port number")
    exit()
port=sys.argv[1]
ser= serial.Serial('/dev/ttyUSB'+port,115200,timeout=5)

while True:
    try:
        print(str(ser.readline().strip()))
    except:
        print(sys.exc_info())
        ser.close()
        exit()

```

Start the program like so

`python3 ./programName.py 1` (or `./programName.py 0`, etc)

The number dictates which of the ttyUSBx devices you are trying to watch (will match with what you see in the arduino IDE).

# Answer
> 2 votes
You can run multiple instances of the Arduino IDE to work with multiple boards at the same time. Start IDE second time with Start menu or desktop shortcut.

Of course you can monitor the COM/tty port with a common serial terminal program too.

# Answer
> 1 votes
Short answer : No.

Long answer : Noooooooooooooooooooooooooooooooooooooo, since one window can only work with one arduino.
That being said, if you open another file, or create new file (Ctrl + N) on existing window, it doesn't make another process.
It is still on the only javaw.exe process running on your computer (you kill that, both window gone for good.)
To make it simple :

* Double click Arduino icon on your desktop, and double click it again, it will run as 2 separate process.
* Double click Arduino icon on your desktop, and then use open file or new file, it won't make another process.

But I think I misunderstood your question. If you're asking for arduinos in multiple USB ports, yeah, one IDE can see wherever you plug it in.

# Answer
> 1 votes
Sloeber, an open source IDE based on Eclipse on which I am a proud contributor, does have this feature, but **the Arduino IDE does not**.

---
Tags: arduino-ide
---


# Question
Title: Why does a delay make my stepper stop? And why does the break command raise an error?
I am using a stepper motor for a project that I want it to stop. I tried *for loops*, *while*, and an *if statement*. All of these were placed inside the *void loop*, because it raised an error.

My code with the if loop:

```
//This program does about 1 rotation or 4100 steps. The program should be able to stop the stepper motor after it does one rotation.
int Pin1 = 8;
int Pin2 = 9;
int Pin3 = 10;
int Pin4 = 11;
int _step = 0;
int _on = 4100;
int _switches = 0;
boolean direct = false;
void setup() {
  pinMode (Pin1, OUTPUT);
  pinMode (Pin2, OUTPUT);
  pinMode (Pin3, OUTPUT);
  pinMode (Pin4, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (_on > 0) {
    switch(_step)
    {
      case 0:
        digitalWrite (Pin1, LOW);
        digitalWrite (Pin2, LOW);
        digitalWrite (Pin3, LOW);
        digitalWrite (Pin4, HIGH);
      break;
      case 1:
        digitalWrite (Pin1, LOW);
        digitalWrite (Pin2, LOW);
        digitalWrite (Pin3, HIGH);
        digitalWrite (Pin4, HIGH);
      break;
      case 2:
        digitalWrite (Pin1, LOW);
        digitalWrite (Pin2, LOW);
        digitalWrite (Pin3, HIGH);
        digitalWrite (Pin4, LOW);
      break;
      case 3:
        digitalWrite (Pin1, LOW);
        digitalWrite (Pin2, HIGH);
        digitalWrite (Pin3, HIGH);
        digitalWrite (Pin4, LOW);
      break;
      case 4:
        digitalWrite (Pin1, LOW);
        digitalWrite (Pin2, HIGH);
        digitalWrite (Pin3, LOW);
        digitalWrite (Pin4, LOW);
      break;
      case 5:
        digitalWrite (Pin1, HIGH);
        digitalWrite (Pin2, HIGH);
        digitalWrite (Pin3, LOW);
        digitalWrite (Pin4, LOW);
      break;
      case 6:
        digitalWrite (Pin1, HIGH);
        digitalWrite (Pin2, LOW);
        digitalWrite (Pin3, LOW);
        digitalWrite (Pin4, LOW);
      break;
      case 7:
        digitalWrite (Pin1, HIGH);
        digitalWrite (Pin2, LOW);
        digitalWrite (Pin3, LOW);
        digitalWrite (Pin4, HIGH);
      break;
      case 8:
        digitalWrite (Pin1, LOW);
        digitalWrite (Pin2, LOW);
        digitalWrite (Pin3, LOW);
        digitalWrite (Pin4, LOW);
      break;
    }

    if(direct == false) {
      _step++;
      _switches++;
      direct = false;
    }else{
      _step--;
      _switches--;
      direct = true;
    }

    Serial.println(_switches);

    if(_step>7) {
      _step=0;
    }

    if(_step<0) {
      _step=7;
    }
    _on--;
    delay(1); // This solves it.
  }
  break; //This raises an error when used with for loop.
}

```

Can anyone help on why the delay makes it stop? And why the break command raises and error?

Arduino UNO. 5 wire stepper.

# Answer
> 1 votes
> ... why the break command raises and error?

Because you are using it wrong! break will end a loop, and is used in the switch...case statements. Read the documentation for break if you need to know more

> I have fixed it, the delay at the end fixes it for some reason. I don’t know why though.

You haven't really fixed it if you don't know why. It seems that you are trying to directly control a 5 wire stepper, i assume your pins must drive a transistor or something as the arduino pins themselves will not work.

The reason it works is because the stepper takes time to energize and move, if you don't wait long enough it won't work, your serial.print must be long enough, as the delay(1) should produce a 1ms delay which is too short.

You are driving your stepper wrong, you have the code setup for a half-step control, but you have 9 states, state 8 in not needed.

you are duplicating effort you don't need with both \_steps and \_switches, they always have the same value.

you can do better on your code as well:

```
int dir = 1
int c = 0

// in loop
c += dir

if (c > max)
{
  dir *= -1
  c = max
}

if (c < min)
{
  dir *= -1
  c = min
}

```

With this you don't have to check the direction to modify your variables.

# Answer
> 0 votes
In simple terms: break() literally breaks out of the immediate loop it is in. Since you were in no loop \[void loop() is not your usual loop functions, it's just Arduino-for keep repeating whatever is inside infinitely. You could use a for/while loop in setup() for how many ever times you want it to run and then use break().\] delay(time in ms), as the name says just pauses the Arduino like a brainfart for how much ever time you put as the parameter. You could check out this link in the future for information of inbuilt functions and other language-related doubts.

---
Tags: arduino-uno, stepper-motor
---


title: NodeMCU backup sketch

text:
# Question
Title: NodeMCU backup sketch
Is it possible to extract a backup of the sketch uploaded to a NodeMCU (as I know that it is possible to backup the firmware).

If so, using which tools?

# Answer
> 2 votes
esptool.py is 'avrdude' for the esp8266. it can read the flash too. but you must know the addresses. tha first copy of the application always start at address 0x1000. the length of the application area depends on the size of the flash and the size of the SPIFFS.

```
> esptool.py read_flash -h
usage: esptool read_flash [-h] [--spi-connection SPI_CONNECTION]
                          [--no-progress]
                          address size filename

positional arguments:
  address               Start address
  size                  Size of region to dump
  filename              Name of binary dump

optional arguments:
  -h, --help            show this help message and exit
  --spi-connection SPI_CONNECTION, -sc SPI_CONNECTION
                        ESP32-only argument. Override default SPI Flash
                        connection. Value can be SPI, HSPI or a comma-
                        separated list of 5 I/O numbers to use for SPI flash
                        (CLK,Q,D,HD,CS).
  --no-progress, -p     Suppress progress output

```

---
Tags: nodemcu
---


# Question
Title: Error when HX711_Arduino_Library installed
First I'm getting this error #include no such directory. Then HX711\_Arduino\_Library installed. Now getting following errors: Arduino: 1.8.9 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), 4M (no SPIFFS), v2 Higher Bandwidth, Disabled, None, Only Sketch, 115200" sketch\_jul18a:34:22: error: no matching function for call to 'HX711::HX711(int, int)'HX711 scale(DOUT, CLK); ^ C:\Users\My Lappy\Desktop\sketch\_jul18a\sketch\_jul18a.ino:34:22: note: candidates are:In file included from C:\Users\My Lappy\Desktop\sketch\_jul18a\sketch\_jul18a.ino:23:0: C:\Users\MyLappy\Documents\Arduino\libraries\HX711\_Arduino\_Library\src/HX711.h:30:3: note: HX711::HX711() HX711(); ^ C:\Users\MyLappy\Documents\Arduino\libraries\HX711\_Arduino\_Library\src/HX711.h:30:3: note: candidate expects 0 arguments, 2 provided C:\Users\MyLappy\Documents\Arduino\libraries\HX711\_Arduino\_Library\src/HX711.h:19:7: note: constexpr HX711::HX711(const HX711&) class HX711 ^ C:\Users\MyLappy\Documents\Arduino\libraries\HX711\_Arduino\_Library\src/HX711.h:19:7: note: candidate expects 1 argument, 2 provided exit status 1 no matching function for call to 'HX711::HX711(int, int)'

Help me with this.

# Answer
There are several HX711 Arduino libraries. Do you have the right one? I would guess no as the library you have installed does not have the constructor that the sketch is using. Either use the correct constructor from the installed library or install another library that has that constructor.

Cheers!
> 0 votes

---
Tags: library
---


# Question
Title: What is the call to cli(); routine in interrupt service routine for SPI?
I see this in examples of ISR code but what is it?

# Answer
Interrupts are normally turned off automatically when an ISR is called.

There are two instructions that allow software to turn off (cli) and on (sei) interrupts to create a sequence of non-interruptable instructions, i.e. an atomic operation or critical section.

In some MCU there are several levels of interrupt priority and an ISR with lower priority may be interrupted by an ISR with higher priority. An atomic operation may also be required in an ISR with lower priority.

There are also cases where an ISR may allow interrupts (with the same or lower priority) to occur after the critical section of the ISR.

Normally an ISR should not contain cli()-sei() especially for the AVR. The hardware will automatically turn off interrupts during the execution of the ISR.

Cheers!
> 2 votes

---
Tags: isr
---


# Question
Title: Tone() conflicts with IRremote library (multiple definition of `__vector_7')
I have just started with Arduino and C++ so I apologise if my question is very basic. I am trying to use tone() with a passive buzzer to create a sound while also using the IRremote library for a remote. However, whenever they are used together, it gives this error:

> Tone.cpp.o (symbol from plugin): In function \`timer0\_pin\_port':
>
> (.text+0x0): multiple definition of \`\__vector\_7'
>
> libraries\IRremote\IRremote.cpp.o (symbol from plugin):(.text+0x0): first defined here
>
> collect2.exe: error: ld returned 1 exit status
>
> exit status 1
>
> Error compiling for board Arduino/Genuino Uno.

This is the code required to recreate this error:

```
#include "IRremote.h"
#include "pitches.h"
int melody[] = {NOTE_C5, NOTE_E6};

void setup() {}

void loop() {
 for (int thisNote = 0; thisNote < 2; thisNote++) {
 tone(3, melody[thisNote], 300);
}
}

```

Please could you advise me on how to fix this issue and if necessary, on a different library or way to create a sound or to receive IR signals?

# Answer
Exactly as @MichelKeijzers wrote the issue is caused by "IRremote" using same timer as "Tone" and the solution to this problem is a little dirty.

Since Tone is included in ArduinoCore (and compiled) we can't easilly modify it so the only thing that worked for me is to modify boarddefs.h file of IRremote library. Since it's code is easilly available after downloading it using "Library Manager" included in ArduinoIDE.

In my tests I used ATmega328P settings.

Edit `C:\Users\youruser\Documents\Arduino\libraries\IRremote\boarddefs.h` and look for your processor number.

For ATmega328 the definition is `#define IR_USE_TIMER2`

I simply changed it to use #define `IR_USE_TIMER1`

And compilation was successfull.

```
Sketch uses 2746 bytes (8%) of program storage space. Maximum is 30720 bytes.
Global variables use 242 bytes (11%) of dynamic memory, leaving 1806 bytes for local variables. Maximum is 2048 bytes.

```

My code:

```
#include "IRremote.h"

#define NOTE_C5  523
#define NOTE_E6  1319

int melody[] = {NOTE_C5, NOTE_E6};

void setup() {}

void loop() {
  for (int thisNote = 0; thisNote < 2; thisNote++) {
    tone(3, melody[thisNote], 300);
  }
}

```
> 6 votes

---
Tags: arduino-ide, ir, remote-control, core-libraries, buzzer
---


title: Which is better millis() or timer?

text:
# Question
Title: Which is better millis() or timer?
I want to create a 30 minutes delay in my program (Arduino).

which is better `millis()` or timer for this purpose?

please give me an example to clarify my doubt ...

Thanks.

# Answer
It depends on your need:

**1. No other activities / main power**

If during those 30 minutes (I guess), the MCU does not have to do anything else (except maybe handling some short interrupts), than you can use a delay. You can use this if your power source is an adapter, but you waste a lot.

* Advantage: Easy to program
* Disadvantage: Power will continue to be used.

**2. No other activities / battery**

If you have the same conditions as above, but using a battery, than as Juraj mention, use the sleep functionality of the Arduino. You need an (external) real time clock or other circuitry to activate the wakeup signal after 30 minutes.

* Advantage: Very less power used during the 30 minute delay
* Disadvantage: Slightly more programming

**3. Other activities**

If you want to do now (or later) other code to be executed during the 30 minute wait, use `millis()`. For example, when you want to extend your project using other libraries that needs a faster than 30 minute response.

* Advantage: You can do other tasks meanwhile
* Disadvantage: More power usage, slightly more programming
> 3 votes

---
Tags: esp8266, millis
---


# Question
Title: request for a member "X" in something not a structure or a union
i was programming a Self Balancing Robot, I am writing the code in vscode using platformio extension.

when i put the code i need to get the angle out of the gyro in another file (named angle.c) and including it in the main program, the ide throws with error, in every line I use the Wire library in the angle.c, however same code copy and paste it in the main program and it works.

P.S. the angle.c is just a file of functions and doesnot have any class.

# Answer
> 1 votes
A .c file is compiled with C compiler. If you include Wire.h which contains a class definition, the C compiler doesn't understand it and generates errors.

If your angle.c file doesn't have C code not compatible with C++, then change the extension of the file to .cpp and it will be compiled with C++ compiler.

---
Tags: arduino-uno, i2c, mpu6050, ide
---


# Question
Title: How to detect patterns in an FFT output?
I have an FFT output from a microphone and I want to detect a specific animal's howl from that (it howls in a characteristic frequency spectrum). Is there any way to implement a pattern recognition algorithm in Arduino to do that? Thanks!

# Answer
> 0 votes
It depends.

First you need to break the problem in steps:

1. If you can make a static analysis, than there is a chance. Meaning, if you can record a snapshot of the howl, and than spend some time processing it.
2. If you need to process it (almost) real time, than I am almost sure the Arduino is way too slow for that. In the next steps will be clear why, and otherwise you can use the next steps to get some idea how to do the analysis.
3. Assume you can do a snapshot of the sound, than you have to store it. The Arduino has only 2 KB of SRAM which is way too small. I assume you want a decent frequency (let's say 40 KHz) of mono (1 channel) samples, which is 40 KB of memory.
4. You need to record this (probably any sound sensor will be fast enough), and store it to some device, either external SRAM (fastest, most expensive), external EEPROM (somewhere in the middle) or SD card (might be slow). EEPROM/SD cannot be written 'forever' so if you want to process a sample every second, you might run in trouble.
5. Than you need to run your algorithm over the static data. I do not know this algorithm, if you have to iterate many times, forget about using SD, use SRAM or EEPROM. Otherwise, read a few blocks (typically 2 or 3, to get 1 or 1.5 KB) and process it. I hope you can store the result also in the Arduino, otherwise write it (if you write much, probably SRAM is the only well feasible solution).

As you can see, you have to break your problem into smaller pieces, and check how the algorithm works (does it need a lot of data, or a snapshot), can it be processed in pieces, or does it need to iterate over the entire sample data a lot, are there intermediate results need to be stored etc.

Note there might be other solutions:

* If you need more speed, try an Arduino Due
* If you need more (internal) SRAM, try a Mega (8 KB) or Due (48 KB)

---
Tags: programming, sound, data, algorithm
---


# Question
Title: Right PIN to activate a wireless relay with ESP8266 ESP-01
I'm trying to program an ESP8266 ESP-01 module to let it connect to my personal wifi network and activate a wireless relay that I've bought.

No problems with Wifi connection so I've omitted the code about it, my problem is to find what is the right PIN to set to LOW/HIGH to control my relay. Setting relayPin to 1 as shown in this code works and with it I can see the embedded LED turning on and off.

```
const int relayPin = 1;

void setup() {
    pinMode(relayPin, OUTPUT);
}

void loop() {
    Serial.println("Close Relay for 100 ms and then Open");
    digitalWrite(relayPin, LOW);
    delay(100);
    digitalWrite(relayPin, HIGH);
    delay(200);
}

```

Surfing the web I've found the following diagram about the ESP8266 ESP-01 module:

I've tried to set relayPin to 0 or to 2 but the relay doesn't activate/deactivate.

So, what is the right PIN number to set in my relayPin constant to control the GPIO0 port?

The relay works succesfully if I give him +3.3V on GPIO0 with an external power.

Thanks in advance

# Answer
> 2 votes
*most* GPIO pins on the ESP8266 "boot" up in **INPUT** mode

You'll need to

```
const int relayPin = 0; // or 2

void setup()
{
    pinMode(relayPin, OUTPUT);
}

```

The reason GPIO1 works is because GPIO1 is serial TxD - so, it's set to output

# Answer
> 1 votes
Looking at better pictures of the PCB on ALIExpress it looks like GPIO0 is used to switch the relay.

What that pin maps to, though, depends on what board you have selected in the IDE.

# Answer
> 0 votes
1 solution I did is to use rx \[GPIO 3\] to drive relay. For this,

1. Need to short the GPIO 0 and GPIO 3(Rx) pin on the relay board.
2. While inserting the ESP-01, either bend the GPIO 0 or completely remove it from ESP-01 board. Be careful, on removing you wil find difficult to program the ESP-01 module again because GPIO 0 should go low at boot time to enable program mode. And this is the reason why GPIO 0 is HIGH on boot.

If you want, you can try this product Smart Switch. Android Based ESP01 Relay Module

# Answer
> 0 votes
I had this exact same problem. Solution was to put 5 volts on the relay. There is a regulator on the wireless relay that gives 3v to the ESP-01 and not 5v. But 5v is required for the relay to work.

# Answer
> -1 votes
You can use any pin of the esp-01 You may want to tell the TX and Rx pins though to behave like regular I/O with the pinMode/Function\_3 command as described here:

https://arduinodiy.wordpress.com/2018/06/14/simple-wifi-relay-board-or-diy-sonoff-sv-sonoff-4-channel-2/

---
Tags: esp8266, relay
---


# Question
Title: Is AREF a stable output Ref voltage with analogReference(INTERNAL)
I'm using an analog input on a NANO board to measure the midpoint between two photo resistive (Cadmium) cells, with the two outside ends tied to GND and a source voltage. Basically a simple voltage divider. So it almost wouldn't matter what reference voltage I used in a case like that, as long as the AnalogReference() was correctly set corresponding to the reference voltage, AND the load did not pull down that voltage.

Well if I used the 5V for my source, and set AnalogReference(DEFAULT), then assuming a worst case load of 4K-ohm, the total load on the 5V regulator is still only 1.25mA. But even so, I figured I could minimize the system load even more by setting AnalogReference(INTERNAL), and using the VREF pin as a source for my voltage divider.

Well it seems to work fine, but I don't know that I've seen any actual examples of what I'm doing, which is using the AREF pin as a source output voltage for my voltage divider. Using vREF as a source, a 4K load would only draw 27.5 microamps with a 1.1V source. But I can't find any spec for the max current I should avoid exceeding, That has me worried maybe I'm not even supposed to be doing that!

So is it acceptable to use the VREF pin as an output for light loads, when using the INTERNAL AnalogReference?

Thoughts?

EDIT: After receiving a "no" answer yesterday, I did some bench checking. I configured my NANO board for Internal, and connected a fully open 100K linear pot from AREF to Ground, with a DVM in parallel. The AREF terminal output was about 1.076, with or without the 100K load. Not quite the 1.1 specified but close enough. I then slowly rotated the pot to increase load. At just under 9K the voltage dropped a somewhat insignificant amount, to 1.075. From there on there were additional small decreases, down to about 1K, at which point i measured about 1.062V. Below 1K, there was a very steep decrease.

Note that this was a "quickie" test, done while powering the NANO from a USB port. However, repeating the test with 12V on the DV input did not alter the results significantly.

Even considering the USB source, from this test I conclude:

1) There does appear to be some buffering on the VREF output. It certainly did not behave as there was a simple case of a 1.1V source in series with a high impedance.

2) Up to a load of 10K, the VREF output seems at least as stable as the 5.0V regulator output.

3) Since a 1.062 drop from an initial no-load voltage of 1.076 equates to less than a 2% difference, I have to conclude that a load on VREF (to ground) greater than 1K (lets say 2K for margin) makes VREF probably useful in cases like i described, with a worst case load of 4K.

4) I repeated my test with a second NANO board. This time the initial no-load voltage was salightly higher, 1.084. However, the response to increasing load and the K point where the slope changed dramatically were unchanged.

Again, this is an arduino NANO board, and probably a clone. Can anyone else verify or disprove my results? I'm sure someone else will need to consider using VREF as I did, and it would be good to know.

# Answer
> 2 votes
No, it is not acceptable.

The datasheet states:

> AVCC is connected to the ADC through a passive switch. The internal 1.1V reference is generated from the internal bandgap reference (VBG) through an internal amplifier. In either case, the external AREF pin is directly connected to the ADC, and the reference voltage can be made more immune to noise by connecting a capacitor between the AREF pin and ground. VREF can also be measured at the AREF pin with a high impedance voltmeter. **Note that VREF is a high impedance source, and only a capacitive load should be connected in a system.**

The 1.1V reference is *only* presented on the AREF pin for the purpose of adding an external bypass capacitor, or for measuring it using a very high impedance meter. Any load applied to the pin *will* cause the reference voltage to droop.

While it may work in certain circumstances it's certainly not recommended. If you want to use it externally you should buffer it through a high-impedance unity-gain voltage follower:

simulate this circuit – Schematic created using CircuitLab

# Answer
> 1 votes
Now, having had the benefit of a support ticket and subsequent discussion with an engineer at TI on this subject, I can confidently offer a *qualified* YES to my own question. It turns out my case is probably the only one that would be within those qualifications.

1. In the case where the RATIO between two hi-resistances is the ONLY thing needed from an A/D measurement, it is acceptable to use AREF and GND for the applied voltage, provided the load is low (see item 2). The main reason is that any droop in the AREF caused by the added load would not affect the ratio.
2. The use of AREF for such a situation should still ensure limiting any load on the AREF pin to about 91uA. For the 1.1V (INTERNAL) source selection, that equates to about a 12K load. The number is based on a reverse calculation that would cause a 1 LSB difference in analog readings, *IF* other analog inputs are expected to be used for other non ratio-metric measurements.
3. Using the AREF pin this way makes it even more important to add a capacitor from the pin to GND.
4. Apparently there is no danger of harming the chip in any way, should the AREF pin become shorted.

I will comment that the engineer responding to my support ticket understood I was trying to avoid a PCB change, but recommended a different approach if I had occasion to make other board changes anyway. His recommendation was to use the EXTERNAL Analog reference option, using the available 3.3V pin for AREF voltage, and using a digital output to supply my voltage divider. The idea here is that I would still have the benefit of short circuit protection, and since I was concerned about power saving, I could switch the Digital output pin to a low state until readings needed to be taken, observing sensible delay for settling time.

A good suggestion indeed, but my reason for answering my own question here is because under the constraints given, using AREF as described in my OP is acceptable, will not affect the ratio measurement, and could not harm the chip.

---
Tags: analogreference, analog
---


title: Detect if laptop is on or not?

text:
# Question
Title: Detect if laptop is on or not?
How would I safely connect an Arduino so that it can detect if a laptop is on or off?

The Arduino would be powered separately by a normal USB charger, since it needs to be turned on even when the laptop is turned off. So I'm thinking I can connect an input on the Arduino to one of the USB ports on the laptop somehow, but how do I do this safely?

Even if I play it safe and connect a current-limiting resistor between the USB voltage and input pin, and perhaps a voltage divider, is there still a problem with connecting one device to another like this? I'm thinking that since each has its own power supply from mains, could there potentially be a problem if I connect the USB port of the laptop to a pin on the Arduino?

Do need to use an optocoupler or relay between them? Or is there an even better way of doing this that I didn't think of?

# Answer
> 2 votes
If your chosen power supply is of a good quality and provides proper ground isolation then it *shouldn't* be a problem to connect the grounds of the two systems together.

However, since there are so many bad power supplies available on the internet (and even some "good" power supplies are somewhat iffy when it comes to grounding) it is safest to hedge your bets and add your own galvanic isolation.

The simplest method is to use an opto-isolator. Use the +5V and GND from your computer's USB port (assuming it's not an always-on charging port - look for a lightning bolt symbol) along with a resistor (470Ω - 1kΩ is good) to drive the LED side of the opto-isolator. The other side then acts as a button to the Arduino:

simulate this circuit – Schematic created using CircuitLab

In this arrangement your input will be LOW when the PC is on. Also R2 could be replaced by the internal pullup of the GPIO pin (`pinMode(PIN, INPUT_PULLUP);`)

As I say, this most likely won't be strictly necessary, but for the minimal cost of an opto-isolator it's silly not to add that extra layer of protection. After all, an opto-isolator is cheaper than a new Arduino or (heaven forbid) a new laptop.

# Answer
> 0 votes
The wall-wart type USB chargers are always double insulated - you'll typically see the square within a square symbol for European markets, though one for the US market alone may not have that marking.

That means that the secondary side is free to float, and can be safely connected to the ground connection of the laptop - whose power supply will typically also be double insulated.

That means you can just connect the 5V USB output to an input on the Arduino - put a high enough current limiting resistor in to allow for differences in voltages - especially in the case that the laptop output is on when the Arduino supply is off, to avoid the input feeding the Arduino through the protection diodes.

You can use an analog input, but if you're only looking for an on/off indication, a digital interpretation would work.

Check the output of the USB socket on the laptop - some are intended to remain live for charging accessories when the laptop is powered but not on. On one of my laptops all the ports are live like this and there's nothing that indicates this.

# Answer
> 0 votes
I don't see any problems connecting the them together like you described.

Make sure not to forget to also connect the USB ground to the Arduino ground, so the electrons have a path to go back.

Adding a current limiting resistor is advisable, for the case that the Arduino isn't powered, but the laptop is. Resistor divider is only needed for Arduino's that run on 3.3V.

# Answer
> -1 votes
The only problems are that (a) the Laptop USB outputs 5V, and the arduino input should not exceed 3.3, and (b) when the Laptop is no longer powered, the 5V pin on its USB no longer has a defined state, and could theoretically spike.

Here's a simple and cheap way to do this with passives. The diode isolates the USB from any "back" voltage. The USB 5V is measured across the resistor, and I'd place a capacitor there to to absorb any voltage spikes from the laptop when it loses power. Finally, the second resistor also indirectly protects the digital input and acts like a voltage converter, between the 5V (4.5 after the diode) and the 3.3V the arduino wants to see. The over-voltage will simply be routed to ground via the chips internal protection diodes, and the current will be limited to about 120 microamps ( 4.5- 3.3 ) / 10K.

You could use an opto isolator, but this is a cheap solution that will work. You will have to share ground between the laptop's USB and your arduino (not shown in the diagram). That will not be an issue however. Especially considering all power adapters offer significant line-to-load isolation. By the way, the 1uF capacitor can be decreased to 100nF or less, depending on how quickly you want to respond to the power loss.

simulate this circuit – Schematic created using CircuitLab

---
Tags: usb, relay, electronics, safety, opto-isolator
---


# Question
Title: i2c Connection for MCP4725(Dac) with Esp8266 wemos d1 mini
------------ *This question has been edited* ------------

*note*: Dac and Adc is12bits

my problem : I use two ESP. Using esp1, I read the Adc amount of the alternating signal (ECG) and send it to esp2 with UDP and I get it. Now, using the same amount of Adc, I would use the MCP4725 to convert the digital value of the Adc to the analog. But I don't know how to do it !

* Do you need sine lookup table like default library example again ??!
* If so, how is it done?!
* I wrote the following code right now, what is your opinion? Explain to me if my code is in error.

I just want the DAC output, to be the ADC signal input.

*Code*:

```
void loop () {

  int noBytes = Udp.parsePacket();
  String received_command = "";

  if ( noBytes ) {
    Udp.read(packetBuffer,noBytes);

    for (int i=1;i<=noBytes;i++)
    {
      received_command += char(packetBuffer[i - 1]);
    }
    int dac_value ;
    dac_value = received_command.toInt();
    Serial.print("dac value: ");Serial.println(dac_value);
    aPin = dac_value ;
    if (!si.i2c_start((I2C_7BITADDR<<1)|I2C_WRITE)) {
      Serial.println("I2C device busy");
      return;
    }

    else{
      Serial.println("i2c is worked");
    }

    for (byte i=1; i<noBytes; i++){
      si.i2c_write(aPin);
      si.i2c_rep_start((I2C_7BITADDR<<1)|I2C_READ);
      si.i2c_stop();
      delay(50);
    }
  }
}

```

---

I use `#include <SlowSoftI2CMaster.h>`.

***si*** is: `SlowSoftI2CMaster si = SlowSoftI2CMaster(4, 5, true);`

Photo:

# Answer
> 0 votes
Ok, I will explain the basic principles and give some tips. This won't be about your code, since it is neither compilable, nor does it make much of a sense to me.

1. **The I2C Protocol:** An I2C connection always needs 2 lines, SDA (which carries the data) and SCL (where the master outputs the clock signal). The communication always get's started by the master with a START CONDITION. Then it transmits the first byte, which consists of the 7 bits long address of the slave device and one bit, that shows if a read or a write operation will be performed. The slave - if there is any with that address - will then respond with an Acknowledgement. The master will transmit it's data and end the transmission with a STOP CONDITION or start a new transmission with a repeated start condition.
2. **Choose the I2C library:** You are using the SlowSoftI2CMaster library because it is architecture independent. As you are a beginner, you should use the SlowSoftWire library, which is a `Wire`-like wrapper library. It gives you the same interface, as the `Wire` library. That is good for beginners, since this hides some of the complexity and most examples and tutorials use the `Wire` library (so you can often copy the code structure). You have to install both libraries (`SlowSoftI2CMaster` and `SlowSoftWire`) in your libraries folder, but you only need to include the `SlowSoftWire` library. Please look at the examples, that come with that library. I will refer to that library in the following points.
3. **Using the `SlowSoftWire` library:** You can declare and initialize the library as in it's `simpleSlowWire.ino` example. For transmitting a new value to the DAC, you have to first use `beginTransmission()` to configure the library for a master write transaction. Then place the data bytes in the libraries buffer with `write()`. And finally do the transmission with `endTransmission()` (this is the only place during this process, where the real I2C action happens on the bus). When you begin the transmission with `beginTransmission()` you must provide the correct address of the DAC. This is meant without the direction bit. The address of the MCP4725 consists of the device code `1100`, the hardwired address pins A1 and A2, and the variable address pin A0. The hardwired address pins are most likely both zero, unless the manufacturer was ordered to program it otherwise (You can check the address with the scanner example). So, if you wire A0 to ground, the address will be `0b1100000`. If you wire A0 to 3.3V, it will be `0b1100001`. The direction bit will be handled by the library - you don't have to worry about it.

4.**The MCP's data protocol:** You cannot simply send the values from the ADC to the DAC. It except's a special data format, which includes command bits to determine it's mode of operation. I think, I have already described how the data is build up in principle and code pretty well in my answer to this question. If there is something special, that you don't understand, you can ask a new question and refer to that answer in it. Also I think, you should use the type `unsigned int` for the `dac_value`, since values from an ADC and values for a DAC both are positive only.

Please keep in mind, that building such projects needs some time investment, until you understand, what actually is happening there. If you use any chip, the datasheet of that chip is always a must read. I personally never haven't worked with the MCP4725. I just have read the datasheet. All information is already there.

---
Tags: arduino-uno, esp8266, i2c, wire-library
---


# Question
Title: Arduino code (on board) runs really slow
Stumbled upon this weirdest behavior, from time to time, my Arduino (UNO) runs gode really slow.

Searching this issue didn't clarify anything, most people have problems with IDE itself. My issue is related to actual board.

Heres a sample of my flow:

* I compile & upload my sketch, all good
* first initiation of program on the board seems to be "fast"
* when I start to "animate" the neopixels it goes 3-4 times slower than it should
* I'll touch the board, and animation goes fast again.

Here's a clip of that, at the end you'll see the "slowness"

* Test environment:
* Live environment:

The Touching part, is almost like if I "add" static electricity from my finger to the board, it wakes up and behaves normally.

For you who are curious about (non related) what animation I'm doing on neopixels, I'm turning on 15 pixels from 0 to 54. Like a "slide effect". (I'm not using delay, only a delay(30) in the loop, rest of the delays are based on `millis()`)

Is there any general info / explanation that would explain this behavior, like in electronics, arduino boards specifically ?

EDIT: I should also add, when printing logs into serial monitor, that slowness also affects the outputs... they appear as "slow" as the pixels flow. When all works normally, I see pixels change and logs 50 times per second (roughly), but in this slow motion, I see pixels change and logs around 20 times per second. Taking out the `Serial` entirely from the code doesn't seem to have effect.

Code:

```
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
#define LEFT_BLINK_IN 2
#define RIGHT_BLINK_IN 3
#define PIN           6
#define NUMPIXELS     54
Adafruit_NeoPixel     leftLight = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel     rightLight = Adafruit_NeoPixel(NUMPIXELS, 10, NEO_GRB + NEO_KHZ800);
int leftBlinkCount   = 0;
int rightBlinkCount  = 0;
int PIXELTOSHOW      = 20;
bool OEM_RIGHT_ON    = false;
bool OEM_LEFT_ON     = false;
int R_PIXEL          = -1;
int L_PIXEL          = -1;
int G_PIXEL          = -1;
int D_PIXEL          = -1;
char LAST_COMMAND;
bool DRL_ON         = false;
int DRL_STARTPIXEL  = 35;
uint32_t COLOR_YEL = rightLight.Color(240, 120, 0);
uint32_t COLOR_RED = rightLight.Color(255, 0, 0);
uint32_t COLOR_BLU = rightLight.Color(0, 0, 255);
uint32_t COLOR_NON = rightLight.Color(0, 0, 0);
uint32_t COLOR_WHI = rightLight.Color(255, 255, 255);

unsigned long rightPrevMillis = 0;
unsigned long leftPrevMillis = 0;
unsigned long generalPrevMillis = 0;
const long PIXEL_SWITCH_INTERVAL = 5;

int DRL_RESETER_LEFT = 0;
int DRL_RESETER_RIGHT = 0;

void welcome()
{
  int totalPixels = (NUMPIXELS + PIXELTOSHOW);
  while (G_PIXEL < totalPixels) {
    unsigned long leftCurrentMillis = millis();
    if (leftCurrentMillis - leftPrevMillis >= 12) {
      leftLight.setPixelColor(totalPixels - G_PIXEL, COLOR_WHI);
      rightLight.setPixelColor(totalPixels - G_PIXEL, COLOR_WHI);
      if (G_PIXEL >= 10) {
        leftLight.setPixelColor(totalPixels - G_PIXEL + PIXELTOSHOW , COLOR_NON);
        rightLight.setPixelColor(totalPixels - G_PIXEL + PIXELTOSHOW , COLOR_NON);
      }
      leftLight.show();
      rightLight.show();
      G_PIXEL++;
      leftPrevMillis = leftCurrentMillis;
    }
  }
  G_PIXEL = 0;
  while (G_PIXEL < totalPixels) {
    unsigned long leftCurrentMillis = millis();
    if (leftCurrentMillis - leftPrevMillis >= 12) {
      leftLight.setPixelColor(G_PIXEL, COLOR_WHI);
      rightLight.setPixelColor(G_PIXEL, COLOR_WHI);
      if (G_PIXEL >= 10) {
        leftLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
        rightLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
      }
      leftLight.show();
      rightLight.show();
      G_PIXEL++;
      leftPrevMillis = leftCurrentMillis;
    }
  }
}

void blinkRight()
{

  //slidePixels(rightBlinkCount, R_PIXEL, rightLight);
  if (rightBlinkCount > 0 && R_PIXEL > -1)
  {
      //Serial.println("RIGHT "+String(rightBlinkCount));
    LAST_COMMAND = ' ';
    unsigned long rightCurrentMillis = millis();
    if (rightCurrentMillis - rightPrevMillis >= PIXEL_SWITCH_INTERVAL) {
      rightLight.setPixelColor(R_PIXEL, COLOR_YEL);
      if (R_PIXEL >= PIXELTOSHOW)
      {
        rightLight.setPixelColor(R_PIXEL - PIXELTOSHOW, COLOR_NON);
        if (G_PIXEL > -1 && DRL_ON == false) {
          leftLight.setPixelColor(R_PIXEL - PIXELTOSHOW, COLOR_NON);
        }
      }
      leftLight.show();
      rightLight.show();
      R_PIXEL++;
      rightPrevMillis = rightCurrentMillis;
    }
    if ( R_PIXEL >= (NUMPIXELS + PIXELTOSHOW)) {
      rightBlinkCount--;
      if ( rightBlinkCount > -1 ) {
        R_PIXEL = DRL_RESETER_RIGHT = 0;
      } else {
        L_PIXEL = G_PIXEL = -1;
      }
      if(DRL_ON){
        D_PIXEL=DRL_STARTPIXEL;
      }
    }
  }

  }

  void blinkLeft() {
  //  slidePixels(leftBlinkCount, L_PIXEL, leftLight);

    if (leftBlinkCount > 0 && L_PIXEL > -1)
  {
          //Serial.println("left  "+String(rightBlinkCount));
    LAST_COMMAND = ' ';
    unsigned long leftCurrentMillis = millis();
    if (leftCurrentMillis - leftPrevMillis >= PIXEL_SWITCH_INTERVAL) {
      leftLight.setPixelColor(L_PIXEL, COLOR_YEL);
      if (L_PIXEL >= PIXELTOSHOW)
      {
        Serial.print(" "+String(L_PIXEL));
        leftLight.setPixelColor(L_PIXEL - PIXELTOSHOW, COLOR_NON);
        if (G_PIXEL > -1 && DRL_ON == false) {
          rightLight.setPixelColor(L_PIXEL - PIXELTOSHOW, COLOR_NON);

        }
      }
      rightLight.show();
      leftLight.show();
      L_PIXEL++;
      leftPrevMillis = leftCurrentMillis;
    }
    if ( L_PIXEL >= (NUMPIXELS + PIXELTOSHOW) ) {
      leftBlinkCount--;
      Serial.println("Count "+leftBlinkCount);
      if ( leftBlinkCount > -1 ) {
        L_PIXEL = DRL_RESETER_LEFT = 0;
      } else {
        L_PIXEL = G_PIXEL = -1;
      }
      if(DRL_ON){
        D_PIXEL=DRL_STARTPIXEL;
      }
    }
  }

}

/*void slidePixels(int &blinkCount, int &blinkPixel, Adafruit_NeoPixel &sideLight){
  if (blinkCount > 0 && blinkPixel > -1)
  {
    LAST_COMMAND = ' ';
    unsigned long leftCurrentMillis = millis();
    if (leftCurrentMillis - leftPrevMillis >= PIXEL_SWITCH_INTERVAL) {
      sideLight.setPixelColor(blinkPixel, COLOR_YEL);
      if (blinkPixel >= PIXELTOSHOW)
      {
        if(G_PIXEL>-1){
          rightLight.setPixelColor(blinkPixel - PIXELTOSHOW, COLOR_NON);
          leftLight.setPixelColor(blinkPixel - PIXELTOSHOW, COLOR_NON);
        }
      }
      rightLight.show();
      leftLight.show();
      blinkPixel++;
      leftPrevMillis = leftCurrentMillis;
    }
    if ( blinkPixel >= (NUMPIXELS + PIXELTOSHOW) ) {
      blinkCount--;
      if ( blinkCount > -1 ) {
        blinkPixel = 0;
      } else {
        blinkPixel = -1;
        if(DRL_ON){
          G_PIXEL = -1;
        }
      }
    }
  }
}*/

int switchRB = 0; // 0 = red, 1 = blue
void slideBlueRed() {
  unsigned long currentMillis = millis();
  if (currentMillis - generalPrevMillis >= 100) {
    if (switchRB == 0) {
      leftLight.setPixelColor(G_PIXEL, COLOR_RED);
      rightLight.setPixelColor(G_PIXEL, COLOR_RED);
    } else {
      leftLight.setPixelColor(G_PIXEL, COLOR_BLU);
      rightLight.setPixelColor(G_PIXEL, COLOR_BLU);
    }
    if (G_PIXEL >= 10) {
      leftLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
      rightLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
    }
    leftLight.show();
    rightLight.show();
    G_PIXEL++;
    generalPrevMillis = currentMillis;
  }
}

void drlLight(){

  unsigned long currentMillis = millis();
  if (D_PIXEL < NUMPIXELS) {
    leftLight.setPixelColor(NUMPIXELS-DRL_RESETER_LEFT, DRL_ON == true ? COLOR_WHI : COLOR_NON);
    rightLight.setPixelColor(NUMPIXELS-DRL_RESETER_RIGHT, DRL_ON == true ? COLOR_WHI : COLOR_NON);
    rightLight.setBrightness(128);
    leftLight.setBrightness(128);
    rightLight.show();
    leftLight.show();
    D_PIXEL++;
   //x //Serial.println(String(DRL_RESETER_LEFT) + " "+ String(NUMPIXELS - DRL_STARTPIXEL));
    if(DRL_RESETER_LEFT+1 < (NUMPIXELS - DRL_STARTPIXEL)){
      DRL_RESETER_LEFT++;
    }
    if(DRL_RESETER_RIGHT+1 < (NUMPIXELS - DRL_STARTPIXEL)){
      DRL_RESETER_RIGHT++;
    }
    generalPrevMillis = currentMillis;
  }

}

void setup() {
  Serial.begin(115200);
  leftLight.begin();
  rightLight.begin();
  pinMode(LEFT_BLINK_IN, INPUT);
  pinMode(RIGHT_BLINK_IN, INPUT);
  delay(50);
  welcome();
}

void loop() {

  if (digitalRead(LEFT_BLINK_IN) == HIGH) {
    if ( OEM_LEFT_ON == false ) {
      OEM_LEFT_ON = true;
      leftBlinkCount++;
      //Serial.println("LEFT "+String(leftBlinkCount));
      if (leftBlinkCount == 1) {
        L_PIXEL = 0;
      }
    }
  } else {
    OEM_LEFT_ON = false;
  }

  if (digitalRead(RIGHT_BLINK_IN) == HIGH) {
    if ( OEM_RIGHT_ON == false ) {
      OEM_RIGHT_ON = true;
      rightBlinkCount++;

      if (rightBlinkCount == 1) {
        R_PIXEL = 0;
      }
    }
  } else {
    OEM_RIGHT_ON = false;
  }

  if(DRL_ON && leftBlinkCount < 1 && rightBlinkCount < 1){
    drlLight();
  }

  blinkRight();
  blinkLeft();
  if(rightBlinkCount < 1 || leftBlinkCount < 1){
    delay(30);
    switch (LAST_COMMAND) {
      case 'q':
      case '?': {
        for ( int gp = 0; gp < NUMPIXELS + PIXELTOSHOW; gp++) {
          leftLight.setPixelColor(gp, COLOR_NON);
          rightLight.setPixelColor(gp, COLOR_NON);
        }
        leftLight.show();
        rightLight.show();
        G_PIXEL = -1;
        break;
      }
      case 's': {
        slideBlueRed();
        //Serial.println("bluuu");
        if (G_PIXEL >= NUMPIXELS ) {
          G_PIXEL = -1;
          switchRB = switchRB == 0 ? 1 : 0;
        }
        break;
      }
      case 'w': {
        welcome();
        if (G_PIXEL >= NUMPIXELS + PIXELTOSHOW) {
          G_PIXEL = -1;
        }
        break;
      }
      case 'd': {
        if(DRL_ON==false){
          D_PIXEL = DRL_STARTPIXEL;
          DRL_ON = true;
          LAST_COMMAND = '-';
        }else{
          D_PIXEL = 0;
          DRL_ON = false;
        }
        break;
      }
    }
    if (Serial.available()) {
      LAST_COMMAND = '-';
      while (Serial.available()) {
        char command = Serial.read();
        G_PIXEL=-1;
        LAST_COMMAND = command;
      }
    }
  }
}

```

# Answer
> 4 votes
This kind of behavior is almost always caused by floating digital input pins. "floating" means not connected to either power or ground, so their voltage is free to float. These input puts have very high impedance (typically less than 1uA of leakage current), so bringing a charged object near them is more enough to change their state.

Probably the easiest way to nail down (and sometimes fix) this problem is to enable the pull-up resistors on the digital inputs.

In you program, this could be as easy changing the mode on the digital input pins from `INPUT` to `INPUT-PULLUP`...

```
void setup() {
  Serial.begin(115200);
  leftLight.begin();
  rightLight.begin();
  pinMode(LEFT_BLINK_IN, INPUT_PULLUP );
  pinMode(RIGHT_BLINK_IN, INPUT_PULLUP );
  delay(50);
  welcome();
}

```

This will almost certainly eliminate the intermittent behavior you are seeing.

What you end up with might not be what you want (you might want the pin to dault to 0 when not connected), in which case you can add an external pull-down resistor or change the software to work with default pull-up.

# Answer
> 3 votes
Now, 3 years later, I found the actual source of your problem. I had a similar problem so I'm posting here for others to find this solution.

The problem is that the NeoPixel library disables ALL interrupts during the time it spends sending the pixel data. The millis() function is dependent on interrupts. It works by incrementing a counter once every millisecond, based on a interrupt, called from a hardware timer. If you disable all interrupts then the counter will not be incremented for the duration.

The NeoPixel library needs to disable them because NeoPixels need very accurate timing of the signals, and you'd suffer from visible intermittent glitches if not.

The millis() counter drops about 30 microseconds per a RGB pixel, or 40 microseconds for a RGBW pixel. You have 54 RGB pixels in your led strip. 54\*0,030 = 1,62 ms. Which means that there's 1,62 milliseconds between each of your millis() updates. I.e. it updates too slow.

Your unstable button must've simply caused nonstop neopixel updates, due to some logic in your code.

There's no easy fix for this, but a few specialized alternative or companion libraries exist that use very device-specific peripherals to work around it. For example, you could use one of the hardware timers to measure the time spent sending NeoPixel data, and then manually go in and update the millis() counter accordingly when done. This requires hacking the NeoPixel library and reading the datasheets for your specific Arduino processor.

---
Tags: arduino-uno
---


# Question
Title: Write and read problem while interfacing 93LC46B EEPROM through SPI
I try to save and read data from 93LC46B EEPROM using SPI with Arduino UNO. I'm following this article https://www.arduino.cc/en/Tutorial/SPIEEPROM . So far I have correctly connected EEPROM pinout (as shown in 93LC46B EEPROM datasheet) with arduino MISO, MOSI, SS, CLK, I copied the code from link and here is the problem, I cant save data to EEPROM, it should be filled with buffer but it is not, whats more everytime I try to read data there are different values on same addresses. How can i solve this problem ? Thanks in advance

# Answer
> 0 votes
The quick answer is that 93LC46B is not compatible with AT25HP512. You can not use that tutorial. There are many differences.

Have a look at this blog instead: http://owlsan.blogspot.com/2012/10/accessing-93c4693c46n-serial-eeprom.html

---
Tags: arduino-uno, spi, eeprom
---


# Question
Title: Create one server in AP mode and another in station mode
I'm trying to connect one ESP8266 to WiFi as a WebServer in station mode and to another ESP8266 as a server (that has no web pages) in AP mode.

The problem is both servers are being created in AP mode, between the ESP's, while one of them (the webserver) should be created in station mode and accessible from WiFi. The only way I can reach the webserver is connecting to the AP and accessing its IP (as access point) from my computer.

What I wanted was to access the webserver connected to my WiFi using the IP that my router gave to the hosting ESP, while the two of them would communicate using the server without web pages.

I've already tried using the same IP for both servers, inverting the order of creation of the servers and using both `ESP8266WiFi.h` and `ESP8266WebServer.h`. I've read something about the later not working with too much code inside the loop and, since the web page I want is pretty simple, I'm using `ESP8266WiFi.h`. Here's my code:

```

#include <ESP8266WiFi.h>
//#include <ESP8266WebServer.h>

WiFiServer internalServer(81);
WiFiServer externalServer(80);
//ESP8266WebServer externalServer(80);
IPAddress IP(192, 168, 4, 15); // Default IP for the AP mode, the one I'm using.
IPAddress mask = (255, 255, 255, 0);
WiFiClient internalClient;
WiFiClient externalClient;

void setup() {

  Serial.begin(115200);

  pinMode(LED_BUILTIN, OUTPUT);

  WiFi.mode(WIFI_AP_STA);

  // Config. AP mode:
  WiFi.softAP("my-access-point", "my-password");
  WiFi.softAPConfig (IP, IP, mask);

    // This connection is ok:
  internalServer.begin();
  Serial.println("Internal server created.");
  while (!internalClient) { // waiting for the internal client to connect before continuing. This works fine.
    internalClient = internalServer.available();
  }
  Serial.println("Internal client found.");

  // Config. STA mode:
  Serial.print("Connecting to Wi-Fi");
  WiFi.begin("my-wifi", "my-wifi-password");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println(" Ready.");

  // Config. external server.
    // This connection isn't working
  externalServer.begin();
  Serial.print("External server created with IP: ");
  Serial.println(WiFi.localIP()); // This is the IP I expected to use to connect to the external server.
                                  // But it is accessible at 192.168.4.15.

void loop() {
  // handling external client:
  externalClient = externalServer.available();
  if(!externalClient) { return; } // proceed only when there is a request.
  String request = externalClient.readStringUntil('\r');
  Serial.println("Request: " + request);

  // The answer is just a hello world:
  String answer = "..."
  externalClient.println(answer)
  Serial.println("Answer: " + answer);

  handleInternalClient();
}

```

The internal client is supposed to turn on the builtin led when it receives "on" from the server and turn it off when it receives "off", and that is working fine so I think the code for it isn't necessary. If you need it, please ask.

What I want is the other ESP talking to this one through 192.168.4.15 in the AP network and my computer talking to it through whatever IP my router gives to it, in my WiFi.

# Answer
It is not documented, but you can construct WiFiServer or ESP8266WebServer with IP address. If you use the IP address of the AP, the server will be available only on the SoftAP. If you use the IP address of the station, the server will be available only on STA interface.

If the IP of the interface is known before `setup()`, you can simply define `WiFiServer internalServer(apIP, 81);` instead of `WiFiServer internalServer(81);`. But if the IP must be first evaluated in `setup()` (from DHCP, or config file), then the following example shows how to set WiFiServer IP and port in `setup()`.

```
#include <ESP8266WiFi.h>

WiFiServer internalServer(81);
WiFiServer externalServer(80);

void setup() {
  ...
  internalServer = WiFiServer(WiFi.softAPIP(), 81);
  externalServer = WiFiServer(WiFi.localIP(), 80);
  internalServer.begin();
  externalServer.begin();

```
> 2 votes

---
Tags: esp8266, wifi, web-server
---


title: APA106 random color when power applied

text:
# Question
Title: APA106 random color when power applied
The APA106 RGB LED is usually blue when 5VDC is applied. Sometimes it is a random color when turning the power supply on and off. How to keep it a consistent color when power is applied?

Normal:

Sometimes:

It’s for an Arduino project, I’ve just isolated the problem to the LED. Dozens of these exhibit this behaviour. The PCB board in the pictures is just a breadboard power supply.

**Update:** DIN to GND still exhibits the same behaviour.

Here is a demo of the problem. 90% of the time at power up the LEDs is blue, but occasionally the color is random like pink or white.

YouTube link to a 38s clip of the problem manifesting

**Update:** At Robert's suggestion, I modified the V-USB bootloader to send the control bits and timings to immediately turn off the APA106 LED. There is still an extremely brief blue pulse (or random color) because power applied to the LED is always faster than any CPU process. It's not perfect, but better.

# Answer
Wire it to the MCU such that power is first applied to the LED under control of the sketch when the sketch is prepared to immediately set the initial color you want. The time taken to accomplish the (power up, set initial color) will have to be less than the eye's ability to perceive the possible color glitch (which, being relatively slow compared to the Arduino, it should be pretty easy to do).

Update:

> There is still an extremely brief blue pulse

That remaining delay is probably the IDE's reset-pulse duration plus the Arduino board's R-C delay on the reset pin. It's probably the best you can do without a lot of hardware (e.g. a switch on every R/G/B pin, designed to power-up "off".)
> 1 votes

---
Tags: rgb-led, neopixel
---


# Question
Title: Is it necessary to reduce the size of libraries?
For example RTClib library have codes for DS1307, DS3231, PCF8523 and softRTC. but I'm only using DS3231 and don't need the extra codes there to occupy my Arduino flash memory.

Does Arduino IDE only "upload" those parts of libraries that is being used in the sketch or just uploads the whole library?

# Answer
> 1 votes
Normally a library supports various kinds of components; because mostly those components share a lot functionality, so it prevents to make very many different libraries.

Note that all functions that you do not call within your program (and are not called from within the library), will NOT end up in your sketch, thus also will not affect your flash memory usage.

If the library is full of `if` statements to make a difference between models, that code is in (if a function is called, the entire function is stored in flash). (Unless the `if` statement can be evaluated compile time, see remark of Edgar Bonet below about link time optimization).

So if you want to remove that 'unnecessary' code (for you at least), than copy the library into your project and remove the unnecessary code yourself.

However, I would not do that until you run out of flash memory.

You can do an easy test:

* Include a library, and compile your sketch. You will see (possibly) some difference.
* Now call a function from the library. Compile the sketch again, you will see the flash memory usage has increased. This means, before that, that function was not part of your compiled sketch.

A thing I would worry more about, is SRAM memory usage, but mostly buffers are created depending on the model, and SRAM is not wasted (since the Arduino Uno has only 2 KB for example).

# Answer
> 1 votes
The Arduino IDE uses the gcc compiler.

Gcc is an optimizing compiler, and is quite good at it. So basically it's going to do a good job of identifying and including only the functions you actually use in your code.

Unless you are quite experienced you will probably not do a better job than the compiler itself.

---
Tags: library, sketch-size
---


# Question
Title: What is the difference between Tools > Board settings in Arduino IDE? ex: ESP32-Dev v. Huzzah32
I had a recent memory issue where the resolution was to change the Tools \> Partition setting. However this setting wasn't available in the Arduino IDE for the boards I was using (Huzzah32 and NodeMCU-32s). I changed the board setting to ESP32-Dev Module, and the addition menu items under Tools appeared. My project compiles and works fine now.

However it never occurred to me to set the Board to the "wrong" type. What's the purpose of a vendor specific board setting when the more generic one appears to work fine? What settings should you use and under what circumstance?

My guess is that the vendor specific board settings are more about the peripheral hardware on the boards (USB ports, LEDs, etc) and that the more of those you are using the more likely you'll need to use a board specific setting. In my case, since my project uses just the WiFi and Bluetooth built into the ESP32 chip itself, that I'm ok, but if I was using a bunch of GPIO and other things I'd need to use the actual Huzzah32. Is that right?

# Answer
> 3 votes
For ESP32 boards the differences are very minor. In general an ESP32 is an ESP32. The only changes are name to pin mappings, and how to upload code.

There are a couple of different ESP32 modules, but in general all the boards use the same (cheapest) module.

If you look at the `pins_arduino.h` file for a variant you see that it is pretty much all in the format:

```
static const uint8_t SDA = 21;
static const uint8_t SCL = 22;

```

Just mapping names to pins. Note that some are special, like SDA and SCL above, which are used as defaults for the Wire library.

The biggest differences are in the boards.txt portion for the board. This is where any differences in the module will be defined.

In general though all the "specific" boards are just the "ESP32-Dev Module" with some options removed, and a new name give to it. So you can usually use ESP32-Dev Module for any board as long as you select the right mode for things like flash.

One big benefit of using the correct board, though, is that a `#define` macro is provided identifying the board. If you want the same code to run differently on different boards (such as using different pins on different boards) you can use that macro to direct the flow of your code.

---
Tags: arduino-ide, compile
---


title: Can I power 25 LED via USB?

text:
# Question
Title: Can I power 25 LED via USB?
So I'm currently working on a project where I build a WordClock. To display the current time I use WS2812B LEDs which should be white when turned on. Only about 25 leds per time will be turned on, the rest will be off. If my calculation is correct that should result in 1,5A (25leds x 60ma = 1500ma = 1,5A). With the little power consumption of the Arduino Nano I think it won't exceed 2 amps at a time. Is it safe to power this from a standard USB port or do I need some of the relatively overpriced (at least here in Germany) led power supply? What's the worst that could happen if I would exceed the amperage of the power supply? Would the LEDs just be dimmed or would it be dangerous in any way?

Thanks in advance

# Answer
Your calculation is correct. 25 LEDs on full white will draw 1.5A.

You cannot drive this from a standard USB port on your PC. These ports can give up to 500mA (higher currents for USB3.0 ports will only be available after additional negatiations - not possible with a Nano). When powering from such a port, the port will either go into emergency shutdown (reenabling after the next reboot), or you will damage the USB port beyond repair.

But you don't need an overpriced power supply, that is meant for these LEDs. The WS2812B LEDs work on 5V, so you can use any 5V DC wallwart power supply, for example a standard USB charger, that gives you at least 2A.

> What's the worst that could happen if I would exceed the amperage of the power supply?

In general you risk to damage the power supply, so that it won't work anymore. Drawing more power than allowed from a power supply is like a short, which is never good. Also too hot wires and such can cause fires.

But that is not always true. I tested a big strip of those LEDs on a simple USB charger myself one time. The charger was not rated high enough for all the LEDs. So the LEDs lit up for a very short time (like a flash) again and again with about 1s between each flash, as the USB charger tried to supply the voltage and did go into emergency shutdown again. This didn't hurt the USB charger, though I would not do this for very long. Also you cannot be sure, that your USB charger will do the same. (I also live in germany, so it might be the same case). Also look at the description of the chargers. Sometimes they write a high current into the title of multiple port chargers, but this current is distributed between the ports, so that you need multiple cables to draw the full current.

As USB chargers are quite cheap, I would suggest to use one of these. Pay extra attention to the current rating and stay well above your requirements (2A should be enough).

**Very important:** Be sure, that you don't draw the LEDs current through the Arduino. This would fry it's protection diode. Instead connect the LEDs power lines directly to the power supply, in parallel to the Arduino.
> 0 votes

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


# Question
Title: Is low memory warning based on a fixed number of on the actual sketch?
I have the following output of my sketch for the Arduino Mega so far:

```
Sketch uses 25020 bytes (9%) of program storage space. Maximum is 253952 bytes.
Global variables use 6919 bytes (84%) of dynamic memory, leaving 1273 bytes for
local variables. Maximum is 8192 bytes.

Low memory available, stability problems may occur.

```

I think 1273 bytes is not so less for most sketches, although mine is quite big (several thousand of lines, and I'm about half).

I was wondering if the IDE is so smart to statically analyze my code to see what my dynamic storage is (about 600 bytes) and/or calculates some expected stack size (several hundred bytes at least).

Or is it just a (very) safe fixed or percentage-based value?

# Answer
> 2 votes
I just did some tests and found the answer.

```
char a[6135];

void setup()
{
  a[0] = 0;
}

void loop()
{
}

```

This sketch does not give a warning:

```
Sketch uses 660 bytes (0%) of program storage space. Maximum is 253952 bytes.
Global variables use 6144 bytes (75%) of dynamic memory, leaving 2048 bytes for local variables. Maximum is 8192 bytes.

```

If I increase the array with 1, I get an error:

```
Sketch uses 660 bytes (0%) of program storage space. Maximum is 253952 bytes.
Global variables use 6145 bytes (75%) of dynamic memory, leaving 2047 bytes for local variables. Maximum is 8192 bytes.
Low memory available, stability problems may occur.

```

Conclusion: below 2 KB (2048 bytes) of free space, the warning is shown.

I did the same test for the Uno, and there the warning is shown when less than 1536 bytes are free.

Both percentages are 75%, so the end conclusion is that the value is based on 75% of memory.

---
Tags: arduino-mega, sketch, memory-usage
---


# Question
Title: Can I connect this LED Matrix to a ESP8266 Huzzah directly?
This tutorial for the 16x32 LED Matrix makes it sound like you have to use an Arduino Uno or Mega, but the tutorial was also written a few years ago. I have a Huzzah ESP8266 (my project is about displaying information from the internet on the LED matrix) but I can't seem to get the library to work with the Huzzah.

I am wondering if it would be possible to somehow hook up the LED matrix directly to the Huzzah. Can anyone make suggestions on this front?

Or do I have to basically make the Uno a slave to the Huzzah ESP8266? Need to figure out how to do that.

Thank you.

# Answer
The Huzzah is a great board but I don't think it is capable of driving a large led matrix by itself. Adafruit also makes a led matrix feather wing which could enable the huzzah : https://www.adafruit.com/product/3090
> 0 votes

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


# Question
Title: How can I pass multiple variables to a function?
Using the FastLED library, I want to light up multiple lights at once.

Currently I am passing in just one light to the function.

```
spell( int LEDNumber )
{
  FastLED.clear();
  leds[LEDNumber] = CRGB (255,255,255); //white
  FastLED.show();
  time = 500;
  delay(t);
}

```

I would like to pass in more than just 1 light at a time.

# Answer
> 2 votes
You may create a `struct` with "x" elements, one for each LED:

```
struct ArrayOfBooleans {
   bool array[4];
};

ArrayOfBooleans myOutputArray;
myOutputArray.array[0] = true;
myOutputArray.array[1] = true;
myOutputArray.array[2] = false;
myOutputArray.array[3] = true;

lightEmUp(myOutputArray);

void lightEmUp(ArrayOfBooleans myOutputArray) {
   bool isFirstLightOn = myOutputArray.array[0];
   // etc
}

```

NoTE: If you run into `Exception 9` issues (using this logic on another board), please check this answer to another post

# Answer
> 1 votes
Easier than I thought. Found it while reading the docs. Imagine that. :)

To pass in multiple variables, just separate them with a comma.

Docs: https://www.arduino.cc/en/Reference/FunctionDeclaration

Relevant code:

```
int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}

```

---
Tags: arduino-uno, functions
---


# Question
Title: how to use hx-53 (IR Transmitter Infrared Sensor Module) with ESP32?
ESP32 tx2 (pin17) and rx2 (pin16) uses 3.3v based signals.

HX-53 data connect to tx2, gnd to gnd and vcc to vin(5v).

But as i can understand HX-53 data input should be 5v based.

How can i solve this problem?

HX-53: https://www.amazon.com/Electronic-Infrared-Emission-Transmitter-Arduino/dp/B07PJC7WSQ

Best regards. GA

# Answer
> 3 votes
The HX-53 look like a IR LED and a current limiting resistor on a small PCB.

It also has a LED and a resistor in series for indication when the invisible IR diode is on or off.

So you can change the resistor to a lower value to match the 3,3 volt output from the ESP32.

Resistor values:

```
221 = 220 ohm   = IR LED
102 = 1000 ohm  = SMD indicator LED

```

So replace the 220 ohm with something near 75 ohm.

**HX-53**

# Answer
> 2 votes
I happen to have one just like yours. I was trying to use it on my Arduino to send commands to my AC like a remote but as it turns out, the Vcc pin on the HX-53 breakout board appears to be a dummy and doesn’t connect to anything as far as i know. By right there should be a transistor circuit driving that LED. As it is now, not only is there insufficient current from the signal pin to drive that IR LED for signal bursts, but the red SMD LED in series with the resistor is also stealing some of the current away from the IR LED. In the end, I had to buy a BJT, a standalone IR LED, some resistors and design my own transistor circuit to drive it.

On the transistor’s collector side I had a connection to Vcc and the IR LED in series with a resistor. On the base side was a connection to the signal pin and a resistor. The emitter was connected directly to Ground. Values of the resistors you use will depend largely on the Vcc, the LED max forward current, the specs of the transistor you choose and available current from the power supply.

Hope this helps.

---
Tags: esp32, ir
---


title: How to cast float into four bytes?

text:
# Question
Title: How to cast float into four bytes?
I'm trying to save GPS coordinates to an EEPROM.

In this example I feed it the latitude of 56060066 as the argument float x

```
void writeFloat(unsigned int addr, float x)
{
  byte seriesOfBytes[3];
  *((float *)seriesOfBytes) = x;
  // Write all four bytes.
  for(int i = 0; i < 4; i++)
  {
    i2c_eeprom_write_byte(0x57, addr, myFloat.bytes[i]); // Write byte to EEPROM
    Serial.println(seriesOfBytes[i],BIN);  // Debug line
  }
}

```

I'm expecting to receive the following four bytes from the serial print:

```
00000011
01010111
01101000
10100010

```

Instead I'm getting these:

```
00101000
11011010
01010101
01001100

```

I've tried changing all sorts of parameters, but can't seem to find the problem. Can anyone spot the issue?

# Answer
If you were to enable the display of warnings you would most likely see it complain about *"dereferencing type-punned pointer will break strict-aliasing rules"* which is what you are doing here.

Basically you are trying to cast an array of four 8-bit values which can have any alignment they like (byte alignment) to a 32-bit float value which needs 4-byte alignment. And the two just don't mesh.

Instead you need to work the other way around - cast a type that has smaller alignment requirements over the type that has larger requirements.

So instead of getting 4 bytes and trying to fill them as a float you get a float and read it as 4 bytes:

```
byte *b = (byte *)&floatVal;

```

Then you can access b\[0\] to b\[3\] quite happily.

Another way to do it is with a union:

```
union {
    float fval;
    byte bval[4];
} floatAsBytes;

floatAsBytes.fval = floatVal;
EEPROM.write(0, floatAsBytes.bval[0]);
EEPROM.write(1, floatAsBytes.bval[1]);
EEPROM.write(2, floatAsBytes.bval[2]);
EEPROM.write(3, floatAsBytes.bval[3]);

```

Also, in your code, you only allocated enough room for 3 bytes, not 4...
> 1 votes

# Answer
You are getting exactly what you said you want. 4 bytes representing the number in float format.

What you are expecting to get, is 4 bytes representing the number in big-endian integer format.

Using Majenkos solution for casting, you need to change the types and reverse the `for` loop for big-endinaness.
I also used `int32_t` because the size of the `int` is 16-bit (2-byte) on the Arduino Uno (and other ATMega based boards) and on the Arduino Due it's 32-bit (4-byte). Its better to define the exact `int` in this case.

```
union {
    int32_t ival;
    byte bval[4];
} int32AsBytes;

void writeInt32(unsigned int addr, int32_t x)
{
    int32AsBytes.ival = x;
    for(int i = 3; i >= 0; i--) // reverse for big-endian
    {
        i2c_eeprom_write_byte(0x57, addr, myFloat.bytes[i]); // Write byte to EEPROM
        Serial.println(int32AsBytes.bval[i], BIN);  // Debug line
    }
}

```
> 2 votes

# Answer
This mucking around with casts and arrays is far too complex.

See: Reading and Writing Data Structures to EEPROM

The library EEPROMAnything.h will accomplish this.

---

## EEPROMAnything.h

The library just consists of this file. Save into your "libraries" folder under the folder name `EEPROMAnything`.

```
#include <Arduino.h>  // for type definitions
#include <EEPROM.h>

template <typename T> unsigned int EEPROM_writeAnything (int ee, const T& value)
{
    const byte* p = (const byte*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
        EEPROM.write(ee++, *p++);
    return i;
}

template <typename T> unsigned int EEPROM_readAnything (int ee, T& value)
{
    byte* p = (byte*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}

```

---

### Example code

```
#include <EEPROM.h>
#include <EEPROMAnything.h>

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  float foo = 56060066;
  EEPROM_writeAnything (0, foo);

  float bar;
  EEPROM_readAnything (0, bar);

  Serial.println (bar);
  }  // end of setup

void loop ()
  {
  }  // end of loop

```

---

### Output from above

```
56060064.00

```

Note you don't get exactly the same number back. This is because of the precision of 4-bytes floats.

---

After re-reading the question I see you are using I2C EEPROM. That changes the answer a bit, but you can see an adaptation of that library for I2C here. The general idea is the same though.

---

> `i2c_eeprom_write_byte(0x57, addr, myFloat.bytes[i]); // Write byte to EEPROM`

Your code seems to be writing all of the bytes to the same address, I don't know how that could work.
> 1 votes

# Answer
```
union Float {
    float    m_float;
    uint8_t  m_bytes[sizeof(float)];
};

float        pi,pi1;
uint8_t      bytes[sizeof(float)];
uint8_t      bytes1[sizeof(float)];
Float        myFloat;

#include <Wire.h>
#define disk1 0x50    //Address of 24LC256 eeprom chip
void setup(void)
{
  unsigned int address = 0;
  Serial.begin(9600);
  Wire.begin();
  pi = 300.78;
  Serial.println("*******************************************");
  Serial.println("pi = "+ String(pi));
  Serial.println("***** Conversion by using type casting *****");
  *(float*)(bytes) = pi;
  for(int i=0;i<4;i++) Serial.println( bytes[i]);
  Serial.println("*******************************************");
  for( int i=0;i<4;i++){
      writeEEPROM(disk1, address, bytes[i]);
      address=address+sizeof(bytes[i]);
  }
   address=0;
   for( int i=0;i<4;i++){
      bytes1[i]=(readEEPROM(disk1, address));
      address++;
      Serial.println(bytes1[i]);
   }
   Serial.println("************Conver Byte to Float*************************");
 pi1 = *(float*)(bytes1);
 Serial.println("pi = "+String( pi1));
 Serial.println("********* Conversion by using union *********");
 myFloat.m_float = pi1;   // assign a float to union
 Serial.println("myFloat.m_Float = "+String( myFloat.m_float));
 Serial.println("myFloat.m_Bytes = "+String(myFloat.m_bytes[0])+String(myFloat.m_bytes[1])+String(myFloat.m_bytes[2])+String(myFloat.m_bytes[3]));  // get the bytes
}
void loop(){}
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB  Wire.send(data);
  Wire.write(data);
  Wire.endTransmission();
  delay(5);
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{

```
> -1 votes

---
Tags: float, byte-order
---


# Question
Title: Sending multiple byte data from Arduino as Slave on SPI
I have been working around the teardown of an induction cooktop and thought of having a tweak in the system. So far, I have deduced following circuitry out of the cooktop- There are two devices communicating with each other in 3-wire SPI mode. The master, which controls power management and Induction circuitry, continuously sends commands and data to the slave. The slave, which is TM1628, receives the master commands and data, then accordingly displays the data on the seven segment or responds with the switch pressed, if any.

The above picture explains it better. Now, I thought of replacing TM1628 with an Arduino. So far so good. I gathered all the data that was being sent by the master and the reply sent by the slave.

But, when I started to code, I got stuck in one place. So the data as sent by the master and its response looks like this -

**(Master to Slave)\**Command1 - Command2 - Data1 - Data2 - ... - Data 14 - Command1 - Command2 - \**(Slave to master)\**Data1 - Data2 - ... - Data5 - \**(And now the repetition)**

When the master is sending the data, I have no issues as the data will continuously be read by Arduino and I can take the action accordingly. But when the Arduino (Working as a slave) needs to send continuously 5 streams of data, depending only on the clock input timing from the master, how could I know that one stream has been written and now the next data has to be written to the SPDR register.

# Answer
> 1 votes
With SPI there is no such thing as "sending" and "receiving". It is a full duplex operation every time. Whenever the master runs the clock the slave both receives bits from the master *and simultaneously* sends bits *to* the master.

These operations are inseparable.

Whatever mechanism you are using to recognise "A byte has arrived from the master" is the *same* mechanism that you use for filling the SPDR register. The bytes where you "send" data to the master are actually bytes where the master is sending *you* data, but you don't care about what that data is. Just like when the master is sending you "commands" you are sending the master data (which you haven't specified) and the master "doesn't care" what that data is.

It's up to you to keep track of how many bytes the master has clocked in and out, and to say "For bytes 19-23 the master is expecting valid data, so I need to make sure that I put data into the SPDR for those bytes".

---
Tags: communication
---


# Question
Title: Header file or library to test i2c FRAM?
I found a header file to test a i2c eeprom 24LC256, but I used this to test my eeprom CAT24C32.The test sketch works fine. I modified the line BLOCKSIZE 8 because my eeprom have 32byte page write only.

I have also a FRAM MB85RC256V, I am wondering if can I use the same header to test the FRAM. I saw the command byte write are same like eeprom, but the page write have a different side of buffer, it says have 32Kbytes. Can I use it?

If I made a mistake please help me. Thanks very much!

Here the .h

```
#ifndef  EEPROM_ROUTINES
#define  EEPROM_ROUTINES

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif
#include <Wire.h>

#define BLOCKSIZE 8
#define I2CADDR 0x57
#define BLOCKSIZE_READ 30

template <class T>
uint16_t writeObjectSimple(uint8_t i2cAddr, uint16_t addr, const T& value){

      const uint8_t* p = (const uint8_t*)(const void*)&value;
      uint16_t i;
      for (i = 0; i < sizeof(value); i++){
            Wire.beginTransmission(i2cAddr);
                  Wire.write((uint16_t)(addr >> 8));  // MSB
                  Wire.write((uint16_t)(addr & 0xFF));// LSB
                  Wire.write(*p++);
            Wire.endTransmission();
            addr++;
            delay(5);  //max time for writing in 24LC256
      }
      return i;
}

template <class T>
uint16_t readObjectSimple(uint8_t i2cAddr, uint16_t addr, T& value){

            uint8_t* p = (uint8_t*)(void*)&value;
            uint8_t objSize = sizeof(value);
            uint16_t i;
            for (i = 0; i < objSize; i++){
                  Wire.beginTransmission (i2cAddr);
                        Wire.write((uint16_t)(addr >> 8));  // MSB
                        Wire.write((uint16_t)(addr & 0xFF));// LSB
                  Wire.endTransmission();
                  Wire.requestFrom(i2cAddr, (uint8_t)1);
                  if(Wire.available()){
                        *p++ = Wire.read();
                  }
                  addr++;
            }
            return i;
}

template <class T>
uint16_t writeObject(uint16_t addr, const T& value){
      const uint8_t* p = (const uint8_t*)(const void*)&value;

      Wire.beginTransmission(I2CADDR);
      Wire.write((uint16_t)(addr >> 8));        // MSB
      Wire.write((uint16_t)(addr & 0xFF));      // LSB

      //in the loop: counts the bytes we may send before
      //our block becomes full
      //but initialise it to the number of bytes up to the
      //next 16-byte aligned address
      uint8_t blockBytes = (addr/BLOCKSIZE + 1)*BLOCKSIZE - addr;
      uint16_t i;
      for (i = 0; i < sizeof(value); i++){
            if (blockBytes == 0){
                  //block is full;
                  Wire.endTransmission(); //dispatch the buffer
                  delay(5);
                  //restart new block
                  addr = (addr/BLOCKSIZE + 1)*BLOCKSIZE;
                  blockBytes = BLOCKSIZE;
                  Wire.beginTransmission(I2CADDR);
                  Wire.write((uint16_t)(addr >> 8));  // MSB
                  Wire.write((uint16_t)(addr & 0xFF));// LSB
            }
            Wire.write(*p++); //dispatch the data byte
            blockBytes--;     //decrement the block space
      }
      Wire.endTransmission();
      delay(5);   //required write delay 5ms
      return i;
}

template <class T>
uint16_t readObject(uint16_t addr, T& value){
      uint8_t* p = (uint8_t*)(void*)&value;

      Wire.beginTransmission(I2CADDR);
            Wire.write((uint16_t)(addr >> 8));        // MSB
            Wire.write((uint16_t)(addr & 0xFF));      // LSB
      Wire.endTransmission();

      //counts the bytes we may read before buffer is depleted
      uint8_t   blockBytes = 0;
      uint16_t  objSize = sizeof(value);
      uint16_t  i;
      for (i = 0; i < objSize; i++){
            if (blockBytes==0){
               //we need a new block
               blockBytes = BLOCKSIZE_READ;
               if (objSize < blockBytes) blockBytes = objSize;
               //get the new block
                Wire.requestFrom((uint8_t)I2CADDR, blockBytes);
            }
            if(Wire.available()){
                  //read a byte from buffer
                  *p++ = Wire.read();
                  blockBytes--;
            }
      }
      return i;
}

#endif

```

Here the skecth to test eeprom

```
#include <Wire.h>
#include "eeprom_routines.h" //definitions of the functions:
                             //writeObject, readObject,
                             //writeObjectSimple, readObjectSimple
#define BLOCK_OPERATIONS 0

#if BLOCK_OPERATIONS>0
  #define __WRITE__(ad, obj) writeObject(ad,(obj))
  #define __READ__(ad, obj) readObject(ad,(obj))
#else
  #define __WRITE__(ad, obj) writeObjectSimple(0x57,ad,(obj))
  #define __READ__(ad, obj)  readObjectSimple(0x57,ad,(obj))
#endif
#define MEM_ADDR_MULTI 3458

//This is the structure we write and read from EEPROM
class MyData{
      long result;
public:
      float  f1;
      float  f2;
      double f3;
      int    i1;
      long   i2;
      long   i3;
      bool  negative;

      long getResult(){
            return result;
      }
      long calcResult(){
            //makes a calculation with its data
            //and stores the result to a private variable
            long    i = (i2+i3)/i1;
            double  f = f3/(f1+f2);
            result = f/i;
            //round off
            result += result>0 ? 0.5 : -0.5;
            if (negative) result=-result;
            return result;
      }
      MyData() : result(0){   }
};

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

      MyData data[5];

      //data[0] - result should be 20
      data[0].i1 = 10;
      data[0].i2 = 150000;
      data[0].i3 = 350000;
      data[0].f1 = 0.5;
      data[0].f2 = 2.5;
      data[0].f3 = 3.0E+6;
      data[0].negative = false;

      //data[1] - result should be -40
      data[1].i1 = data[0].i1;
      data[1].i2 = data[0].i2;
      data[1].i3 = data[0].i3;
      data[1].f1 = data[0].f1;
      data[1].f2 = data[0].f2;
      data[1].f3 = 2*data[0].f3;
      data[1].negative = true;

      //data[2] - result should be 80
      data[2].i1 = data[0].i1;
      data[2].i2 = data[0].i2;
      data[2].i3 = data[0].i3;
      data[2].f1 = data[0].f1;
      data[2].f2 = data[0].f2;
      data[2].f3 = 4*data[0].f3;
      data[2].negative = false;

      //data[3] - result should be -20
      data[3].i1 = data[0].i1;
      data[3].i2 = -data[0].i2;
      data[3].i3 = -data[0].i3;
      data[3].f1 = data[0].f1;
      data[3].f2 = data[0].f2;
      data[3].f3 = data[0].f3;
      data[3].negative = false;

      //data[4] - result should be -2
      data[4].i1 = data[0].i1;
      data[4].i2 = -data[0].i2;
      data[4].i3 = -data[0].i3;
      data[4].f1 = data[0].f1*10;
      data[4].f2 = data[0].f2*10;
      data[4].f3 = -data[0].f3;
      data[4].negative = true;

      Serial.println ("Data before writing to eeprom");
      for (int i=0; i<5; i++){
            data[i].calcResult();
            Serial.print("data-"); Serial.print(i);
            Serial.print(": result = ");
            Serial.println(data[i].getResult());
      }
      Serial.print("Size of each object: ");
      Serial.println(sizeof(MyData)) ;

      Serial.println ("Writing data to eeprom");
      int memaddr = MEM_ADDR_MULTI;
      long t0 = millis();
      for (int i=0; i<5; i++){
            memaddr += __WRITE__(memaddr, data[i]);
      }
      long t1 = millis();
      Serial.print ("...writing finished. Elapsed time: ");
      Serial.println(t1-t0);
      delay(1000);

      Serial.println ("Reading data from eeprom");
      MyData read[5];
      t0 = millis();
      memaddr = MEM_ADDR_MULTI;
      for (int i=0; i<5; i++){
            memaddr += __READ__(memaddr, read[i]);
      }
      t1 = millis();
      Serial.print ("Time to read: "); Serial.println(t1-t0);

      for (int i=0; i<5; i++){
            Serial.print ("Read object: #");
            Serial.println(i);
            long storedResult = read[i].getResult();
            Serial.print ("  >stored result = ");
            Serial.println(storedResult);
            long newResult = read[i].calcResult();
            Serial.print ("  >recalculated result = ");
            Serial.println(newResult);
            if (storedResult== newResult &&
                  storedResult==data[i].getResult() )
                  Serial.println ("SUCCESS");
            else  Serial.println ("FAIL");
      }
}

void loop() {
}

```

Here the serial output of eeprom CAT24C32 test

```
Data before writing to eeprom
data-0: result = 20
data-1: result = -40
data-2: result = 80
data-3: result = -20
data-4: result = -2
Size of each object: 27
Writing data to eeprom
...writing finished. Elapsed time: 126
Reading data from eeprom
Time to read: 15
Read object: #0
  >stored result = 20
  >recalculated result = 20
SUCCESS
Read object: #1
  >stored result = -40
  >recalculated result = -40
SUCCESS
Read object: #2
  >stored result = 80
  >recalculated result = 80
SUCCESS
Read object: #3
  >stored result = -20
  >recalculated result = -20
SUCCESS
Read object: #4
  >stored result = -2
  >recalculated result = -2
SUCCESS

```

# Answer
> 1 votes
At Fujitsu's site is said

> Furthermore, applications that have used other products with I2C interfaces, such as EEPROMs and microcontrollers, can now replace EEPROMs, with the new FRAM products

So you can use it without any modifications in your code.

---
Tags: i2c, eeprom
---


# Question
Title: Optimizing code to use less Flash Memory and SRAM
I'm trying to reduce my sketch size and managed to reduce both SRAM and Flash memory.

```
From:
1570 SRAM - 32144 Flash memory
To:
644  SRAM - 19458 Flash memory

```

This are what I've done so far:

Enabling LTO

Using PROGMEM

Dropping `string` and using `char`

Dropping bootloader

Using port manipulation

Using registers to declare pins output/input

Removing/Optimizing/Combining; unnecessary/repeated codes in the sketch

*Using EEPROM is not an option for me.*

What else i can do to take optimization one or two step further?

# Answer
What you can do in addition to the items you mentioned:

**SRAM reduction**

* Use the smallest amount of data type for integers, e.g. use an 8 bit data type instead of the default integer, this saves you one byte for every variable. See remark below about types. I made my own types (if not existing) for int32\_t, uint32\_t, int16\_t, uint16\_t, int8\_t and uint8\_t and always use the smallest possible.
* Use unsigned instead of signed for types that cannot be negative. This might save you one byte if you can prevent using an unsigned byte instead of a signed int because a value can be in range \[128..255\]. The same for unsigned int instead of signed long.
* Use bit fields if you use multiple booleans inside a struct or class. Make sure the bit fields are declared consecutively.
* Pack data in smart structures ... I.e. if you have two variables, where one can be 0..7 and another can also be 0..7, store this together using bit fields (in combination with boolean to bit field above).
* Prevents float/doubles (see KIIV's comment below), instead:
* Instead of using a float, multiply the value by the needed accuracy and store it in an integer (if you don't need high accuracy and it fits in the integer type).
* In case you need a lot of strings to be stored, and those strings do not have characters above 128, you can save 1 bit per byte, of course this means quite some programming work to handle 7 bits 'ASCII' characters.
* The same, if you have to store a lot of values that can be e.g. 0 to 50, you can use 6 bits instead of 8 bits; you cannot use bit fields, but you can make a smart array and program your own get/set functions to access the 6 bit values.
* If you use libraries which declare big buffers, try to minimize those buffers, this might cause to copy them and manually change them yourself.
* Prevent your own buffers to be made global, instead use them as a local variable temporarily when you need them. If you have two of such buffers, you don't have both buffers allocated at the same time; note however, that during execution, that buffer still needs space (so you have to calculate or make a guess/estimation what the maximum stack size will be).

**Flash Reduction**

* Don't use duplicated code blocks, but make functions with parameters to differ between the differences of the duplicated code.
* Instead of lookup tables, create a function that calculates it (if possible). Of course the gain depends on the length of the lookup table and the length of the function.
* Instead of debugging strings, use numbers.

**Both SRAM/Flash Reduction**

* Split your application over multiple MCUs, of course this adds some kind of communication protocol (UART, I2C, SPI).
> 5 votes

# Answer
*I'm having flashbacks to my early days as a C programmer in the 80's.*

Some thoughts in addition to all of the excellent advice already given ...

* Depending on how much data your application uses, you may want to read / write data to an SD card (or other external storage). While there is a certain amount of overhead for the libraries, the payoff is you then have virtually unlimited storage. This is the equivalent of how we used to store data on 5 1/4" diskettes back in the old days.
* Avoid static variables whenever possible.
* Keep the scope of a variable as small as possible.
* As a philosophy you should consider `unsigned char` to be your default data type and only 'upgrade' to a bigger footprint when your code requires.
> 0 votes

---
Tags: programming, sketch-size
---