# Question
Title: What happens if there is a runtime error?
What happens if there is a runtime error in a program? Will execution of the program just stop? Is there some way I can get the Arduino to tell me what the error is?

# Answer
> 21 votes
First, let's see a few examples of what can go wrong.

# Uninitialized local variables

```
void setup() {
  int status;
  pinMode(13, OUTPUT);
  digitalWrite(13, status);
}

```

As pointed out by Edgar Bonet in the comments, local variables like `status` in the code above are not implicitly initialized by the C++ compiler. So, the outcome of the code above is indeterminate. To avoid that, make sure you always assign values to your local variables.

Things are a bit different with global and static variables:

> Global and static variables are guaranteed to be initialized to 0 by the C standard.

Source: AVR Libc Reference Manual - Frequently Asked Questions - Shouldn't I initialize all my variables?

That means you shouldn't worry about initializing them to 0 in your code. In fact, you should really avoid it, as the initialization may waste memory. Only initialize them to values other than 0.

# Memory overflow

```
int array[10];
int v = array[100];
array[-100] = 10;

```

The first problem here is that you don't know what will be assigned to v, but worse is that you don't know what you messed up with the assignment to position -100 of `array`.

# Jump to an illegal instruction

```
void doSomething( void ) {
    for (int i = 0; i < 1000; i++);
}

void setup ()
{
    void (*funcPtr)( void );

    funcPtr = &doSomething;
    funcPtr(); // calls doSomething();

    funcPtr = NULL;
    funcPtr(); // undefined behavior
}

```

The first call to `funcPtr()` will actually be a call to `doSomething()`. Calls like the second one may lead to undefined behavior.

# Other bad things that may happen

Well, you can run out of RAM, for example. What else. In any case, I think your program will keep running, probably not the way you intended it to.

# Kinds of Protection

In computer systems, problems like these are usually dealt with at various levels:

1. By the compiler
2. By the programming language runtime (as in Java for example).
3. By the operating system or the processor (if your memory access a position outside the boundaries of the address space reserved to your program, the OS or the processor may have safety mechanisms to prevent that)

Arduinos only have limited protection of the compiler, and probably nothing else. The good news is that they aren't multi-tasked, so the only program being affected is yours. In any case, any of those bugs will lead to erratic behavior.

# The Answers

The assumptions are the all of the problems I stated above are runtime problems.

> What happens if there is a runtime error in a program?

The program will continue and what happens will depend on the side-effects of the runtime error. A call to the null function pointer will probably make the program jump to an unknown location.

> Will execution of the program just stop?

No, it will keep going as if nothing extraordinary happened, probably doing what you didn't intend it to do. It may reset or act erratically. It may turn some inputs into outputs and burn a sensor or two (but that's *highly unlikely*).

> Is there some way I get the Arduino to tell me what the error is?

I don't think so. As I said earlier, the protection mechanisms aren't there. There's no runtime support from the language, no OS, no hardware checks for out-of-bounds memory access (the bootloader doesn't count as either). You just have to be careful with your program and probably set your own safety nets.

The reason for the lack of protection is probably because Arduino controllers are too cheap, have too little memory, and should not run anything too important (yes, there seems to be a disclaimer by AVR somewhere for you not to use the MCUs normally used by Arduino in life support systems).

# Answer
> 9 votes
There are no runtime exceptions. There is only undefined behaviour.

Really, there are no exceptions *at all*. If you try to perform an invalid operation, it's results will be unknown.

There is no runtime checking at all, except what **you** implement. Your program is running on bare-metal hardware. It's the Desktop equivalent of running in ring-0 all the time, because the ATmega *doesn't have rings*.

# Answer
> 6 votes
There is one mechanism that can get MCU from erratic state and it's the **watchdog timer**. If you're implementing some code that will repeatedly run in a loop, that will not run anytime longer than some fixed time, you can set this time as watchdog period and enable the timer.

Then, you have to repeatedly reset the timer in the loop. If your code freezes at some condition loop that will never end, then the watchdog will count to zero and eventually reset the MCU.

This way you are losing data, but if you run the AVR WDT in interrupt mode, you can store some data before resetting the MCU.

So the watchdog timer can guard your code from occasional unintended endless loops.

Documentation: AVR132: Using the Enhanced Watchdog Timer

# Answer
> 5 votes
You'd need a hardware debugger for something like this. But usually you'll see the program not behaving as you expect it to and will have to look at that section of the code to identify the problem.

A common/quick/easy way to do this is to add print statements to print out the values of variables or just anything so you know the program gets to that point in the code without a problem. This will help you isolate the problem further.

I believe VisualMicro has some debugging functionality built in.

# Answer
> 3 votes
I would assume the AVR CPU doesn't have any error detection or recovery tools. It may just stop, or keep going ignoring the error and the consequences. Like sachleen said, you should add some debug statements in your program that print out data in the middle of an operation, to test if it's working. If you use an emulaor and set breakpoints, you could easily find a problem.

# Answer
> -1 votes
I wrote an \*.ino environment:

```
// Testing environment for Arduino sketch files.
// Aduino IDE 2.3.0
// Author   : Anders Munck
// Released : 2024 02 09

#include <iostream>

const bool LOW=false;
const bool HIGH=true;
const bool INPUT=false;
const bool OUTPUT=true;
const unsigned char LED_BUILTIN=13;

using namespace std;

void where(std::string hank)
{ cout <<"Where : "<<hank<<"\n"; }

int random(int max)
{ return std::rand(); }

unsigned long klokken=0;
unsigned long int millis()
{ klokken++;
  cout <<"When : "<< klokken <<"\n";
  return klokken;
}

class SERIAL
{ public:
    void begin(int Baud)
    { cout<<"Arduino sketch : Serial.begin()\n"; };
    void end()
    { cout<<"Arduino sketch : Serial.end()\n"; };
    void print(std::string A)
    { cout<<"Arduino sketch : print()\n"; };
    void println(std::string A)
    { cout<<"Arduino sketch : println()\n"; };
} Serial=SERIAL();

void digitalWrite(unsigned char A,bool S)
{ cout << "Arduino sketch : digitalWrite()\n"; }

void pinMode(unsigned char A,bool S)
{ cout << "Arduino sketch : pinMode()\n"; }

// Include Your Arduino sketch file here:
#include "signal.ino"

int main()
{ setup();
  for(int i=0;i<100;i++){ loop(); };
  return 0;
}

```

The purpose is to get run time error messages from the \*.ino sketch.

You will not get usefull timing information this way, as the program is running on another processor.

I run it with a GPU C++ IDE.

Please regard my code as preliminary ad-hoc program; You may need to develop further for Your needs.

---
Tags: sketch
---


title: FastLed (WS2812B) and IRRemote problem

text:
# Question
Title: FastLed (WS2812B) and IRRemote problem
I am trying to control my WS2812B with a remote control. To archive this, I am using IRRemote library. The problem is that this two libraries doesn't work together.

I did some research and found out that it is a problem with timers.But, inside the IRRemote library file (boarddefs.h) there is a possibility to choose different timer (It uses TIMER2 as default, so I supposed that FastLed uses also Timer2).

So when I change the timer in boarddefs.h file to TIMER1, it is also now working fine for me. I keep recieving random IR codes. When I stop using FastLed library, I recive correct codes.

Some workaround to this problem is to read IR signal only once irrecv is idle:

```
  while (!irrecv.isIdle());  // if not idle, wait till complete
  if (irrecv.decode(&results)) {
     ...
  }

```

It makes around 80% of readings correct.

I am using arduino NANO clone. My question is, if there is any way to use IRRemote and FastLed libraries together other than using two arduino NANO (use one to read IR and other to control LEDs)?

# Answer
update in 2021, similar problem, fastLED causing unintelligible IR codes, adding that while loop:

```
while (!irrecv.isIdle());  // if not idle, wait till complete

```

just before the ir check worked for me, not 100% of the codes are correct but more than good enough for my use, you life saver
> 2 votes

# Answer
The WS2812B chips are highly timing-dependent. You have to clock out bits within a range of ±150 ns. This isn't likely to work well with clocking in bits from an IR remote. You are finding errors on the IR codes - that doesn't surprise me.

I suggest you use your idea of two Nanos. One can be reading IR codes. The other can display a stream of pixels and then "ask" the other one (eg. via serial or I2C) if a different command has arrived. That way the timing can be shifted in such a way that both processors are not interrupted when they are busy.
> 1 votes

# Answer
I want to add my two cents at the solution posted bt @BenAshmore, that allow to mediate between fast updates and receiving sensible data:

```
void loop() {

 if(IrReceiver.decode()){
    if( IrReceiver.decodedIRData.protocol == UNKNOWN ){
        wantData=true;
    }else{
        wantData=false;
        Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
    }
    IrReceiver.resume(); // Enable receiving of the next value
  }

  if(!wantData || IrReceiver.isIdle() ){
    FastLED.show();

  }

```

basically if I receive messy IR data I know there is something incoming and just in that case I interrupt the FastLed updating until I read something good.
> 0 votes

---
Tags: serial, led, timers
---


title: String or unsigned char to uint8_t

text:
# Question
Title: String or unsigned char to uint8_t
I'm attempting to save a string to EEPROM of an ESP8266 radio and then read it back before I encrypt the data (evenutally I would like to save the encrypted data but I'm simplifing things at the moment). Here is the source code:

```
#include <Arduino.h>
extern "C"
{
    #include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Key Slot number
uint8_t KEY_SLOT = (uint8_t)9;

ATCAIfaceCfg cfg;
ATCA_STATUS status;

void writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
  byte len = strToWrite.length();
  EEPROM.write(addrOffset, len);
  for (int i = 0; i < len; i++)
  {
    EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
  }
}

String readStringFromEEPROM(int addrOffset)
{
  int newStrLen = EEPROM.read(addrOffset);
  char data[newStrLen + 1];
  for (int i = 0; i < newStrLen; i++)
  {
    data[i] = EEPROM.read(addrOffset + 1 + i);
  }
  data[newStrLen] = '\0';
  return String(data);
}

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

    // Init the constuctor for the library
    cfg.iface_type = ATCA_I2C_IFACE;  // Type of communication -> I2C mode
    cfg.devtype = ATECC608A;          // Type of chip
    cfg.atcai2c.slave_address = 0X30; // I2C address of the Adafruit Breakout Board
    cfg.atcai2c.bus = 1;
    cfg.atcai2c.baud = 100000;
    cfg.wake_delay = 1500; // Delay of wake up (1500 ms)
    cfg.rx_retries = 20;
    atca_trace_config(stdout);
}

void loop()
{
    ATCA_STATUS status = atcab_init(&cfg);
    if (status != ATCA_SUCCESS)
    {
        Serial.println(F("atcab_init() failed : Code -> 0x"));
        Serial.println(status, HEX);
    }
    writeStringToEEPROM(0, "test");
    String retrievedString = readStringFromEEPROM(0);
    uint8_t plaintext = atoi(retrievedString.substring(1,3).c_str());
    uint8_t iv[IV_LENGTH_CBC];
    uint8_t cypherdata[sizeof(plaintext)];

    Serial.println("Beginning of the encryption !");
    status = aes_cbc_encrypt(&cfg, plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
    if (status == ATCA_SUCCESS)
    {
        Serial.println("encrypted");
    }
    else
    {
        // See file atca_status.h for the code Error
        Serial.print(F("Impossible do the encryption | Code Error 0x"));
        Serial.println(status, HEX);
        return;
    }
}

```

