# Question
Title: Remotely uploading code to an Arduino board over the internet
I recently used Particle Photon that allows me to upload firmware (.bin file) remotely over the internet.

I would like to use something like this for my Arduino but I cannot find anything like that. Does anyone know any possible way to upload firmware to my Arduino board remotely connected to internet via Ethernet shield of any WiFi module?

# Answer
> 5 votes
You can upload to your Arduino board over Ethernet if you flash it with a special bootloader named Ariadne.

You will need an Ethernet module or shield that uses the W5100, W5200, or W5500 Ethernet controller chip. You can not use the ENC28J60 Ethernet controller with Ariadne.

You will need an ISP programmer to burn the Ariadne bootloader to your Arduino board. If you don't own an ISP programmer, you can use a spare Arduino board as an "Arduino as ISP" programmer. If you're going to purchase an ISP programmer, I recommend the 6 pin USBasp. The USBasp works well with the Arduino IDE and is very reasonably priced. You can buy them on eBay.

A description of how the Ariadne upload over Ethernet process works:

1. Compile the sketch you want to upload.
2. Use avr-objcopy to convert the .hex file of the sketch generated from the Arduino IDE compilation into a binary (.bin) file.
3. Reset the Arduino board to activate the bootloader code. You could do this by pressing the reset button on the board but the need to have physical access to the board negates much of the advantages of uploading over Ethernet. For this reason, the upload will typically be accomplished by sending a command to your Arduino board which triggers the application to reset the microcontroller by activating the watchdog timer and then allowing it to time out. There is a library named EthernetReset bundled with the Ariadne hardware package for this purpose, but you can easily implement your own solution if you have other needs.
4. Start a TFTP upload of the .bin file to the IP address of your Arduino board within the 10 seconds that the bootloader is activated after the reset. The upload doesn't need to finish within the 10 second window, it only needs to start.

You can get the Ariadne bootloader, as well as detailed instructions, here: https://github.com/loathingKernel/ariadne-bootloader

# Answer
> 1 votes
This will do it. ESP8266 as wireless AVR (arduino) ISP programmer.

https://github.com/rene-win/esp\_avr\_programmer

or

https://github.com/jeelabs/esp-link

The ESP8266 can be programmed with the Arduino IDE. So it can be used for a lot of Arduino projects. And it can be OTA (Over The Air) programmed as well.

https://arduino-esp8266.readthedocs.io/en/latest/ota\_updates/readme.html

---
Tags: arduino-uno, arduino-mega, ethernet, firmware
---


# Question
Title: Control I2C relay board from two Arduino Uno
how can I make multi master Arduino device to work with single I2C device? As both the master device are 20 m away from Slave device,

I am using the I2C relay board to connect with 2 Arduino boards and need to connect I2C device and create the two way switching technique from this.

Any suggestions here will be a great help.

# Answer
> 3 votes
What you want is to operate in *multi-master* mode. This is a supported configuration of I2C - however the Arduino API has no support for it.

It involves each master identifying if a collision has occurred and stopping transmission if it has - to then retry transmission later on.

The Arduino hardware can do it, but the software can't. You would have to bypass the software and control the I2C interface yourself (or locate a better library than the Wire library that supports multi-master).

# Answer
> 1 votes
The answers by Majenko and chrisl are far too optimistic in my opinion.

A distance of 20 meters is not possible. The I2C bus can be 20 cm or 50 cm.

There is no library that supports a multi-master bus for the Arduino Uno.

You have to change your project. Make one Arduino board the Master, and let the Master retrieve data from the other board and the Master writes to the relay board. You need a bus capable of such a distance or use wireless. The RS-485 bus has no problems with 20 meters. Adafruit has a number of RFM69 modules, those should have no problem with 20 meters.

---

There are chips that translate the I2C bus signals into differential signals that can be used with a twisted pair cable (for example a cheap Cat5 ethernet cable). The SparkFun Differential I2C Breakout makes it easy to put a I2C device at a longer distance.
(*Thanks to @PimV for this addition*).

