# Question
Title: OBOE: Need help understanding, possible type conversion issue
I have an algorithm that its main purpose is decoding, converting, or what have you a string of uppercase letters (A-Z) into a number. This is almost like converting a base 26 number into base 10, however I believe that a base 26 number encoded would actually include numbers, I am working strictly with uppercase letters, I digress.

I have an implantation working in C++11, in fact most of the controller algorithm was a direct copy, with a slight change to the indexOf method.

The C++11 version works as I expect it to. So initially I thought the new indexOf method was incorrect, but after a simple test, it is working as expected. I have narrowed down the problem to a line in the convertTo10 where I am calling the pow function.

As you can see from the Serial.println()'s in the convertTo10 method, the output is printing exactly what we expect, 0 & 26.

However, the output of this function is 25. WHAT?

I have read the docs on the pow method from the Arduino lib, and it takes in two floats and returns a double. Even if the issue was a type conversion issue, converting a double to an int truncates the number, it does not round it. Well, this is from working with C++.

Any help with this issue would be much appreciated.

```
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <inttypes.h>

#include <Arduino.h>
#include <avr/pgmspace.h>
#include <Wire.h>

const char _values[26] = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
    'U', 'V', 'W', 'X', 'Y', 'Z'
};

const int _val_len = 26;

int indexOf(char needle);
int convertTo10(String value, int len);

String x = "BA";
int len = 2;

void loop() {
  Serial.print(x);
  Serial.print("=> ");
  Serial.println(convertTo10(x, 2));
  delay(50000);
}

int convertTo10(String value, int len) {
    int lastIndex = len - 1;
    double output = 0;
    int pos = 0;
    Serial.println();
    for (int i = lastIndex; i >= 0; i--) {
        int r = indexOf(value[i]);

        output += (r * pow((_val_len, pos));
        Serial.print("     output => ");
        Serial.println( output );
        pos++;
    }
    return output;
}

int indexOf(char needle) {

    int first = 0;
    int last = _val_len - 1;
    int mid;

  do {
    mid = (first + last) / 2;

    if (_values[mid] == needle)
      return mid;
    if (_values[mid] > needle)
      last = mid - 1;
    else
      first = mid + 1;
  } while (first <= last);

  return -1;
}

```

For Reference, Here what it is outputting:

```
BA =>
     output => 0.00
     output => 26.00
25

```

# Answer
> 3 votes
way too complicated:

```
int convertTo10(char *num_26, int len) {
  int tmp = 0;  //hold the output
  int i = 0;  //indexing the input
  while (len--) tmp = tmp * 26 + (num_26[i++]-'A');
  return tmp;
}

```

note:

1. "\* 26" can be further simplified;
2. error checking could be built-in here, or somewhere else (better).
3. better structuring could get rid of one of the temporary variables.

# Answer
> 3 votes
Your code is incredibly complex for a simple thing like converting a number from another base. This works (prints 26):

```
const char * test = "BA";

long convertTo10 (const char * s)
  {
  long result = 0;
  for (const char * p = s; *p; p++)
    {
    result *= 26;   // base
    result += *p - 'A';  // make zero-relative
    }
  return result;
  } // end of convertTo10

void setup()
  {
  Serial.begin (115200);
  Serial.println ("Starting.");
  Serial.println (convertTo10 (test));
  }

void loop() { }

```

With input "CBA" it prints 1378 as expected. Sketch size: 2,300 bytes of program memory. The sketch size reduces to 2,236 bytes if I make the function return `int` (as you did) rather than `long`.

You don't need to use `String` (in fact it saves RAM and avoids memory fragmentation to not use it). You don't need to pass the length, with both `char*` and `String` you can deduce the length. If you use `long` as the return type you can handle larger numbers.

By using `pow` you are bringing in a library which is not needed and which will consume program memory. By using `double` you are introducing possible inaccuracies since double does not necessarily store numbers exactly. Your code used 7,604 bytes of program memory once I corrected the syntax error and added an empty `setup` function.

---

Also, the method I illustrate above is *much* faster. I timed it at converting "BA" in 4.3 µs, whereas the method using the `pow` function takes 442 µs. So the simpler method is also 100 times faster.

---
Tags: c++
---


# Question
Title: How often can I ping an HC-SR04 ultrasonic sensor?
In my current project, I want the sensor to be continuously scanning for a value of less than 30cm. I was wondering how long of a delay I need (if any) between each call of the ping function. It currently works at 150ms between each ping call with no problem. The less the delay, the better for my project. This is the ping function:

```
void ping() {
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
}

```

For example, would having a delay of only 5ms be sufficient?

# Answer
> 1 votes
> How often can I ping an HC-SR04 ultrasonic sensor?

This ping() function is vulnerable to interrupts during the pulseIn(). This implies that a delay needs to wait for queued interrupts as from, for instance, Serial output. Input interrupts may still affect the results. This function only works in very simple sketches.

Possible solutions are to 1) disable during the pulse measurement (not the wait for pulse start), 2) use a more advanced method to allow concurrent events (such as timer capture).

Cheers!

# Answer
> 0 votes
Documentation from elecfreaks.com recommends 60 milliseconds between measurements. That'll cut down your time by ~60% (from your 150ms delay). It works for me.

---
Tags: millis, hc-sr04
---


# Question
Title: Why these specific voltage divider resisters needed for Arduino Uno RX TX pins?
I have an Arduino Uno attached to a Parallax Boe-Bot shield, and plugged into the shield breadboard, the Parallax WX ESP8266 Wi-Fi SIP.

When I attach the DO/DI pins of the ESP8266 board to the RX/TX pins of the Uno, it does not work without a very narrow range of resisters in a voltage divider configuration. I'm trying to learn more about electronics and I would like to know, why these specific values in this specific case?

The DI/DO pins of the SIP are documented as "SIP - output high (set by Vin voltage, either 3.3 or 5.0 V), low 0 V. Input high \>Vin/2, input low

When I attach the Parallax shield 5V to the SIP Vin, and the DO to a 220 resister to RX, and also DO to a 1K resister to ground, and DI to 220 to TX and also DI to 1K to ground, serial communications works fine.

If I use the shield 3.3V to SIP Vin, it does not work.

If instead of 220 / 1K, I use 470 / 2K, or 4.7K / 10K, for example, it doesn't work.

If I only set up the voltage divider on the RX pin, it doesn't work.

However, if instead, with either 5V or 3.3V to the SIP Vin, and no resisters, I can run the Uno TX direct to the SIP DI, and the SIP DO to a digital pin, and run that digital pin with SoftwareSerial, for example.

I can run both DI and DO directly with SoftwareSerial, and either 5V or 3.3V to supply Vin.