and here is the error message:

EDIT\**: Found out that the "Save to EEPROM" portion of my code wasn't working so I corrected that. Here is the new code:

```
#include <Arduino.h>
extern "C"
{
    #include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Key Slot number
uint8_t KEY_SLOT = (uint8_t)9;

ATCAIfaceCfg cfg;
ATCA_STATUS status;

void setup()
{
    Serial.begin(74880);
    // Init the constuctor for the library
    cfg.iface_type = ATCA_I2C_IFACE;  // Type of communication -> I2C mode
    cfg.devtype = ATECC608A;          // Type of chip
    cfg.atcai2c.slave_address = 0X30; // I2C address of the Adafruit Breakout Board
    cfg.atcai2c.bus = 1;
    cfg.atcai2c.baud = 100000;
    cfg.wake_delay = 1500; // Delay of wake up (1500 ms)
    cfg.rx_retries = 20;
    atca_trace_config(stdout);
}

void loop()
{
    ATCA_STATUS status = atcab_init(&cfg);
    if (status != ATCA_SUCCESS)
    {
        Serial.println(F("atcab_init() failed : Code -> 0x"));
        Serial.println(status, HEX);
    }
    uint addr = 0;
    struct
    {
      uint val = 0;
      char str[16] = "";
    } data;

    EEPROM.begin(512);// commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
    strcpy(data.str,"test");
    EEPROM.put(addr,data);
    EEPROM.commit();
    EEPROM.get(addr,data);
    Serial.println(String(data.str));

    uint8_t plaintext = atoi(data.str);
    //uint8_t plaintext[16] = "test";
    uint8_t iv[IV_LENGTH_CBC];
    uint8_t cypherdata[sizeof(plaintext)];
    uint8_t decryptdata[sizeof(plaintext)];

    Serial.println("Beginning of the encryption !");
    status = aes_cbc_encrypt(&cfg, &plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
    if (status == ATCA_SUCCESS)
    {
        Serial.println("encrypted");
        status = aes_cbc_decrypt(&cfg, cypherdata, sizeof(cypherdata), iv, decryptdata, KEY_SLOT);
        if (status == ATCA_SUCCESS)
        {
            Serial.print("Decrypted text is : ");
            for (size_t i = 0; i < sizeof(decryptdata); i++)
            {
                Serial.print((char)decryptdata[i]);
            }
            Serial.println("");
        }
    }
    else
    {
        // See file atca_status.h for the code Error
        Serial.print(F("Impossible do the encryption | Code Error 0x"));
        Serial.println(status, HEX);
        return;
    }
    delay(1000);
}

```

Now I'm seeing this in the terminal (no errors on compile!):

```
encrypted
ERROR Decrypt : ATCA_BAD_PARAMI2C send 1 bytes to addr 0x30: 01

```

When I change (the aes\_cbc\_encrypt function expects a length of 16)

```
sizeof(plaintext)

```

to

```
16

```

I see:

```
Decrypted text is : ␀␀␀␀␀␀␀␀l��?���?

```

When I proved that the encrypt/decrypt portion of my code was working, this is what "plaintext" was:

```
 uint8_t plaintext[16] = "test";

```

# Answer
> 0 votes
The function `atoi()` tries to interpret a string as a textual representation of a number written in decimal. For example, `atoi("42")` returns the integer 42. Here:

```
uint8_t plaintext = atoi(data.str);

```

You are asking it to interpret `"test"`, which does not look like a number. In such a case, `atoi()` returns zero. I do not know what was your intent, but it was probably not this.

Further down, you have

```
uint8_t cypherdata[sizeof(plaintext)];
uint8_t decryptdata[sizeof(plaintext)];

```

Given that `plaintext` is a single byte, its length is one. Thus this is declaring two arrays of length one. Again, you probably meant something else.

---

From you comment, I understand that you want `plaintext` to represent the string `"test"` as an array of `uint8_t`. Since both `char` and `uint8_t` represent bytes, no conversion is needed. You can simply use the address of the original `char` array and “pretend” it is the address of an array of `uint8_t`:

```
uint8 *plaintext = (uint8_t *) data.str;

```

---
Tags: esp8266, string, eeprom, platformio
---


# Question
Title: Code review for timer using RTC and OLED screen
I am building a small art project to display my current age with an accuracy of 1/100th of a second. I am using a XIAO SAMD21, a DS3231 RTC, and a 128x32 OLED screen. Here is what it looks like right now without the battery:

My aim is to fit this and a battery into a locket / necklace. I want to make as low-power as possible so that it can last at least an hour or two on a 75 mAh Li-po. I can't use a bigger battery since it wouldn't fit in the necklace.

I wrote the code to the best of my ability and it looks like it works really well. I just want a sanity check to make sure there isn't a simpler way of doing things. In particular I feel like the calculation of the age in the main loop, the syncing with RTC, and maybe the display updates, could be done in a better way. Maybe there are some things I do with interrupts and the 'alarms' in the RTC? Just power on the display every other second maybe. I am also considering using an epaper display and removing the power LED.

The code is attached here. I use the Adafruit libraries to drive the SSD1306 on the OLED screen, and one of the DS3231 libraries to interface with the RTC. Parts of it are adapted from examples, so there may be some extraneous imports or declarations I don't need.

```
// TUNIO 2024
// Age Pendant

// TO DO:
// current loop is 17 to 18 milliseconds long - need less than 5 for accurate centi-second counting

// Libraries
#include <SPI.h>
#include <Wire.h>
#include <DS3231.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED Setup ~ copied from example
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// RTC Setup
RTClib myRTC;

// Initializations for periodic sync with RTC
uint32_t remote_time = 0;
uint32_t sync_interval_ms = 1800000; // sync with RTC every sync_interval_ms milliseconds // about an hour is good
uint32_t last_millis_synced = 0; // the last time we synced with RTC
uint32_t system_time = 0; // the local system time

// Initializations for age calcs
// QUESTION us 32 bit enough to store the age of someone? What if they live to 100?
uint32_t born_utime = 788888888; // date of birth in unixtime // 788888888
uint32_t total_age_secs = 0;
uint32_t sec_remainder = 0;
uint8_t age_years = 0;
uint8_t age_months = 0;
uint8_t age_days = 0;
uint8_t age_hours = 0;
uint8_t age_mins = 0;
uint8_t age_secs = 0;

// initializations for centi-second counting
uint8_t oldsec = -1;
uint8_t newsec = -1;
uint32_t offset = 0;
uint8_t age_cs = 0;

// screen saving vars
bool invert = false;

//// debug
//uint32_t start_millis=0;
//uint32_t end_millis=0;

void setup() {
  Serial.begin(57600);
  Wire.begin();
  delay(250);

  // display setup
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.dim(true);
  display.setTextColor(SSD1306_WHITE);
  display.clearDisplay();
  display.setTextSize(2); // 1 default
  display.setRotation(3); //0 default, 1, 2, 3

  // turn off built in LED
  pinMode(LED_BUILTIN , OUTPUT);
  digitalWrite(LED_BUILTIN , HIGH);

  // do first sync
  sync_time_with_rtc();
}

void loop() {
//  //debug
//  start_millis = millis();

  // sync every sync_interval_ms with RTC
  if (millis() - last_millis_synced >= sync_interval_ms) {
    sync_time_with_rtc();
  }

  // Calculate time elapsed since birth in years, months, etc.
  system_time = local_time_now();
  total_age_secs = system_time - born_utime; // age in seconds
  age_years = num_time_units(total_age_secs, 31558149.756); // second arg is num of: secs in a year
  age_months = num_time_units(sec_remainder, 2629745.568); // ... secs in a month
  age_days = num_time_units(sec_remainder, 86401.505); // ... secs in day
  age_hours = num_time_units(sec_remainder, 3600); // ... in an hour
  age_mins = num_time_units(sec_remainder, 60); // ... in an minute
  age_secs = sec_remainder;

  // display the age calculated
  show_age_on_display(5, 3); // input top left coordinates of where the age will be displayed

//  //debug
//  end_millis = millis();
//  Serial.println(end_millis - start_millis,DEC);
}

// Prints the provided age to the LCD with the correct formatting
void show_age_on_display(int col, int line) {
  newsec = age_secs;
  if (newsec != oldsec) {
    offset = -1 * (millis() % 1000);
    if (age_secs % 11 == 0) {invert = ! invert;} // invert display to save pixels burning every 11 secs
    oldsec = age_secs;
  }

  display.clearDisplay();
  display_at_location(age_years, col, line);
  display_at_location(age_months, col, line + (13 + 5) * 1);
  display_at_location(age_days, col, line + (13 + 5) * 2);
  display_at_location(age_hours, col, line + (13 + 5) * 3);
  display_at_location(age_mins, col, line + (13 + 5) * 4);
  display_at_location(age_secs, col, line + (13 + 5) * 5);
  age_cs = floor(((millis() + offset) % 1000) / 10);
  display_at_location(age_cs, col, line + (13 + 5) * 6);

  display.fillRect(0, display.height() - 18, display.width(), 18 - ((18 * age_cs) / 100), SSD1306_INVERSE); // progress bar completes every second

  display.invertDisplay(invert);
  display.display();
}

// display integer value <100 at given location with "0" padding
void display_at_location(uint8_t value, uint8_t this_col, uint8_t this_line){
  display.setCursor(this_col, this_line);
  if (value < 10) display.print(F("0"));
  display.print(value, DEC);
}

// input seconds and returns number of whole time unit, sets remainder variable
uint32_t num_time_units( uint32_t secs, float time_unit) {
  int num_units = floor(secs / time_unit);
  sec_remainder = secs - round(num_units * time_unit);
  return num_units;
}

// syncs time with the RTC: call on sync_interval, power ons, AND when wake from sleep
void sync_time_with_rtc() {
  digitalWrite(LED_BUILTIN , LOW); // briefly flash the LED every sync with the RTC
  remote_time = myRTC.now().unixtime();
  last_millis_synced = millis();
  system_time = local_time_now();
  digitalWrite(LED_BUILTIN , HIGH);
}

// fetches the unixtime according to Arduino
uint32_t local_time_now() {
  return remote_time + floor((millis() - last_millis_synced) / 1000);
}

```