# Answer
> 0 votes
The `Wire` library has no complete multi-master support (as I remember). You can join the bus as slave and becoming master by using the master functions for the time of these transmissions (on execution of `endTransmission()` the master style I2C transmission is started. When it's finished the library will change to slave again). But you will run into problems, when the two masters send at the same time.

The I2C protocol incorporates a technique named bus arbitration. When two masters write to the bus at the same time, the first one to write a `1` on the bus, must retreat from transmission and become slave again. Unfortunately it seems, that the `Wire` library doesn't implement this.

So you might not run into problems, until the master are sending simultaneously. Depending on what the Arduinos also have to do, you may be able to recover from such a condition by using the Watchdog Timer to reset both masters, when they are stuck there.

Or you try to find a good I2C/TwoWire library, that works for Arduino and has Bus arbitration implemented.

---

Sidenote: 20m is quite a long distance for I2C. It is designed for short distances, mostly on the same PCB (hence it is called Inter Integrated Circuit, short IIC or I2C). You may not run into issues, but you should keep this in mind. The bus will have a greater capacitance and you may need strong pullup resistors.

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


title: Unexpected behavior of ++myCount

text:
# Question
Title: Unexpected behavior of ++myCount
I'm new to Arduino and C. This behavior is not what I'd expect:

```
Serial.begin(9600);
while ( ! Serial );

int myCount = 0;

for (int i=0; i<10; i++) {
    myCount = min( ++myCount, 8 );
    Serial.print( myCount );
    Serial.print( "  " );
}

```

I would expect:

```
1  2  3  4  5  6  7  8  8  8

```

But I get:

```
2  4  6  8  8  8  8  8  8  8

```

Why is my code counting by 2?

# Answer
> 5 votes
Jaromanda X is indeed correct - `min()` is defined on line 92 of Arduino.h, thusly:

```
#define min(a,b) ((a)<(b)?(a):(b))

```

Therefore when the `++mycount` is substituted for the `a`, it is in fact substituted *twice*, in both the `(a)<(b)` *and* the `(a):(b)`, leading to the increment by 2, each time `min(++mycount,8)` is executed.

As VE7JRO mentions, as it is defined in this way, the reference for `min(x,y)` states:

> **Warning**
>
> Because of the way the min() function is implemented, avoid using other functions inside the brackets, it may lead to incorrect results
>
> ```
> min(a++, 100);   // avoid this - yields incorrect results
>
> min(a, 100);
> a++;            // use this instead - keep other math outside the function
>
> ```

As the second example states, keep *any* incrementing *outside* of the `min()` macro.

Alternatively, I think that you could use the `inline` function to workaround this issue:

```
#undef min
inline int min(int a,int b) {return ((a)<(b)?(a):(b)); }

```

Because `inline` provides a *real* function call (with parameters) it avoids the use of macros and substitution, which gives rise to the issue that you encountered.

`inline` is a much better (safer) way to implement the functionality provided by macros, in many cases. For more information, see Inline functions in C++ or read a C++ reference.

---
Tags: programming
---


title: Arduino MEGA Timer Help

text:
# Question
Title: Arduino MEGA Timer Help
Nick Gammon posted some code to setup a counter on an Arduino UNO using timer2 to generate a 38KHZ signal, and I've used it on several IR projects.

On my current project, I'm using FreeRTOS for the Arduino, and the source says it uses timers 0-3 for its own kernel operation, so the timer code obviously will interfere with the RTOS.

I'm using an Arduino MEGA for this project, and AFAICT it also has a timer4 and timer5. Unfortunately, my programming ability for the ATMel products is lacking at that level, so I'm looking for some help to create a timer that will generate a 38KHZ output using timer4 or timer5 of the MEGA 2560 on any output pin. Interrupts shouldn't be used because it would also probably cause issues with RTOS.

BTW, on the Arduino MEGA, you can do a context switch between tasks in less that 200usec, and be able to determine what task YOU want to execute next.

# Answer
> 0 votes
Using a pre-emptive Real Time Operating System on a Arduino board with a AVR microcontroller (Arduino Uno, Leonardo, Mega 2560) is an academic exercise.

The FreeRTOS is reliable, and for someone that is used to write multitasking code, it can be useful.
In my opinion, the FreeRTOS does not match with the simple AVR Arduino boards:

* Not enough ram memory.
Every task gets its own stack. The ram memory is limited on a AVR board. That means that every task should be written very careful to limit the stack usage.
* Not enough ram when the fun is about to start.
When there are a few tasks and perhaps a few interrupt routines, then a number of buffers and message queues are needed. There is not enough ram memory for that.
* The Arduino was not developed with a multitasking system in mind.
The Arduino libraries are not suitable for that. Some functions wait for something (Serial.parseInt, Wire.requestFrom, Wire.endTransmission) and that makes a RTOS work worse than expected.
* The FreeRTOS is large, it requires memory and cpu time.

Without FreeRTOS, some known techniques are very efficient for the AVR Arduino boards:

* A Finite State Machine uses very little ram memory.
A Finite State Machine without `delay()` that uses `millis()` can be very responsive.
* Avoiding interrupt routines.
It is often possible to avoid interrupt routines. Reading buttons can often be done by polling the buttons in the `loop()`.
* Avoiding the String object and moving text into PROGMEM can be used to have enough memory for a more complex and reliable sketch.

At this moment the "FreeRTOS by Richard Barry" is in the Library Manager. It is a smaller version of FreeRTOS and it only uses the WatchDog timer. It has no conflict with Arduino libraries.

A larger FreeRTOS version and many examples can be found at https://github.com/feilipu/avrfreertos
Not every version of FreeRTOS uses the WatchDog timer. Look for the file `FreeRTOSBoardDefs.h` to see which timer is used for your specific Arduino board.

crusader27529, I don't see a problem to remove the FreeRTOS and call the three tasks sequencially.

```
void loop() {
  task1();
  task2();
  task3();
}

```

---
Tags: arduino-mega
---


title: Defining array in switch case

text:
# Question
Title: Defining array in switch case
I’m completely new to arduino, so be polite. I’m trying to program my esp32 to drive neopixels as seven segment display. So I take a digit and pass it to switch case and in switch case I mention which led number should be lit. \`

```
function showDigits(digit){

switch(digit){

 case 1:
   int a[]={1,3,4,.....};
  break;

 case 2:
    int a[]={1,3,4,6,8,...};
   break;
  .
  .
  .
default:
   int a[]={1,2,3,4,5,6,7,8,9,....};
  }
}

```

Now this is throwing multiple errors including redeclare of array a in same scope. Is there any better way to code this?

# Answer
If you want to declare multiple variables with the same name inside different case statements, you can enclose the code inside each of them inside curly braces:

```
case 1:{
    Code...
break;}
case 2:
...

```

The curly braces will set the limits for the variables scope to just this case.
> 3 votes

# Answer
While I don't discourage you from doing it yourself. I would go the easy route and use an available library. As is, or if need be, after modifying it. For me, it is the better way as I'm not that good at programming.

https://learn.adafruit.com/adafruit-neopixel-uberguide/neomatrix-library

And this looks good.

**FastLED NeoMatrix**

> Better support for ESP32 than Adafruit::Neopixel

https://github.com/marcmerlin/FastLED\_NeoMatrix
> 0 votes

# Answer
I see several issues with your code.

First one is the issue of "scope". If you define the `int a[]` inside the `switch` it will be destroyed as soon as the `switch` will finish and no code that runs outside of its brackets will be able to access it.

I also think that array of `integers` is the wrong choice here. It would be much less memory consuming to use array of `boolean` that mean if each LED should be lit or not. You can use it later like that:

```
if (a[4]) { digitalWrite(LED4, HIGH); } else { digitalWrite(LED4, LOW); }

```

or even better using "ternary operator":

```
digitalWrite(LED4, (a[4] ? HIGH : LOW));

```

Third problem is that your function is incorrectly defined and it does not contain any type information. This is C and not Python so the types are EXTREAMLY important! The correct definition of your function should be:

```
void showDigits(int digit)

```

Take a look at this example that compiled correctly:

```
void showDigits(int digit)
{
  bool a[6] = {false, false, false, false, false, false};
  switch (digit)
  {
    case 1:
      a[0] = true;
      a[1] = false;
      break;
    case 2:
      a[1] = false;
      break;
    default:
      a[0] = true;
  }

  if (a[4]) {
    digitalWrite(4, HIGH);
  } else {
    digitalWrite(4, LOW);
  }
};

```

The `switch..case` is a very particular syntax. If you don't use the `break;` at the end of a `case` the execution will actually continue to next `case` definition, and compiler told you that you tried to define `int a[]` several times in the same scope. (which is a no-no)
> 0 votes

---
Tags: arduino-ide, switch, esp32
---


# Question
Title: How can I connect nearly 450 LEDs to an arduino without drawing too much current?
The question seems simple, but there's more to it:

I'm connecting 4 74HC595 shift-registers to an arduino pro micro. 28 of the 32 outputs will be used to control LED segments of numbers. Each segment uses 14-20 LEDs and so I will be using a transistor for each segment. Now here's my problem: With the maximum amount of LEDs activated (at time 08:08), the LEDs will draw nearly 10A. How can I use another transistor to make the shift-registors work with the arduino even though it shouldn't be drawing all current from the arduino, but from an external power source. I have found a suitable adapter from 230V to 5V 12A. The 12A is just to ensure that nothing goes wrong. The LEDs alone will draw 9.76A.

I know how to connect the arduino to the power source, but how do I run extra wires from the power source around the arduino to provide the LEDs their power?

# Answer
> 5 votes
First you should consider changing your whole idea so that your LEDs don't draw nearly 10A.

I am assuming that for each segment you have 14-20 LEDs wired in parallel, each with its own current limiting resistor. That is very wasteful.

Instead you should be grouping the LEDs in chains of series LEDs which you then place in parallel.

Assuming you have normal red LEDs with a forward voltage of around 2V and a typical current draw for maximum brightness of 20mA, you can connect them up in chains of, say, 5 LEDs with one current limiting resistor, and power them from 12V not 5V.

3 chains of 5 LEDs (15 LEDs) would be 3x20mA = 60mA per segment. 4 chains of 5 LEDs (20 LEDs) would be 4x20mA = 80mA.

With 08:08 displaying that's 26 segments plus dots. Assuming each segment has 20 LEDs that's a total of 26x4 = 104 chains of 5 LEDs, totalling 520mA.

And then you should do away with the resistors as well, and use constant current LED sinks, such as the TLC59116, which can handle the higher input voltage.

If you don't want to do that, then more transistors will be needed:

simulate this circuit – Schematic created using CircuitLab

I have only showed 2 digits, 2 segments, 2 chains per segment, and 2 LEDs per chain to save space.

To drive it you need 1 GPIO per segment in one digit and 1 GPIO per digit. So for 4 digits at 7 segments that's 11 GPIO.

# Answer
> 1 votes
simulate this circuit – Schematic created using CircuitLab

Change the 74HC595 to TPIC6B595. Each output can sink 150mA from up to a 50V source. Strings of 3 LEDs in parallel powered from a 12V source (with current limit resistor per string) are easily handled, no extra transistors are needed. The 12V positive goes to the + of each string (the top anode), the - (bottom cathode) goes to the TPIC6B595 output. Here is a video of 8 TPIC6B595s running displays made two strings of 3 LEDs in parallel for the large digits, one string of 3 LEDs for the small digit. https://www.youtube.com/watch?v=6HZ0Mr51jUY Each string draws 25 or so mA. The board that drives the display holds up to 12 shift register chips and is controlled by an Atmega328P set up like an Arduino.

The shift registers are easy to use as well. I use SPI.transfer to send data to them. Create an array to map the shift register outputs to the segments:

```
byte fontArray[] = {
    0b00111111, // 0 with the bits mapped to segments DP-g-f-e-d-c-b-a
    0b00000110, // 1   0 = segment off, 1 = segment on
    etc.
}

```

The digit layout:

```
    a
f       b
    g
e       c
    d       and DP if used.

```

Then to update the display, say you have 4 shift registers all daisy chained:

```
digitalWrite (ssPin, LOW);
SPI.transfter(fontArray[digit0]);
SPI.transfter(fontArray[digit1]);
SPI.transfter(fontArray[digit2]);
SPI.transfter(fontArray[digit3]);
digitalWrite (ssPin, HIGH); // all outputs update on this rising edge

```

Dirt simple really. No need for a Mega.

---
Tags: led, transistor, arduino-pro-micro
---


title: 4 digit 7 segments display wrong number

text:
# Question
Title: 4 digit 7 segments display wrong number
I'm an Arduino newbie having problems with 4 digit 7 segments display. I want to display some thousands to 4 digit 7 segments display but it display only 0000. I want to receive data from serial with string. And display the data to 4 digit 7 segments display... So test make String = '2575'... but it's not work. What's wrong in my codes? Any suggestions here will be a great help. thanks

```
int segments[] = {A0, A1, A2, A3};

byte digits[10][7] =
{
  { 1,1,1,1,1,1,0 }, // 0
  { 0,1,1,0,0,0,0 }, // 1
  { 1,1,0,1,1,0,1 }, // 2
  { 1,1,1,1,0,0,1 }, // 3
  { 0,1,1,0,0,1,1 }, // 4
  { 1,0,1,1,0,1,1 }, // 5
  { 1,0,1,1,1,1,1 }, // 6
  { 1,1,1,0,0,0,0 }, // 7
  { 1,1,1,1,1,1,1 }, // 8
  { 1,1,1,0,0,1,1 }  // 9
};

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

  for(int i=2;i<10; i++) {
    pinMode(i, OUTPUT);
  }

  for(int i=0; i<4; i++) {
    pinMode(segments[i], OUTPUT);
  }
}

void loop() {
  String IncomingData = "2575";

  for(int i=0; i<4; i++) {
    digitalWrite(segments[i], LOW);
    int digit = atoi(IncomingData[i]);
    displayDigit(digit);
    delay(5);
    digitalWrite(segments[i], HIGH);
  }
}

void displayDigit(int num){
  int pin = 2;
  for(int i=0;i<7;i++){
    digitalWrite(pin+i, digits[num][i]);
  }
}

```

# Answer
You call `atoi()` with a char. Parameter of `atoi` is `const char*`. To convert ASCII code of digit to the digit use

`int digit = IncomingData[i] - '0'`
> 1 votes

---
Tags: arduino-uno, 7-segment
---


# Question
Title: How to add if condition in RFID example?
Using an Arduino Mega 2560 and PN532 NFC/RFID module, I want to be able to scan a card and see if its value is (0xF0, 0x21, 0x5D, 0xA7). It should print `"accepted"` in the serial monitor.

However during compilation it keeps telling me:

```
iso14443a_uid:99:11: error: expected primary-expression before ']' token

if (uid[] = {0xF0, 0x21, 0x5D, 0xA7}){
        ^

exit status 1 expected primary-expression before ']' token

```

This is my code:

/\**************************************************************************/ /\*! This example will attempt to connect to an ISO14443A card or tag and retrieve some basic information about it that can be used to determine what type of card it is.

```
    Note that you need the baud rate to be 115200 because we need to print
    out the data and read from the card at the same time!

    To enable debug message, define DEBUG in PN532/PN532_debug.h

*/
/**************************************************************************/

/* When the number after #if set as 1, it will be switch to SPI Mode*/
#if 0
  #include <SPI.h>
  #include <PN532_SPI.h>
  #include "PN532.h"

  PN532_SPI pn532spi(SPI, 10);
  PN532 nfc(pn532spi);

/* When the number after #elif set as 1, it will be switch to HSU Mode*/
#elif 0
  #include <PN532_HSU.h>
  #include <PN532.h>

  PN532_HSU pn532hsu(Serial1);
  PN532 nfc(pn532hsu);

/* When the number after #if & #elif set as 0, it will be switch to I2C Mode*/
#else
  #include <Wire.h>
  #include <PN532_I2C.h>
  #include <PN532.h>
  #include <NfcAdapter.h>

  PN532_I2C pn532i2c(Wire);
  PN532 nfc(pn532i2c);
#endif

void setup(void) {
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }

  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // Set the max number of retry attempts to read from a card
  // This prevents us from waiting forever for a card, which is
  // the default behaviour of the PN532.
  nfc.setPassiveActivationRetries(0xFF);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A card");
}

void loop(void) {
  boolean success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);

  if (success) {
    Serial.println("Found a card!");
    Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("UID Value: ");
    for (uint8_t i=0; i < uidLength; i++)
    {
      Serial.print(" 0x");Serial.print(uid[i], HEX);
    }
    Serial.println("");
    // Wait 1 second before continuing
    delay(1000);
  }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Timed out waiting for a card");
  }
  if (uid[] = {0xF0, 0x21, 0x5D, 0xA7}){
    Serial.println("Success");
    }
}