It's only when I want to connect DO/DI direct to use the Uno's UART (because I don't want serial-driving interrupts to interfere with servo pulses) that I have to carefully select these resisters (through trial and error) and be sure to power with the 5V. Some combinations get communication with errors, but just these specific values (out of the resisters I happen to have on hand) work.

I understand that it is something to do with 3.3V vs TTL serial, but I would like the details. (I will be picking up a logic level converter to try in place of the voltage divider.)

EDIT:

By "not working" -- in all but two cases, with fresh batteries, the SIP seems to get data from the Uno TX, and the DO lamp on the SIP flashes, but Serial.read() sees nothing on the Uno regardless of configured rates. In one of the two cases (I can't recall which) unintelligible, incomplete data is read on the RX pin, and in the last, good case -- where *both* pins have voltage dividers and the SIP is powered by the 5V line of the Arduino shield (for the Boe-bot) -- with those specific resister values -- the data from the SIP DO is received on the Serial, from pin RX.

# Answer
The output of a voltage divider is:

Vout = Vin * R2 / (R1 + R2)

Where R2 is the resistor in your case which is connected to ground.

See: Sparkfun - voltage dividers

Now in your example of 220 / 1k you have a multiplier of:

```
Vout = Vin * 1000 /1220 = Vin * 0.82

```

If both boards are running at 5V you don't need the voltage divider at all, but if you do use it the output would be:

```
Vout = 5 * 0.82 = 4.1

```

Now the Atmega328P chip on the Uno has the electrical characteristics defined in the datasheet, amongst others is that a digital pin high has to have a minimum of 0.6 * Vcc (if Vcc is in the range 2.4V to 5.5V)

So if Vcc is 5V (which it is on the Uno) you have to have 0.6 * 5 (that is, 3V) as the minimum for it to be recognised as high.

So, using the voltage divider of 220/1k you have a high still being 4.1V which is in the range 3 to 5V.

However if you have the board set to 3.3V then the output of the voltage divider will be 3.3 * 0.82 = 2.76V which is too low to be recognized as high.

For sending serial from a 3.3V board to a 5V board, simply omit the voltage divider, and then the 3.3V (for high) is in range (it has to be 3+ volts).

However for sending *from* a 5V board *to* a 3.3V board you *do* need a voltage divider (or level shifter) because 5V is too much for a 3.3V board. You can use a voltage divider calculator to simplify the maths.

Something like 1k/1.8k would be about right.

```
Vout = 5 * 1800 / 2800 = 3.21

```

---

According to the documentation for the Parallax WX ESP8266 Wi-Fi Module:

> **(9) Level shifters and buffers**
>
> To ensure maximum compatibility with a wide range of 3.3V and 5V microcontrollers and development boards, the Parallax Wi-Fi module includes voltage level shifters and buffers to ensure that the logic voltage levels at the SIP header are set by the VIN voltage level. If you supply 3.3V to VIN, then the IO pins logic voltage level will be 3.3V. If you supply 5V to VIN, then the IO pins logic voltage level will be 5V

I don't see why you need to use a voltage divider or level shifter in the first place.

---

## References
> 2 votes

---
Tags: arduino-uno, serial, esp8266, uart
---


title: Arduino Nano timer, please advice

text:
# Question
Title: Arduino Nano timer, please advice
I'm new here and in the Arduino world. I try to put together a system to cut the power of a LED night light after a preset time. The light is powered by a 5V accu and I would like to avoid to re-charge the accu each morning if the light stays on all night... I purchased an Arduino Nano, a RTC module and a mini OLED display. I would like to kindly ask you for help in putting the system together: programming the Arduino and connecting the module together. The RTC module should open the possibility to completely automate the system (turn power on and off between precise times) and the OLED Display should give the feedback of the current settings. The RTC and OLED modules are just "nice to have", my main goal would be to have an automatic cutting of of the power after a certain time (i.E. 60 min.) after initialization of the system (through a push button, for example). Thank you in advance for your advices!

# Answer
> 1 votes
As Juraj said, you don't need an RTC for this. You just have to:

1. turn the LED on
2. wait for 60 minutes
3. turn it off

And do this every time the user presses a push-button.

The code that does this is pretty trivial:

```
const uint8_t BUTTON_PIN = 2;
const uint8_t LED_PIN = 3;
const uint32_t MINUTE = 60000;
const uint32_t ON_TIME = 60 * MINUTE;

void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    if (digitalRead(BUTTON_PIN) == LOW) {  // button pressed
        digitalWrite(LED_PIN, HIGH);       // LED on
        delay(ON_TIME);                    // wait
        digitalWrite(LED_PIN, LOW);        // LED off
    }
}

```

Now, you can build on top of that whatever “nice to have” functionality you want.

---
Tags: timers
---


title: Stop Buzzer after some seconds/time?

text:
# Question
Title: Stop Buzzer after some seconds/time?
This is a "water level alarm/display" sketch using and Arduino and ultrasonic sensor. The buzzer gets on when the water level hits 100% or more. But most of the time the water level will stay @ 100%, and I dont want the buzzer to run for long time. How can I set the buzzer to make sound only for 15 seconds ? It should turn off after 15 seconds, even if the water level is @ 100%

```
#define trigPin 8
#define echoPin 9
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int BUZZER = 10 ;

void setup(){
      int duration,distance,percentage,heightTank;
      Serial.begin (9600);
      pinMode(trigPin,OUTPUT);
      pinMode(echoPin,INPUT);
      lcd.begin(16,2);
      lcd.print("HELLO");
        pinMode(BUZZER,OUTPUT);
}

void loop(){
      int duration,distance,percentage,heightTank,deviation;
      //You'll probably want to change the next 2 lines.
      // The first one is the max. level of the water.
      // The next one is how high the sensor is above that max. level.
      heightTank=65;
      deviation=4;

      digitalWrite(trigPin,HIGH);
      delayMicroseconds(1000);
      digitalWrite(trigPin,LOW);
      duration=pulseIn(echoPin,HIGH);
      distance=(duration/2)/29.1;
      percentage=100-(((distance-deviation)*100)/heightTank);
      Serial.println(distance);
      Serial.println(percentage);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Current tank");
      //lcd.print(distance);
      //lcd.print(" cm");
      lcd.setCursor(0,1);
      lcd.print("level: ");
      lcd.print(percentage);
      lcd.print(" %");
      delay(1000);

      digitalWrite(BUZZER,HIGH);
  if (percentage > 99) {digitalWrite(BUZZER,HIGH); delay(100); digitalWrite(BUZZER,LOW); delay(100);}
  else  {digitalWrite(BUZZER,LOW);}
  }

```

# Answer
Try this at the end of `loop`

```
static unsigned long lastBuzzer = 0;

if(percentage > 99 && lastBuzzer == 0) {
    lastBuzzer = millis();
}

if(percentage > 99) {
    if(millis() - lastBuzzer < 15000L) {
        digitalWrite(BUZZER,HIGH);
        delay(100);
        digitalWrite(BUZZER,LOW);
        delay(100);
    }
} else  {
    digitalWrite(BUZZER,LOW);
    lastBuzzer = 0;
}

```

lastBuzzer is the last buzzer activation time (in ms). It's use to control that buzzing stop after 15 seconds. It's zero when the percentage is \< 99; it's not zero when percentage \>= 100.

(Not tested). (Two `if's` instead of one for clarity).
> 0 votes

# Answer
For this you will have to implement a *finite state machine*. This is a very common paradigm in the embedded world. I recommend you start by studying this tutorial: The Finite State Machine, by Majenko.

Four your particular problem, I would implement a machine with three states: IDLE, ARMED and ALARM, the ALARM state being the only one in which the buzzer is on. The transitions would be:

* ARMED → ALARM when the level hits 100%
* ALARM → IDLE after 15 seconds spent in the ALARM state
* IDLE → ARMED when the level gets below 90%

Note that the only difference between IDLE and ARMED is that the IDLE state will not go into ALARM when the level reads 100%, as you have to go through the ARMED state before. The threshold at 90% percent is meant to add some hysteresis. You can tweak the threshold value to your taste.

I leave the implementation to you. It should be easy one you have studied Majenko's tutorial.

---

**Edit**: Just to illustrate the generality of the concept, I would like to point out that the code in Look Alterno's answer can be thought of as a finite state machine where the state is implicitly encoded into the variables `lastBuzzer` and `percentage`. The implicit state is:

* ARMED when lastBuzzer == 0
* ALARM when percentage \> 99 && millis() - lastBuzzer \< 15000L
* IDLE when percentage \> 99 && millis() - lastBuzzer \>= 15000L

The line `lastBuzzer = 0` establishes the ARMED state as soon as percentage ≤ 99. Note that this lacks hysteresis: if the reading fluctuates between 99% and 100%, the alarm will sound again and again.

I personally prefer using an *explicit* state variable, as it makes the code clearer to me. But then, the best approach is whichever makes the code clearer *to you*.
> 0 votes

---
Tags: arduino-uno, programming, arduino-nano
---


# Question
Title: Locking ATmega328 from reading back the hex file
I want to completely block the access to an ATmega328. How do I do this?

I have Atmel ICE, AVR studio 7 and Arduino.

Bootloader - optiboot\_atmega328 Fuses(without lock) - 0x05, 0xDE, 0xFF

Steps I am executing:

1. Program fresh ATmega328 with bootloader using Atmel Studio.
2. Burn the fuses as mentioned above.
3. Go to Arduino and program the code.
4. Come back to Atmel Studio \>\> lock bits \>\> enable no further programming and verification.\>\> Fuse bits\>\> disable reset.

Is the above way OK? Or should I add something to the above?

I have programmed the fuse bit with "Further programming and verification disabled". I read out the hex file and it does not match even I programmed the same hex into a different micro and it didn't work. This seems to be fine. But will high Voltage programmer brick this wall?

Note: When I program the above fuse bit. I am unable to disable the RESET or SPI. It says **one or more register differ**

I want avoid a readback via high voltage programmer too.

**I have too many people to steal my code I want to avoid it. Kindly help**

Siddharth

# Answer
> 1 votes
Locking out programming prevents writing, and locking out verification prevents reading, via all programming methods.

Note that there is no way to prevent *erasing* the chip, which will clear both the lock bits and the flash.

# Answer
> 1 votes
"Locking" the chip only has any effect when using one of the hardware programming interfaces. Yes, it prevents anyone with a programmer from reading the data from the chip (verify disabled).

However, it does not stop software on the chip itself from reading the contents of the chip. And that includes the bootloader.

Since you use a bootloader it is possible (if implemented in your bootloader, I am not familiar with what is implemented in Optiboot) to use the bootloader to read the contents of the chip through USB.

To properly protect your software you will have to either remove the bootloader and only program through a hardware programmer or ensure that the bootloader has no method to read or otherwise access the flash memory of the chip (intentional or otherwise).

---
Tags: arduino-uno
---


# Question
Title: Checksum is wrong - Air Quality Monitoring Station PMS5003, BME280 | Code review
I working at air quality station. I measure particulate matter with PMS5003 and meteorological parameters with BME280. Everything seems to work just fine, but sometimes program hangs on checksum calculations.

I wonder if the problem lies either in my software or in hardware. Can anyone have a look at my code and tell me how I can improve it. Thanks in advance :)

Here's my code:

```
#include <Arduino.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

// needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager
#include <PubSubClient.h>
#include <Wire.h>
#include <SPI.h>

// BME280 Sensor
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

//Constants
#define TOKEN "TOKEN"
char thingsboardServer[] = "SERVER_ADDRESS";

// Settings for PMS5003
#define LENG 31  //0x42 + 31 bytes equal to 32 bytes
#define TIMEOUT 10000 //Microseconds to wait for PMS do wakeup

unsigned char buf[LENG];
char ergebnisstr[50];

struct dustvalues {
 unsigned int PM10Val=0; // Byte 4&5
 unsigned int PM2_5Val=0; // Byte 6&7
 unsigned int PM01Val=0; // Byte 8&9
 unsigned int Beyond03=0; // Byte 16&17
 unsigned int Beyond05=0; // Byte 18&19
 unsigned int Beyond1=0; // Byte 20&21
 unsigned int Beyond2_5=0; // Byte 22&23
 unsigned int Beyond5=0; //Byte 24&25
 unsigned int Beyond10=0; //Byte 26&27
};

struct dustvalues dustvalues1, dustvalues2;

//unsigned char gopassive[]={ 0x42, 0x4d, 0xe1, 0x00, 0x00, 0x01, 0x70 }; //don't need here
//unsigned char readinpassive[]={ 0x42, 0x4d, 0xe2, 0x00, 0x00, 0x01, 0x71 };
unsigned char gosleep[]={ 0x42, 0x4d, 0xe4, 0x00, 0x00, 0x01, 0x73 };
unsigned char gowakeup[]={ 0x42, 0x4d, 0xe4, 0x00, 0x01, 0x01, 0x74 };

// BME280 init
Adafruit_BME280 bme;

// Connection to PubSubClient
WiFiClient espClient;
PubSubClient client(espClient);

int status = WL_IDLE_STATUS;
unsigned long lastSend;

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

    wifiManager.autoConnect("AP", "pass");
    Serial.println("Connected to the network :)");
    delay(500);
    //  pins for RGB diode
    pinMode(12, OUTPUT);
    pinMode(13, OUTPUT);
    pinMode(14, OUTPUT);
    //BME280 sensor check
    if (! bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
    }
    // set server for MQTT PubSubClient Library
    client.setServer( thingsboardServer, 1883 );
    lastSend = 0;

}

void loop() {

    if (!client.connected()) {
    reconnect();
    }
    if ( millis() - lastSend > 30000 ) { // Update and send only after 1 seconds
    getpms5003();
    getAndSendTemperatureAndHumidityData();
    lastSend = millis();
    }
    client.loop();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Connecting to ThingsBoard node ...");
    // Attempt to connect (clientId, username, password)
    if ( client.connect("Stacja3", TOKEN, NULL) ) {
      Serial.println( "[DONE]" );
    } else {
      Serial.print( "[FAILED] [ rc = " );
      Serial.print( client.state() );
      Serial.println( " : retrying in 5 seconds]" );
      // Wait 5 seconds before retrying
      delay( 5000 );
    }
  }
}

void getAndSendTemperatureAndHumidityData()
{
  Serial.println("Collecting temperature data.");

  // Reading temperature or humidity takes about 250 milliseconds!
  float humidity = bme.readHumidity();
  // Read temperature as Celsius (the default)
  float temperature = bme.readTemperature();

  float pressure = bme.readPressure() / 100.0;

  // Check if any reads failed and exit early (to try again).
  if (isnan(humidity) || isnan(temperature) || isnan(pressure)) {
    Serial.println("Failed to read from BME sensor!");
    return;
  }

  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.print(" *C ");
  Serial.print("Pressure: ");
  Serial.print(pressure);
  Serial.print("hPa");

  String temperature1 = String(temperature);
  String humidity1 = String(humidity);
  String pressure1 = String(pressure);

  // Just debug messages
  Serial.print( "Sending temperature, humidity & pressure : [" );
  Serial.print( temperature1 ); Serial.print( "," );
  Serial.print( humidity1 ); Serial.print( "," );
  Serial.print( pressure1 );
  Serial.print( "]   -> " );

  // Prepare a JSON payload string
  String payload = "{";
  payload += "\"temperature\":"; payload += temperature1; payload += ",";
  payload += "\"humidity\":"; payload += humidity1;  payload += ",";
  payload += "\"pressure\":"; payload += pressure1;
  payload += "}";

  // Send payload
  char attributes[150];
  payload.toCharArray( attributes, 100 );
  client.publish( "v1/devices/me/telemetry", attributes );
  Serial.println( attributes );
}

bool checkValue(byte *buf, byte leng){
    int receiveSum, checkSum;
    for(byte i = 0; i < (leng - 2); i++){
        receiveSum += int(buf[i]);
    }
    receiveSum += 0x42;
    checkSum = (buf[leng-2] << 8) + buf[leng-1];
    testCheckValue(receiveSum, checkSum);
    if(receiveSum == checkSum){
        return true;
    }
    return false;
}

void testCheckValue(int calc, int found){
    byte strSize = 64;
    char strOut[strSize];
    snprintf(strOut, strSize, "Checksum Calculated: %d\nChecksum Found: %d\n", calc, found);
    Serial.print(strOut);
}

unsigned int transmitPM(char HighB, char LowB, unsigned char *buf){
 unsigned int PMValue;
 PMValue=((buf[HighB]<<8)+buf[LowB]);
 return PMValue;
}

void getpms5003(void){
  unsigned char found=0;

  Serial.println("PMS5003 Wakeup: ");
  Serial.write(gowakeup,7);
  Serial.println();
  Serial.println("gowakeup ist out");
  delay(30000); //Stable data should be got at least 30 Second from wakeup (Datasheet!)
  while (found<2){
   delay(TIMEOUT);
   if(Serial.available()>0){
    if(Serial.find(0x42)){  //start to read when detect 0x42
     Serial.println("0x42 found");
     Serial.readBytes(buf,LENG);
     if (buf[0] == 0x4d){ //second byte should be 0x4D
       found++;
       if(checkValue(buf,LENG)){
        Serial.println("Checksum okay");

        if(found==1){
         dustvalues1.PM01Val=transmitPM(3,4,buf);
         dustvalues1.PM2_5Val=transmitPM(5,6,buf);
         dustvalues1.PM10Val=transmitPM(7,8,buf);

         if (dustvalues1.PM2_5Val <= 36) {
           // digtal write green pin
           digitalWrite(12, LOW);
           // digitalWrite(13, HIGH);
           digitalWrite(14, HIGH);
         }

         if ((dustvalues1.PM2_5Val > 36 ) && (dustvalues1.PM2_5Val <= 80)) {
           // diode change to yellow
           digitalWrite(12, LOW);
           // digitalWrite(13, HIGH);
           digitalWrite(14, LOW);
         }

         if(dustvalues1.PM2_5Val > 84) {
           // diode change to red
           digitalWrite(12, HIGH);
           // digitalWrite(13, HIGH);
           digitalWrite(14, LOW);
         }

         sprintf(ergebnisstr,"PM2.5:%4dug/m3\nPM10: %4dug/m3\n",dustvalues1.PM2_5Val,dustvalues1.PM10Val);
         Serial.println(ergebnisstr);
         Serial.flush();

         // Just debug messages
         Serial.print( "Sending air quality PM2.5 & PM10 values: [" );
         Serial.print( dustvalues1.PM2_5Val ); Serial.print( "," );
         Serial.print( dustvalues1.PM10Val);
         Serial.print( "]   -> " );

         // Prepare a JSON payload string
         String payload = "{";
         payload += "\"pm25\":"; payload += String(dustvalues1.PM2_5Val); payload += ",";
         payload += "\"pm10\":"; payload += String(dustvalues1.PM10Val);
         payload += "}";

         // Send payload
         char attributes[100];
         payload.toCharArray( attributes, 100 );
         client.publish( "v1/devices/me/telemetry", attributes );
         Serial.println( attributes );
       }
        if(found==2){
         dustvalues2.PM01Val=transmitPM(3,4,buf);
         dustvalues2.PM2_5Val=transmitPM(5,6,buf);
         dustvalues2.PM10Val=transmitPM(7,8,buf);
         sprintf(ergebnisstr,"PM1: %4dug/m3\nPM2.5:%4dug/m3\nPM10: %4dug/m3\n",dustvalues2.PM01Val,dustvalues2.PM2_5Val,dustvalues2.PM10Val);
         Serial.println(ergebnisstr);
         Serial.flush();
        }
      }else{
       Serial.println("Checksum not okay");
       Serial.flush();
       if(found>0)found--;
       delay(500);
      }
     }
   }
   }
   }

  found=0;
  Serial.println("PMS5003 - go to sleep");
  Serial.write(gosleep,7);
  Serial.println();
 }

```

My hardware:

PMS 5003 Datasheet - http://www.aqmd.gov/docs/default-source/aq-spec/resources-page/plantower-pms5003-manual\_v2-3.pdf

# Answer
Cited from the documentation

> Check code=Start character1+ Start character2+……..+data13 Low 8 bits

Please try to change the code as follows:

```
...
bool checkValue(byte *buf, byte leng){
    int receiveSum, checkSum;
    receiveSum += 0x42;
    for(byte i = 0; i < (leng - 2); i++){
        receiveSum += int(buf[i]);
        receiveSum = receiveSum & 0xFFFF;
    }

    checkSum = (buf[leng-2] << 8) + buf[leng-1];
    testCheckValue(receiveSum, checkSum);
    if(receiveSum == checkSum){
        return true;
    }
    return false;
}
...

```

Or use the updated code by the same author :PMS7003-on-Particle
> 1 votes

---
Tags: programming, c, code-review
---


title: Arduino Servo with Serial

text:
# Question
Title: Arduino Servo with Serial
I have an interesting problem. I want to control ESC and servo with Arduino. I'm using HC-12 to communicate with 2 Arduino and I'm using SoftwareSerial on the nano.

```
#include <SoftwareSerial.h>
#include <Servo.h>

SoftwareSerial mySerial(2, 3); // RX, TX
Servo esc,servo1;

String okunan;
int escval;

void setup() {
  okunan="";
  esc.attach(9);
  servo1.attach(10);
  mySerial.begin(2400);
  Serial.begin(9600);
}

void loop() {
   while (mySerial.available()) {
    delay(3);  //delay to allow buffer to fill
      char c = mySerial.read();  //gets one byte from serial buffer
      okunan += c; //makes the string readString
   }

  if(okunan.length()>0)
  {
    Serial.println(okunan);
    //escval= map(okunan.substring(0,okunan.indexOf(',')).toInt(),0,1023,,2000);

    servo1.writeMicroseconds(map(okunan.toInt(),0,179,1000,2000));

    okunan="";

mySerial.flush();
  }
  delay(20);
  }

```

When I use a potentiometer, It works successfully. But When I use with serial and if three digit value(between 0-179, for example, 120) comes from serial(HC-12), motor works and stops continuous and irregular. If the value is under three digit there is no problem.

Also, if I delete the ESC variable(servo) or add a new servo to code, it always starts and stops interestingly(Using or not it doesn't matter. If I add Servo servo2 etc., it is going crazy.

I've tried on Uno. That is the same.

Thanks in advance...

# Answer
Like Mikael Patel said, `SoftwareSerial` disables interrupts for the entire character receive time. Bad juju.

This answer lists the alternatives:

* `HardwareSerial` is always the best. Simply connect the device to pins 0 & 1 and use the pre-defined `Serial` variable. On some Arduinos, there are extra HardwareSerial ports, called `Serial1`, `Serial2`, etc. The UNO only has `Serial`. `Serial` would not interfere with the Servo.
* `AltSoftSerial` is the best of the software serial libraries. Only one instance is allowed, and it is must be used on the Input Capture pins (pins 8 & 9 for a Nano). It would not interfere with the Servo.
* My `NeoSWSerial` is next best. It works on any two pins, but only at baud rates 9600, 19200 and 38400. Receiving characters does not disable interrupts, but transmitting does (i.e., TX would interfere with the Servo).
* `SoftwareSerial` is the worst choice. It works on any two pins, but it is very inefficient. It disables interrupts for the entire time that a character is being sent **OR** received, and it cannot transmit and receive at the same time (unlike all other choices). This can interfere with other parts of your sketch, other device communications, or with libraries (e.g., Servo).

In your case, I would suggest connecting the HC-12 to pins 0/1 and use `Serial`. No software serial library required, but you will have to disconnect pin 0 to upload new sketches over USB. Some people put a switch in that wire so it's easy to upload a new sketch.

If you need debug prints, I would suggest using AltSoftSerial and an extra TTL Serial-to-USB adapter (aka FTDI module) to your PC. Then print your debug messages to the `AltSoftSerial` variable:

```
#include <AltSoftSerial.h>
AltSoftSerial debugPort; // always pins 8 & 9

   ...

void loop()
{
  if (something) {
    debugPort.println( F("something happened!") );

```

Or, if the HC-12 connection is receive only, don't connect pin 1 (TX). Then your debug prints won't go to the HC-12.

BTW, don't use `delay` and don't use `String`. They will get you into trouble sooner or later.
> 1 votes

---
Tags: arduino-nano, servo, softwareserial, code-review, hc-12
---


title: Why would anyone use Arduino in 2017?

text:
# Question
Title: Why would anyone use Arduino in 2017?
Sorry for clickbait question but it really bugs me why Arduino is still a thing in the age of ARM based boards like Pine64, Raspberry Pi, Bannana Pi, Whatever Pi etc.

I'm more or less aware of Arduino capabilities as I used to program PLC controllers but I don't really see any rational reason to use Arduino platform over ARM devboards (unless we need mission-critical level reliability however I believe commercial realtime OSes for ARM boards also exist). Even PLC and in general industrial controllers seem to shift towards platforms driven by actual RT OSes underneath running on powerfull hardware.

Getting 30$ quad core 1.2 ghz ARM board with 512M RAM, ethernet, GPIO, I2C, SPI, USB, SD card and actual Linux OS which can do virtually everything whatsoever over 25$ Arduino Uno board with abacus level performance, similar or inferior i/o, capable of only pretty basic stuff sounds to me like no brainer. Arduino sounds to me like **extremely** cost ineffective solution for almost anything. And I can't seem to find any rational explanation to why people still use such thing now? Maybe as Linux engineer I'm a bit biased towards Unix based solutions because I feel "safe" in this ecosystem but still I think my points are kind of objective no matter if availability of unix itself on platform is considered serious advantage or not.

# Answer
This is the ATtiny.

It costs \< $1 and is completely capable of *most* tasks that a hobbyist requires of a chip. Truthfully, it’s more than capable of many tasks a pro requires as well. It’s *perfect* for adding just a little bit of smarts to a project. Not every project needs an ARM chip, dual cores, or a Linux distro running. In fact, in *low power* situations, that’s likely the last thing I want. How long does your smart phone battery last? A day? I’ve heard of people powering ATtiny based projects on 3 AAs for over a year!

The Arduino is an excellent little dev board for these micros. For the cost of a few cups of coffee I can have one for my work bench. Heck, I’ve used them at work as dev boards for prototyping. It’s cheap enough to put one on the desk of *every* dev on a project. We can verify our code works *on the target architecture* very early in the dev process. That was unheard of just a decade ago.
> 4 votes

# Answer
An arduino board is really a breakout for a micro processor. Microprocessors you can get separately. A rPi is really a full system without that modularity.

There are also other size factors for that breakout board, many of which are much smaller than a rasberry pi and will have a much better battery life. And very often the abacus-level perf and half a dozen GPIO pins is all you really need.

Also some people enjoy having direct control over the chip in a way that a semi-stripped linux OS on a poorly documented platform just doesn't give. Hard realtime when you don't have full control over the system means you need to trust the RT-OS writers to actually hold to their documented deadlines.
> 3 votes

---
Tags: arduino-uno, raspberrypi, performance
---


# Question
Title: Global variable won't update inside void loop arduino
I need to update my global variable once I get a 'overdtrue' response and light up my LED but only my LED is lighting up but my global variable is not updated.

Here is my code

```
int x = 0;

void loop() {
if (content.indexOf("ovrdtrue") > 0)
 {
  x++;
  digitalWrite(ledPin, HIGH);

 }
fsrReading = analogRead(fsrAnalogPin);
Serial.print("Analog reading = ");
Serial.println(fsrReading);
Serial.print("X: ");
Serial.println(x);
}

```

The x value should be 1 but only the LED has light up. Please help.

# Answer
> 1 votes
It seems like I forgot to include an if else condition above the ovrdtrue.

```
if(content.indexOf("true") > 0)
{
  digitalWrite(ledPin, HIGH);

}

```

Arduino is reading this condition even though the data received "ovrdtrue" but this contains some word "true" so this is the one getting read and not the ovrdtrue condition. I just changed the condition variable not close to the word true and it worked fine. I'm sorry for this.

# Answer
> 0 votes
You never set the LED pin to LOW, so it will stay lit up regardless of the global variable.

# Answer
> 0 votes
Are you sure the LED is not lighted from the start? It's unclear if in the Setup you set the light on or off (or it is default on or off).

Print a Serial print inside the if statement to be sure that the if block is entered, also print before the if the value of content to be sure if 'ovrdtrue' is found in the string.

Also, since you want the LED on in this situation, explicitly set it off in the setup.

# Answer
> 0 votes
> Here is my code

your code ran without setup()?

you are conditionally incrementing "x", and if your condition doesn't hold true, the increment doesn't take place.

---
Tags: variables
---


# Question
Title: AT Commands HM10 BLE Module - Not working
I got the ble module to work fine following online guide. However when i changed the baud rate: AT+BAUD1 which changed to 19200 however ever since i was not able to get at commands to work.

tried: arduino nano, FTDI programmer, software serial, normal tx, rx

```
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(8,9); //RX|TX

void setup(){
  Serial.begin(9600);
  BTSerial.begin(9600); // default baud rate
  while(!Serial); //if it is an Arduino Micro
  Serial.println("AT commands: ");
}

void loop(){
  //read from the HM-10 and print in the Serial
  if(BTSerial.available())
    Serial.write(BTSerial.read());

  //read from the Serial and print to the HM-10
  if(Serial.available())
    BTSerial.write(Serial.read());
}

```

# Answer
> 3 votes
You changed the baud rate that the Bluetooth module uses to communicate with your Arduino but you forgot to change the baud rate that the Arduino uses to communicate with the Bluetooth module. These must match. From consulting the SoftwareSerial library's reference page, you can see that is set by this line of your code:

```
BTSerial.begin(9600)

```

That sets the software serial communication rate at 9600 baud. You need to change it to this:

```
BTSerial.begin(19200)

```

---
Tags: arduino-uno, bluetooth
---


# Question
Title: HC-05 Bluetooth Module Blinking Red Light-Arduino Uno
I have looked on google for an answer to my problems to no avail. The you tube video I am following is here: https://www.youtube.com/watch?v=f1v0IMegCvU So basically on my android, I can't see the HC-05 device show up and the module itself is flashing red unlike the video's flashing blue light. I have connected the circuit exactly like he has in the video with the 2 10K resisters. I am using the same app. What is wrong? Here is my code as I copied from the video.

```
void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.println("Connection Successful!");
}
void loop()
{
  if(Serial.available()>0){
    int data=Serial.read();
    switch(data){
      case 'a': LEDON();break;
      case 'b': LEDOFF();break;
      default : break;
    }
  }
  delay(50);
}
void LEDON(){
  Serial.println("Led On!");
  digitalWrite(13,HIGH);
}
void LEDOFF(){
  Serial.println("Led Off!");
  digitalWrite(13,LOW);
}

```

I also get the error avrdude: stk500\_getsync() attempt 1 of 10: not in sync: resp=0x00 when connected through usb. I do not get any errors when just flashing the arduino without any wires connected to the arduino. I know that the port is correct. Any ideas would be helpful. Thanks.

# Answer
There are several issues to consider:
• Program downloading
• HC-05 serial communication
• Bluetooth pairing

For the first issue: The serial-over-USB connection between the development computer and the Uno ties up the Uno's hardware serial RX and TX pins. There will be a conflict if the development computer transmits when the HC-05's TX is connected to the Uno's RX. This can be resolved by disconnecting the HC-05 TX when downloading a program.

For the second issue: The Uno schematic shows 1KΩ resistors between TX and RX on the ATmega328P and RX and TX on the USB chip (ie on an ATmega16U2, or a CH340, etc). If the HC-05's TX drive is strong enough, it will overcome the drive from the USB chip and work ok. Note, I would leave out the voltage divider (on the HC-05 RX line) that the video shows.

For the third issue: The HC-05 in the video mentioned in the question has a blue LED that blinks steadily when the HC-05 isn't paired, and blinks at a long interval when it is paired. Many HC-05's have red LEDs instead of blue; the LED color is not an issue. Some HC-05's don't blink at all when paired; that's not an issue either. What is an issue is that (according to description in question) your HC-05 keeps on blinking, so apparently isn't paired up.

Whether the HC-05 pairs with an Android app is more or less independent of whether you have the HC-05 connected to an Arduino; you should be able to pair your phone with the HC-05 when just Vcc and ground are connected to the HC-05. If you are having trouble with pairing, try another app; try powering the HC-05 down and up; and try a different HC-05. I mention trying another app because one serial-terminal app I installed on my Android phone needed the app or the HC-05 to be restarted to pair up after loss of pairing, and the serial-terminal app I replaced it with did not need those actions. Note, pairing takes a few steps on my phone: in Settings / Wireless, search for Bluetooth devices; select device; enter its passcode; run an app and tell the app which Bluetooth device to use.
> 2 votes

# Answer
Try this code(it's simpler):

```
char data ;
void setup()
{
    Serial.begin(9600);
    pinMode(13, OUTPUT);
}
void loop()
{
   if(Serial.available() > 0)
   {
      data = Serial.read();
      Serial.print("\n");
      if(data == '1')
      {
         digitalWrite(13, HIGH);
         Serial.print("on");
      }
      else if(data == '0')
      {
        digitalWrite(13, LOW);
        Serial.print("off");
      }
   }
}

```

Upload this to your Arduino. Open your phone, go to bluetooth settings and connect to HC05 with password 1234. Download an app from here: https://github.com/Mayoogh/Arduino-Bluetooth-Basic Now your circuit should work. Arduino to HC05 connections: 5V -\> 5V GND-\> GND RX -\> TX TX -\> RX LED connection: connect LED to pin 13 and the GND pin beside it(it's fine if you don't use resistor).
> 1 votes

---
Tags: arduino-uno, bluetooth, android
---


# Question
Title: Will a genuine Arduino board have the same issues with High Sierra as other non genuine ones?
I think my question is quite specific to High Sierra. I am very new and have bought a starter Elegoo kit to learn the basics. I did not realise that their boards are not the real thing.

I have an iMac running High Sierra and although the Mac recognises the board (I checked this through the apple menu) every time i try to upload code i get the error message:

*avrdude: stk500\_recv(): programmer is not responding avrdude: stk500\_getsync() attempt 1 of 10: not in sync: resp=0x00*

I have watched several videos on line that have taken me through installing drivers including one specific to High Sierra. However the problem continues.

Does anyone know if i buy a genuine Arduino board, will i have the issues? Will Arduino just not work with High Sierra.

Any help or advice would be so appreciated by someone very new and trying to learn!

Thank you

Paddy

# Answer
From reading both your questions, I'm not sure whether you've gotten your board to upload yet.

But here's another data point: I just tried an Arduino Mega r2 and iMac with High Sierra - worked perfectly, first try. Arduino IDE 1.6.12.

In your other question, you said you were getting a solid green LED and a blinking yellow one. The green LED is the power LED. The yellow one is programmable so it sounds like the Blink sketch is already loaded and running.

If you're still getting upload errors, check the Arduino IDE Tools menu and check you hardware selections in the Arduino IDE Tools menu. Here are mine; your /dev/cu.usbmodemxxx number might be different but there should only be one of those if you only have one Arduino plugged in:
> 0 votes

# Answer
As long as the firmware on the ATMega16U2 chip is the same as on a Genuine Arduino and the bootloader on the ATMega2560 chip is the same as on a Genuine Arduino then your boards should function exactly the same as a Genuine Arduino.

If you find a Genuine Arduino works but your boards don't then there must be a difference, and that can really only be in the software on the chips - so reprogramming the chips to match a Genuine Arduino would probably help.

I haven't heard reports of High Sierra not working with Genuine Arduino boards, but given the severity of some of the bugs that have crept in recently, it seems likely that more problems are hidden away under the hood that no one really knows about yet.
> 0 votes

# Answer
I use High Sierra on my ageing 2011 MacBook and it works with reputable Arduino clones (it is difficult to get a genuine Arduino in Australia, although compatible Freetronics boards are available from a major retailer).

There were some problems with ARDUINO 1.8.4 but the latest works flawlessly.

Anything with a CH340G chip is out, but then the CH340G don't seem to last anyway.
> 0 votes

---
Tags: arduino-uno, mac-os, osx, upload
---


# Question
Title: Programmer only uploading with its own power source
Can anyone explain to me why the following occurs (See image below)?

When I connect the pins according to situation 1, everything works fine and I am able to upload my project. However when I connect the pins according to situation 2 it gives me the following error:

> wrong direction/command: 0x00 0x08, expected 0x01 0x08 esp8266

Both supply the same constant 3.3V and after the project is uploaded it runs with the pins connected as in both scenarios.

(All the other factors are constant in both scenarios. Think of pulling down IO0 etc.)

# Answer
This will not work for the same reason you can not measure the voltage of a battery by only connecting the measurement device to the positive battery terminal. You always need a ground reference.

Perhaps you were thinking all grounds, no matter where they come from, are the same. This is only true if all your power supplies are grounded. But this is usually not the case. In fact it can be dangerous and can lead to other problems such a ground loops.

So, connect your grounds together and try your circuit again.
> 2 votes

# Answer
You *must always connect the grounds*. Without the grounds connected, even when using a separate power supply, there can be no circuit. With no circuit, no electrons can flow.

I cover it in detail in this blog post.
> 2 votes

# Answer
There's no problem with supplying a separate power supply to the ESP8266 but you always need to connect the grounds between the "programmer" and the ESP8266.
> 1 votes

---
Tags: esp8266, power, uploading
---


title: 16x2 LCD showing blocks under text

text:
# Question
Title: 16x2 LCD showing blocks under text
I have a LCD connected to a Arduino Mega 2560 using the instructions in `LiquidCrystal` library. It is not the first time I am using a 16x2 LCD but I never have encountered a problem like this. When I first connect the Arduino Mega to PC I see a row of blocks in first row of LCD which looks like normal to me. Then after that there is a block of white under each character.

Now I have searched a little and saw whole blocks which was due to bad soldering or bad wiring or etc. I have checked soldering and wiring twice. used 3 different LCD's and 2 different Mega's and it is still the same.

Any suggestions?

These are the images from when I turn it on:

**\[SOLVED\] Update :**

Looks like the POT was broken and did not respond the way it used to. So i replaced `V0` with a 2.5k resistor and connected them to GND. Here is the updated image :

# Answer
The row of white blocks is what you get before the screen's initialized. It's normal.

The shadow behind the characters is because you have the contrast turned up too high. Adjust it down a little.
> 12 votes

# Answer
If your contrast is not adjustable by a pot, there's a resistor that goes on the contrast pin that controls the level of contrast, which is what is causing the dark blocks.
> 1 votes

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


title: Accesing the USART registers by Arduino

text:
# Question
Title: Accesing the USART registers by Arduino
I'm having a hard time understanding how the Arduino libraries are defining the address for accessing the registers of the USART modules.

I cant find definition for `udr(pointer)` as used in the delegated constructor for Hardware Serial. So how does the class gets the underlying address? And what type of declaration is this?

```
HardwareSerial::HardwareSerial(
  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
  volatile uint8_t *ucsrc, volatile uint8_t *udr) :
    _ubrrh(ubrrh), _ubrrl(ubrrl),
    _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc),
    _udr(udr),
    _rx_buffer_head(0), _rx_buffer_tail(0),
    _tx_buffer_head(0), _tx_buffer_tail(0)
{
}

```

# Answer
It is handed the addresses when the object is constrcted:

```
 HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR);

```

`&UDR` is passed as `*udr`. That is then assigned to `_udr` in the initialiser list.
> 0 votes

---
Tags: serial, library
---


title: How to identify RGBW LED pins?

text:
# Question
Title: How to identify RGBW LED pins?
I have a RGBW LED but I don't know how to identify the negative and the colors pins.

I tried different combinations with an Arduino Uno but it never produce light.

I never used it so I am not sure if its name name RGBW LED.

# Answer
Brand Name: LEDGUHON

Model Number:JH-4RGBW14G
> 2 votes

# Answer
The pin with a + is the anode of one colour. The three next to it are also anodes.

Each anode is connected to one LED. The cathode of that LED is connected to the pin directly opposite the anode.
> 2 votes

---
Tags: arduino-uno, led, pins, led-strip
---


# Question
Title: WS2811 LEDs have the wrong color unless I touch the data wire
This is an electrical/hardware issue, but for background, here's my setup:

I'm using a Wemos D1 mini in conjunction with Home Assistant running on a RPi3. The MQTT setup works fine and the commands are being executed perfectly, but the colors are completely off unless I'm touching the data wire.

For instance, if I request solid blue and am touching the wire, they all turn blue. If I let go of the wire, the first LED turns red and the rest are a strong green. If I touch the wire, they go back to blue. Any colors or patterns requested show likewise confusing changes.

What kind of effect is causing this, and what can I do to fix it?

Using a Tanbaby 5V 60A for power

Lights are Alitove WS2811 5V 12mm RGBs

# Answer
> 0 votes
It sounds like the bits are getting garbled. There is more than one wire, which one do you mean? Data? Earth? Power?

From the Adafruit NeoPixels best practices guide:

* Before connecting NeoPixels to any large power source (DC “wall wart” or even a large battery), add a capacitor (1000 µF, 6.3V or higher) across the + and – terminals.
* Place a 300 to 500 Ohm resistor in series between the Arduino data output pin and the input to the first NeoPixel. This resistor must be at the NeoPixel end of the wire to be effective!
* Try to minimize the distance between the Arduino and first pixel.
* Avoid connecting NeoPixels to a live circuit. If you simply must, always connect ground first, then +5V, then data. Disconnect in the reverse order.
* If powering the pixels with a separate supply, apply power to the pixels before applying power to the microcontroller.

---
Tags: esp8266, rgb-led
---


# Question
Title: Do I have to wire up my WS2812 LED strip in "series", if I want to address each LED individually?
Let's assume I want to make an asterisk (`*`) out of LED strips. I want to control each leg individually, while still being connected to only one GPIO pin. The layout I had in mind, looks like this:

Since it's an LED strip with individually addressable LEDs, I can't just supply 5V, GND, and DATA to the middle and expect it to work (I highly assume).

If I want to do this, I assume I need to keep running them in "series", basically meaning I hook up one of the strips to the Arduino, then at the end of the strip I run a long wire to the start of one of the others and then repeat. Something like this:

but only for the data wire, as I can simply power all of them in the middle. If not, how can I do this? What happens if I hook up 5 strips' DATA to a single GPIO pin on the Arduino? Are all 5 strips shared then, so each strip's first LED is also the first I would turn on?

# Answer
The LEDs are "addressed" in series; if you address the first LED then you address *all* connected first LEDs. So yes, you must connect the Data Out of the previous LED/strip to the Data In of the next in order to address all of them individually.
> 4 votes

---
Tags: led, led-strip, ws2812
---


# Question
Title: Not sure why eeprom isn't reading back correctly
I'm new to saving data on eeprom and I'm obviously doing something wrong but I'm not sure what. I have one program which both writes to and reads the internal eeprom on a attiny85 and this seems to work. However when I try to use this program to write and then remove the power from the attiny, then reprogram it with another program to read the eeprom it gives values of -1 for time and NAN for temperature.

My program which works is as follows, the program to read the eeprom only is the same however I deleted all the sections which write. If you want me to add that program let me know.

I am using at attinyavr programmer from sparkfun and I have connected pins 3 & 4 on the attiny to an arduino uno which is connected to the serial monitor so that I can see the output (described here: http://www.instructables.com/id/Easy-ATTiny-Serial-Communication-with-Tiny-AVR-Pro/#CP78RMAJ76GI6JQ)

Feel free to direct me to another answer if someone else has had the same problem, at the moment I think I will figure this out eventually but I suspect it will take me a few days so thought I would ask hopefully it's obvious to someone else.

(I'm aware that the time won't be correct since it should be unsigned long not an int, was just changing it round to test if that was the problem which it seems not to be).

Any help is really appreciated!!! Thanks :) /\*

```
ATTINY85 pin 3 -> Arduino Uno pin 0
ATTINY85 pin 4 -> Arduino Uno pin 1
Program choose 1MHz clock
 */

#include <EEPROM.h>
#include <SoftwareSerial.h>
// Definitions
#define rxPin 3     // Make pin 3 on the
#define txPin 4

SoftwareSerial mySerial(rxPin, txPin);

int currentTime;
int getTime;

int sensorPin = 7; // This is the 7th pin on the ATtiny85,
                         // it is an analog input when reading as digital
call it 7? analogpintochannel function
                          // (On the HLT tutorial it is labelled as Pin2: Analog input 1, SCK )
float temperature = -500.00f;     // Create a new float called temperature and give it the value -500 to start with
float getTemperature = -500.00f;
int eepromAddress = 0;       // initialize variable for position in eeprom to store data collected
int getEepromAddress = 0;

// the setup routine runs once when you press reset:
void setup() {
  pinMode(sensorPin, INPUT);    // make pin 7 on the ATTiny an input pin
  mySerial.begin(9600);         // begin software serial at rate of 9600

}

// the loop routine runs over and over forever:
void loop() {

  static int countDataCollected = 0;  // initialize a count variable to count the data collected, static int should set to 0 only first time, second time loop goes round it shouldn't reset to 0

  if (countDataCollected==0) delay(90000); // put delay here so it gives me time to load the read eeprom program if required before it changes the eeprom in case that was the problem.

  if((countDataCollected>=0) and (countDataCollected < 10)) {

    currentTime = millis();
    temperature = analogRead(sensorPin)*5.0/1024.0;  // read value on pin 7, multiply it to find temperature
    temperature = temperature - 0.5;
    temperature = temperature / 0.01;

    mySerial.print("\n\nData number: ");
    mySerial.print(countDataCollected);
    mySerial.print("\tTime: ");
    mySerial.print(currentTime);
    mySerial.print("\tTemperature: ");
    mySerial.print(temperature);
    mySerial.print("\tCurrent eeprom address: ");
    mySerial.print(eepromAddress);
    mySerial.print("\t");
    mySerial.print(getEepromAddress);

    EEPROM.put(eepromAddress, currentTime);
    EEPROM.get(getEepromAddress, getTime);
    mySerial.print("\tGot time: ");
    mySerial.print(getTime);

    eepromAddress = eepromAddress + sizeof(currentTime);
    getEepromAddress = getEepromAddress + sizeof(getTime);
    mySerial.print("\teeprom address: ");
    mySerial.print(eepromAddress);
    mySerial.print("\t");
    mySerial.print(getEepromAddress);

    EEPROM.put(eepromAddress, temperature);
    EEPROM.get(getEepromAddress, getTemperature);

    eepromAddress = eepromAddress + sizeof(temperature); //Move address to the next byte after float 'myfloat'.
    getEepromAddress = getEepromAddress + sizeof(getTemperature);
    mySerial.print("\tGot temperature: ");
    mySerial.print(getTemperature);
    mySerial.print("\teeprom address: ");
    mySerial.print(eepromAddress);
    mySerial.print("\t");
    mySerial.print(getEepromAddress);
    mySerial.println();

    }

  // wait two seconds so as not to send massive amounts of data
  delay(2000);
  countDataCollected=countDataCollected+1;

  mySerial.print("\n\nNext data number =");
  mySerial.print(countDataCollected);
}

```

# Answer
Fixed by resetting the attiny85 fuse to stop the EEPROM being cleared when the attiny was reprogrammed.

As far as I understand (I am a newbie at AVR programming so may be wrong)

The arduino bootloader (in the Arduino IDE) sets the attiny fuses. One of the fuses that it sets (also the attiny85 default setting) clears the EEPROM when reprogramming. To see how the bootloader is setting the fuses to you can turn on verbose comments in the Arduino IDE, and run the bootloader. When I ran the bootloader it set the fuses as follows: pattiny85 -cusbtiny -e -Uefuse:w:0xff:m -Uhfuse:w:0xdf:m -Ulfuse:w:0xe2:m

i.e. arduino bootloader settings, efuse: 0xff, hfuse: 0xdf (need to change to d7), lfuse: 0xe2 (affects the clock),

You can use a fuse calculator (http://www.engbedded.com/fusecalc/) to determine how to change the fuse settings so the the EEPROM is not cleared. (In the fuse calculator tick the box for "Preserve EEPROM memory through the chip erase cycle, EESAVE=0"). When the box is ticked the hfuse setting is D7 rather than DF

Also note that the bootloader in Arduino sets the lfuse to 0xe2, this is different from the default (it affects the setting 'Divide clock internally by 8' if 0xe2 is used it's an 8Mhz clock, the default prior to loading the boatloader is 1Mhz). Noting this because I initally reset everything to default and then had clock problems.

The hfuse can be set to d7 by downloading and running the AVR programming software https://sourceforge.net/projects/winavr/ and then setting the fuse using avrdude in a command window. (more information on AVR setting fuses here http://www.ladyada.net/learn/avr/index.html)

I ran avrdude in a command window with the instruction: avrdude -c usbtiny -p attiny85 -U hfuse:w:0xd7:m

("-c usbtiny" specifies the programmer used so this may vary, the attiny was connected to my computer USB port using the sparkfun attiny AVR programmer).
> 1 votes

---
Tags: attiny, eeprom
---


# Question
Title: Serial monitor in Arduino IDE for RobotDyn ESP8266-Pro via CP2102
I bought a couple of "ESP8266-Pro" micro-controllers from a Chinese company named RobotDyn. There's no real documentation with them, but I've bought a lot of other stuff from them in the past that worked out really well, so I took a chance.

After some work, I am finally able to program the board with the Arduino IDE 1.8.1.

The problem is that I am unable to get the serial monitor working to see what's going on with the code.

What do I need to do to get this to work, or is it simply not possible? In order to program the board, I need to connect EN to VIN, and both IO0 and IO15 to GND. I assume I have to disconnect that to actually run the board after programming, but I don't know and haven't gotten anything to work yet.

Here's a photo of the board hooked up for programming. What do I need to do to restart it with the serial monitor working?

# Answer
> 1 votes
You applied connections like it was a plain esp8266. The board has the necessary pull-ups and pull-downs. Connect it at first only to GND, VCC, TX, RX. The button pulls gpio0 LOW to enter flashing mode at power up.

# Answer
> 0 votes
So it seems that the trick to being able to monitor serial output on the RobotDyn ESP8266-Pro is to **NOT** have `DTR` and `CTS` from the CP2102 programmer connected to the board's `RST` and `IO12` pins.

With only the four remaining lines connected (`VCC`, `GND`, `TXO`, and `RXI`), you will see normal serial output on the the Arduino IDE's serial monitor **after uploading firmware completes**.

This works for me with the board set as "Generic ESP8266 Module" or as "NodeMCU 1.0 (ESP-12E Module)".

This still doesn't get you serial monitoring when you just plug in the device, though. It only works after firmware has been uploaded. Still working on that.

---
Tags: serial, esp8266, arduino-ide
---


# Question
Title: Moving a character around an LCD screen - is there a better way?
I have some basic programming experience but I am a novice at both C and Arduino.

I messed around with the example LCD code to try to move a character around with the onboard keypad. I also wanted the actual move to occur only once the button is released, like you would expect from a keypad.

The code works, but I have a feeling all the empty WHILE loops inside the main loop() function I used are not the best practice.. :)

How did I do? Is there a more convenient/elegant solution I missed and can learn from?

Thanks, and sorry for the messy code!

```
void loop()
{
  lcd.clear();
  lcd.setCursor(posCol,posRow);      //initialized beforehand
  lcd.print("O");                    //random char to move
  lcdOld = btnNONE;

  while (read_LCD_buttons() == btnNONE)     //do nothing while nothing is pressed
  {
  }

  lcdOld = read_LCD_buttons();

  while (read_LCD_buttons() == lcdOld)     //do nothing while button is down
  {
  }

  switch (lcdOld)               // depending on which button was pushed, we perform an action
   {
   case btnRIGHT:
     {
     posCol++;
     break;
     }
   case btnLEFT:
     {
     posCol--;
     break;
     }
   case btnUP:
     {
     if (posRow == 1)
     {
        posRow = 0;
        break;
     }
     else
     {
     break;
     }
     }
   case btnDOWN:
     {
     if (posRow == 0)
     {
        posRow = 1;
        break;
     }
     else
     {
     break;
     }
     }
   case btnSELECT:
     {
     break;
     }
     case btnNONE:
     {
     break;
     }
 }
}

```

# Answer
> 3 votes
You could encapsulate the logic of detecting a button release into its own function:

```
// Return the button that was just released, or btnNONE.
int releasedButton()
{
    static int last_button = btnNONE;
    int previous_button = last_button;
    last_button = read_LCD_buttons();
    if (last_button == btnNONE)
        return previous_button;
    else
        return btnNONE;
}

```

Then the logic in the loo gets simplified:

```
void loop()
{
    switch (releasedButton()) {
        ...
    }
}

```

---
Tags: lcd
---


# Question
Title: understanding timer overflow detection code
I am trying to understand in details the (great tutorial and) code of Nick Gammon **''Improved sketch using Timer 1''**, available here: http://www.gammon.com.au/forum/?id=12075 . I post the whole code at the end of this in the case the web page would go down.

I find the code quite clear: Nick wants to estimate the value of a capacitor by measuring its characteristic discharge time. For this he uses one of the Arduino timers, together with an interrupt raised by the analog comparator. As the Arduino timer he uses is only 16 bits and he uses a pre-factor of 1 at 16MHz, he expects overflow of the timer to occur so he keeps track of the number of overflows that happened:

```
ISR (TIMER1_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows
}  // end of TIMER1_OVF_vect

```

However, what I do not understand is why he tries to find a 'missed overflow' in the ISR raised by the analog comparator (this is in the `ISR (ANALOG_COMP_vect)` function body):

```
// if just missed an overflow
    if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
      overflowCopy++;

```

So my questions are:

* How could a missed overflow happen? 'Naively' I would guess that, as soon as the analog comparator ISR is called, the timer stops incrementing so that it should not overflow after the comparator ISR fires, am I wrong?
* If there is a timer overflow happening, I understand why one wants to check TIFR1 at TOV1 (this is the overflow flag, set automatically at timer overflow, which should be cleared as a side-effect of execution of `ISR(TIMER1_0VF_vect)` according to datasheet), why add also the `&& timer1CounterValue < 256` in the if condition? I understand that `256` is a 'small' value, any reason for this exact numerical value?

# Copy of the whole code:

```
/*
Capacitance meter

Author: Nick Gammon
Date:   27 June 2013

Pulse pin (D2): Connect to capacitor via 10K resistor.

Reference voltage of 0.632 of output pin (pulsePin) connected to D7.
In my case I used 3.06V because I measured 4.84 on the 5V pin.

Measure pin (D6) connected to first leg of capacitor, other leg connected to Gnd.

Like this:

Capacitor to test:

D2  ----> 10K ----> D6 ----> capacitor_under_test ----> Gnd

Reference voltage:

+5V ----> 1.8K ---> D7 ---> 3.1K ----> Gnd

*/

const byte pulsePin = 2;
const float resistance = 10000.0;

volatile boolean triggered;
volatile boolean active;

volatile unsigned long timerCounts;
volatile unsigned long overflowCount;

ISR (TIMER1_OVF_vect)
{
  ++overflowCount;               // count number of Counter1 overflows
}  // end of TIMER1_OVF_vect

ISR (ANALOG_COMP_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  if (active)
    {
    // if just missed an overflow
    if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
      overflowCopy++;
    // calculate total count
    timerCounts = (overflowCopy << 16) + timer1CounterValue;  // each overflow is 65536 more
    triggered = true;
    digitalWrite (pulsePin, LOW);  // start discharging capacitor
    }
  }  // end of ANALOG_COMP_vect

void setup ()
  {
  pinMode (pulsePin, OUTPUT);
  digitalWrite (pulsePin, LOW);

  Serial.begin (115200);
  Serial.println ("Started.");
  ADCSRB = 0;           // (Disable) ACME: Analog Comparator Multiplexer Enable
  ACSR =  bit (ACI)     // (Clear) Analog Comparator Interrupt Flag
        | bit (ACIE)    // Analog Comparator Interrupt Enable
        | bit (ACIS0) | bit (ACIS1);  // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on rising edge)
   }  // end of setup

void startTiming ()
  {
  active = true;
  triggered = false;

  // prepare timer
  overflowCount = 0;            // no overflows yet
  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;      // Counter to zero
  TIFR1 = bit (TOV1);  // clear overflow bit
  // Timer 1 - counts clock pulses
  TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

  // get on with it
  digitalWrite (pulsePin, HIGH);  // start charging capacitor
  // start Timer 1, no prescaler
  TCCR1B =  bit (CS10);

  } // end of startTiming

void finishTiming ()
  {
  active = false;
  Serial.print ("Capacitance = ");
  float capacitance = (float) timerCounts * 1000.0 / 16.0 / resistance;
  Serial.print (capacitance);
  Serial.println (" nF");
  triggered = false;
  delay (3000);
  }  // end of finishTiming

void loop ()
  {
  // start another test?
  if (!active)
    startTiming ();

  // if the ISR noted the time interval is up, display results
  if (active && triggered)
    finishTiming ();

  }  // end of loop

```

# Answer
> 2 votes
> 'Naively' I would guess that, as soon as the analog comparator ISR is called, the timer stops incrementing

It doesn't. The timer stops only when you ask it to stop.

Now, consider this scenario:

* `overflowCount` = 0, `TCNT1` = 0xfffc
* the `ANALOG_COMP` interrupt fires, which automatically disables servicing nested interrupts
* while `ISR(ANALOG_COMP_vect)` is executing its prologue (saving the execution context), Timer 1 overflows, which sets the `TOV1` flag, but the corresponding interrupt is for now pending
* when `timer1CounterValue = TCNT1;` gets executed, `TCNT1` is now 0x0008.

At this point, we have `overflowCount` = 0 and `timer1CounterValue` = 0x0008. If we have no provision for detecting the overflow, we will grossly underestimate the time. This can be fixed by accounting for the missed overflow as

```
// if just missed an overflow
if (TIFR1 & bit(TOV1))
    overflowCopy++;

```

The is still an issue however. Think of what would happen if the timer overflows after executing `timer1CounterValue = TCNT1;` but before reading the `TOV1` flag. Then we would unduly increment `overflowCopy`. This is why the code tests for `(TIFR1 & bit(TOV1)) && timer1CounterValue < 256`. There is no reason for choosing this particular small value, other than the test being easier to perform in assembly. The compiler is probably smart enough to notice it doesn't need to do a subtraction for this particular value.

---
Tags: interrupt, atmega328, timers
---


title: 5v input on ATmega328p running on 3.3v

text:
# Question
Title: 5v input on ATmega328p running on 3.3v
The ATmega328p can run on 5v but will it cause problems if it runs on 3.3 v and one input signal is 5v?

# Answer
> 0 votes
Logic levels can be different across differently made integrated circuits and processors. You should not directly connect differently powered devices together. Logic level differences (as described here) should be dealt with using logic level converting devices such as this one.

# Answer
> 0 votes
The voltage at any input *must* be less than VCC+0.3V unless it is restricted to only a few milliamperes (so it doesn't burn out the clamping diode). Use a proper voltage translator if it is available, otherwise use a 1kohm or greater resistor (at the cost of life expectancy for the MCU).

---
Tags: atmega328, voltage-level
---


# Question
Title: How to connect RFID Module to Arduino UNO
I brought 860mhz-960mhz UHF rfid reader module for chip card skimmer from follow link:

https://www.alibaba.com/product-detail/860mhz-960mhz-UHF-rfid-reader-module\_60312310172.html

I want to do communication with arduino uno so is it possible to connect

VCC to VCC GND to GND RX to TX TX to RX

and what is meaning of EN and GPIO if any one know please help me to do serial communication.

# Answer
Its just a simple RFID module based on UART working on 5V. EN stands for enable, to enable the chip. It has to be connected to VCC too. Because its active high signal. GPIOs are general purpose io pins. No need of them if you are just reading from RFID.
> 1 votes

---
Tags: arduino-uno, rfid
---


# Question
Title: Creating String Arrays and passing each index value to a variable after a given period
Is there a way to take an input string, store it into a array and then pass each index of that array to a variable to hold before being overwritten by the next array index value?

For example:

A number of input values which are of type:String are being created

```
String 1 is given as "Value: 7.93 22-10-2017 10:33:32"
String 2  is given as "Value: 8.93 22-10-2017 12:10:15"
.
.
.
String 10  is given as "Value: 6.93 22-10-2017 18:03:04"

```

The string structure is known but its contents as such will vary

After a time period of say 60sec. The contents of array\[0\] which will be String 1 will be assigned to a given variable "output"

After the next 60sec time period .The contents of array\[1\] Which will be String 2 will be stored into the same "Output" variable in which the previous value will be now overwritten

This continues until array\[9\] i.e String 10 in which the array will begin over and start to populate "output" with newly presented string values

# Answer
Solution Used Below:

```
// Input 1-3 represents input string

String Input1 ="Value: 7.93 22-10-2017 10:33:32";
String Input2 ="Value: 8.93 22-10-2017 12:10:15";
String Input3 ="Value: 8.93 22-10-2017 12:10:15";
String message[] ={Input1,Input2,Input3};

// Assigned 'Output' Variable will be populated by each index of the array
String Output;

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

// Each index of the array will be stepped through and passed to 'Output'
//delay() will control period between each index value

void loop()
     {
         for (int i = 0; i < 3; i++)
            {
                  Output=message[i];
                  Serial.println(Output);
                  delay(5000);
            }

     }

```
> 0 votes

---
Tags: string, array
---


# Question
Title: Connect a sensor to Arduino without knowing much info about the sensor
I am planning to buy a formaldehyde sensor and I would like to connect it to an **Arduino Uno** board (and later to a Raspberry). As far as I know, the sensor comes in a small box/bag without any other external components (e.g. amplifiers etc.). So I will end up having in my hand a sensor with two copper terminals for connection (see image below):

Is it possible to connect this to an Arduino board without having a connection scheme? If yes, where do I connect the two terminals of this sensor to the 5V, GND and the A## ports? Also, how to translate the voltage coming from the sensor to ppm (parts per million) only by having general specifications from the manufacturer and not some kind of table of conversion? Also, would I need an external component for this? If yes, which component?

I know that this question sounds very stupid, but so far I've used sensors that come with a code on Seeed Grove with a clear description and I assumed that the code is there because there is a link between the producer of a certain sensor and Groove. Thank you!

FYI: The producer writes some things about the sensor but that doesn't help me a lot:

> This sensor is of the two-electrode electrochemical type, operating by the diffusion principle and as such requires no external sampling hardware. In the presence of formaldehyde gas a small direct current is produced; the sensor requires no power supply of its own but this current requires amplification to make it readable using external data collection equipment.

# Answer
> 2 votes
You have linked to the datasheet of the sensor.

In the datasheet, look at the "Application Circuit" section. You must build this circuit. The sensor produces a very small electric current, and the application circuit is high-gain amplifier to translate that very small electric current to a varying voltage you can sample with the Arduino ADC.

Note on the circuit, the wire labled "To ADC" -- that is the part which you connect to your arduino.

As for calibration, the datasheet itself notes that the process is non-trivial, or that they can perform a calibration, for an additional fee, at the time you order a batch of sensors. Presumably their calibration will include the precise resistor values used to set the gain of the amplifier, and also an equation to associate PPM values to the analog voltage provided at the "To ADC" wire.

As for reading the circuit diagram (schematic), you may already know resistors and capacitors. For the other items, search online for the part numbers given, to find out what they are.

The datasheet also notes that the application circuit is available pre-built from the sensor manufacturer. You may want to contact them to determine how to purchase one for yourself.

Most electronics products have a datasheet that explains all you typically need to know about the device, such as it's operating parameter minima and maxima, typical values, typical outputs, etc. This sensor is no different, except that the calibration procedure is not described in great detail due to the complexity.

---
Tags: arduino-uno, sensors
---


# Question
Title: Connecting multiple component's VCC wires to one Arduino UNO R3 5V Pin
Apologies for the title gore and whether this seems to be a fairly basic question, I'm an Arduino noob.

I'm working on a wearable sensor system project at my university using an Arduino UNO R3 to handle all the sensors and power them. I'm currently powering the board with a USB connection and will be powering my components from the board's 5V pin as they can all safely operate with that voltage. The individual components do not exceed their I/O pins max current and their combined current usage doesn't exceed the boards maximum current.

My question comes in here: in the past if I've needed to connect multiple components to the ground and 5V pins of an Arduino board, I was always taught to use a matrix board to solder my component's 5V and GND wires to, where they could then be powered from two soldered wires from the microcontrollers 5V and GND pins.

Given that this is a wearable system, I would like to minimise any unnecessary hardware and so proposed to my supervisor that we cut out the matrix board and simply solder the VCC wires of the components together to one header pin which we can then plug into the 5V pin on the board to draw power. He strongly cautioned against this but wasn't able to provide a concrete reason as to why it would be a problem; as far as I can see the fundamental theory is the same and we are simply cutting out an unnecessary middle man.

Is there something I'm missing here or does this solution seem like it would work fine? Additionally, if this solution works for VCC, would the same principle work for sharing a grounded connection?

# Answer
Assuming you have suitable soldering skill, there are some considerations when you solder lots of wires to one header:

* Lots of wires means lots of weight. The strain of several wires may degrade your connection or header over time, especially for a wearable system, where I assume the parts would be subject to some movement.
* The width of the connection when all the wires are soldered to it. It might touch adjacent pins, or lean on them, creating mechanical stress. Heatshrink or sleeving can help with the electrical contact issue, but won't remove the mechanical risk.
* Lots of wires soldered to one point may make the system more difficult to service. Instead of desoldering the wire to one component, you have to either desolder them all, or cut the wire to the one suspect component and then solder together wire stubs later to replace it.

When referring specifically to power supply pins, you'll need to consider the peak current requirements of anything you power from it. Based on https://playground.arduino.cc/Main/ArduinoPinCurrentLimitations it seems like you shouldn't be pulling more than 200mA from the Vcc PIN. Check the *maximum* current draw of all of your components that you want to power, add them together, and make sure it's under the limit of the Arduino board.
> 0 votes

---
Tags: arduino-uno, power, pins
---


# Question
Title: Fatal Exception Error on ESP8266 + Arduino
When I was trying to blink an LED using ESP8266, I had an issue with it. After successfully uploaded the code (https://diyhacking.com/esp8266-tutorial/), the blue LED stayed on & when I opened the serial monitor using Arduino IDE 1.6.12, I only saw "Fatal Exception" error (showed in the picture). I couldn't see how the code works and the worst thing was I couldn't even try the AT command.

The connections:

Arduino \<---\> ESP8266 (ESP-07)

```
Tx  <--->   Tx
Rx  <--->   Rx
GND <--->   GPIO0
GND <--->   GND
3.3v<--->   CH_PD
3.3v<--->   VCC
            GPIO2 -> LED

```

I have been trying to troubleshoot this issue but haven't got the solution yet. I am afraid there is an issue with the firmware or the worst situation, I spoiled my ESP8266.

# Answer
Looking at your serial monitor window it shows "Geuino Uno". I think you forgot to change the target of the compiler to "Generic ESP8266" like shown in the how-to and you probably uploaded bad code to your module.
> 1 votes

# Answer
If you are getting fatal error exception like this:

```
Exception (3):
epc1=0x401003e9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4000cbd9 depc=0x00000000

```

In infinite loop in your Serial Monitor of the Arduino IDE then go to this link, download the software, and follow the procedure and erase the flash memory to solve the error.

This does not solve fatal error that occurs due to your program but in case your device goes in such condition that it can't be able to access program memory then it will work and try at least one time to solve the problem.

This is the procedure to hard reset the NodeMCU (https://www.youtube.com/watch?v=MHrm7axsImI&t=146s):

1. Install latest Python version in your PC. (https://www.python.org/downloads)
2. Open cmd prompt as administrator.
3. Go to C:\Program Files or C:\Program Files (x86)-\>python (your version)-\>Script. For this type `cd c:\Program Files (x86)\python(your version)\Script` then press enter.
4. Type `pip install esptool`.
5. Download ESPlorer.zip (v 0.2.0-rc6) from https://esp8266.ru/esplorer
6. Extract the downloaded file.
7. Open the executable jar file.
8. Go to NodeMcu firmware site (https://github.com/nodemcu/nodemcu-firmware/releases) and download file (nodemcu\_float\_0.9.6-dev\_20150704.bin) and copy this file into the C:\Program Files (x86)/python(your version)/Script folder.
9. Now in cmd prompt just type:

```
esptool.py --port COM(your port no.) --baud 115200 erase_flash

```

And press enter.

Note: you can see your NodeMCU board's port number in Device Manager .
> 0 votes

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