# Answer
> 0 votes
I see quite a bit of floating point computations here. Since the SAMD21 doesn't have a floating point unit, all float operations are implemented in software, which can be quite expensive. As an optimization, I suggest to stay as much as possible in the integer realm. For example:

```
uint32_t total_minutes = total_age_secs / 60;
age_secs = total_seconds - total_minutes * 60;
uint32_t total_hours = total_minutes / 60;
age_mins = total_minutes - total_hours * 60;
uint16_t total_days = total_hours / 24;
age_hours = total_hours - total_days * 24;
age_years = total_days / 365;
uint16_t remaining_days = total_days - age_years * 365;
age_months = remaining_days * 12 / 365;
age_days = remaining_days - age_months * 365 / 12;

```

Note that there is some rounding here: a day is assumed to be exactly 86400 seconds instead of 86399.9999 (I don't know where you found the number 86401.505), a year is assumed to be 365 days, and all months are assumed to be equal. If you found this approximations too rough (mostly the year), you may use 365.25 = 1461 / 4 days per year and 1461 / 48 days per month. You can do this by replacing the last four lines with:

```
age_years = total_days * 4 / 1461;
uint16_t remaining_days = total_days - age_years * 1461 / 4;
age_months = remaining_days * 48 / 1461;
age_days = remaining_days - age_months * 1461 / 48;

```

---
Tags: power, code-review, rtc, oled, seeeduino-xiao
---


title: SdFat.h pin selection ESP8266

text:
# Question
Title: SdFat.h pin selection ESP8266
This super simple code, that saves data to a csv file, works perfectly fine on my Arduino Uno (I am using the default SPI pins).

However, for my project I need to use an ESP8266. Does the library automatically use the default SPI pins for any other boards?

In my code I have tried changing the CS pin from 10 to 15 for the ESP8266. All I get is "Initialization failed"! I figure, I need to somehow change the other SPI pins like MOSI, MISO and SCK. Is there a way to do this? I'm an absolute noob so sorry in advance if I oversaw some kind of easy fix.

```
#include <SdFat.h>

SdFat sd;
SdFile file;

void setup() {
  Serial.begin(9600);
  if (!sd.begin(10, SD_SCK_MHZ(50))) {
    Serial.println("Initialization failed!");
    return;
  }

  if (!file.open("data.csv", O_RDWR | O_CREAT | O_AT_END)) {
    Serial.println("Error opening file!");
    return;
  }

  file.println("Sensor1,Sensor2,Sensor3");
}

void loop() {
  float sensorReading1 = 1;
  float sensorReading2 = 1;
  float sensorReading3 = 1;

  file.print(sensorReading1);
  file.print(",");
  file.print(sensorReading2);
  file.print(",");
  file.println(sensorReading3);

  file.sync();

  delay(1000);
}

```

# Answer
So I just tried again and somehow I happened to replace the SD\_SCK\_MHZ(50), that worked on my arduino Uno, with SPI\_HALF\_SPEED. Now the same code as above works perfectly fine on my esp8266.
> 0 votes

---
Tags: esp8266, nodemcu, sd-card
---


# Question
Title: Guide to code for multitasking and non blocking timers
I'm beginning to do kind of sophisticated things (well.. for my entry level skill) and I have to control a display with 3 LED and 4/5 types of events and status.

I'm using the BlinkWithoutDelay example duplicating all the variables for different status/events but the code is really messy, full of puzzling nested `if` statements.

How to simplify the things? I don't know what to choose, because OOP could be a choice but I think it will hurt the low-memory thing inside the Arduino Uno/Leonardo. Interrupts could be another choice but I think they are like threads, and following the KISS principle I'd like to stay away from them.

So, can someone advice me some article/tutorial/code-to-read/whatever to understand how to use a lot of LEDs and keep a lot internal status without screw my brain?

## EDIT:

It is a little bit hard to reproduce a simple skelton of my messy code, but it looks like this (in pseudocode maybe)

```
void loop() {
    if(state==0) handleState0();
    if(state==1) handleState1();
    if(state==2) handleState2();
    if(state==3) handleState3();
    readButtons();
    readSensors();
    …
}

// this is a block of variables that I have to copy-and-paste
// every time I have to blink a led (hoping that there is
// nothing blocking that can skrew up everything)
unsigned long previousMillis_1 = 0;
const long interval_1 = 1000;
int ledState_1 = LOW;

void handleState1() {
  // Green led blinking, yellow is fixed
  // this is a copy-and-paste code hard to maintain,
  // easily broken from any blocking call (like also I2C)
  // and hard to refactor or isolate
  unsigned long currentMillis_1 = millis();
  if(currentMillis_1 - previousMillis_1 >= interval_1) {
    previousMillis_1 = currentMillis_1;
    if (ledState_1 == LOW) ledState_1 = HIGH;
    else ledState_1 = LOW;
    digitalWrite(pinGreen, ledState_1);
    digitalWrite(pinYellow, LOW);
}

unsigned long previousMillis_2 = 0;
const long interval_2 = 1000;
int ledState_2 = LOW;

void handleState2() {
  // Yellow led blinking, green is fixed
  // same as before
  unsigned long currentMillis_2 = millis();
  if(currentMillis_2 - previousMillis_2 >= interval_2) {
    previousMillis_2 = currentMillis_2;
    if (ledState_2 == LOW) ledState_2 = HIGH;
    else ledState_2 = LOW;
    digitalWrite(pinYellow, ledState_2);
    digitalWrite(pinGreen, LOW);
}

void handleButtonPressed() {
  // this skrew everything and because is blocking
  // and should be inserted in the main loop with
  // some global variables: active/disable, counter,
  // and non-blocking vars like previousMills, interval, etc etc
  Serial.println("\ndisplayAccessDenied");
  for(int i=0; i<3; i++) {
    digitalWrite(pinRed, LOW);
    delay(100);
    digitalWrite(pinRed, HIGH);
    delay(100);
  } digitalWrite(pinRed, LOW);
}

```

I feel a little bit lost but all the Arduino example arounds are super simple and to make a middle-level LED interface I have to screw my minds with something that is not working as 100% and other than Arduino I find only super-hard articles on microprocessors with low-level C code. But the pasted example is not working at 100% AND super hard to read, maintain, etc.

# Answer
> 3 votes
It is not really clear what you want here...

If you want to execute things in a certain time, then take a look at http://playground.arduino.cc/Code/Scheduler

Or, if you want more than just that (multiple tasks, preemptive multitasking) https://launchpad.net/arduos (arduOS can also just serve to run things in a certain time, but without having to use a function all the time)

While OOP MIGHT take more program memory, an object without virtual functions only takes the RAM the variables in it take (if you have a byte (1 byte) and an int (2 bytes) in an object it would take 3 bytes)

On the AVR-architecture (the one most Arduinos use) the program is directly executed from a flash-memory and only the variables are in the RAM

The if-state-handling you are doing there can be done easier using arrays like:

```
typedef void(*handler)(void)
handler stateHandlers[STATES] = {&handle1, &handle2, &handle3 ...
// handle? are functions without the () !
void handleState(int state)
{
    if(state >= STATES)
        return;
    stateHandlers[state]();
}

```

Obviously, you can also use arrays to store the states of the LEDs.

Also note that `HIGH` is just 1 and `LOW` is 0, so technically a bit would be enough to store the states.

# Answer
> 2 votes
Following the KISS principle, I have recently published the Instructable "Simple Multi-tasking in Arduino on any board"

It covers non-blocking delays, non-blocking serial output, non-blocking user input, removing delays from third party libraries, and loop timers, so you can see and adjust the response/latency of your tasks.

Here is some example code

```
void loop() {
 callTask_1(); // do something
 callTask_2(); // do something else
 callTask_1(); // check the first task again as it needs to be more responsive than the others.
 callTask_3(); // do something else
}

```

The trick is that each callTask..() method must return quickly so that the other tasks in the loop get called promptly and often. The rest of the instructable covers how to keep your tasks running quickly and not holding everything up, using a temperature controlled, stepper motor driven damper with a user interface as a concrete example.

Finally the instructable moves the code, unchanged, to an ESP32 to add remote control via Wifi, Bluetooth or BLE, to the temperature controlled, stepper motor driven damper.

Drop me a message/email via Instructables or my website, if you are unclear about anything in the instructable.

# Answer
> 1 votes
Cosa supports a large number of mechanisms for multi-tasking. The latest addition is an abstract class for Jobs (delayed or periodic functions) and Job Schedulers. This abstraction allows functions to be scheduled on micro-, milli- and seconds level.

To get started please see the Cosa example sketches. If you have an Logic Analyzer (Salea Logic for instance) there are a number of example sketches that show pulse generation.

There is also a binding of the Job Scheduler to a seconds tick level. This is abstracted to Clock and Alarms.

For higher abstraction of multi-tasking Cosa also implements FSM, Proto-threads, Threads (multi-stacks), UML Capsules, and more.

# Answer
> 1 votes
Here's an example of blinking two LEDs independently:

```
// Which pins are connected to which LED
const byte greenLED = 12;
const byte redLED = 13;

// Time periods of blinks in milliseconds (1000 to a second).
const unsigned long greenLEDinterval = 500;
const unsigned long redLEDinterval = 1000;

// Variable holding the timer value so far. One for each "Timer"
unsigned long greenLEDtimer;
unsigned long redLEDtimer;

void setup ()
  {
  pinMode (greenLED, OUTPUT);
  pinMode (redLED, OUTPUT);
  }  // end of setup

void toggleLED (const byte which, unsigned long & whenToggled)
  {
   if (digitalRead (which) == LOW)
      digitalWrite (which, HIGH);
   else
      digitalWrite (which, LOW);
  // remember when we toggled it
  whenToggled = millis ();
  }  // end of toggleLED

void loop ()
  {
  // Handling the blink of one LED.
  if ( (millis () - greenLEDtimer) >= greenLEDinterval)
     toggleLED (greenLED, greenLEDtimer);

  // The other LED is controlled the same way. Repeat for more LEDs
  if ( (millis () - redLEDtimer) >= redLEDinterval)
    toggleLED (redLED, redLEDtimer);

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

  }  // end of loop

```

Note that instead of copying and pasting the blinking code, I made a generic function. That way any bugs are easily fixed.

---

For more LEDs you could use an array:

```
const int NUMBER_OF_LEDS = 5;
// Which pins are connected to which LED
const byte LED_PINS [NUMBER_OF_LEDS] = { 8, 9, 10, 11, 12 };
// Time periods of blinks in milliseconds (1000 to a second).
const unsigned long LED_INTERVALS [NUMBER_OF_LEDS] = { 200, 400, 100, 1000, 2000};
// Variable holding the timer value so far. One for each "Timer"
unsigned long timeLEDtoggled [NUMBER_OF_LEDS];

void setup ()
  {
  for (int i = 0; i < NUMBER_OF_LEDS; i++)
    pinMode (LED_PINS [i], OUTPUT);
  }  // end of setup

void toggleLED (const byte which, unsigned long & whenToggled)
  {
   if (digitalRead (which) == LOW)
      digitalWrite (which, HIGH);
   else
      digitalWrite (which, LOW);
  // remember when we toggled it
  whenToggled = millis ();
  }  // end of toggleLED

void loop ()
  {
  // see if it is time to toggle the LEDs
  for (int i = 0; i < NUMBER_OF_LEDS; i++)
    if ( (millis () - timeLEDtoggled [i]) >= LED_INTERVALS [i])
       toggleLED (LED_PINS [i], timeLEDtoggled [i]);

  /* Other code that needs to execute goes here. */
  }  // end of loop

```

If anything, the above code is simpler, but it blinks 5 LEDs at different rates. Now you can have more sophisticated tests than that, but the general concept is the same.

---

## References

# Answer
> 0 votes
Use the NonBlockingSequence library. It has clean examples for applying blinking sequences without delay. (Example Link)

```
    #include <NonBlockingSequence.h>

class Blinking_Led{

  private:
  // Declare Sequence
  ClassNonBlockingSequence<Blinking_Led> Sequence;

  // led pin
  byte _pin;

  // Define step-functions
  bool led_on(){
    digitalWrite(_pin,1);
    return true;
  }
  bool led_off(){
      digitalWrite(_pin,0);
      return true;
  }

  public:
  Blinking_Led(){};
  void init(byte pin,unsigned long pause){

    // define the led pin
    _pin=pin;
    pinMode(_pin,OUTPUT);

    // This line explain important fact for the Sequence
    Sequence.AttachedObj(this);
    // Sequence should use steps defined inside this class only

    // Add steps
    Sequence.AddNewStep(&led_on);
    Sequence.AddDelayInMillis(pause);
    Sequence.AddNewStep(&led_off);
    Sequence.AddDelayInMillis(pause);
    Sequence.Repeat();
    // repeat the sequence infinite number of times

  }

  Blink(){ // use familiar name for led
    Sequence.DoSequence();
  }

};

// Declare new objects
Blinking_Led Led1;
Blinking_Led Led2;

void setup() {

  //  Led.init( pin , blinking time )
  Led1.init(13,200);
  Led2.init(12,1500);

}

void loop() {
  // put your main code here, to run repeatedly:
  Led1.Blink();
  Led2.Blink();
}

```

---
Tags: programming
---


# Question
Title: Having issues with RS232 UART wiring to a physical PC connection
**TL;DR:** Attempting to connect UART2 on ESP32-WROOM to a physical PC RS232 results in odd behavior and ESP32 crashes or errors. Suspect electrical design problems. Wondering if I need special consideration for voltages or diodes to avoid feedback to GPIO connectors on ESP side.

---

Hello! I'm relatively new to the community. I'm attempting to build a tool that will interact with a video conference bridge on its serial port to do room automation (mute/unmute/answer/raise\_blinds/dim\_lights/etc). Since the bridge interface is serial, I want to have two usable RS232 ports. One to interact with the bridge and the other to act as a console for troubleshooting and configuration.

I've purchased several ESP32-WROOM kits and have a good portion of the rest of the tool built, but I'm now struggling with getting UART2 to talk to my physical serial port on my PC so I can troubleshoot the actual bridge interactions. I've built a test sketch that just sends "Hello!" every second or so to UART2 and echoes anything it receives on UART2 back to UART0. UART0 is set for 115200 and UART2 is set to 9600. I have changed this to match and it made no difference.

**Configuration:**

* UART0 is 115200,8N1 on standard USB console.
* UART2 is 9600,8N1 on default GPIO 17/18 (TX2/RX2).
* Pin17/18 and ground are wired to an 8 port single row header which is then plugged into a Teansic RJ45 breakout board.
* Using Arduino IDE serial monitor to observe. Shows as COM3 on my PC.
* UART2 is connected to a StarTech USB to RJ45 adapter made specifically for Cisco consoles (ICUSBROLLOVR) it shows as COM7 and I'm just using Putty to observe.

**Sketch:**

```
#include <HardwareSerial.h>

#define RXD2 16
#define TXD2 17
#define Serial0 Serial
#define Serial2 SerialPort

HardwareSerial Serial2(2);

void setup() {
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  Serial0.begin(115200);
}

void loop() {
  while (Serial2.available()) {
    Serial0.printf("[%012d]      In: ", esp_timer_get_time());
    //Serial0.print(char(Serial2.read()));
    Serial0.print(Serial2.readStringUntil('\n'));
    Serial0.print("\n");
  }
  while (Serial0.available()) {
    Serial2.printf("\n[%012d]  Insert: ", esp_timer_get_time());
    //Serial0.print(char(Serial2.read()));
    Serial2.print(Serial0.readStringUntil('\n'));
    Serial2.print("\n");
  }
  Serial0.printf("[%012d]     Out: ", esp_timer_get_time());
  Serial0.print("Hello!\n");
  Serial2.print("Hello!\n");
  delay(1100);

}

```

**Behaviors:**

When I connect my PC up, it receive characters but they are (consistent) garbage of about the right number of characters. It looks like:

```

▒::
   ▒[▒::
        ▒[▒::
             ▒[▒::
                  ▒[▒::
                       ▒

```

I sometimes receive phantom characters in from the PC even though I'm not sending anything.

If I loop UART2 back on itself (connect TX to RX at my serial header) I get a perfect response back out UART0 as though the input was coming from the PC.

If I send data from the PC to UART2, it results in crashes/errors similar to the following. The error implies it is rebooting, but it is not:

```
rst:0x7 (TG0WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0
[000000011533]     Out: Hello!
[000001111758]      In:
[000002111056]     Out: Hello!

```

I've observed the electrical output with an oscilloscope and it casually looked like a good RS232 signal. I went so far as to convert my character string to little endian binary and add the start and stop bits and it looks exactly like it should to me except that I am expecting that 0 and 1 should be in the range of -3 to -10 and +3 to +10 and instead the pattern appears to be about +400mV for 1 and markbits and just above zero for a 0 (relative to ground).

I have found very little to reference for RS232 to an actual PC. Almost everything appears to be logic level connections ESP32 to ESP32 or peripheral board to ESP32.

I suspect that this is a case of needing circuitry to convert the logic level voltages to external RS232 +10/-10v ranges and perhaps diodes or something to prevent phantom feedback since TX/RX have a shared ground, but I'm flying blind. I'm hoping someone here has experience with this and can point me to an answer or better reference materials.

# Answer
> 0 votes
I think I found the answer to my own question by Googling around for widgets.

There are a bunch of kits out there that do just this but Sparkfun was kind enough to provide me with a diagram on exactly how to build it.

SparkFun tutorial

I'll leave this out here for others and I'm still looking for feedback, but I think I have my answer.

It wasn't obvious to me (but should have been) that the board is only going to deal with low voltage positive (TTL) signals and the onboard UART doesn't magically make it inverted, higher voltage signals.

---
Tags: serial, uart, serial-data, rs232
---


# Question
Title: Attempt to change an ESP8266's flashs layout over-the-air
## Backstory

Several Tasmota devices based on an ESP8285 have to be flashed with alien firmware. The devices' programming ports are not accessible (except for one dummy device which was cracked open for testing).
The Tasmota firmware currently installed is based on the Arduino core, uses `ESP8266httpUpdate.h` and allows to OTA-update from a http server.

## Problem

The problem is that the Tasmota firmware for the ESP8266 (=8285) family always uses a 1MB partition scheme while my specific device is based on the ESP8285**H16** which incorporates 2MB of flash. The second half of flash memory is therefore unused.

## What I want to do

Using only **over-the-air updates** I want to update the Tasmota devices' flash layout so that the full 2MB of flash can be used and eventually upload a firmware that is bigger than what's currently possible.
Ideally the final flash layout uses a completely new partition scheme.

## How can it be achieved?

I know this can be challenging and will probably require multiple intermediate firmware versions. This is okay because the upgrade process will not happen "in the field" (but still no physical access to the chips) and occasional fails are acceptable - the process will be tested beforehand.

There's already a related answer from @Majenko here, but it covers the ESP32. While I know where to start with an ESP32, I'm a bit puzzled with the ESP8266/8285:

I tried to read the whole flash images of the device to get a picture of what I'm dealing with and found the flash layout to be completely different from what I'm used to (ESP32).
Mainly, there wasn't a partition table at flash address 0x8000 while the Espressif documention specifies this exact address.

I found almost no documentation about the ESP8266 partition scheme as defined by the Arduino core:

* Where in flash is the partition table?
* If there is none, how does OTA work on ESP8266?
* Where in flash is the bootloader?
* Where does the filesystem begin (if there is one)?

# Requirements

* **The flash layout needs to be changed using only OTA updates**
* Any information stored in the current flash or filesystem may be deleted
* Multi-step updates are no problem
* There's physical access to **one** device so the routine can be tested

### Edit: Illustration

This is the normal OTA routine according to the docs:

and this is what I have in mind:

But for this I need to know the borders of each section, ideally during runtime.

# Answer
> 1 votes
As it turns out the update routine of `ESPhttpUpdate.h` works just fine when the flash layout changes after an OTA update. At least in my case where the second half of flash memory is unused. If there was a file system in the initial installation, it will be lost.
Though, it should be possible to even preserve the filesystem if it is copied to the right location **before** a firmware with different partition scheme is uploaded, but I have no need to follow that path now...

## to summarize...

1. A Tasmota firmware was installed on a 2MB ESP8285H16. Since Tasmota firmware for ESP8266/8285 devices uses only 1MB of flash - maybe something like ~500kB sketch, ~400kB OTA, ~100kB FS).
The second half of flash was unused and the maximum size of a firmware that could be directly uploaded over-the-air was therefore ~400kB .
2. An intermediate firmware was provided on a http server for the device to update.
This firmware:

* was built for a 2MB flash layout (1MB sketch, ~700kB OTA, ~256kB FS)
    * contains nothing but Wifi login and the OTA routine Upon success, this update will leave the flash in the new layout
3. With the additional 300kB of OTA memory, the device could now be updated to the final firmware. This firmware was built with the same partitioning like the intermediate firmware.

This is the platformio.ini which was used in my case:

```
[env:esp8285]
platform = espressif8266
framework = arduino
board = esp8285

board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.2m256.ld
board_build.mcu=esp8285
board_upload.flash_size=2MB
board_build.flash_mode=dout

monitor_speed = 115200
upload_port = COM5

```

If there is only little space left for OTA in the original flash layout, the firmware binary can be gzip'ed to save some memory.

---
Tags: esp8266, esp32, flash, ota
---


# Question
Title: Why does my Arduino show weird characters with my code?
When I had the code run just the LCD it worked perfectly fine, but when I added an HC-SR04 without changing the text it showed weird characters. All I had the code do with the HC-SR04 was print it in the serial monitor.

```
// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 5, e = 4, d4 = 3, d5 = 2, d6 = 1, d7 = 0;
const int trigPin = A0;
const int echoPin = A1;
LiquidCrystal lcd(rs, e, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.print("zach is cool");
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  long duration, inches, cm;
  lcd.setCursor(0, 1);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}

long microsecondsToInches(long microseconds) {
  // According to Parallax's datasheet for the PING))), there are 73.746
  // microseconds per inch (i.e. sound travels at 1130 feet per second).
  // This gives the distance travelled by the ping, outbound and return,
  // so we divide by 2 to get the distance of the obstacle.
  // See: https://www.parallax.com/package/ping-ultrasonic-distance-sensor-downloads/
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the object we
  // take half of the distance traveled.
  return microseconds / 29 / 2;
}

```