```

# Answer
> 1 votes
As has been noted in the comments you can't compare arrays like that. Instead you have to iterate through each entry and compare the individual elements.

If it's just a few entries, then you can do it manually:

```
if ((uid[0] == 0xF0) && (uid[1] == 0x21) && (uid[2] == 0x5D) && uid[3] == 0xA7) {
    // ...
}

```

If your values are both in arrays then you can use the `memcmp()` function to compare them:

```
uint8_t compare[] = {0xf0, 0x21, 0x5d, 0xa7};

if (memcmp(uid, compare, 4) == 0) {
    // ...
}

```

`memcmp` returns 0 if the two arrays match up to the number of bytes given (4 in this case), or a negative or positive number if the one is "less than" or "more than" the other.

---
Tags: arduino-mega, adafruit, rfid, compilation-errors
---


# Question
Title: how to compile arduino sketch from termnial without using arduino ide
I want to know how can I compile and upload the arduino sketch from my terminal instead of using Arduino IDE. I want to use a different IDE for writing code.

# Answer
> 0 votes
As a contributor to Sloeber, an Eclipse Plugin dedicated to Arduino and other micro controllers, I can tell you it's all a matter of using the correct version of `gcc` and provide the correct options.

Even if that might seem simple, it's not like that, so my advice is to download Sloeber and look at the build console output where we print all the statements used to fulfill the build task: you can infer a lot from that.

As Sloeber is also open source, you can also inspect how we create those build commands for the different boards and tool chains.

# Answer
> 0 votes
I have been using PlatformIO for about 2 years now I think. It’s simply amazing.

https://platformio.org

You can use it standalone just for the CLI compile or bundled with VisualCode Studio for a complete IDE solution.

---
Tags: arduino-ide, uploading, ide, upload
---


title: Programming a switching AC current?

text:
# Question
Title: Programming a switching AC current?
I tried using this code to output AC power from one H-bridge and then another, switching every second, but when I connected a motor to it, it just seemed to output direct current. This is the code I was using (by the way, the motor controller I'm using has a max frequency of 20 kHz, so that's not the problem as far as I know):

```
int EnablePin = 8;
int duty;
int PWMPinA;
int PWMPinB;

const byte CPin = 0;  // analog input channel
int CRaw;      // raw A/D value
float CVal;    // adjusted Amps value

void setup() {
  pinMode(EnablePin, OUTPUT);
  pinMode(PWMPinA, OUTPUT);
  pinMode(PWMPinB, OUTPUT);
}

void loop() {

  digitalWrite(EnablePin, HIGH);

  for(duty = 0; duty <= 20000; duty += 1){

    PWMPinA=11;  // Timer2
    PWMPinB=3;
    analogWrite(PWMPinA, 255);
    analogWrite(PWMPinB, 0);
    delayMicroseconds(50);

    if(PWMPinA == 11) {
      PWMPinA = 3;
      PWMPinB = 11;
    } else {
      PWMPinA = 11;
      PWMPinB = 3;
    }

  }
  for(duty = 20000; duty>=0; duty -= 1){

    PWMPinA=6;  // Timer2
    PWMPinB=5;
    analogWrite(PWMPinA, 255);
    analogWrite(PWMPinB, 0);
    delayMicroseconds(50);

    if(PWMPinA == 6) {
      PWMPinA = 5;
      PWMPinB = 6;
    } else {
      PWMPinA = 6;
      PWMPinB = 5;
    }
  }
}

```

# Answer
> 0 votes
Sounds like you have it sorted already but the first major problem with your original code is that you use `PwmPinA` and `PwmPinB` in `setup()`, before they are assigned any values.

I'd be surprised if the compiler didn't warn about that. Never ignore compiler warnings! :-)

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


# Question
Title: vk2828u7g5lf GPS module over SoftwareSerial
So my goal was simple. Trying to get a GPS speed, and show it on a display (later use it to control a stepper motor). I am using the vk2828u7g5lf GPS module from Banggood, which after days of tinkering and trying several tutorials, I managed to make it work with ONLY the following code:

```
    boolean gpsStatus[] = {false, false, false, false, false, false, false};
unsigned long start;

#include <SoftwareSerial.h>
SoftwareSerial gpsSerial(3,2); // RX, TX

void setup()
{
  gpsSerial.begin(9600);
  // START OUR SERIAL DEBUG PORT
  Serial.begin(19200);
  //
  //Settings Array contains the following settings: [0]NavMode, [1]DataRate1, [2]DataRate2, [3]PortRateByte1, [4]PortRateByte2, [5]PortRateByte3,
  //[6]NMEA GLL Sentence, [7]NMEA GSA Sentence, [8]NMEA GSV Sentence, [9]NMEA RMC Sentence, [10]NMEA VTG Sentence
  //NavMode:
  //Pedestrian Mode    = 0x03
  //Automotive Mode    = 0x04
  //Sea Mode           = 0x05
  //Airborne < 1G Mode = 0x06
  //
  //DataRate:
  //1Hz     = 0xE8 0x03
  //2Hz     = 0xF4 0x01
  //3.33Hz  = 0x2C 0x01
  //4Hz     = 0xFA 0x00
  //
  //PortRate:
  //4800   = C0 12 00
  //9600   = 80 25 00
  //19200  = 00 4B 00  **SOFTWARESERIAL LIMIT FOR ARDUINO UNO R3!**
  //38400  = 00 96 00  **SOFTWARESERIAL LIMIT FOR ARDUINO MEGA 2560!**
  //57600  = 00 E1 00
  //115200 = 00 C2 01
  //230400 = 00 84 03
  //
  //NMEA Messages:
  //OFF = 0x00
  //ON  = 0x01
  //
  byte settingsArray[] = {0x03, 0xFA, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //
  configureUblox(settingsArray);
}

void loop()
{
  while(1) {
    if(gpsSerial.available())
    {
    // THIS IS THE MAIN LOOP JUST READS IN FROM THE GPS SERIAL AND ECHOS OUT TO THE ARDUINO SERIAL.
    Serial.write(gpsSerial.read());
    }
  }
}

void configureUblox(byte *settingsArrayPointer) {
  byte gpsSetSuccess = 0;
  Serial.println("Configuring u-Blox GPS initial state...");

  //Generate the configuration string for Navigation Mode
  byte setNav[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, *settingsArrayPointer, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  calcChecksum(&setNav[2], sizeof(setNav) - 4);

  //Generate the configuration string for Data Rate
  byte setDataRate[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, settingsArrayPointer[1], settingsArrayPointer[2], 0x01, 0x00, 0x01, 0x00, 0x00, 0x00};
  calcChecksum(&setDataRate[2], sizeof(setDataRate) - 4);

  //Generate the configuration string for Baud Rate
  byte setPortRate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, settingsArrayPointer[3], settingsArrayPointer[4], settingsArrayPointer[5], 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  calcChecksum(&setPortRate[2], sizeof(setPortRate) - 4);

  byte setGLL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B};
  byte setGSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32};
  byte setGSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39};
  byte setRMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40};
  byte setVTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46};

  delay(2500);

  while(gpsSetSuccess < 3)
  {
    Serial.print("Setting Navigation Mode... ");
    sendUBX(&setNav[0], sizeof(setNav));  //Send UBX Packet
    gpsSetSuccess += getUBX_ACK(&setNav[2]); //Passes Class ID and Message ID to the ACK Receive function
    if (gpsSetSuccess == 5) {
      gpsSetSuccess -= 4;
      setBaud(settingsArrayPointer[4]);
      delay(1500);
      byte lowerPortRate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xB5};
      sendUBX(lowerPortRate, sizeof(lowerPortRate));
      gpsSerial.begin(9600);
      delay(2000);
    }
    if(gpsSetSuccess == 6) gpsSetSuccess -= 4;
    if (gpsSetSuccess == 10) gpsStatus[0] = true;
  }
  if (gpsSetSuccess == 3) Serial.println("Navigation mode configuration failed.");
  gpsSetSuccess = 0;
  while(gpsSetSuccess < 3) {
    Serial.print("Setting Data Update Rate... ");
    sendUBX(&setDataRate[0], sizeof(setDataRate));  //Send UBX Packet
    gpsSetSuccess += getUBX_ACK(&setDataRate[2]); //Passes Class ID and Message ID to the ACK Receive function
    if (gpsSetSuccess == 10) gpsStatus[1] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("Data update mode configuration failed.");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[6] == 0x00) {
    Serial.print("Deactivating NMEA GLL Messages ");
    sendUBX(setGLL, sizeof(setGLL));
    gpsSetSuccess += getUBX_ACK(&setGLL[2]);
    if (gpsSetSuccess == 10) gpsStatus[2] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA GLL Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[7] == 0x00) {
    Serial.print("Deactivating NMEA GSA Messages ");
    sendUBX(setGSA, sizeof(setGSA));
    gpsSetSuccess += getUBX_ACK(&setGSA[2]);
    if (gpsSetSuccess == 10) gpsStatus[3] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA GSA Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[8] == 0x00) {
    Serial.print("Deactivating NMEA GSV Messages ");
    sendUBX(setGSV, sizeof(setGSV));
    gpsSetSuccess += getUBX_ACK(&setGSV[2]);
    if (gpsSetSuccess == 10) gpsStatus[4] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA GSV Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[9] == 0x00) {
    Serial.print("Deactivating NMEA RMC Messages ");
    sendUBX(setRMC, sizeof(setRMC));
    gpsSetSuccess += getUBX_ACK(&setRMC[2]);
    if (gpsSetSuccess == 10) gpsStatus[5] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA RMC Message Deactivation Failed!");
  gpsSetSuccess = 0;

  while(gpsSetSuccess < 3 && settingsArrayPointer[10] == 0x00) {
    Serial.print("Deactivating NMEA VTG Messages ");
    sendUBX(setVTG, sizeof(setVTG));
    gpsSetSuccess += getUBX_ACK(&setVTG[2]);
    if (gpsSetSuccess == 10) gpsStatus[6] = true;
    if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
  }
  if (gpsSetSuccess == 3) Serial.println("NMEA VTG Message Deactivation Failed!");

  gpsSetSuccess = 0;
  if (settingsArrayPointer[4] != 0x25) {
    Serial.print("Setting Port Baud Rate... ");
    sendUBX(&setPortRate[0], sizeof(setPortRate));
    setBaud(settingsArrayPointer[4]);
    Serial.println("Success!");
    delay(500);
  }
}

void calcChecksum(byte *checksumPayload, byte payloadSize) {
  byte CK_A = 0, CK_B = 0;
  for (int i = 0; i < payloadSize ;i++) {
    CK_A = CK_A + *checksumPayload;
    CK_B = CK_B + CK_A;
    checksumPayload++;
  }
  *checksumPayload = CK_A;
  checksumPayload++;
  *checksumPayload = CK_B;
}

void sendUBX(byte *UBXmsg, byte msgLength) {
  for(int i = 0; i < msgLength; i++) {
    gpsSerial.write(UBXmsg[i]);
    gpsSerial.flush();
  }
  gpsSerial.println();
  gpsSerial.flush();
}

byte getUBX_ACK(byte *msgID) {
  byte CK_A = 0, CK_B = 0;
  byte incoming_char;
  boolean headerReceived = false;
  unsigned long ackWait = millis();
  byte ackPacket[10] = {0xB5, 0x62, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  int i = 0;
  while (1) {
    if (gpsSerial.available()) {
      incoming_char = gpsSerial.read();
      if (incoming_char == ackPacket[i]) {
        i++;
      }
      else if (i > 2) {
        ackPacket[i] = incoming_char;
        i++;
      }
    }
    if (i > 9) break;
    if ((millis() - ackWait) > 1500) {
      Serial.println("ACK Timeout");
      return 5;
    }
    if (i == 4 && ackPacket[3] == 0x00) {
      Serial.println("NAK Received");
      return 1;
    }
  }

  for (i = 2; i < 8 ;i++) {
  CK_A = CK_A + ackPacket[i];
  CK_B = CK_B + CK_A;
  }
  if (msgID[0] == ackPacket[6] && msgID[1] == ackPacket[7] && CK_A == ackPacket[8] && CK_B == ackPacket[9]) {
    Serial.println("Success!");
    Serial.print("ACK Received! ");
    printHex(ackPacket, sizeof(ackPacket));
    return 10;
        }
  else {
    Serial.print("ACK Checksum Failure: ");
    printHex(ackPacket, sizeof(ackPacket));
    delay(1000);
    return 1;
  }
}

void printHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex
{
  char tmp[length*2+1];
  byte first ;
  int j=0;
  for (byte i = 0; i < length; i++)
  {
    first = (data[i] >> 4) | 48;
    if (first > 57) tmp[j] = first + (byte)7;
    else tmp[j] = first ;
    j++;

    first = (data[i] & 0x0F) | 48;
    if (first > 57) tmp[j] = first + (byte)7;
    else tmp[j] = first;
    j++;
  }
  tmp[length*2] = 0;
  for (byte i = 0, j = 0; i < sizeof(tmp); i++) {
    Serial.print(tmp[i]);
    if (j == 1) {
      Serial.print(" ");
      j = 0;
    }
    else j++;
  }
  Serial.println();
}

void setBaud(byte baudSetting) {
  if (baudSetting == 0x12) gpsSerial.begin(4800);
  if (baudSetting == 0x4B) gpsSerial.begin(19200);
  if (baudSetting == 0x96) gpsSerial.begin(38400);
  if (baudSetting == 0xE1) gpsSerial.begin(57600);
  if (baudSetting == 0xC2) gpsSerial.begin(115200);
  if (baudSetting == 0x84) gpsSerial.begin(230400);
}

```

However, this one doesn't have a simple getSpeed() function, so I've tried to move to a library like TinyGPS that does have said function. Everything compiles fine, but it seems I am not getting a GPS signal with this script, while I have an accurate reading with about 7 satellites of the first script. I've triple checked the baud rates, and they all match, so I am stuck here.

```
    #include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(3,2);

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
  Serial.begin(19200);

  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");

  ss.begin(9600);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();

  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

```

The result of the last script looks like this:

```
Testing TinyGPS library v. 13
by Mikal Hart

Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
-------------------------------------------------------------------------------------------------------------------------------------
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   52    0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   104   0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   169   0         0
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   221   0         0

```

A list of libraries I've tried: \- NeoGPS \- NeoGPS (customized version of a forum) \- TineGPS \- AdafruitGPS

And some more random (video) tutorials online. If anyone could help me out on this one, I would be highly grateful! (and perhaps keep some hair on my head)

# Answer
The clue lies in this part of your first sketch:

```
//NMEA Messages:
//OFF = 0x00
//ON  = 0x01
//
byte settingsArray[] = {0x03, 0xFA, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //
configureUblox(settingsArray);

```

The final entry in your configuration is `0x00` which is "turn off NEMA messages".

There's two things to note here:

1. You are not configuring the GPS receiver in your second code, and
2. All other GPS libraries of note parse NEMA messages, which your first code turns off.

You will need to replicate the configuration code from your first sketch in your second sketch, but *turning ON NEMA messages*.
> 1 votes

---
Tags: arduino-uno, arduino-nano, softwareserial, gps
---


title: Will this sensor work with arduino?

text:
# Question
Title: Will this sensor work with arduino?
I'm building an electronic gate. I'm needing a photoelectric sensor to detect cars. This one in the link looks decent. it runs on 12v so I will need to power it separately from the arduino. But does this mean it also puts 12v back to the signal wire? Will that work with ardunio without burning the circuit? How many V can i send into an arduino pin?

thanks

photo electric sensor

# Answer
The sensor you specified states:

```
Output: SPDT Relay Output

```

If accurate, it may be inferred that the output is simply 3 contacts where one is normally open and the other is normally closed and the 3rd is the common. If true then you can treat the output as if it were an ordinary Single Poll Double Throw (SPDT) switch. Note, with regard to processors, an ordinary switch may need to de-bounced. This depends on how the state of the switch is used.
> 1 votes

---
Tags: sensors
---


# Question
Title: How to find the difference between two timestamps
I'm using this time library to access the properties of unix timestamps like hours / minutes / etc. What I want to do is get the current time, and an estimated arrival time, and find the difference between them in minutes.

Here's my code: (My estimated time is coming from an API as an INT)

```
time_t timeEstimated = timeInt;
time_t timeNow = now();

```

But how do I find the difference between these two timestamps in minutes? I'd like to try and avoid all of the conditionals / math that would come with converting to hours / minutes / seconds / dates and subtracting each component if possible.

# Answer
> 2 votes
Unix timestamps are just a count of seconds since a standard origin (1970.0 UTC), thus a simple subtraction, followed by a conversion from seconds to minutes:

```
float minutes_remaining = (timeEstimated - timeNow) / 60.0;

```

---
Tags: esp8266, timers, time, rtc
---


title: Arduino MEGA with RTOS

text:
# Question
Title: Arduino MEGA with RTOS
I've been coding for FreeRTOS on the MEGA 2560, and was using some LEDs to determine activity per task by toggling each individual LED each time through the task, and monitoring the time using a scope on the LED pin(s). All worked fine until I added the code for the last task.

Only the LED for the last task showed activity, and I assumed I screwed up in the new code, and spent a full day re-doing the code and troubleshooting. Well, it turns out that the code was working just fine. The problem appears to be RTOS is not manipulating the appropriate LED for each task, but using some other pin. The same configuration but with simple test code works fine.

I've tried just about everything I know, with negative results. The 3 tasks are running OK (I still need to do much more testing) so it's not like there is an issue with stack overflow, plus I decided to make ALL the variables as global variables to minimze stack use, and possible conflicts with the variables, which were the same on two of the original programs. I'm using about 600 bytes of RAM for those variables, and have tons of spece in the MEGA in all aspects. The code only uses 14K of the 256K available.

So, I'm officially stumped, and I assume that there's a problem with the task switching somehow, but I'd expect the code to crash eventually if that were the case, but it runs for hours and hours.

Does anyone have any real experience with FreeRTOS that have experienced similar issues related to simple digitalRead and/or digitalWrite problems similar to what I'm seeing?

# Answer
> 1 votes
Well, DUMBO (that would be me) found the problem, and it was a real bonehead error.

When I applied the stand-alone code to the RTOS environment, I did not reallocate pin assignments, so there were multiple I/O events writing to the same port that was using the Test LEDs.

I knew that FreeRTOS couldn't be that bad, as if the I/O went to the incorrect pins, the code would be useless.

So, don't take shortcuts, even if you're not ready to complete all segments of the project. Check for duplicate definitions or they will bite you in the ass.......

---
Tags: arduino-mega
---


# Question
Title: Program is working wrong while melody playing
My robot working fine but when I added buzzer and melody into code then is something wrong. Melody is playing when accelerometer is activated but rest of the code need to wait to end of melody. I want to play melody in background when program works. How to do it? There is my code:

```
#include <RedBot.h>
#include <RedBotSoftwareSerial.h>
RedBotAccel accel;
RedBotMotors motors;
int CM;
long CZAS;
bool started = false;
const int buzzer = A0;

int shortTone = 80;
int longTone = 200;
int standardDelay = 50;
int delayBetweenBars = 50;

void setup()
{
   Serial.begin(9600);
   accel.enableBump();
   accel.setBumpThresh(150);
   pinMode(A2, OUTPUT);  //Trig
   pinMode(A3, INPUT);   //Echo
   pinMode(buzzer, OUTPUT);  //Buzzer
}

void pomiar_odleglosci()
{
   digitalWrite(A2, HIGH);
   delayMicroseconds(10);
   digitalWrite(A2, LOW);
   CZAS = pulseIn(A3, HIGH);
   CM = CZAS / 58;
}

void loop(){

   while (!accel.checkBump() && !started) delay(100);
   started = true;

   if(started = true)
   {   DarudeSandstorm();
   }

   pomiar_odleglosci();
   Serial.print("Odleglosc: ");
   Serial.print(CM);
   Serial.println(" cm");

   if(CM>10)
   {
      motors.drive(100);
   }
   else
   {
      motors.drive(-100);
      delay(400);
      motors.stop();

      delay(400);

      motors.rightMotor(100);
      delay(700);
      motors.stop();

      motors.drive(100);
   }

}
//melody

```

# Answer
> 1 votes
You are using delay() in many parts of your code, which makes it very trick. I see a couple of possibilities here:

1 - if you have extra time and patience, get rid of all delays and find your around it counting millis() or some similar technique.

2 - if you have some extra bucks, get another controller just to play the melody, an ATtiny85 should be cheap and practical for this.

There is also the super-lazy, almost-no-work-at-all, relatively cheap solution: use a small media/MP3 player module, which also would allow you to have more than one melody and eventually adtiional noises.

---
Tags: arduino-uno
---


title: Setting Fuse Bits From Arduino IDE?

text:
# Question
Title: Setting Fuse Bits From Arduino IDE?
I've come to understand fuse bits in the last few weeks. I'm working on a bitbanging project on an Arduino Pro Micro, and the signals I'm working with are around 30uS each. For this reason, I think I'll need to unset the CKDIV8 to unlock the full 16MHz speed of my micro controller.

Regardless, I can't figure out how to even do that. Is it possible to modify fuse bits through the Arduino IDE? If so, where?

The only other info I've found on this subject so far is that I can do it by chaining two micro controllers together, but at that point we're getting into application specific stuff and I'm nervous to play with the fuse bits by myself until after I've followed a step-by-step guide. I'd hate to, say, erase the bootloader.

# Answer
The Arduinos are shipped without `CKDIV8` enabled.

New chips without bootloader and the chips after chip erase are having `CKDIV8` active.

And you can change the clock prescaller in software, but it mess up everything that depends on it. Delays, serial baud rate and USB as well.

However fuse setings are stored in boards.txt definition file. None of the bootloaders would work with default settings. They are usually compiled for `16MHz @5V` and `8MHz @3.3V` with xtal or resonator. But the custom boards may have much more options.
> 0 votes

---
Tags: arduino-ide, bootloader
---


title: Intermittent jittering servo

text:
# Question
Title: Intermittent jittering servo
I'm controlling a Hitech HS-625MG servo from a 10k slider via a Nano. For a while the motion tracks the slider position even when moved quickly.

Then, for no reason I can find, it will stop following smoothly & only move in jittery steps & then move as expected again!

The code is cut & paste from the pot-servo example..

```
#include <Servo.h>

Servo myservo_1;  // create servo object to control a servo

int potpin_1 = A0;  // analog pin used to connect the potentiometer

int val_1;    // variable to read the value from the analog pin

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

void loop() {
  val_1 = analogRead(potpin_1);             // reads the value of the potentiometer (value between 0 and 1023)

  val_1 = map(val_1, 0, 1023, 0, 180);      // scale it to use it with the servo (value between 0 and 180)

  myservo_1.write(val_1);                   // sets the servo position according to the scaled value

  delay(15);                                // waits for the servo to get there
                                            // have tried values ranging from 5 to 25 same behaviour
}

```

YouTube vid of the behaviour

Anyone seen this kinda thing before?

EDIT: That is the full code listing & here's the circuit diagram, the same as the knob example frome the Servo examples page except the servo is not being powered by the Nano but is sharing the same power supply. (sorry not next to it at the moment)

# Answer
# A servo motor requires a lot of current.

Many have problems when using a servo motor. Sometimes it works a few seconds and then it starts to jitter or it moves a little and then stops or it does nothing and makes a small click noise.

The problem is that servo motors requires a lot of current. Even the small servo motors can require a peak current of 0.5 A. Larger, stronger, and faster servo motors can easily request a peak of a few Amps.

To find the maximum current for the servo motor, look at the stall current of the servo motor.
When a servo starts to turn, it needs a short peak current. That peak current can be near the stall current.

Don't buy a "strong" and "fast" servo motor.
That may sound appealing, but it is better to start with a humble and timid servo motor.
*The servo motors have a DC motor with gears inside. Because of the gears it is already strong.*

Use a power supply of 5V with enough Amps to be able to supply the stall current of the servo motor.
Use that power supply to power the servo motor (the red wire).
Connect the GND of the power supply to the GND of the servo motor (the black wire) and the GND of the Arduino board.

**The 5V pin of the Arduino board can not supply enough power for a servo motor.**
It is in the official Arduino examples, but many run into problems with not enough power.
> 1 votes

---
Tags: arduino-nano, servo
---


# Question
Title: What bootloader is present by default on Arduino Uno?
Or where can i find information of default bootloaders present on each Arduino board. All I could look up was it could be one of these bootloaders on the atmega chip :-

.Atmega .Atmega8 .bt .caterina .caterina-Arduino\_Robot .caterina-LilyPadUSB .gemma .lilypad .optiboot .stk500v2

This was the list present in the folder ~\Arduino\hardware\arduino\avr\bootloaders.

# Answer
> 2 votes
It is defined in the file "boards.txt" (`arduino-1.8.7\hardware\arduino\avr\boards.txt`).

For example the Arduino Uno is called "Arduino/Genuino Uno" and it has the bootloader: `uno.bootloader.file=optiboot/optiboot_atmega328.hex`

You can find that hex file in the folder `arduino-1.8.7\hardware\arduino\avr\bootloaders\optiboot`.

The official Arduino boards are shipped with the newest bootloaders.
Sometimes the bootloaders are improved or changed. That is mentioned in the Release Notes.
For example the latest change to a bootloader is that the Arduino Nano has now the same optiboot bootloader as the Arduino Uno.

When buying a Arduino clone board, anything is possible.

Some companies make there own Arduino-compatible boards with their own bootloaders.

# Answer
> 1 votes
Optiboot Bootloader for Arduino and Atmel AVR

https://github.com/Optiboot/optiboot/wiki

Take a look at this information.

---
Tags: arduino-uno
---


# Question
Title: ets Jan 8 2013,rst cause:4, boot mode:(1,7)
I am facing a issue with the ESP8266-01 as the following below:

chksum 0x42 csum 0x42 ~ld ets Jan 8 2013,rst cause:4, boot mode:(1,0) wdt reset

Anyone has the solution please help!!

```
#include <LiquidCrystal.h>  //Load liquid Crystal Library
LiquidCrystal LCD(12, 11, 5, 4, 3, 2);  //Create Liquid Crystal Object called LCD
#include <ESP8266WiFi.h>

const char* ssid     = "your-ssid";
const char* password = "your-password";
const char* host = "your-localhost";

#define in 7
#define out 8
#define trigPin 10
#define echoPin 13
#define relay 2
#define led 6            //red color
#define led2 A0           //yellow color
#define led3 9           //green color

int count = 0;

int distanceCm;
long duration;

void IN()
{
    count++;
    LCD.clear();
    LCD.print("Number of Item:");
    LCD.setCursor(0,1);
    LCD.print(count);
    delay(10);
    LCD.setCursor(3,1);
    LCD.print(distanceCm);
    delay(10);
    LCD.setCursor(6,1);
    LCD.print(" cm");
    if(distanceCm <= 3){
     delayMicroseconds(10);
     LCD.setCursor(10,1);
     LCD.print("Full");
     digitalWrite(led, HIGH);
  }else{
    digitalWrite(led, LOW);
  }

  if(distanceCm > 3 && distanceCm <= 5){
     delayMicroseconds(10);
     LCD.setCursor(10,1);
     LCD.print("Enable");
     digitalWrite(led2, HIGH);
  } else{
    digitalWrite(led2, LOW);
  }

  if(distanceCm > 5){
     delayMicroseconds(10);
     LCD.setCursor(10,1);
     LCD.print("Empty");
     digitalWrite(led3, HIGH);
  } else {
    digitalWrite(led3, LOW);
  }
  delay(500);
}

void OUT()
{
  count--;
  LCD.clear();
  LCD.print("Number of Item:");
  LCD.setCursor(0,1);
  LCD.print(count);
  delay(10);
  LCD.setCursor(3,1);
  LCD.print(distanceCm);
  LCD.setCursor(6,1);
  LCD.print(" cm");
   if(distanceCm <= 3){
     delayMicroseconds(10);
     LCD.setCursor(10,1);
     LCD.print("Full");
     digitalWrite(led, HIGH);
  }else{
    digitalWrite(led, LOW);
  }

  if(distanceCm > 3 && distanceCm <= 5){
     delayMicroseconds(10);
     LCD.setCursor(10,1);
     LCD.print("Enable");
     digitalWrite(led2, HIGH);
  } else{
    digitalWrite(led2, LOW);
  }

  if(distanceCm > 5){
     delayMicroseconds(10);
     LCD.setCursor(10,1);
     LCD.print("Empty");
     digitalWrite(led3, HIGH);
  } else {
    digitalWrite(led3, LOW);
  }
  delay(500);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(10);

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  LCD.begin(16,2);
  LCD.print("Item Counter");
  delay(2000);

  pinMode(in, INPUT);
  pinMode(out, INPUT);
  pinMode(relay, OUTPUT);

  LCD.clear();
  LCD.print("Item In Box:");
  LCD.setCursor(0,1);
  LCD.print(count);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

 // ESP.restart();
}

int value = 0;

void loop() {

 delay(0);
 delay(5000);
  ++value;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(50);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distanceCm = duration * 0.034/2;

//******************************************************//
//IR Sensor Counting Object
  if(digitalRead(in))
  IN();
  if(digitalRead(out))
  OUT();

  if(count<=0)
  {
    LCD.clear();
    digitalWrite(relay, LOW);
    LCD.clear();
    LCD.print("No Item in box");
    LCD.setCursor(0,1);
    LCD.print("box is empty");
    delay(200);
  }
   else{
    digitalWrite(relay, HIGH);
   }

  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 8095;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  if(WiFi.status() != WL_CONNECTED){
    WiFi.begin(ssid,password);
    while (WiFi.status()!= WL_CONNECTED)
    {
      Serial.println("Waiting for connection");
      delay(0);
    }
  }

  String IRCount, myDistance;
  IRCount = String(count);
  myDistance = String(distanceCm);
  // We now create a URI for the request
  String url = "/Registration/write_data.php";
  url += "?item=";
  url += IRCount;
  url += "&distance=";
  url += myDistance;

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  int timeout = millis() + 5000;
  while (client.available() == 0) {
    if (timeout - millis() < 0) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println("closing connection");
  delay(0);
}

```

# Answer
> 1 votes
esp-01 has 4 io pins: RX, TX, io 0 and io 2. other pins are not accessible. io 6 to io 11 are wired to on-board flash memory and can't be used.

what are you thinking by using other pins then 0 and 2? how did you wire those sensors and leds to esp-01?

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


# Question
Title: Message Interpreter and Handler - How to store a function name in a struct?
For a project, I need to store an array of structures in PROGMEM. Array `MessageTable[]` will be composed of about ten `struct InMessage` elements. InMessage looks sort of like this:

```
struct AvcInMessage {
  MessageHandler  msgHandler;
  byte            dataSize;
  byte            data[8];
  char            description[20];
};

```

MessageHandler is not a data type... yet. I'm not really sure what data type to use. I want to be able to pick a message from the table and then call `MessageTable[x].msgHandler()` if that makes sense. I'm almost positive that this involves a pointer. Does someone here have an idea about what I'm looking for?

# Answer
```
typedef void (*MessageHandler)(void);   // def messagehandler as pointer to func

struct AvcInMessage {
  MessageHandler  msgHandler;
  byte            dataSize;
  byte            data[8];
  char            description[20];
} InMessage[] = {
   {
      function1, <datasize>, {<byte0>, <byte1>, ..., }, "DescriptionHere"
   },
   // etc, for however many elements InMessage[] has.
};

```

The `typedef` defines a "pointer to function of void returning void" - fix up the argument count and types, and the return type to your needs. We're assuming each element's function has the same kind of arglist and return type. (Update: Sorry for the bug in my first iteration).

The next statement both defines the array of struct and initializes N of them. Provide an element count in the `[]` if you don't have a full set of initializers at compile time.
> 3 votes

---
Tags: array, pointer, struct
---


# Question
Title: My Arduino Code but it will not compile, I cannot find what is wrong with it
I tried convining and LCD display, ultrasonic sensons, LEDs and an IR reciever code into one main code. Seperately they work fine, but when I put them toguether it gives me the following error: "Error compiling for board Arduino/Genuino Mega or Mega 2560."

The full error when I compile is :

```
Arduino: 1.8.5 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `__vector_13'
libraries/IRremote/IRremote.cpp.o (symbol from plugin):(.text+0x0): first defined here
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

```

https://drive.google.com/file/d/1YNOqxE0mAZJsQrV7\_zMbRZ\_jkur19rXt/view?usp=sharing

# Answer
> 1 votes
The processor has a fixed number of hardware devices such as timers and serial ports. If two libraries try to use the same device (in this case it looks like timer 2) then you won't be able to compile (let alone run) the code without resolving the issue. Possibly one of them could be altered to use a different timer, however this may not be trivial.

As an example, say you have one alarm clock, but you want to have it ring at both 5 a.m. and 7 a.m. You can't do that per se, you might need to get a second clock.

---

Looking at the source code in `(install directory)/hardware/tools/avr/avr/include/avriomxx0_1.h` I see that vector 13 is indeed for Timer 2;

```
/* Timer/Counter2 Compare Match A */
#define TIMER2_COMPA_vect_num   13
#define TIMER2_COMPA_vect       _VECTOR(13)
#define SIG_OUTPUT_COMPARE2A        _VECTOR(13)

```

---
Tags: arduino-mega
---


# Question
Title: Arduino RGB LED not working all the time?
I was creating an RGB LED System with one 1 RGB LED controlled by an IR Remote. I wanted to assign a button to trigger a mood-light which cycles through the rainbow, and that works fine. But when I try to make a mode where you can change RGB Values directly, it doesn't work properly. I assigned numbers on the remote to switch the colour that you are changing (e.g 1 is red, 2 is green etc.), and the volume controls how much light is coming but when I have two colors with positive values it only displays one. I have no idea why because the moodlight works fine and even transitions smoothly.

```
//www.elegoo.com
//2016.12.9

#include "IRremote.h"

// Define Pins
int BLUE = 3;
int GREEN = 5;
int RED = 6;

int addValue = 10;

int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

int blueValue = 0;
int greenValue = 0;
int redValue = 0;

bool isMoodLightOn = false;
bool isBlueModeOn = false;
bool isGreenModeOn = false;
bool isRedModeOn = true;

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

/*-----( Function )-----*/
void translateIR() // takes action based on IR code received

// describing Remote IR codes

{

  switch(results.value)

  {
  case 0xFFA25D: Serial.println("POWER"); break;
  case 0xFFE21D: Serial.println("FUNC/STOP"); break;
  case 0xFF629D: Serial.println("VOL+"); break;
  case 0xFF22DD: Serial.println("FAST BACK"); break;
  case 0xFF02FD: Serial.println("PLAY/PAUSE");
                 isMoodLightOn = !isMoodLightOn;
                 if (isMoodLightOn == false) {
                  isBlueModeOn = true;
                  isGreenModeOn = false;
                  isRedModeOn = false;

                  setColor(redValue, greenValue, blueValue);
                 } else {
                  isBlueModeOn = false;
                  isGreenModeOn = false;
                  isRedModeOn = false;
                 }
                 break;
  case 0xFFC23D: Serial.println("FAST FORWARD"); break;
  case 0xFFE01F: Serial.println("DOWN");
                 if (isBlueModeOn) {
                  if (blueValue > 0) {
                    blueValue = blueValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isGreenModeOn) {
                  if (greenValue > 0) {
                    greenValue = greenValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isRedModeOn) {
                  if (redValue > 0) {
                    redValue = redValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 break;
  case 0xFFA857: Serial.println("VOL-"); break;
  case 0xFF906F: Serial.println("UP");
                 if (isBlueModeOn) {
                  if (blueValue < 100) {
                    blueValue = blueValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isGreenModeOn) {
                  if (greenValue < 100) {
                    greenValue = greenValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isRedModeOn) {
                  if (redValue < 100) {
                    redValue = redValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 break;
  case 0xFF9867: Serial.println("EQ"); break;
  case 0xFFB04F: Serial.println("ST/REPT"); break;
  case 0xFF6897: Serial.println("0"); break;
  case 0xFF30CF: Serial.println("1"); isRedModeOn = true; isGreenModeOn = false; isBlueModeOn = false; break;
  case 0xFF18E7: Serial.println("2"); isRedModeOn = false; isGreenModeOn = true; isBlueModeOn = false; break;
  case 0xFF7A85: Serial.println("3"); isRedModeOn = false; isGreenModeOn = false; isBlueModeOn = true; break;
  case 0xFF10EF: Serial.println("4"); break;
  case 0xFF38C7: Serial.println("5"); break;
  case 0xFF5AA5: Serial.println("6"); break;
  case 0xFF42BD: Serial.println("7"); break;
  case 0xFF4AB5: Serial.println("8"); break;
  case 0xFF52AD: Serial.println("9"); break;
  case 0xFFFFFFFF: Serial.println("REPEAT"); break;

  default:
    Serial.println(" other button   ");

  }// End Case

  delay(500); // Do not get immediate repeat

} //END translateIR
void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode");

  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);

  setColor(redValue, greenValue, blueValue);

  isBlueModeOn = true;
  isGreenModeOn = false;
  isRedModeOn = false;

  irrecv.enableIRIn(); // Start the receiver

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

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  setColor(redValue, greenValue, blueValue);

  if (irrecv.decode(&results)) // have we received an IR signal?

  {
    translateIR();
    irrecv.resume(); // receive the next value
  }

  setColor(redValue, greenValue, blueValue);

  if (isMoodLightOn == true) {
      int delayTime = 10; // fading time between colors

      redValue = 255; // choose a value between 1 and 255 to change the color.
      greenValue = 0;
      blueValue = 0;

      // this is unnecessary as we've either turned on RED in SETUP
      // or in the previous loop ... regardless, this turns RED off
      // analogWrite(RED, 0);
      // delay(1000);

      for(int i = 0; i < 255; i += 1) // fades out red bring green full when i=255
      {
        redValue -= 1;
        greenValue += 1;
        // The following was reversed, counting in the wrong directions
        // analogWrite(RED, 255 - redValue);
        // analogWrite(GREEN, 255 - greenValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }

      redValue = 0;
      greenValue = 255;
      blueValue = 0;

      for(int i = 0; i < 255; i += 1) // fades out green bring blue full when i=255
      {
        greenValue -= 1;
        blueValue += 1;
        // The following was reversed, counting in the wrong directions
        // analogWrite(GREEN, 255 - greenValue);
        // analogWrite(BLUE, 255 - blueValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }

      redValue = 0;
      greenValue = 0;
      blueValue = 255;

      for(int i = 0; i < 255; i += 1) // fades out blue bring red full when i=255
      {
        // The following code has been rearranged to match the other two similar sections
        blueValue -= 1;
        redValue += 1;
        // The following was reversed, counting in the wrong directions
        // analogWrite(BLUE, 255 - blueValue);
        // analogWrite(RED, 255 - redValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }
  }
  setColor(redValue, greenValue, blueValue);
}/* --(end main loop )-- */

void setColor(int red, int green, int blue) {
  analogWrite(BLUE, blue);
  analogWrite(GREEN, green);
  analogWrite(RED, red);
}

```

# Answer
> 0 votes
I will formulate my comment as a longer answer.

Inside your `loop()` function, you use `setColor()` twice, directly in the lowest level. When you are not in the moodlight mode, the whole if statement after it will not be executed, so there isn't much happening inside one iteration of the function and it will cycle through very fast, setting the colors again and again.

THe `setColor()` function only consists of calls to `analogWrite()`. It configures the Atmegas hardware, so that a PWM signal will be generated at the pin. For doing so, the corresponding hardware registers (for one of the timers). This also let's the PWM wave start again. If you are doing this very fast (meaning in the range of the PWM signal itself or faster), you will destroy the complete PWM waveform by starting over and over again. Image it as if you wait press the replay button on your music player again and again very fast. You would be able to recognize the music, as it is chopped up due to the replaying.

The aforementioned two lines are not necessary either, since the output of the PWM wave is done by hardware and does not require any code after it has been turned on by `analogWrite()`. So you can simply delete those two lines.

---
Tags: ir, rgb-led
---


# Question
Title: nodemcu esp8266 does not boot up when 5V pin is connected as a VIN source
Whenever I boot up the esp8266 or flash code via usb ,I have to remove vin pin otherwise it does not boot up.

If I remove vin pin then flash and boot up happens and then i am able connect vin with 5 V relay.(using VIN to power up relay) .

I dont understand what it has to do with VIN pin.please suggest.

I am using below pins for eight devices

```
//relay pin setup for funct
int relayOne = 5;
int relayTwo = 4;
int relayThree = 0;
int relayFour = 2;
int relayFive = 14;
int relaySix = 12;
int relaySeven = 13;
int relayEight = 15;

```

# Answer
> 1 votes
IO pins 0, 2 and 15 are boot configuration pins. 15 must be LOW at boot, 2 must not be LOW at boot and 0 determines the flashing mode. For normal run pin 0 must be HIGH. The NodeMcu board has necessary pull-up and pull-down circuits.

You can connect to pins 0, 2 and 15 only devices which don't change the boot state.

---
Tags: esp8266, bootloader, relay
---


title: Syntax of binary Constants

text:
# Question
Title: Syntax of binary Constants
I was trying to compile some Arduino code on the PC for testing when I noticed some strange syntax for numerical binary constants.

Convetion seems to be to declare them like so:

```
    static const uint8_t smiley[] = {
        B00111100,
        B01000010,
        B10100101,
        B10000001,
        B10100101,
        B10011001,
        B01000010,
        B00111100 };

```

However, when I try to compile this with g++ I get

> **error: ‘B00111100’** was not declared in this scope

Now when I exchange this for `B` for the standard C/C++ prefix `0B` it works, but I don't want to change the code that I want so simulate!

Is there some clever macro magic at play here?

# Answer
There is a file (binary.h) with every possible permutation of number between 0 and 255 represented as binary in it. They're stored as C-preprocessor macros:

```
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
... etc ...

```

Quite why Arduino decided to do this is anyone's guess. It makes, as you have seen, for non-portable code.

Personally, I *never* use (and would *never* recommend any one else should use) those macros, and instead use the GCC standard binary literal representation `0b....`.
> 4 votes

---
Tags: constants, c-preprocessor
---


# Question
Title: Use a button on LCD shield to pause the code
I'm creating a Temperature logging device with thermocouple K and SD card breakout and a RGB LCD Shield Kit w/ 16x2 Character Display (with buttons).

Everything runs ok: temperature displaying on the LCD and logging on txt file on the micro SD card work well

Now I try to configure button on the shield

1. button UP to reset measurements and timer , it works
2. button Down to pause measurements, then when pushed again, continue measurements. I don't know how to do that (how to go out the while condition).

```
 if (buttons) {

if (buttons & BUTTON_UP) {

  lcd.clear();
  lcd.print("RESET ");
  if (SD.exists("datalog.txt")) {

    SD.remove("datalog.txt");
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
  }

  else {

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    // if the file is available, write to it:

  }
 StartTime = millis();

  delay(500);

}
if (buttons & BUTTON_DOWN) {
  lcd.clear();
  lcd.print("STOP");
  while (buttons & BUTTON_DOWN){

      ;
  }

```

}

I already thank you for your help,

Vincent

# Answer
You are not saying much about how `buttons` is valorized or its data type, but assuming it is a numeric variable which gets somehow set by, let's say a `readButtons()` function, then consider the following snippet replacing your *while-loop*:

```
do {
  delay(10);
  // re-evaluate whatever sets the buttons variable
  buttons = readButtons();
while(!(buttons & BUTTON_DOWN));

```

The loop above will continue until the button down is pressed and it's a little resilient regarding contact bouncing, but not 100% reliable, so I assume the `readButtons()` performs also some debouncing.
> 0 votes

---
Tags: lcd
---


# Question
Title: Converting hexadecimal string to floating point value
I am reading data from an energy meter over modbus protocol and I am getting hex values from there. I want to convert that hex string to floating point value. For example - 0x416f0000 denotes a value of 14.9375.Reference

Can anyone please help me how to do it on Arduino IDE?

# Answer
> 3 votes
If you do indeed have an ASCII string of hexadecimal numbers (and not a raw binary float), then your best option may be to do the conversion in two steps:

1. convert the string to a 32 bit unsigned number using `strtoul()`
2. reinterpret the binary pattern of this integer as a float.

For example, the following program:

```
void setup() {
    const char modbus_data[] = "416F0000";
    union {
        uint32_t i;
        float f;
    } data;
    data.i = strtoul(modbus_data, NULL, 16);

    Serial.begin(9600);
    Serial.println(data.f, 4);
}

void loop(){}

```

prints `14.9375`.

Note that for `strtoul()` to function properly, the hex string must be followed by a character that is not a valid hex digit (a `\0` in the example above).

---
Tags: arduino-ide
---


# Question
Title: Power on reset with arduino uno can never happen. Can this be fixed?
When an Arduino Uno is powered on, the USB chip's DTR output pin may (is, in fact) low for a while. This means that the capacitor C5 is connected from the 328p reset pin to ground. Thus, when power is applied, the reset pin is held low for 10's of milliseconds after power up (while C5 charges) .

Thus, when the 328p starts, the reason for reset (the MCU register) always is "external reset", not "power on reset", even when power turns on.

This can be fixed by removing C5, or opening the "reset en" jumper, but then the chip is never reset by the falling of DTR,...that is, bootloading is disabled.

Is there a solution that allows POR and external reset for the bootloader? Thanks!

# Answer
See 'DTR-reset' circuit of Arduino Uno below.

After powering-on, when DTR is set low (because a sketch is coming in) the falling edge causes a negative pulse on the 328P's external reset pin of ca. 3 ms (see here). The width of this reset pulse is independent of the time that DTR stays low.

During powering-on the 328P's reset pin is low until the capacitor C5 is sufficiently charged. How long this takes depends mainly on the start-up behavior of Vcc. When DTR is low the capacitor will charge faster because RN2D (from capacitor C5 to ground) is bypassed.

But the main thing is that the power-on reset and the external reset have the same effect (see datasheet): when the rising voltage passes a certain threshold a timer is started and after it times out program execution starts at 0x0000 or at the Boot Reset Address (depending on the setting of the fuses). So, in the powering-on situation it makes no sense to differentiate between Power On Reset and External Reset.
> 2 votes

# Answer
I have answered my own question.
I added a pull-UP resistor on the DTR line to VCC. Now capacitor C5 does not need to be charged up on power up: both sides of the capacitor start at VCC. Thus, the 328p recognizes a power-up as a "power-up reset", instead of an "external reset", and my sketch starts after 75-milliseconds or so on power up. Basically, my circuit is like PimV's diagram, but with the resistor RN2D to VCC, rather than to ground. At least for the Uno, this fix seems to work. I suspect this relies on the USB chip (mega16u) being in reset, and it's pins tri-stated, for a while after power up.
> 2 votes

---
Tags: arduino-uno, hardware, reset
---


# Question
Title: Data loging while browsing a menu on LCD shield
I'm new in arduino and not particularly awaken when it comes to code ;) . I'm developing a device SD logging Temperatures from 2 thermocouple . Hardware works well and I'm now trying to refine use of the LCD with a menu.

I want to be able to, while logging data on the SD card (lets say every second), browsing a menu to:

* See current temperatures
* see the max value from the measurements
* see time already elapsed
* etc.

I've used a menu code from (https://www.instructables.com/id/Arduino-Uno-Menu-Template/)

The thing is when I enter a sub-menu(menuItem()), while I'm not out of this sub menu the code is not looping anymore, so data logging would be paused.

So my question is: how should I organize my code to be able to do a repetitive task in background(logging temperatures) while browsing a menu giving information and/or proposing actions (Stop datalogging, reset etc).

Here is the code from instructables modified to be used with adafruit LCD shield:

```
/***************************************************************************************
    Name    : LCD Button Shield Menu
    Author  : Paul Siewert
    Created : June 14, 2016
    Last Modified: June 14, 2016
    Version : 1.0
    Notes   : This code is for use with an Arduino Uno and LCD/button shield. The
              intent is for anyone to use this program to give them a starting
              program with a fully functional menu with minimal modifications
              required by the user.
    License : This program is free software. You can redistribute it and/or modify
              it under the terms of the GNU General Public License as published by
              the Free Software Foundation, either version 3 of the License, or
              (at your option) any later version.
              This program is distributed in the hope that it will be useful,
              but WITHOUT ANY WARRANTY; without even the implied warranty of
              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
              GNU General Public License for more details.
 ***************************************************************************************/
/*
   This program is designed to get you as close as possible to a finished menu for the standard Arduino Uno LCD/button shield. The only required modifications
   are to add as menu items to the master menu (menuItems array) and then modify/adjust the void functions below for each of those selections.
*/

// You can have up to 10 menu items in the menuItems[] array below without having to change the base programming at all. Name them however you'd like. Beyond 10 items, you will have to add additional "cases" in the switch/case
// section of the operateMainMenu() function below. You will also have to add additional void functions (i.e. menuItem11, menuItem12, etc.) to the program.
String menuItems[] = {"ITEM 1", "ITEM 2", "ITEM 3", "ITEM 4", "ITEM 5", "ITEM 6"};

// Navigation button variables
int readKey;

// Menu control variables
int menuPage = 0;
int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5);
int cursorPosition = 0;

// Creates 3 custom characters for the menu display
byte downArrow[8] = {
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b10101, // * * *
  0b01110, //  ***
  0b00100  //   *
};

byte upArrow[8] = {
  0b00100, //   *
  0b01110, //  ***
  0b10101, // * * *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100  //   *
};

byte menuCursor[8] = {
  B01000, //  *
  B00100, //   *
  B00010, //    *
  B00001, //     *
  B00010, //    *
  B00100, //   *
  B01000, //  *
  B00000  //
};

#include <Wire.h>
#include <LiquidCrystal.h>

// Setting the LCD shields pins
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

void setup() {

  // Initializes serial communication
  Serial.begin(9600);

  // Initializes and clears the LCD screen
  lcd.begin(16, 2);
  lcd.clear();

  // Creates the byte for the 3 custom characters
  lcd.createChar(0, menuCursor);
  lcd.createChar(1, upArrow);
  lcd.createChar(2, downArrow);
}
//////////////////////////////////////////////
void loop() {
  mainMenuDraw();
  drawCursor();
  operateMainMenu();

  Serial.print("Loop");
}
///////////////////////////////////////////////
// This function will generate the 2 menu items that can fit on the screen. They will change as you scroll through your menu. Up and down arrows will indicate your current menu position.
void mainMenuDraw() {
  Serial.print(menuPage);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(menuItems[menuPage]);
  lcd.setCursor(1, 1);
  lcd.print(menuItems[menuPage + 1]);
  if (menuPage == 0) {
    lcd.setCursor(15, 1);
    lcd.write(byte(2));
  } else if (menuPage > 0 and menuPage < maxMenuPages) {
    lcd.setCursor(15, 1);
    lcd.write(byte(2));
    lcd.setCursor(15, 0);
    lcd.write(byte(1));
  } else if (menuPage == maxMenuPages) {
    lcd.setCursor(15, 0);
    lcd.write(byte(1));
  }
}

// When called, this function will erase the current cursor and redraw it based on the cursorPosition and menuPage variables.
void drawCursor() {
  for (int x = 0; x < 2; x++) {     // Erases current cursor
    lcd.setCursor(0, x);
    lcd.print(" ");
  }

  // The menu is set up to be progressive (menuPage 0 = Item 1 & Item 2, menuPage 1 = Item 2 & Item 3, menuPage 2 = Item 3 & Item 4), so
  // in order to determine where the cursor should be you need to see if you are at an odd or even menu page and an odd or even cursor position.
  if (menuPage % 2 == 0) {
    if (cursorPosition % 2 == 0) {  // If the menu page is even and the cursor position is even that means the cursor should be on line 1
      lcd.setCursor(0, 0);
      lcd.write(byte(0));
    }
    if (cursorPosition % 2 != 0) {  // If the menu page is even and the cursor position is odd that means the cursor should be on line 2
      lcd.setCursor(0, 1);
      lcd.write(byte(0));
    }
  }
  if (menuPage % 2 != 0) {
    if (cursorPosition % 2 == 0) {  // If the menu page is odd and the cursor position is even that means the cursor should be on line 2
      lcd.setCursor(0, 1);
      lcd.write(byte(0));
    }
    if (cursorPosition % 2 != 0) {  // If the menu page is odd and the cursor position is odd that means the cursor should be on line 1
      lcd.setCursor(0, 0);
      lcd.write(byte(0));
    }
  }
}

void operateMainMenu() {
  int activeButton = 0;
  while (activeButton == 0) {
    int buttons;

    buttons = lcd.readButtons();

    switch (buttons) {
      case 0: // When button returns as 0 there is no action taken
        break;
      case 2:  // This case will execute if the "forward" button is pressed
        buttons = 0;
        switch (cursorPosition) { // The case that is selected here is dependent on which menu page you are on and where the cursor is.
          case 0:
            menuItem1();
            break;
          case 1:
            menuItem2();
            break;
          case 2:
            menuItem3();
            break;

        }
        activeButton = 2;
        mainMenuDraw();
        drawCursor();
        break;
      case 8:
        buttons = 0;
        if (menuPage == 0) {
          cursorPosition = cursorPosition - 1;
          cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
        }
        if (menuPage % 2 == 0 and cursorPosition % 2 == 0) {
          menuPage = menuPage - 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        if (menuPage % 2 != 0 and cursorPosition % 2 != 0) {
          menuPage = menuPage - 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        cursorPosition = cursorPosition - 1;
        cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));

        mainMenuDraw();
        drawCursor();
        activeButton = 2;
        break;
      case 4:
        buttons = 0;
        if (menuPage % 2 == 0 and cursorPosition % 2 != 0) {
          menuPage = menuPage + 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        if (menuPage % 2 != 0 and cursorPosition % 2 == 0) {
          menuPage = menuPage + 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        cursorPosition = cursorPosition + 1;
        cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
        mainMenuDraw();
        drawCursor();
        activeButton = 2;
        break;
    }
  }
}

// If there are common usage instructions on more than 1 of your menu items you can call this function from the sub
// menus to make things a little more simplified. If you don't have common instructions or verbage on multiple menus
// I would just delete this void. You must also delete the drawInstructions()function calls from your sub menu functions.
void drawInstructions() {
  lcd.setCursor(0, 1); // Set cursor to the bottom line
  lcd.print("Use ");
  lcd.print(byte(1)); // Up arrow
  lcd.print("/");
  lcd.print(byte(2)); // Down arrow
  lcd.print(" buttons");
}

void menuItem1() { // Function executes when you select the 1st item from main menu
  int activeButton = 0;

  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Sub Menu 1");

  while (activeButton == 0) {
    int buttons;

    buttons = lcd.readButtons();
    switch (buttons) {
      case 16:  // This case will execute if the "back" button is pressed
        buttons = 0;
        activeButton = 1;
        break;
    }
  }
}

void menuItem2() { // Function executes when you select the 2nd item from main menu
  int activeButton = 0;

  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Sub Menu 2");

  while (activeButton == 0) {
    int buttons;

    buttons = lcd.readButtons();
    switch (buttons) {
      case 16:  // This case will execute if the "back" button is pressed
        buttons = 0;
        activeButton = 1;
        break;
    }
  }
}

void menuItem3() { // Function executes when you select the 3rd item from main menu
  int activeButton = 0;

  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Sub Menu 3");

  while (activeButton == 0) {
    int buttons;

    buttons = lcd.readButtons();
    switch (buttons) {
      case 16:  // This case will execute if the "back" button is pressed
        buttons = 0;
        activeButton = 1;
        break;
    }
    }
  }

```

I thank you for your help, and hope it will be helpful for others

# Answer
The key is that the menu code must never wait as the `operateMainMenu()` function does. Instead, it has to test the buttons, do a required task, if any, quickly, and return. This means it depends on being called very frequently so it can respond to the buttons quickly, but also must return quickly when there is nothing to do. You make those calls from your `loop()` function, typically.

Look at the Arduino example, "BlinkWithoutDelay". In that example everything is decided by reading the time - millis(), where in your case, you'll be deciding by testing and reacting to the buttons. Just remember never to loop to wait for an input; just test for it once and act on it or just go away if it isn't there.

Your `loop()` function will do nothing but give each "worker" routine an opportunity to do something:

```
void loop(){
   menuRun();
   dataLogRun();
}

```

, for instance. Each of those functions gets a frequent opportunity to do one of its tasks - or not - and return, so the next one gets a chance. A loop like this one runs extremely frequently when there is nothing to do, meaning both the menu function and the data-logging function can be very responsive when something is needed.
> 3 votes

---
Tags: arduino-uno, lcd, temperature-sensor, datalogging
---


# Question
Title: ESP8266 Stops Working if I don't provide Wifi during specifc step
To test the WiFi connection I'm sharing the WiFi of my cellphone.

If I stop the WiFi sharing during the command below, the ESP8266 stops working. It only works if I do a hardware reset.

If I don't stop the WiFi it works normally.

```
    if(client->POST(urlCal, host, payload))
  { RetornoPost = client->getResponseBody(); }

```
* HTTPS Redirect (Version 2.0)
* ESP8266 library version 2.4.2

Does anyone know why ESP8266 stops working?

# Answer
> 0 votes
If by "stops working" you mean it doesn't do whatever follows the `client->POST` method invocation, then your interpretation is correct and you could have found my very same information if you had read the open issues on the library **before** submitting your own.

If I were the author of the library I would be upset by such behavior.

---
Tags: esp8266
---


# Question
Title: Problem with serial connection. Data garbled
I have a hardware device that sends data over the serial port and over a socket connection.

I have the TX of the device connected to the RX of the ESP8266, RX of the device to TX of the ESP8266.

Comm speed is set to 115200 on both.

Code is nothing more than

```
void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() { // run over and over
  if (Serial.available()) {
    Serial.write(Serial.read());
  }
}

```

I listen on the socket and on the serial port at the same time. On the socket port i get correct data (ASCII characters). On the serial monitor of the Arduino i get garbled data. Also, it looks like the Arduino IDE cannot cope with the volume of data. I am sending appx 100 char/sec.

Any ideas?

**Update Aug 13 '18**

Ok, I found out that I was trying to hook up an RS232 to an UART and that, to accomplish this, I need a RS232 to TTL converter like the max3232. I will go that road and update the question if I have it.

---

Ok, i found out that i was trying to hook up an RS232 to an UART and that, to accomplish this, i need a RS232 to TTL converter like the max3232. I will go that road and update the question if i have it.

# Answer
I think RS232 signals are outside the TTL limits; I don't know if you've done any permanent damage.

On the interfacing itself:

https://www.sparkfun.com/tutorials/215

On the damage part:

https://forum.arduino.cc/index.php?topic=26139.0
> 1 votes

---
Tags: serial, esp8266
---


title: Arduino pins vs Esp8266MOD

text:
# Question
Title: Arduino pins vs Esp8266MOD
I had used Arduino Uno & RFID but now i want to run same code in Esp8266MOD. i have installed all the drivers and everything else to run esp8266 in Arduino IDE but i dont know how to connect rfid in esp8266. Can someone please compare which arduino pin & esp8266 pin are similar

```
 * Typical pin layout used:
 * ------------------------------------------------------
 *             MFRC522      Arduino       NodeMCU
 *             Reader/PCD   Uno/101       ESP8266MOD
 * Signal      Pin          Pin           Pin
 * ------------------------------------------------------
 * RST/Reset   RST          9             ?
 * SPI SS      SDA(SS)      10            ?
 * SPI MOSI    MOSI         11 / ICSP-4   ?
 * SPI MISO    MISO         12 / ICSP-1   ?
 * SPI SCK     SCK          13 / ICSP-3   ?

```

# Answer
table filled

```
 * Typical pin layout used:
 * ------------------------------------------------------
 *             MFRC522      Arduino       NodeMCU
 *             Reader/PCD   Uno/101       ESP8266MOD
 * Signal      Pin          Pin           Pin
 * ------------------------------------------------------
 * RST/Reset   RST          9             any, recommended 5
 * SPI SS      SDA(SS)      10            any, recommended 4, possible 15
 * SPI MOSI    MOSI         11 / ICSP-4   13
 * SPI MISO    MISO         12 / ICSP-1   12
 * SPI SCK     SCK          13 / ICSP-3   14

```

io 15 is SS if esp8266 is slave. but this pin must be LOW at boot. you can use it as SS if SS pin of reader doesn't pull-up.

io 4 and io 5 are untroubled pins.

io 0 and io 2 are with io 15 boot configuration pins and can be used only if they don't change the required boot state.

io 1 and io 3 are Serial interface

io 16 is RTC pin and is used for wake up from deep slepp

warning: does the reader work with 3.3 V?
> 0 votes

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