# Answer
It looks like you have the LCD connected to pins 0 and 1. Those are the Serial Rx and Tx pins. When you also use Serial in your sketch it creates a conflict. Move those two lines from the LCD to different pins and update the sketch.
> 3 votes

# Answer
With the following code, I ran an HCSR04 and a 16x2 LCD with Arduino UNO. It ran successfully.

```
#define trigPin 8
#define echoPin 9
#define pinIR 7
// Define variables:
float duration=0.00;
float distance=0.00;
int visitor,sum,threshold,temp;

// declaring variables to hold the new and old IR states
boolean oldIRState = LOW;
boolean newIRState = LOW;

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
  // Define inputs and outputs:
  pinMode(pinIR, INPUT);
  pinMode(trigPin, OUTPUT);

  pinMode(echoPin, INPUT);
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Visitor=");
  lcd.print(visitor);

  //Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin by setting it LOW:
  newIRState = digitalRead(pinIR);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);
  // Calculate the distance:
  distance = duration /58.82 ;

  // Print the distance on the Serial Monitor (Ctrl+Shift+M):
  Serial.print("Distance = ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(1000);
  if(distance<=10 && abs(temp)>=70)
  {
    visitor++;
    lcd.clear();
    lcd.print("Visitor=");
    lcd.print(visitor);

  for(int i=0;i<500;i++)
 {

 sum +=distance;
 delay(5);

 }
 threshold = sum/500;
  }

temp=threshold-distance;

 if ( newIRState != oldIRState )
  {

    if ( newIRState == LOW && visitor>0 )
    {

        visitor--;
         lcd.clear();
    lcd.print("Visitor=");
    lcd.print(visitor);

      }

    }
    oldIRState = newIRState;

}

```

You can follow this code and circuit arrangement. I also suggest you check the HCSR04 and LCD separately with The Arduino. You can also check this Arduino UNO pinout configuration guideline This will be helpful for any Arduino UNO project you work on.
> 0 votes

---
Tags: arduino-uno, lcd
---


# Question
Title: Same LED but different brightness on same PIN
I connected a led to pin 7 (with a small resistance to avoid burning it) and tried the code below, with and without pinMode as output

```
void setup() {
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  digitalWrite(7, HIGH);
  delay(5000);
  digitalWrite(7, LOW);
  delay(200);

  Serial.println("hello world");
}

```

Why does commenting the line `pinMode(7, OUTPUT);` make the led dimmer ?

# Answer
All the pins are configured as INPUT by default on startup. So if you leave out the `pinMode(7, OUTPUT);`, pin 7 will still be configured as input. An Input doesn't provide any current (or only a very very low leak current), so the LED will be off in this time.

When you write HIGH to a pin, while it is configured as INPUT, you are activating the internal pullup resistor. This is a resistor (typically about 10kOhm) from the pin to Vcc (HIGH level) inside the microcontroller itself. Now a small current - set by the total resistance (your resistor + internal pullup) - can flow through the diode, making it light up very dim.

Configuring a pin as INPUT with the internal pullup resistor activated can be done in one command: `pinMode(7, INPUT_PULLUP);`, which makes the intent more clear, but does exactly the same under the hood as setting to INPUT and writing HIGH to the pin.
> 7 votes

---
Tags: led, voltage-level
---


# Question
Title: strip.clear() is not clearing/turning off the NeoPixel strip after resetting the ESP8266
In the code below which is running on a WEMOS D1 (ESP8266), a NeoPixel strip turns on 1 LED in red which moves left to right and then right to left whilst the board attempts to connect to Wi-Fi in the `while (WiFi.status() != WL_CONNECTED)` loop.

If I hold down the button 'SW' connected to the pin D7 and click the reset button, the code turns on the 7 segment display, however the LED on the NeoPixel strip which was last lit remains on (as though it is 'frozen'). Once I exit the `while(configRPM > 0){` loop, all goes back to normal and the NeoPixel strip unfreezes.

I thought `strip.clear()` would clear the NeoPixel strip near the start of `setup()` but that does not appear to work. I thought adding a delay might fix it and it hasn't. Why is the NeoPixel strip not turning off when the board is reset and how do I fix it?

Here is the code:

```
#include <ESP8266WiFi.h> // Include the ESP8266WiFi library.
#include <ELMduino.h> // Include the ELMduino library.
#include <Adafruit_NeoPixel.h> // Include the Adafruit NeoPixel library.
#include <Encoder.h>
#include <TM1637Display.h>
#include <EEPROM.h>

// Define the addresses where you want to store your variables in EEPROM
#define ADDR_MINIMUMRPM 0
#define ADDR_MAXIMUMRPM (ADDR_MINIMUMRPM + sizeof(int))

#define CLK D1
#define DT D2
#define SW D7

#define CLK_TM1637 D5
#define DIO_TM1637 D6

TM1637Display display(CLK_TM1637, DIO_TM1637);
Encoder encoder(CLK, DT);

int configTriggered = 0;
int buttonReleased = 0;
int configRPM = 0;
int minimumRPM = 2500;
int maximumRPM = 6000;
int currentPosition = minimumRPM - 100;
int oldPosition = -1000;
int newPosition = 0;

// WiFi credentials and server details
const char* ssid = "WIFI_OBDII"; // Set the SSID of the ELM327.
WiFiClient client; // WiFiClient is a class that defines how to create objects that represent WiFi clients. client is an object of this class, allowing the ESP8266 to function as a WiFi client.
ELM327 myELM327; // Creates an object named myELM327 of the ELM327 class. This object represents an instance of the ELM327 OBD-II interface, allowing the program to interact with it using methods provided by the ELM327 class.

const int neopixel_Count = 16; // Indicates that there are 16 NeoPixels in the strip, with IDs ranging from 0 to 15.
Adafruit_NeoPixel strip(neopixel_Count, D8, NEO_GRB + NEO_KHZ800); // Initializes a NeoPixel strip object with 16 NeoPixels connected to pin D2, using the color order Green-Red-Blue and a data transmission frequency of 800 KHz.

const int potentiometer_Pin = A0; // Sets the constant variable potentiometer_Pin to A0, being the ID of the analog pin

int rpm = 0; // RPM variable which is taken from the car and used in the code.

void setup() { // Setup function to initialize NeoPixels and establish WiFi and ELM327 connections.
  pinMode(SW, INPUT_PULLUP);
  Serial.begin(9600);
  display.clear();

  strip.begin(); // Initialize NeoPixels.
  delay(100);
  strip.clear(); // Initialize all pixels to 'off'.

  EEPROM.begin(sizeof(minimumRPM) + sizeof(maximumRPM));
  EEPROM.get(ADDR_MINIMUMRPM, minimumRPM);
  EEPROM.get(ADDR_MAXIMUMRPM, maximumRPM);

  if (digitalRead(SW) == LOW){
    configRPM = 1;
    display.setBrightness(0x0f); // Set brightness to maximum
    delay(50);
  }

  while(configRPM > 0){
    if (digitalRead(SW) == HIGH) {
      buttonReleased = 1;
      delay(50);
    }

    if (digitalRead(SW) == LOW && buttonReleased == 1 && configRPM == 1) {
      buttonReleased = 0;
      configRPM = 2;
      minimumRPM = currentPosition;
      Serial.println("Value saved for minimum RPM is " + String(minimumRPM));
      currentPosition = maximumRPM;
      display.showNumberDec(currentPosition);
      delay(50); // Debounce delay
    }

    if (digitalRead(SW) == LOW && buttonReleased == 1 && configRPM == 2) {
      buttonReleased = 0;
      configRPM = 0;
      maximumRPM = currentPosition;
      Serial.println("Value saved for maximum RPM is " + String(maximumRPM));
      display.clear();

      EEPROM.put(ADDR_MINIMUMRPM, minimumRPM);
      EEPROM.put(ADDR_MAXIMUMRPM, maximumRPM);
      EEPROM.commit();
      EEPROM.end();

      delay(50); // Debounce delay
    }

    newPosition = encoder.read();

    if (newPosition != oldPosition) {
      if (newPosition > oldPosition) {
        currentPosition += 100; // Increase by 100 for each clockwise turn
      } else {
        currentPosition -= 100; // Decrease by 100 for each counterclockwise turn
      }

      // Limiting the current position within 0 to 9990
      if (currentPosition < 0) {
        currentPosition = 0;
      } else if (currentPosition > 9900) {
        currentPosition = 9900;
      }

      display.showNumberDec(currentPosition);
      oldPosition = newPosition;
    }
  }

  Serial.println("Connecting to " + String(ssid)); // Print the SSID in the serial monitor.

  WiFi.mode(WIFI_STA); // Set the Wi-Fi mode as 'station' where the ESP8266 act as a client of a network.
  WiFi.begin(ssid); // Initates the process for connecting to the Wi-Fi network of the ELM327.

  while (WiFi.status() != WL_CONNECTED) { // While the Wi-Fi status of the ESP8266 is not connectied to the ELM327 Wi-Fi network, execute the following code.
    movePixels("right", neopixel_Count, 100); // Move from the left most LED to the right most LED with a delay of 100 milliseconds.
    movePixels("left", neopixel_Count, 100); // Move from right most LED to left most LED with a delay of 100 milliseconds.
    Serial.print("."); // Print "." in the serial monitor.
  }

  Serial.println("\nConnected to Wifi. The IP address of the ESP8266 is: " + WiFi.localIP().toString()); // Print the IP address of the ESP8266.

  if (!client.connect(IPAddress(192, 168, 0, 10), 35000)) { // This line tries to connect the client object to a server at the IP address 192.168.0.10 and port 35000. If the connection fails, it executes the code inside the if block.
    Serial.println("Connection to ELM327 failed. Resetting and restarting the ESP8266."); // If the connection fails, print this line.
    ESP.reset(); //  completely resets the ESP8266 microcontroller, disconnecting it from any Wi-Fi network and restarting its setup process defined in the setup() function.
  }
  myELM327.begin(client); // Initialize ELM327.
}

void loop() { // Loop function to continuously read RPM and update NeoPixels.
  rpm = myELM327.rpm(); // Read the RPM from the ELM327.

  if (myELM327.nb_rx_state == ELM_SUCCESS) { // Check for ELM327 communication status. If successful, do the following.
    Serial.print("RPM: " + rpm); // Print the RPM to the serial monitor.
    updateNeopixels(rpm); // Update the NeoPixels based on RPM.
  } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) { // Check if the ESP8266 is not currently receiving a message from the ELM327.
    myELM327.printError(); // Print ELM327 error if communication is not successful.
  }
}

void updateNeopixels(int rpm) { // Function to update NeoPixels based on RPM
  strip.clear(); // Clear all NeoPixels.

  if (rpm >= 2500 && rpm < 5900) { // If the RPM is between the two values, do the following. The max RPM for this loop is higher to make all LEDs red for between 5800 and 5900.
    // Specifying the number of LEDs on the left and right to create a converging effect.
    int leftIndex = map(rpm, 2500, 5800, 0, neopixel_Count / 2 - 1); // Map the RPM from 2500 to 5800 to the range of 0 to 7.
    int rightIndex = neopixel_Count - 1 - leftIndex; // Take the leftIndex from 15.

    // For example, if the RPM is 5800, leftIndex = 7 and rightIndex = 8.

    // Map RPM to colors
    int red = map(constrain(rpm, 2500, 5800), 2500, 5800, 0, 255); // Map RPM to the amount of 'red' of the LEDs. The higher the RPM, the more red.
    int green = map(constrain(rpm, 2500, 5800), 2500, 5800, 255, 0); // Map RPM to the amount of 'green' of the LEDs. The higher the RPM, the less green.

    // For example, if the RPM is 5800, red = 255 and green = 0. This will apply to all LEDs to be lit.

    // Left side of the strip
    for (int i = 0; i <= leftIndex; i++) { // The loop increments i by 1 whilst i <= leftIndex, moving towards the right end of the strip. i++ is done after the body of the loop completes.
      strip.setPixelColor(i, strip.Color(red, green, 0)); // Set the color of the NeoPixel matching the ID of i.
    }

    // Right side of the strip (mirroring the left side)
    for (int i = neopixel_Count - 1; i >= rightIndex; i--) { // The loop decreases by 1 whilst i >= rightIndex, moving towards the left end of the strip. i-- is done after the body of the loop completes.
      strip.setPixelColor(i, strip.Color(red, green, 0)); // Set the color of the NeoPixel matching the ID of i.
    }

  } else if (rpm >= 5900) { // If the RPM is at least 5900, do the following.
    for (int i = 0; i < neopixel_Count; i++) { // The loop increments i by 1 whilst i < neopixel_Count (16) as you can't send a single command to change the colour of all LEDs.
      strip.setPixelColor(i, strip.Color(255, 0, 255)); // Set the color of each NeoPixel to purple.
    }
  }
  strip.setBrightness(map(analogRead(potentiometer_Pin), 0, 1023, 0, 255)); // Map the potentiometer value to brightness range (0-255) and set the strip brightness accordingly. 1023 is the max value obtainabled from the analog-to-digital (ADC) converter.
  strip.show(); // Update the NeoPixel strip.
}

void movePixels(String direction, int numPixels, int delayTime) { // Function to move NeoPixels from left to right and then right to left.
  for(int i = 0; i < numPixels; i++) { // The loop increments i by 1 whilst i < numPixels (16).
    int index;
    if (direction == "right") { // If direction is equal to 'right'...
      index = i; // Set index to i.
    } else if (direction == "left") { // If direction is equal to 'left'...
      index = numPixels - 1 - i; // Set index to numPixels (16) - 1 - i.
    } else { // Handle an invalid direction input (neither right or left).
      return; // Exit the function with no response.
    }
    strip.setPixelColor(index, strip.Color(255, 0, 0)); // Set the LED which shares the ID of index as red.
    strip.setBrightness(map(analogRead(potentiometer_Pin), 0, 1023, 0, 255)); // Map the potentiometer value to brightness range (0-255) and set the strip brightness accordingly. 1023 is the max value obtainabled from the analog-to-digital (ADC) converter.
    strip.show(); // Update the NeoPixel strip.
    delay(delayTime); // Adjust the delay based on potentiometer value.
    strip.setPixelColor(index, 0); // Turn off the LED at the current position.
  }
}

```

# Answer
> 2 votes
We can have a look at the `clear()` function inside the Adafruit\_Neopixel library. In Adafruit\_Neopixel.cpp you can find at line 3396 (searching for `clear(void)` will get you there):

```
void Adafruit_NeoPixel::clear(void) { memset(pixels, 0, numBytes); }

```

This is a very short function. `memset()` sets all bytes in a defined range to the provided value. So all bytes in `pixels` will be set to zero. Though this is only the libraries internal memory. **There is no IO action here, no code sending data to the Neopixels.**

That means: `clear()` only acts on the libraries internal representation of the strip, just like `setPixel()` and its siblings. **To actually send the data to the Neopixels you still need to call `strip.show()`**, which then takes the libraries internal representation of the strip and sends the data out through the digital pin to the Neopixels.

I want to encourage people to look into the source code of libraries, they use. When you learn how to read them, you can get quick answers even without understanding the actual full implementation of the library.

---
Tags: esp8266, led, button, reset, neopixel
---


title: Grove relay stuttering

text:
# Question
Title: Grove relay stuttering
I have bought this Grove relay: Grove - Relais | Kiwi Electronics. I use it to drive a low-power water pump with a 9v battery. So the pump circuit is isolated from the Arduino circuit. When the Arduino sends 'high' to the relay, this relay begins to stutter. Contract-release at high frequency. This only happens if the pump is attached. I have bought multiple relays and they all behave in the same way. When I use a non-grove relay, such as Twee-kanaals 5V relais module | Kiwi Electronics I do not have this issue. I made a small film of both relays: https://photos.app.goo.gl/szHHE5EGqjHzJy3f7 (shared google photo's album). Why does this happen? What can I do to correct this issue with the Grove-relais? I want to use these Grove-relays because they need to be used by students that are used to work with Grove components. Please help!

The code:

```
void setup() {
  Serial.begin(9600);
  pinMode(7, OUTPUT);
  Serial.println("start");
  delay(1000);
}

void loop() {
  digitalWrite(7, HIGH);
  delay(2000);
  digitalWrite(7, LOW);
  delay(3000);
}

```

This is the schema:

# Answer
> 0 votes
The Grove relay in your photo (the black one) clearly says DC3V: you are presumably energising the coil, as well as controlling it, with DC5V.

Perhaps you should try their 5V version:

---
Tags: relay
---


title: Removing the L from F_CPU in assembly

text:
# Question
Title: Removing the L from F_CPU in assembly
I am developing a mixed c++ /asm project. In the asm I am using F\_CPU to do some busy waiting as follows. However, by default, the F\_CPU is defined with a trailing L (for long). The asm is not able to cope with the L. I can fix this by manually defining a new define in the asm, but that's a pretty dirty solution. What's the correct way to fix this?

```
.macro _delay_1u
.rept (F_CPU/1000000)
nop
.endr
.endm

```

# Answer
You have an XY problem: You want to busy-wait some cycles depending on the system's clock frequency. You think you can realize that with (inline) assembly and a repetition macro. But as you found, the assembler does not accept C literals with suffixes, as it has no usage for the type information.

However, this is a possible solution to do busy-wait in C++: built-in functions of the compiler. In this case you want to use `__builtin_avr_delay_cycles()`.

This simple sketch shows the effectively generated machine code. It contains some calls of `digitalWrite()` to separate the different delays.

```
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  // delay 1us
  __builtin_avr_delay_cycles(F_CPU / 1000000UL);
  digitalWrite(LED_BUILTIN, LOW);
  // delay 1 cycle
  __builtin_avr_delay_cycles(1UL);
  digitalWrite(LED_BUILTIN, HIGH);
  // delay 10 cycles
  __builtin_avr_delay_cycles(10UL);
  digitalWrite(LED_BUILTIN, LOW);
  // delay 100 cycles
  __builtin_avr_delay_cycles(100UL);
}

```

Commonly you will not have access to the intermediately generated files, because the IDE uploads the resulting machine code directly to the target. However, as long as the IDE is running, you can access the files from some temporary location. In my case, this is the path "/tmp/arduino\_build\_119348", and I copied the linked sketch to save it. It is an ELF file named "test.ino.elf".

The tool "avr-objdump" (exists in your Arduino IDE installation) disassembles the binary code of `loop()` for further investigation:

```
avr-objdump -d test.ino.elf

```

If you want, you can redirect the output into a file.

The relevant part is this quite at the end:

```
 2c4:   81 e0           ldi r24, 0x01   ; 1
 2c6:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2ca:   85 e0           ldi r24, 0x05   ; 5
 2cc:   8a 95           dec r24
 2ce:   f1 f7           brne    .-4         ; 0x2cc <main+0xc8>
 2d0:   00 00           nop
 2d2:   80 e0           ldi r24, 0x00   ; 0
 2d4:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2d8:   00 00           nop
 2da:   81 e0           ldi r24, 0x01   ; 1
 2dc:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2e0:   83 e0           ldi r24, 0x03   ; 3
 2e2:   8a 95           dec r24
 2e4:   f1 f7           brne    .-4         ; 0x2e2 <main+0xde>
 2e6:   00 00           nop
 2e8:   80 e0           ldi r24, 0x00   ; 0
 2ea:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2ee:   81 e2           ldi r24, 0x21   ; 33
 2f0:   8a 95           dec r24
 2f2:   f1 f7           brne    .-4         ; 0x2f0 <main+0xec>
 2f4:   00 00           nop

```

The different delays are clearly visible. The following parts have the number of cycles in parentheses.

Since the system's clock of my chosen target is 16 MHz, the delay of 1us needs to wait 16 cycles:

```
 2ca:   85 e0           ldi r24, 0x05   ; (1)
 2cc:   8a 95           dec r24         ; (1)
 2ce:   f1 f7           brne    .-4     ; (1 if not taken, 2 if taken)
 2d0:   00 00           nop             ; (1)

```

We have nCycles = 1 + 4 * (1 + 2) + 1 + 1 + 1 = 16.

To delay 1 cycle, the compilers inserts exactly one `nop`:

```
 2d8:   00 00           nop

```

To delay more cycles, a loop is used, as before. This is the delay of 10 cycles:

```
 2e0:   83 e0           ldi r24, 0x03   ; (1)
 2e2:   8a 95           dec r24         ; (1)
 2e4:   f1 f7           brne    .-4     ; (1 if not taken, 2 if taken)
 2e6:   00 00           nop             ; (1)

```

We have nCycles = 1 + 2 * (1 + 2) + 1 + 1 + 1 = 10.

And the delay of 100 cycles is:

```
 2ee:   81 e2           ldi r24, 0x21   ; (1)
 2f0:   8a 95           dec r24         ; (1)
 2f2:   f1 f7           brne    .-4     ; (1 if not taken, 2 if taken)
 2f4:   00 00           nop             ; (1)

```

We have nCycles = 1 + 32 * (1 + 2) + 1 + 1 + 1 = 100.
> 2 votes

# Answer
Just as a complement to the busybee's answer: the avr-libc provides the macros `_delay_ms()` and `_delay_us()` for busy-wait delays. Internally, they use `__builtin_avr_delay_cycles()` and `F_CPU` to provide the required number of delay cycles. For example, on an Uno,

```
_delay_us(0.25);  // delay for 0.25 µs

```

compiles to

```
rjmp .  ; 2 cycles
rjmp .  ; 2 cycles

```

which takes exactly 0.25 µs (4 cycles at 16 MHz) and takes less code space than four `nop`s.
> 2 votes

---
Tags: arduino-ide, assembly, compiler
---


# Question
Title: ESPAsyncDNSServer cannot find AsyncUDP anymore
I'm using this ESP32AsyncDNSServer library on my ESP32 application. Suddenly (I'm not sure what I did) it does not compile anymore:

> .pio/libdeps/Aphrodite/ESPAsyncDNSServer/src/ESPAsyncDNSServer.h:8:10: fatal error: AsyncUDP.h: No such file or directory

Here the related code of the library:

```
#ifdef ARDUINO_ARCH_ESP32
#ifndef Stream_h
#include <Stream.h>
#endif
#include <AsyncUDP.h>
#else
#include <ESPAsyncUDP.h>
#endif

```

but of course `AsyncUDP.h` *does* exist:

> /home/mark/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src/AsyncUDP.h

What could prevent the compiler to find it?

# Answer
for whatever reason, adding this to your platformio.ini `env` section helps:

```
[env]
lib_compat_mode = strict # default is "soft"

```

I guess the more clean version would be to add this to your `lib_deps`

```
lib_deps =
    ESP32 Async UDP # important! otherwise "AsyncUDP.h" blabla is missing..
    <your libs following>

```
> 1 votes

---
Tags: esp32, platformio
---


# Question
Title: Running code inside void loop() vs inside a separate function with an infinite loop in it
I'm writing a program for running a stepper motor at a high RPM using accelStepper on a NodeMCU esp8266. Super New to the accelStepper but reading, experimenting and learning as I go

When the code to cycle the stepper one way and then the other is inside the `void loop()` it works as expected, but there's a bunch of other inputs I need to check in there for setting up the system and when they are all inside the `void loop()` they slow down the cycle noticeably as it does various digital and analog reads.

While the stepper is cycling I only really need to watch one e-stop input instead of everything so I figured to create a separate function with an infinite loop in it, call the stepper code there and just check the one input and return out of the function when done

Testing this and it partially works but the stepper only makes it part way to its end point and then abruptly stops (instead of decelerating) and then reverse and same thing.

Probably not even the right way of trying to solve my issue but it's what I came up with tonight. Any help would be much appreciated.

Here's the **entire** test code I'm using. When I un-comment the block of code inside the `void loop()` and comment out the call to the go\_to function it works perfectly fine. When that basically exact same block of code is run inside the go\_to instead, it gives the weird results

```
    #include <AccelStepper.h>

    const int DIR = D6;
    const int STEP = D7;

    AccelStepper stepper(1,STEP,DIR);

    int EndPoint = 50000

    void setup()
    {
      stepper.setMaxSpeed(8000);
      stepper.setAcceleration(10000);
      stepper.setMinPulseWidth(10);
      stepper.setCurrentPosition(0);
      delay(2000);  // need to prevent partial run when loading
    }

    void loop()
    {
      /*  if this code runs it works perfectly
      stepper.run();
      if (stepper.currentPosition()==EndPoint)
        {
        NewEndPoint=0;
        stepper.moveTo(NewEndPoint);
        }
      else if (stepper.currentPosition()==0)
        {
        NewEndPoint=EndPoint;
        stepper.moveTo(NewEndPoint);
        }
        */

      go_to();

    }

    void go_to()
    {
      for(;;) // have tried while(true) also, same results
      {
      stepper.run();
      if (stepper.currentPosition()==EndPoint)
        {
        NewEndPoint=0;
        stepper.moveTo(NewEndPoint);
        }
      else if (stepper.currentPosition()==0)
        {
        NewEndPoint=EndPoint;
        stepper.moveTo(NewEndPoint);
        }
      }
    }

```

The reason I'm trying to get this to work is for the full program, there's several digital and analog reads than need to be done for speed, distance, number of cycles etc. that all must be in the `void loop()`, or called from there, and if they are in the same loop where the `stepper.run()` is it slows the RPM down a lot so I'm trying to get the `stepper.run()` into it's own loop where it's not looking at any inputs it doesn't need to but I ran into this problem and don't see why it's reacting the way it is.

# Answer
> 1 votes
`loop` already runs indefinitely, hence its name. You don't need to add another loop in your `go_to` function. Remove that and it should be functionally identical.

# Answer
> 1 votes
The ESP8266 has additional code that needs to run between iterations of the loop function. If you are going to trap it elsewhere in some while loop, then you need to also be sure to call `delay(0);` or `yield;` in there so that it can handle its other business. If the code around loop doesn't get run in time, then the board resets from the watchdog IIRC. I believe that is the symptom you are seeing.

And like the others say, there is no good reason for a blocking loop in your code. Let the loop function be the loop.

# Answer
> 0 votes
The simplest way to fix all of this is going to be to keep your stepper code within the loop function, but keep a variable that "remembers" when the stepper is running. Use that variable to know when not to do the time-consuming tasks. Let `loop()` return after each iteration whether the stepper is running or not. No `yield()` call will be needed. Just make sure to know when the stepper is running and don't do the long jobs if when is.

Perhaps something like this (untried!) code-structure:

```
void loop()
{
   static bool isStepping = false;
     :
   if( !isStepping ){
      /* call time-consuming tasks here; */

      if( time to start the stepper now ){
         /* set up any stepping conditions you need to here; */
         isStepping = true;
   }

   if( isStepping ){
      /* run one iteration of the stepper code; */
      if( stepping is complete ){
         isStepping = false;
      }
   }
}  // let your loop() return after each stepper iteration

```

---
Tags: esp8266, stepper
---


title: Problem adding IR receiver to smart car

text:
# Question
Title: Problem adding IR receiver to smart car
I’m making a smart car using an arduino uno, sensor shield v5, motor control with a L298N and a servo motor + HC-SR04 ultrasound sensor. I want to add a IR receiver on the board so I can also control the car with a remote.

The problem is when I add in the code for the IR Receiver and make the 3 additional connections, the right motor doesn’t respond anymore, it only moves at the beginning, though slower than the left one during the initial setup, then only the left motor functions properly.

Here is the whole code with comments next to the IR-Receiver specific code:

```
#include <Servo.h>
#include <IRremote.h> //IR Receiver
Servo servo ;
const int trigPin = 13;
const int echoPin = 12;
const int servoPin = 11;
const int enAPin = 6;
const int in1Pin = 7;
const int in2Pin = 5;
const int in3Pin = 4;
const int in4Pin = 2;
const int enBPin = 3;
const int receiverPin = 9; //IR Receiver

IRrecv irrecv(receiverPin);  //IR Receiver
decode_results signals; //IR Receiver

enum Motor { LEFT, RIGHT };
void go(enum Motor m, int speed)
{
  digitalWrite (m == LEFT ? in1Pin : in3Pin , speed > 0 ? HIGH : LOW );
  digitalWrite (m == LEFT ? in2Pin : in4Pin , speed <= 0 ? HIGH : LOW );
  analogWrite(m == LEFT ? enAPin : enBPin, speed < 0 ? -speed : speed );
}

void testMotors ()
{
  static int speed[8] = { 128, 255, 128, 0 , -128, -255, -128, 0};
  go(RIGHT, 0);
  for (unsigned char i = 0 ; i < 8 ; i++)
    go(LEFT, -speed[i]), delay(200);

  for (unsigned char i = 0 ; i < 8 ; i++)
    go(RIGHT, speed[i]), delay(200);
}

unsigned int readDistance()
{
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  unsigned long period = pulseIn(echoPin, HIGH);
  return period * 343 / 2000;
}

#define NUM_ANGLES 7
unsigned char sensorAngle[NUM_ANGLES] = {60, 70, 80, 90, 100, 110, 120};
unsigned int distance [NUM_ANGLES];

void readNextDistance()
{
  static unsigned char angleIndex = 0;
  static signed char step = 1;
  distance[angleIndex] = readDistance();
  angleIndex += step ;
  if (angleIndex == NUM_ANGLES - 1) step = -1;
  else if (angleIndex == 0) step = 1;
  servo.write(sensorAngle[angleIndex]);
}

void setup () {
  Serial.begin(9600);  //IR Receiver
  irrecv.enableIRIn();  //IR Receiver

  pinMode(trigPin , OUTPUT);
  pinMode(echoPin, INPUT);
  digitalWrite(trigPin, LOW);
  pinMode(enAPin, OUTPUT);
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  pinMode(enBPin, OUTPUT);
  servo.attach(servoPin);
  servo.write(90);
  go(LEFT, 0);
  go(RIGHT, 0);
  testMotors();
  servo.write(sensorAngle[0]);
  delay(200);
  for (unsigned char i = 0 ; i < NUM_ANGLES ; i ++)
    readNextDistance(), delay (200);
}

void loop () {

 //IR Receiver:
  if (irrecv.decode(&signals)) {
        Serial.println(signals.value);
        irrecv.resume();
        if (signals.value == 0xFFA25D) {
          Serial.println("yeees");
        }
  }

  readNextDistance ();

  unsigned char tooClose = 0;
  for (unsigned char i = 0 ; i < NUM_ANGLES ; i++)
    if (distance[i] < 200)
      tooClose = 1;

  if (tooClose) {
    go(LEFT, 180);
    go(RIGHT, -80);
  } else {
    go(LEFT, -180);
    go(RIGHT, 180);
  }
  delay (50);
}

```

# Answer
Finally found the problem: it is due to the IRremote library using the same timers than the Servo.

Solutions are to change the specified timer that the IRremote library uses in the library files (didn't work for me though) **or** to not use a library for either the IR receiver or the Servo **or** to change the physical connection of the component plugged in a pin also used by a timer.

Link to an Arduino Forum post suggesting an alternative for controlling the Servo without a library
> 1 votes

---
Tags: ir, arduino-motor-shield, remote-control, hc-sr04, l298n
---


# Question
Title: How to send unmodulated IR-Signal via cable?
I need to generate en (extended) NEC signal. I have connected an Arduino with a display-device via an IR cable.

`Arduino --> IR-cable --> IR-input of display device`

**IR-cable:**

One plug is cutted and the 3 wires are connected with the arduino.

The arduino should generate NEC Signals, and the display shall react to it. Basically the arduino acts like a wired remote control.

The problem is: There are many tutorials around, that show how to do this with a sensor (e.g by using this library). But none of the tutorials says how to do it with a cable.

I found out, my previous attempts all failed, because I tried to generate a modulated NEC-signal to the display. The display however does not understand it, because there is no device that demodulates the signal. The IR sensor normally does this, which is missing in this case.

e.g. This is, what an modulated NEC signal looks like:

`00 4e ff 61`

The library generates the moduled signal (pulse bursts) and this is how it works for IR sensors.

But how do I have to send my IR-command, that the display understands it? How do I send a not-modulated IR signal?

**The following graphic demonstrates the issue:**

I do not have IR-LED Transmitter, Amplifier, Limiter, Band Pass Filter, Demodulator, Integrator, Comparator.... I just want to create the green Output-signal directly from my Arduino

# Answer
> 4 votes
There are two major components to an infra-red signal. One is the high frequency carrier wave signal that pulses the LED on and off. This frequency has to match that of the receiver and is used with either a high-pass or band-pass filter to filter out ambient IR light and allow it to only react to a real signal.

The second component, and it sounds like this is the one you are interested in, is the on-off pulsing of that carrier wave in different combinations and with different timings to denote binary 0 and 1.

**Without knowing what your cable actually is, and we'd need to see a datasheet to get all the proper information, all this is just surmising.**

I would imagine that you provide power and ground to the emitter cable, and the third pin is a logical "on/off" signal that enables and disables the carrier frequency to the LED. That would allow you to send any codes you like as long as you know the timing of the signal.

In the library you link to is all the timing you need in the ir\_NEC.cpp file. The times are defined as:

```
#define NEC_BITS          32
#define NEC_HDR_MARK    9000
#define NEC_HDR_SPACE   4500
#define NEC_BIT_MARK     560
#define NEC_ONE_SPACE   1690
#define NEC_ZERO_SPACE   560
#define NEC_RPT_SPACE   2250

```

The actual data format is defined in the `sendNEC` function:

```
void  IRsend::sendNEC (unsigned long data,  int nbits)
{
    // Set IR carrier frequency
    enableIROut(38);

    // Header
    mark(NEC_HDR_MARK);
    space(NEC_HDR_SPACE);

    // Data
    for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
        if (data & mask) {
            mark(NEC_BIT_MARK);
            space(NEC_ONE_SPACE);
        } else {
            mark(NEC_BIT_MARK);
            space(NEC_ZERO_SPACE);
        }
    }

    // Footer
    mark(NEC_BIT_MARK);
    space(0);  // Always end with the LED off
}

```

The `mark` and `space` functions take a number of microseconds to perform either an ON or OFF of the PWM signal. That is somewhat simpler for you, since it is just an ON or OFF of a digital IO pin to control the output of the emitter cable. So where you have a MARK you turn on the output, then delay for the specified time. For a space you turn off the output and again delay for the specified time.

So you can just replicate the operation of that sendNEC function but with your own output control and timing in it instead of using the functions in that library.

---

**Edit:** It seems the cable doesn't need power - just provide the ground connection and the signal connection. Of course, this is assuming that it isn't just an LED on a wire. If it is just an LED on a wire then you would need to just use the library you link to as it is.

# Answer
> 1 votes
I needed the same thing, so I created a library for it: https://github.com/dennisfrett/Arduino-Direct-NEC-Transmitter.

It basically just pulls the pin high and low with the correct timings for the NEC protocol.

---
Tags: ir, arduino-micro
---


title: mcufriend 2.4 tft mega 2560

text:
# Question
Title: mcufriend 2.4 tft mega 2560
Please help me w/ my 2.4 mcufriend TFT on my Mega2560.

I've followed any instructions I can find, including:

2.4" TFT LCD Shield isn't working on Arduino Mega

I still get a show white screen. I wonder if my TFT is different or is it broken? Mine looks like this:

I did run the example code from SWtft. I got this output on serial:

```
TFT LCD test

LCD driver chip: 6TFT LCD test
LCD driver chip: 6767
Benchmark                Time (microseconds)
Screen fill              1786024
Text                     413024
Lines                    2569212
Horiz/Vert Lines         226196
Rectangles (outline)     176972
Rectangles (filled)      4682244
Circles (filled)         2703104
Circles (outline)        1119540
Triangles (outline)      815028
Triangles (filled)       2867288
Rounded rects (outline)  469268
Rounded rects (filled)   5733992
Done!

```

# Answer
I have one of these TFT LCD shields, but mine is a ILI9335. It has taken me nearly 2 weeks to find a working Library and code for my 9335 driver and I am now setting about creating sketches based around my working Library. Library - TFTLCD using st7783 controller Unfortunately most sellers of these shields (excluding good reputable companies) do not adivise of which Driver is onboard the shield and it becomes difficult to locate a working Library for the driver of the purchased shield.

ALSO, check that the Libraries you have are working for your version of Arduino IDE. Some of my libraries would not compile in v1.0.5 but will in v1.6.3 (and vice versa) If there is no Library specific to your 6767 Driver (and I must say I have not seen one in my searches for the 9335 Driver) then you may have to download as many different Libraries to locate a sketch that works for yours. Once you have a working Library then it is just a matter of modifying it for your purposes.

Good luck in finding a working solution for your shield.

Lance..
> 1 votes

# Answer
There are several of these boards on sale (mostly from China).

The following IDs of the different chips are taken from a file named `mcufriend_kbv_2_8.txt` from an archive named `Mcufriend_kbv_2.8.zip` which provides a whole library(supposely an UTFT fork) supporting these PCBs. Here in the Arduino.cc forum is one of the download links.

```
----- HX8347-A 240x320  ID=0x8347 new Untested
ILI9320  240x320  ID=0x9320
ILI9325  240x320  ID=0x9325
ILI9327  240x400  ID=0x9327
ILI9329  240x320  ID=0x9329
ILI9335  240x320  ID=0x9335
ILI9341  240x320  ID=0x9341
ILI9481  320x480  ID=0x9481
ILI9486  320x480  ID=0x9486
ILI9488  320x480  ID=0x9488
LGDP4535 240x320  ID=0x4535
RM68090  240x320  ID=0x6809
R61505V  240x320  ID=0xB505
R61505W  240x320  ID=0xC505 new Untested
R61509V  240x400  ID=0xB509
----- S6D0139  240x320  ID=0x0139 removed due to lack of tester
S6D0154  240x320  ID=0x0154
SPFD5408 240x320  ID=0x5408
----- SSD1963  800x480  ID=0x1963 new Untested
SSD1289  240x320  ID=0x1289
ST7781   240x320  ID=0x7783
ST7789V  240x320  ID=0x7789

```

A white screen is the result of choosing the wrong chip. Choose the right one (by ID) and it will work.
> 0 votes

# Answer
1. You need to modify these #define parameters of TouchScreen() from

```
#define YP A3
#define XM A2
#define YM 9
#define XP 8

```

to

```
#define YP A2
#define XM A1
#define YM 6
#define XP 7

```
2. Only insert the 4th line if (identifier == 0x6767) identifier = 0x7575; into setup() as below

............

```
  tft.reset();

  uint16_t identifier = tft.readID();

  if(identifier==0x0101)
      identifier=0x9341;

  if (identifier == 0x6767)
      identifier = 0x7575;

  if(identifier == 0x9325) {

    Serial.println("Found ILI9325 LCD driver");

  } else if(identifier == 0x4535) {

    Serial.println("Found LGDP4535 LCD driver");

  }else if(identifier == 0x9328) {

    Serial.println("Found ILI9328 LCD driver");

  } else if(identifier == 0x7575) {

    Serial.println("Found HX8347G LCD driver");

  } else if(identifier == 0x9341) {

    Serial.println("Found ILI9341 LCD driver");

  } else if(identifier == 0x8357) {

    Serial.println("Found HX8357D LCD driver");

  } else {

    Serial.print("Unknown LCD driver chip: ");

    Serial.println(identifier, HEX);

    Serial.println("If using the Adafruit 2.4\" TFT Arduino shield, the line:");

    Serial.println("  #define USE_ADAFRUIT_SHIELD_PINOUT");

    Serial.println("should appear in the library header (Adafruit_TFT.h).");

    Serial.println("If using the breakout board, it should NOT be #defined!");

    Serial.println("Also if using the breakout, double-check that all wiring");

    Serial.println("matches the tutorial.");

    return;

  }

```
3. Try it.
> 0 votes

# Answer
Most likely not supported controller or disabled in .cpp file. Firstly find out your ID like for example ID=0x6767. Then look in the MCUFRIEND\_kvb library folder "extras" to enable support for example in our case 0x6767 is 8347D. Lastly go to library root and edit MCUFRIEND\_kvd.cpp and uncomment asin ou example: #define SUPPORT\_8347D. Save the modified .cpp file then upload example graphic test.
> 0 votes

---
Tags: arduino-mega, shields, lcd
---