# Question
Title: Use and definition of a destructor class
I created a class for TFT buttons and messages when using a Wemos 2.4 tft touch display.

In a code I use about 12 buttons (3 different screens with 4 buttons in each screen ), for example in my home control code "Main Screen" has `Lights`, `Windows` `Alarms`, `Temperatures`, and each screen below has set of others.

Since button's life expectancy is only for current screen (also in `loop()` since it monitor press at defined location), and each button take no little resources as show below in lib's `.h` file (other class with touch function are not show here), I would like to know how to create a destructor to free up space, since main resources are used in `MessageTFT` class.

```
#ifndef TFT_GUI_h
#define TFT_GUI_h

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>

extern XPT2046_Touchscreen ts; /* Touch screen */
extern Adafruit_ILI9341 tft;   /* Graphics */

const uint8_t _pos_corr_factor[3] = {3, 6, 9}; /* Center text inside a box */
class MessageTFT
{
public:
  uint8_t a, b;
  int xc, yc;
  uint8_t txt_size = 1;
  uint8_t screen_rotation = 0;
  uint8_t border_thickness = 1;
  uint16_t face_color = ILI9341_GREEN;
  uint16_t border_color = ILI9341_RED;
  uint16_t txt_color = ILI9341_BLACK;

  char txt_buf[30];
  bool roundRect = false;

public:
  MessageTFT(Adafruit_ILI9341 &_tft);
  void drawMSG();
  void text(char *txt);
private:
  uint8_t _radius = 15;

private:
  void _drawFace();
  void _drawBorder();
  void _put_text();
};
#endif

```

# Answer
Destructors, despite their name, are not used to destroy the object. They are, instead, a "hook" that is called *when* the object is destroyed. Much like the "constructor" is called *when* the object is created - it doesn't *do* the creating.

A destructor is intended to "clean up" an object before it is deleted. That usually entails freeing any memory allocated at runtime (through `malloc()`, `new`, etc) by the object.

Since you don't do anything at runtime that needs to be cleaned up there is nothing for your destructor to do. All your variables are simple statically allocated memory as part of the object istelf, so those automatically get destroyed when the object is destroyed.

You can think of it as crushing a car. The seats, engine and steering wheel all get crushed without you having to worry about it. But first you want to take the dog out of the boot - you *really* don't want him in there when the car gets crushed, it'll get really really messy and the dog will be lost forever ... :(
> 6 votes

---
Tags: class
---


# Question
Title: Serial Monitor in Arduino works, but other Serial Terminal work only one way
I have a Arduino code working on a Adafruit Feather STM32F405 Express, and as long as I test it with Arduino serial Monitor, everything works perfect. As I want to use a serial terminal (a C# application, or the "Terminal Br@y++") through the same COM port, then I can write my commands, there are executed (output pins send expected signal), but I don't received the serial feedback.

My Arduino code :

```
void setup() {
  Serial.begin(115200); // initialise USB Serial Port
  pinMode(pumpP, OUTPUT);  // Pump Pin is an output
}
void loop() {
    if (Serial.available() > 0) {
      command = Serial.readStringUntil('\n');
    }
    if (command == "do-it"){
        digitalWrite(5, HIGH);
        Serial.println("did it!");
    }
}

```

In my Arduino Serial Monitor, I write "do-it", and I recieved "did it!" and I can see the Pin 5 changing level. In all serial application I could use, I can see the pin 5 changing level, but not the "did it!".

I configured Arduino as described on this Adafruit page : https://learn.adafruit.com/adafruit-stm32f405-feather-express/arduino-ide-setup \[ *summary: use STM32F4 library, board number = "Adafruit Feather STM32F405", USB support = "CDC ( Generic Serial supercedes USART)", upload method = "STM32CubeProgrammer (DFU)"* \] And I connect the DFU pin to 3,3V during upload, and reset the board after it.

The worst in this story, is that at first time, it worked OK. Since a week or two, I don't get it to work again.

# Answer
Thank you @Majenko, you gave the solution : I checked the box "RTS/CTS" in the "handschake" section of Terminal by Bray, and I got all my serial message back from the STM32.

I guess this is a common think on more that stm32? how did you know, is that somewhere written in Arduino documentation?

for people like me who do not know what is RTS/CTS, here you are: http://www.brainboxes.com/faq/items/what-is-rts--cts-hardware-flow-control- or not so straight-forward https://en.wikipedia.org/wiki/RS-232#RTS,\_CTS,\_and\_RTR

Funny to figure out that this "5 pin communication" is virtualise in USB.

@Majenko: if you want to "own" the solution, I let you do write it yourself, I will set your answer as solution.
> 1 votes

---
Tags: serial, stm32
---


title: Convert float to int error

text:
# Question
Title: Convert float to int error
I am trying to convert 1.06 to 106 by multiplying by 100 but the answer comes 105, I do not know why. Variable ver can be any decimal in this format x.xx

```
float ver = 1.06;
int vers = ver * 100;
vm[0] = (vers / 100U) % 10;
vm[1] = (vers / 10U) % 10;
vm[2] = (vers / 1U) % 10;
Serial.println(vers);

```

Could you let me know what I am doing wrong or maybe I have to do something else.

# Answer
> 5 votes
1.06 is not a float. The closest float is 1.059999942779541015625. If you multiply that by 100 you get a number that, again, is not a float. Rounding to the nearest float yields 105.99999237060546875, which is the result of the expression `ver * 100`, and just one ULP short of 106. Yes, floating point computations do quite usually involve rounding steps.

Casting to an `int` implicitly rounds towards zero, and you get 105, which is the correct result. Correct according to the rules of IEEE 754 arithmetics.

You may want to `round()` to the nearest integer before the cast.

> Variable ver can be any decimal in this format x.xx

No, a `float` cannot be “any decimal” in this format. Floats are stored in binary, and most decimal numbers (numbers that can be written with a finite number of decimal digits) cannot be written in binary with a finite number of bits.

Except for a few values (namely the multiples of 0.25), `ver` can only store an *approximation* of the decimal number.

---
Tags: float
---


# Question
Title: What is the simplest way to emulate the original gameboy's cpu using Arduino?
My initial question assumes it is possible to emulate the original GameBoy system using an Arduino board.

Additional information in non-technical terms: I am looking to create an Arduino based device that accepts cartridges as input devices (in some cases they will also function as output devices) I am interested primarily in the Hexadecimal/pixel based "logic" which gameboy games uses to display game data.

What is the simplest way to emulate the original gameboy's hexadecimal based pixel logic to fetch, decode, and execute data using Arduino?

Before flagging this question, please comment so that I may clarify as this is a complex question to ask and I am willing to re word it as necessary.

# Answer
> 0 votes
(Assembling an answer from the comments)

The consensus is that there is no "simple way to emulate the original gameboy cpu using Arduino". That a more powerful platform is required.

Multiple commenters expressed difficulty with the novel concept of "hexadecimal/pixel based logic". It is suggested that this concept may be without merit.

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


title: How to convert String to byte array

text:
# Question
Title: How to convert String to byte array
I have the code, it's purpose is to receive the string from a comport like: `Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456` and translate it into four byte arrays `byte user1[16], user2[16], pass1[16], pass2[16]`. Here's the code:

```
String inString = ""; // COM port incoming data buffer

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Start");
}

void loop() {
  // put your main code here, to run repeatedly:
  // Receive data from com port
  while (Serial.available() > 0) {
    int inChar = Serial.read();

    if (inChar != '\n') {
      inString += (char)inChar;
    } else {
      // New line
      String Action = inString.substring(0, 3);
      if (Action == "Set") {
        SetCard(inString);
      } else if (Action == "Get") {
        Serial.println("1");
      } else {
        Serial.println(Action);
      }
      inString = "";
    }
  }
}

void SetCard(String Data) {
  Serial.println(Data);
  // Data Set@user1@user2@pass1@pass2
  // Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
  byte user1[16], user2[16], pass1[16], pass2[16];

  String user1str = inString.substring(4, 20);
  String user2str = inString.substring(21, 37);
  String pass1str = inString.substring(38, 54);
  String pass2str = inString.substring(55, 71);

  Serial.println("Strings");
  Serial.println(user1str);
  Serial.println(user2str);
  Serial.println(pass1str);
  Serial.println(pass2str);

  Serial.println("Arrays");
  user1str.getBytes(user1, 16);
  user2str.getBytes(user2, 16);
  pass1str.getBytes(pass1, 16);
  pass2str.getBytes(pass2, 16);

  writeByteArray(user1, 16);
  writeByteArray(user2, 16);
  writeByteArray(pass1, 16);
  writeByteArray(pass2, 16);
}

void writeByteArray(byte array[], int arrlength)
{
  for (int j = 0 ; j < arrlength ; j++) //print the block contents
  {
    Serial.write (array[j]);//Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
  }
  Serial.println("");
}

```

When I run this code and send my string through a com port I expect the output:

```
Start
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
Strings
1234567890123456
1234567890123456
1234567890123456
1234567890123456
Arrays
1234567890123456
1234567890123456
1234567890123456
1234567890123456

```

And yet, I receive

```
Start
Set@1234567890123456@1234567890123456@1234567890123456@1234567890123456
Strings
1234567890123456
1234567890123456
1234567890123456
1234567890123456
Arrays
123456789012345
123456789012345
123456789012345
123456789012345

```

Why? And how do I receive desired output? getBytes docs

# Answer
> Why? And how do I receive desired output? getBytes docs

The String member function getBytes() will null-terminate the string. You must add space for that.

```
  byte user1[17], user2[17], pass1[17], pass2[17];
  ...
  user1str.getBytes(user1, sizeof(user1));
  ...
  Serial.print((char*) user1);

```

That should do the trick.
> 2 votes

# Answer
Using String.getBytes(buffer, len) to get bytes.

"len" is the length to copy, but usually need to add 1 for the end of string '\0'.

For example:

```
String s = "123";
int count = s.length();  // lenth() is 3
s.getBytes(buffer, count);   // copied "12\0" => HEX(31 32 00)
s.getBytes(buffer, count + 1);   // copied "123\0" => HEX(31 32 33 00)

```

The official document not mentioned those above, and it's not reasonable for the modern function design.

Misunderstanding in that and waste our life so much.
> 1 votes

---
Tags: arduino-uno, string, convert
---


# Question
Title: Delay() and millis() functions don't work in cpp external files
I'm currently facing an issue using **delay()** and **millis()** functions in an external cpp file. The issue is that when I used delay() in my main program (meaning .ino file) it works well but when I call the same function in an external cpp file, I'm stuck in the delay function. Concerning the setup, the .hpp linked to the used cpp is well included in the .ino file and the librairy Arduino.h is included in my cpp. I also tried to replace delay by a loop using millis but the value returned by millis is always 0. I'm using an Arduino mega2560 and a water level sensor in the follwing example. The Arduino IDE version is 1.8.16.

Here is an extract from my ino file:

```
#include <Arduino.h>
#include "DS3231.h"
#include "MyGardenClock.hpp"
#include "sensors.hpp"
#include <LiquidCrystal.h>
#include "Keypad.h"
#include <Wire.h>

///Time object creation
DS3231 clock; //Clock object -> contains basic Real Time Clock functions
RTCDateTime dt; //Struct from DS3231 lib - contains date and time
mG_RTC myClock; //Object that contains specific clock functions to my project like printing date and time on the lcd...

///LCD object creation
//--Pin allocation
const int rs = 2, en = 1, d4 = 4, d5 = 7, d6 = 8, d7 = 10;
//--LCD dynamic object creation
LiquidCrystal* pLCD = new LiquidCrystal(rs, en, d4, d5, d6, d7);

///Keypad parametrization and object creation
//Define col nb and row nb
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {52, 50, 48, 46}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {44, 42, 40, 38}; //connect to the column pinouts of the keypad
//Keypad dynamic object creation
Keypad* pKpd = new Keypad(makeKeymap(hexaKeys),rowPins,colPins,ROWS,COLS);

///Sensors object creation
//WaterLvl Sensors
//--Pin allocation
const int WtrLvlAnalogPin = 8; //pin used to read value from water lvl sensor
const int WtrLvlPowerPin = 35; //pin used to power the sensor before reading a value
//--WaterLvl dynamic object creation
Water_Lvl_Sensor* pWtrLvlSens = new Water_Lvl_Sensor(WtrLvlAnalogPin,WtrLvlPowerPin); //contains the delay and millis functions that don't work

/////////// TEST FUNCTIONS ///////////
void testLCD_Kpd(Keypad*,LiquidCrystal*); //test lcd and keypad
void testWtrLvlSens(Water_Lvl_Sensor*,LiquidCrystal*); //test water lvl sensor

void setup()
{
    Serial.begin(9600);
    pLCD->begin(16,2);
    testLCD_Kpd(pKpd,pLCD);
    testWtrLvlSens(pWtrLvlSens,pLCD);

}

void loop()
{

}
////////////////////// TEST FUNCTIONS ///////////////////////////
void testLCD_Kpd(Keypad* pKpd, LiquidCrystal* pLCD)
{
   char test;
   test ='i';

   pLCD->print("Hello");
   do
   {
    test = pKpd->waitForKey();
   }while(test=='i');
   pLCD->clear();
   delay(3000); //This one work well
   pLCD->print("test = ");
   pLCD->print(test);

}

void testWtrLvlSens(Water_Lvl_Sensor* pWLS,LiquidCrystal* plcd)
{
  int wtrLvl;
  wtrLvl = pWLS->getCurrentWaterLvlValue();
  plcd->setCursor(0,1);
  plcd->print("wtrLvl = ");
  plcd->print(wtrLvl);

}

```

Here is an extract from my cpp file:

```
#include <Arduino.h>
#include "sensors.hpp"

/********************************************
*   CLASS WATER LvL SENSOR DESCRIPTION      *
********************************************/
///Constructor
//-- Assign pin number (analog & digital)
//-- Define pinMode for VCC + set to low
//-- read and store actual waterLevelValue as initial val
Water_Lvl_Sensor::Water_Lvl_Sensor(int anPinNb, int DigPinNb)
{
  //Variable used for millis
  unsigned long prevTime;
  unsigned long currentTime;
  const unsigned long delayTime = 100;

  Serial.begin(9600); //to debug

  //Assign analog and digital pin numbers
  analogPinNumber = anPinNb;
  VCC_digitalPinNumber = DigPinNb;
  pinMode(VCC_digitalPinNumber, OUTPUT); //Digital pin to power the sensor
  digitalWrite(VCC_digitalPinNumber,HIGH);//Turn sensor ON before reading initial value

  //delay(100); //not working ???
  prevTime = millis(); //get and store actual time
  do
  {
    currentTime = millis(); //get actual time
    Serial.println(currentTime); //print actual time (debug only)
  }while(currentTime<(prevTime+delayTime)); //while time spent < 100

  currentValue = analogRead(analogPinNumber); //read analog value

  digitalWrite(VCC_digitalPinNumber,LOW); //turn sensor OFF
  historyValue = currentValue; //init history val
  minValue = 0; //default value - sensor dry
  maxValue = 520; //default value - sensor under water
}

```

Does anyone has a solution?

I hope I've given enough details. If not, please feel free to ask.

Thanks!

# Answer
> 10 votes
The Arduino framework does some initializing for you before going into `setup()` and `loop()`, for example configuring Timer0 correctly for `millis()`, `delay()` and siblings. This is done in the `main()` function, which then after the first initializing calls `setup()` and `loop()`.

But the creation of globally defined objects (and thus the execution of their constructors) is done even before the `main()` function. At that time neither `millis()`, nor `delay()` will work, since the hardware Timer0 is needed to be configured correctly for them to work. The hardware timer generates interrupts with a specific frequency and in the corresponding ISR (Interrupt Service Routine) the variable for `millis()` is incremented. If the Timer0 isn't configured, it's interrupt cannot trigger and thus `millis()` will stay zero. So you cannot do all that in the constructor of the object, or you always need to create the object in `setup()` or `loop()`.

For this very reason most hardware related Arduino libraries use a `.begin()` method to initialize the hardware related stuff. That function can be called on the global object in the `setup()` function, when everything else is already configured correctly.

**What to do now?** Create a `.begin()` method for your class. Move all the code from the constructor (except for the pin number assignment) into this `.begin()` function. And then call that function in `setup()`.

---
Tags: arduino-mega, millis, cpp
---


title: Check pin capabilities at compile time

text:
# Question
Title: Check pin capabilities at compile time
Are there board-independent functions to check pin capabilities at compile time? I.e.

* Can the pin be used as output, as in `digitalWrite()`?
* Does the pin support PWM, as in `analogWrite()`?
* Does the pin support ADC, as in `analogRead()`?
* Does the pin support interrupts, as in `attachInterrupt()`?

I'm looking for functions/macros like e.g. `isDigitalOutput(pin)` which would return false for input-only pins such as A6 and A7 on a 328P, but true on a Mega where those pins are input/output.

# Answer
> 1 votes
For compatibility with `analogWrite()` there's `digitalPinHasPWM(p)` macro which returns 1 when PWM is supported on pin `p`.

For `analogRead()` there's `analogInputToDigitalPin()` which can be used as

```
#if ((p-PIN_A0 < 0) || (analogInputToDigitalPin(p-PIN_A0) != p))
#error Not an analog pin!
#endif

```

For `attachInterrupt()` there is `digitalPinToInterrupt(p)` which returns `NOT_AN_INTERRUPT` if the pin `p` doesn't support interrupts.

I still haven't found anything to test compatibility with `digitalWrite()`.

---
Tags: interrupt, pins, analogread, analogwrite, digitalwrite
---


# Question
Title: Trying to program a Led Counter Want a Led to flash every 5 minutes however it flashes twice every second (Noob)
Heres the code i've Wrote i feel like the issue lies in how ive used the if statement

```
int ledPinS = 13; //Classifies pin 13 as Connected to an LED
                //Flashes every second
int ledPinM = 12; //Classifies pin 13 as Connected to an LED
                //Flashes every minuite

byte seconds;

byte minutes;

  void setup() {
   pinMode(ledPinS, OUTPUT);
   digitalWrite(ledPinS, LOW);
   pinMode(ledPinM, OUTPUT);
   digitalWrite(ledPinM, LOW);
  }

    void loop() {
     while (seconds<=59){//flash every second and reset when Seconds =59
     delay(900);
     digitalWrite(ledPinS,HIGH);
     delay(100);
     digitalWrite(ledPinS,LOW);
     seconds++;
    }
 delay(200);   // flash ledPin M Once when Seconds = 59
 digitalWrite(ledPinM,HIGH);
 delay(100);
 digitalWrite(ledPinM,LOW);
 seconds = 0;
 minutes++; // add a minute
 if(minutes=5){ // if minutes = 5 flash ledPinM twice and reset
          delay(200);
        digitalWrite(ledPinM,HIGH);
        delay(100);
        digitalWrite(ledPinM,LOW);
        delay(200);
        digitalWrite(ledPinM,HIGH);
        delay(100);
        digitalWrite(ledPinM,LOW);
        minutes = 0;
    }
}

```

Any Help would be Appreciated.

# Answer
Although your code is formatted horribly, it does appear to be mostly correct.

I also recommend making your pin numbers "const int". This tells the compiler that they cannot be changed. Otherwise you could change those values in your code accidentally.

You also have un-initialized variables. Best practice would be to declare and initialise them at the same time. E.g.

```
byte seconds = 0;

```

Props for adding comments, though. Well done there.

You need an extra equals sign in your if statement.

```
if (minutes = 5) {

```

should be

```
if (minutes == 5) {

```

Classic mistake. We've all done it. You are assigning the value of 5 to minutes instead of checking for equality. This will always return true.
> 0 votes

---
Tags: programming, c++, arduino-pro-mini
---


title: Connecting Arduino with Philips Hue

text:
# Question
Title: Connecting Arduino with Philips Hue
I'm trying to control Philips Hue lights through an Arduino Uno (with a WiFi shield Model R3). Both the shield and the Philips Hue Bridge are connected to the same network and I'm trying to send JSON commands from the Arduino to the Hue Bridge from the following code taken from here.

```
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>

char ssid[] = "mynetwork";     //  your network SSID (name)
char pass[] = "mypass";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Hue constants
const char hueHubIP[] = "192.168.0.50";  //Hue Bridge IP
const char hueUsername[] = "myhue";  //Hue username
const int hueHubPort = 80;

IPAddress server(192,168,0,50);
WiFiClient client;

//Hue variables
boolean hueOn;  // on/off
int hueBri;  // brightness value
long hueHue;  // hue value
String hueCmd;  // Hue command

unsigned long buffer=0;  //buffer for received data storage
unsigned long addr;
IPAddress ip;

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

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();

  ip = WiFi.localIP();
  Serial.println(ip);

}

void loop()
{

    String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);
    command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);

}

/* setHue() is our main command function, which needs to be passed a light number and a
 * properly formatted command string in JSON format (basically a Javascript style array of variables
 * and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
 */
boolean setHue(int lightNum,String command)
{
  if (client.connect(server, 80))
  {
    Serial.println(F("connected to server"));
    while (client.connected()&& status == WL_CONNECTED)
    {
      client.print(F("PUT /api/"));
      client.print(hueUsername);
      client.print(F("/lights/"));
      client.print(lightNum);  // hueLight zero based, add 1
      client.println(F("/state HTTP/1.1"));
      client.println(F("keep-alive"));
      client.print(F("Host: "));
      client.println(hueHubIP);
      client.print(F("Content-Length: "));
      client.println(command.length());
      client.println(F("Content-Type: text/plain;charset=UTF-8"));
      client.println();  // blank line before body
      client.println(command);  // Hue command
    }
    client.stop();
    return true;  // command executed
  }
  else
    return false;  // command failed
}

  //client.flush();
  //client.stop();

/* A helper function in case your logic depends on the current state of the light.
 * This sets a number of global variables which you can check to find out if a light is currently on or not
 * and the hue etc. Not needed just to send out commands
 */
boolean getHue(int lightNum)
{
  if (client.connect(server, 80))
  {
    client.print(F("GET /api/"));
    client.print(hueUsername);
    client.print(F("/lights/"));
    client.print(lightNum);
    client.println(F(" HTTP/1.1"));
    client.print(F("Host: "));
    client.println(hueHubIP);
    client.println(F("Content-type: application/json"));
    client.println(F("keep-alive"));
    client.println();
    while (client.connected()&& status == WL_CONNECTED)
    {
      if (client.available())
      {
        client.findUntil("\"on\":", "\0");
        hueOn = (client.readStringUntil(',') == "true");  // if light is on, set variable to true

        client.findUntil("\"bri\":", "\0");
        hueBri = client.readStringUntil(',').toInt();  // set variable to brightness value

        client.findUntil("\"hue\":", "\0");
        hueHue = client.readStringUntil(',').toInt();  // set variable to hue value

        break;  // not capturing other light attributes yet
      }
    }
    client.stop();
    return true;  // captured on,bri,hue
  }
  else
    return false;  // error reading on,bri,hue
}

void printWifiData() {

  //WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

  void printCurrentNet() {
  //SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  }

```

}

The above code gets my Arduino connected to `mynetwork` and I have also connected Hue Bridge to the same but it throws an error of `No Socket Available`.

**UPDATE (9th March 2016):**

I implemented suggestions `1` and `4` given by slash-dev and was able to get rid of `No Socket Available` error. Following is the updated code:

```
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>

char ssid[] = "mynetwork";     //  your network SSID (name)
char pass[] = "mypass";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Hue constants
const char hueHubIP[] = "192.168.0.50";  //Hue hub IP
const char hueUsername[] = "myhue";  //Hue username
const int hueHubPort = 80;

IPAddress server(192,168,0,50);
WiFiClient client;

//Hue variables
boolean hueOn;  // on/off
int hueBri;  // brightness value
long hueHue;  // hue value
String hueCmd;  // Hue command

unsigned long buffer=0;  //buffer for received data storage
unsigned long addr;
IPAddress ip;

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

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println(F("WiFi shield not present"));
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print(F("Attempting to connect to WPA SSID: "));
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print(F("You're connected to the network"));
  printCurrentNet();
  printWifiData();
}

void loop()
{

    String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);
    command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);

}

/* setHue() is our main command function, which needs to be passed a light number and a
 * properly formatted command string in JSON format (basically a Javascript style array of variables
 * and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
 */
boolean setHue(int lightNum,String command)
{
  client.stop();
  if (client.connect(server, 80))
  {
    Serial.println(F("connected to server"));
    while (client.connected()&& status == WL_CONNECTED)
    {
      client.print(F("PUT /api/"));
      client.print(hueUsername);
      client.print(F("/lights/"));
      client.print(lightNum);  // hueLight zero based, add 1
      client.println(F("/state HTTP/1.1"));
      client.println(F("Connection: keep-alive"));
      client.print(F("Host: "));
      client.println(hueHubIP);
      client.print(F("Content-Length: "));
      client.println(command.length());
      client.println(F("Content-Type: text/plain;charset=UTF-8"));
      client.println();  // blank line before body
      client.println(command);  // Hue command
    }
    client.flush();
    client.stop();
    return true;  // command executed
  }
  else
    return false;  // command failed
}

/* A helper function in case your logic depends on the current state of the light.
 * This sets a number of global variables which you can check to find out if a light is currently on or not
 * and the hue etc. Not needed just to send out commands
 */
boolean getHue(int lightNum)
{
  client.stop();
  if (client.connect(server, 80))
  {
    client.print(F("GET /api/"));
    client.print(hueUsername);
    client.print(F("/lights/"));
    client.print(lightNum);
    client.println(F(" HTTP/1.1"));
    client.print(F("Host: "));
    client.println(hueHubIP);
    client.println(F("Content-type: application/json"));
    client.println(F("Connection: keep-alive"));
    client.println();
    while (client.connected()&& status == WL_CONNECTED)
    {
      if (client.available())
      {
        client.findUntil("\"on\":", "\0");
        hueOn = (client.readStringUntil(',') == "true");  // if light is on, set variable to true

        client.findUntil("\"bri\":", "\0");
        hueBri = client.readStringUntil(',').toInt();  // set variable to brightness value

        client.findUntil("\"hue\":", "\0");
        hueHue = client.readStringUntil(',').toInt();  // set variable to hue value

        break;  // not capturing other light attributes yet
      }
    }
    client.flush();
    client.stop();
    return true;  // captured on,bri,hue
  }
  else
    return false;  // error reading on,bri,hue
}

void printWifiData() {

  //WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print(F("IP Address: "));
  Serial.println(ip);
}

  void printCurrentNet() {
  //SSID of the network you're attached to:
  Serial.print(F("SSID: "));
  Serial.println(WiFi.SSID());
}

```

# Answer
> 1 votes
I suspect a low RAM failure. Here are some suggestions that will dramatically lower your RAM usage:

**1)** You still have `Serial.print` using double-quoted C string constants. Use `F("C string")` for those, too. For example:

```
  Serial.println( F("WiFi shield not present") );

```

Every double-quoted C string uses RAM in addition to FLASH program space. You have already saved a bunch, but you should get rid of the above uses.

---

**2) Don't use `String` for `setHue`.**

TL;DR - it will use extra RAM, FLASH, CPU time, and cause inexplicable or random failures.

Instead, use C strings, aka `char` arrays for variables, or double-quoted string constants. When the constants are wrapped with the **F()** macro, they don't use *any* RAM.

Here is an example of how to define and call a `setHue` with C strings instead of `String`:

```
--> See complete code below in UPDATE 3/9/2016 section <--

```

This just prints the C strings to `Serial`, but I hope you can see how they could also be printed to the `client`.

---

**3) Don't use `String` for `getHue`.**

Here is an example of how to define and call a `getHue` that uses C strings instead of `String`:

```
--> See complete code below in UPDATE 3/9/2016 section <--

```

Just copy and paste the displayed JSON into the Serial Monitor "Send" field. The debug prints will display what gets parsed.

* NOTE: It's not clear if the JSON attributes always come back in the same order. This example expects the same order in which they were sent. Other techniques would have to be used to accommodate *any* order.

---

**4)** Be sure to call `client.flush()` before *every* `client.stop()`.

---

**Summary:** I would guess that the combination of non-F() "C strings" wasting RAM, plus the `String` use of RAM (doubled or more), is leading to a low-RAM failure. The above approach will lower RAM usage dramatically, and also save more than 1.6kB in program space. After implementing these changes, almost all RAM will be available for the WiFi libraries.

---

## UPDATE 3/9/2016

Here's my changes, merged into your second sketch.

```
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>

char ssid[] = "mynetwork";     //  your network SSID (name)
char pass[] = "mypass";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Hue constants
const char hueHubIP[] = "192.168.0.50";  //Hue hub IP
const char hueUsername[] = "myhue";  //Hue username
const int hueHubPort = 80;

IPAddress server(192,168,0,50);

// Uncomment this to *really* use the Wi-Fi sheild.
// Comment this to read & write everything to the Serial Monitor for testing.
//#define REAL_WIFI
#ifdef REAL_WIFI
WiFiClient client;
#else
HardwareSerial & client = Serial; // redirect 'client' to the Serial Monitor
#endif

//Hue variables
boolean hueOn;  // on/off
int hueBri;  // brightness value
long hueHue;  // hue value
String hueCmd;  // Hue command

unsigned long buffer=0;  //buffer for received data storage
unsigned long addr;
IPAddress ip;

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

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println(F("WiFi shield not present"));
    // don't continue:
#ifdef REAL_WIFI
    while (true);
#else
    status = WL_CONNECTED;
#endif
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print(F("Attempting to connect to WPA SSID: "));
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print(F("You're connected to the network"));
  printCurrentNet();
  printWifiData();
}

void loop()
{
  setHue
    ( 1,
      F("{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

  setHue
    ( 2,
      F("{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

  setHue
    ( 1,
      F("{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

  setHue
    ( 2,
      F("{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

//  getHue( 1 );
//  getHue( 2 );
}

/* setHue() is our main command function, which needs to be passed a light number and a
 * properly formatted command string in JSON format (basically a Javascript style array of variables
 * and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
 */
boolean setHue
  ( int                        lightNum,
    const __FlashStringHelper *header,
    int                        parameter,
    const __FlashStringHelper *trailer )
{
#ifdef REAL_WIFI
  client.stop();

  if (client.connect(server, 80))
#endif
  {

    Serial.println(F("connected to server"));
#ifdef REAL_WIFI
    if (client.connected()&& status == WL_CONNECTED)
#endif
    {
      client.print(F("PUT /api/"));
      client.print(hueUsername);
      client.print(F("/lights/"));
      client.print(lightNum);  // hueLight zero based, add 1
      client.println(F("/state HTTP/1.1"));
      client.println(F("Connection: keep-alive"));
      client.print(F("Host: "));
      client.println(hueHubIP);

      // Calculate total command length.
      int cmdLength =
        strlen_P( (const prog_char *)header ) +
        1 +   //   Assume one digit for parameter...
        strlen_P( (const prog_char *)trailer );

      //  ... and add room for more digits if necessary.
      if (parameter > 9)
        cmdLength++;
      if (parameter > 99)
        cmdLength++;

      client.print(F("Content-Length: "));
      client.println( cmdLength );
      client.println(F("Content-Type: text/plain;charset=UTF-8"));
      client.println();  // blank line before body
      client.print( header );  // Hue command pieces
      client.print( parameter );
      client.println( trailer );
    }
    client.flush();
#ifdef REAL_WIFI
    client.stop();
#endif
    return true;  // command executed
  }
#ifdef REAL_WIFI
  else
    return false;  // command failed
#endif
}

//---------------------------------------------------------------------
// Utility function to extract one `bool` value from the client stream.
//   No buffers are used.  Each character is handled as it is received.
//   (you may want/need to add a timeout)

static bool clientParseBool( char delim )
{
  bool val = false;
  uint8_t count = 0; // number of chars we've read for the value

  while (status == WL_CONNECTED) {
    if (client.available()) {
      char c = client.read();
      if (c == delim)
        break; // done!
      if ((c == ' ') || (count++ > 0))
        continue; // skip spaces and anything after the first non-space char

      if (c == 't')
        val = true;
    }
  }

  // Debug prints
  Serial.print( F("bool ") );
  Serial.println( val );

  return val;
}

//-------------------------------------------
// Utility function to extract one 'unsigned 16-bit int' value from the client stream.
//   No buffers are used.  Each character is handled as it is received.
//   (you may want/need to add a timeout)

static uint16_t clientParseUint( char delim )
{
  uint16_t val = 0;

  while (status == WL_CONNECTED) {
    if (client.available()) {
      char c = client.read();
      if (c == delim)
        break; // done!
      if (c == ' ')
        continue; // skip spaces

      if (isdigit(c))
        val = val*10 + (c - '0'); // accumulate one digit of the bri value
    }
  }

  // Debug prints
  Serial.print( F("int ") );
  Serial.println( val );

  return val;
}

//-------------------------------------------

/* A helper function in case your logic depends on the current state of the light.
 * This sets a number of global variables which you can check to find out if a light is currently on or not
 * and the hue etc. Not needed just to send out commands
 */
boolean getHue(int lightNum)
{
  bool gotHue = false;

#ifdef REAL_WIFI
  client.stop();
  if (client.connect(server, 80))
#endif
  {

    client.print(F("GET /api/"));
    client.print(hueUsername);
    client.print(F("/lights/"));
    client.print(lightNum);
    client.println(F(" HTTP/1.1"));
    client.print(F("Host: "));
    client.println(hueHubIP);
    client.println(F("Content-type: application/json"));
    client.println(F("Connection: keep-alive"));
    client.println();

    if (status == WL_CONNECTED)
    {
        client.findUntil("\"on\":", "\0");
        hueOn = clientParseBool(',');

        if (status == WL_CONNECTED)
        {
            client.findUntil("\"bri\":", "\0");
            hueBri = clientParseUint(',');

            if (status == WL_CONNECTED)
            {
                client.findUntil("\"hue\":", "\0");
                hueHue = clientParseUint(',');

                gotHue = true;  // captured all three: on,bri,hue
            }
        }
    }

    client.flush();
#ifdef REAL_WIFI
    client.stop();
#endif
  }

  return gotHue;
}

void printWifiData() {

  //WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print(F("IP Address: "));
  Serial.println(ip);
}

void printCurrentNet() {
  //SSID of the network you're attached to:
  Serial.print(F("SSID: "));
  Serial.println(WiFi.SSID());
}

```

A few notes:

* I did not have the extra blank line in my original `setHue`, so I put it back in to match your sketch.
* I added a `REAL_WIFI` define that I could comment out for testing on `Serial`. When I run it, I get this output:
> WiFi shield not present
> You're connected to the networkSSID:
> IP Address: 0.0.0.0
> connected to server
> PUT /api/myhue/lights/1/state HTTP/1.1
> Connection: keep-alive
> Host: 192.168.0.50
> Content-Length: 65
> Content-Type: text/plain;charset=UTF-8
> {"on": true,"hue": 50100,"sat":255,"bri":255,"transitiontime":22}
> connected to server
> PUT /api/myhue/lights/2/state HTTP/1.1
> Connection: keep-alive
> Host: 192.168.0.50
> Content-Length: 65
> Content-Type: text/plain;charset=UTF-8
> {"on": true,"hue": 65280,"sat":255,"bri":255,"transitiontime":24}
* You can copy and paste the above output if you want to add and test `getHue` with just the Serial Monitor (i.e., comment out `#define REAL_WIFI`).
* I added a 10-second delay between each `setHue`, just to pace the output, and to give the "transition-time" um... some time to work. The transition time is in seconds, so `loop` will call `setHue` again, *before* the requested transition has completed. You won't see much change when you keep telling it to gradually change to the new color, but it only gets to transition a little bit. Without any delay, I don't think you'll see anything. This could be your current problem! With 10 seconds, at least it will get about half-way there. :-(

# Answer
> 3 votes
I wonder if you are running out of RAM? Those sockets use RAM, and you have quite a few string constants, like this:

```
  client.println("Content-Type: text/plain;charset=UTF-8");

```

Change that (and all similar ones) to use the `F()` macro:

```
  client.println(F("Content-Type: text/plain;charset=UTF-8"));

```

# Answer
> 1 votes
With reference to this example, perhaps you should call `client.stop()` right before you call `client.connect()` at the start of `setHue()` and `getHue()`. You should also call not only `client.stop()`, but also `client.flush()` at the end of both functions, just in case: Flush first, then stop.

On a different note, correct your HTTP headers from `client.println(F("keep-alive"));` to `client.println(F("Connection: keep-alive"));`.

# Answer
> 0 votes
For anyone else that comes across this. The reason it takes about 10 seconds to run this, is because of the Original: `while (client.connected())` or in the OP's Post above the `while (client.connected()&& status == WL_CONNECTED)`. Either are located in the setHue.

I commented that while loop out *(and the opening { and closing } brackets for that while loop or you'll get an error of course)*, and the hue light changed instantaneously.

If you put a print to serial line in that loop, you'll see that it runs that loop continuously, which causes the long delay.

If you come upon this post from the original https://www.makeuseof.com/tag/control-philips-hue-lights-arduino-and-motion-sensor/ note that you should change the main loop's if statements to:

```
if((digitalRead(pir) == 1) && (activated == false) )

```

and

```
if((digitalRead(pir) == 0) && (activated == true) )

```

That way the setHue only is called on a change of state.

---
Tags: wifi, networking
---


# Question
Title: NodeMCU 1.0 - Exception 9 `Fatal exception 9(LoadStoreAlignmentCause):`
I am getting this error in my code.
`Fatal exception 9(LoadStoreAlignmentCause):`

Using core version `2.4.2`

Stack trace

```
Decoding stack results
0x40213e9c: dns_gethostbyname at core/dns.c line 1472
0x40204c21: ESP8266WiFiGenericClass::hostByName(char const*, IPAddress&, unsigned int) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp line 468
0x40205038: WiFiClient::connect(char const*, unsigned short) at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/WiFiClient.cpp line 98
0x4020306b: setPostString(int, int, Array8Int, char*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 516
0x40203f8a: uploadAgrigis(char const*) at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 335
0x40209080: Print::println() at /home/tony/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/Print.cpp line 178
0x402048e0: loop() at /home/tony/Arduino/sketches/tempo1_vs11e_Master_NodeMCU_Rain_Wind/tempo1_vs11e_Master_NodeMCU_Rain_Wind.ino line 243

```

struct declaration

```
struct Array8Int {
    int array[8];
};

```

loop

```
char post[300] = "";
int pulseChange05m = rainCheck(slaveData);
int now10 = floor(unixtimeServer/10)*10;
Array8Int slaveData = slaveCheck(now()); // update slaveData array
setPostString(now10, pulseChange05m, slaveData, post);

```

functions

```
void setPostString(int unixtimeEvent, int pulseChange, Array8Int postData, char* postStr) {
  bool flag = true;
  float rainHour = pulseChange*0.25;
  if (hour() == 10) { // 7 AM palmital
    rainCount = 0;
    rainCount05m = 0;
  }
  rainCountHour = rainCount;
  int humidityBme280HourAvg = 0;
  int pressureBme280HourAvg = 0;
  int temperatureBme280HourAvg = 0;
  int lightSensorHourAvg = 0;
  int pressureBme280HourMin = 100000;
  int temperatureBme280HourMin = 1000;
  int temperatureBme280HourMax = -1000;
  int counterLoop = counterHour;
  for(int i=0;i<counterLoop;i++) {
    lightSensorHourAvg += lightSensorHour[i];
    pressureBme280HourAvg += pressureBme280Hour[i];
    temperatureBme280HourAvg += temperatureBme280Hour[i];
    temperatureBme280HourMax= max(temperatureBme280HourMax,temperatureBme280Hour[i]);
    pressureBme280HourMin = min(pressureBme280HourMin,pressureBme280Hour[i]);
    temperatureBme280HourMin = min(temperatureBme280HourMin,temperatureBme280Hour[i]);
    humidityBme280HourAvg += humidityBme280Hour[i];
  }
  pressureBme280HourAvg = pressureBme280HourAvg/counterLoop;
  temperatureBme280HourAvg = temperatureBme280HourAvg/counterLoop;
  lightSensorHourAvg = (int)lightSensorHourAvg/counterLoop;

  strcat(postStr, stationId);
  strcat(postStr,"&3="); // chuva hora
  strcat(postStr, dtostrf(rainHour,6,2,charDummy));
  strcat(postStr,"&8=");
  strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
  strcat(postStr,"&9="); //temperature avg
  strcat(postStr, dtostrf(temperatureBme280HourAvg,6,2,charDummy));
  strcat(postStr,"&10="); //temperature avg
  strcat(postStr, dtostrf(temperatureBme280HourMax,6,2,charDummy));
  strcat(postStr,"&11="); //temperature avg
  strcat(postStr, dtostrf(temperatureBme280HourMin,6,2,charDummy));
  strcat(postStr,"&20=");
  strcat(postStr, dtostrf(pressureBme280HourAvg,10,0,charDummy));
  strcat(postStr,"&22=");
  strcat(postStr, dtostrf(pressureBme280HourMin,10,0,charDummy));
  strcat(postStr,"&101=");
  strcat(postStr, dtostrf(lightSensorHourAvg,6,0,charDummy));
  strcat(postStr,"&time=");
  strcat(postStr, dtostrf(unixtimeEvent,16,0,charDummy));
  strcat(postStr,"&endline=1");
  strcat(postStr, "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
}
int rainCheck(Array8Int slaveData) {
  int pulseChange = slaveData.array[0];
  return pulseChange;
}

```

# Answer
> 4 votes
> Fatal exception 9(LoadStoreAlignmentCause):

This is caused by you (or some code you are running) attempting to read or write a 32 bit value from memory that is not "aligned" to 32 bits. It is most often the result of trying to cast portions of a byte array (for instance a buffer received over UDP) to a 32-bit integer. The compiler is not clever enough to know that the byte array portion you are casting isn't at a 32-bit boundary and thus doesn't know to use the 8-bit load/store instructions to access the memory.

Mapping a `struct` over a buffer can also have similar issues where the buffer is 8-bit aligned and the `struct` contains 32-bit words.

You can combat it by forcing the alignment of any buffers which you treat in such a way with the `__attribute__((aligned(4))` tag:

```
uint8_t __attribute__((aligned(4))) buffer[128];

```

You can also "pack" structures to tell the compiler "These variables are mis-aligned and should not be padded to 32-bits":

```
struct foo {
    uint8_t bar1;
    uint32_t bar2;
} __attribute__((packed));

```

If in doubt, though, just pull individual bytes out of buffers (or wherever) and build up your larger integers manually with bit shifting and OR operators (`<<` and `|`), and do the reverse for filling byte buffers.

# Answer
> 0 votes
I had this error including on new cards it worked on one card and not on another the reason is that my eeprom was not initialized the nodemcu 8266 that was working properly, was the one I used for development. Because i was using test to write on my eeprom so the value was put in it. I did not understand what append After, I try flashing reload original setup etc... I read your answer and I pass this program (which is a stupid manual writing of my eeprom) I make it running once and after that I could load my other programs without problems

```

    #include <EEPROM.h>
struct credential {
  char WIFI_SSID [39] = " ";
  char WIFI_PASSWORD [39] = " ";
  char SMTP_HOST[44] = " ";
  uint16_t SMTP_PORT = 465;
  char AUTHOR_EMAIL[39] = " ";
  char AUTHOR_PASSWORD[39] = " ";
  char RECIPIENT_EMAIL[39] = " ";
  uint16_t  NbOfProbe = 1; //number of probe 1-to 16
  char TypeOfDevice[16] = "f";// F or f fridge R freezer O hot  exemple fRoFRr
  char AlertMin [54] = "30";//with always a sign like-10+0+2 the sign act like a separator
  char AlertMax [54] = "38";//with always a sign like-10+0+2 the sign act like a separator
  uint16_t  NbOfMinNormMail = 60 ;//time to wait in sec between 2 normal messages eg 14400 sec(4 hours)
  uint16_t  PowerOffMinWait = 1 ;
  uint16_t  TempOffLimitWait = 1;
  char AlertPowerMsg[41] = "alerte coupure de courant "; //Message alerte coupure de courant
  char AlertTempMsg[41] = "alerte temperature hors limite";
  char NormalTempMsg[41] = "Tout est ok ";
  char DateMsg[16] = "vide";
};
typedef struct credential settingcredent;
settingcredent parametersEeprom;
uint addr = 0;
void setup()
{
  Serial.begin(115200);
delay (100);
/*
  // fake data
  struct {
    uint val = 0;
    char str[20] = "";
  } data;
*/
  // commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
  // this step actually loads the content (512 bytes) of flash into
  // a 512-byte-array cache in RAM
 //                                                                          EEPROM.begin(512);

  // read bytes (i.e. sizeof(data) from "EEPROM"),
  // in reality, reads from byte-array cache
  // cast bytes into structure called data
 //
 showeprom ();

  strncpy(parametersEeprom.WIFI_SSID,"myssid",39);
  strncpy(parametersEeprom.WIFI_PASSWORD,"passmyssid",39);
  strncpy(parametersEeprom.SMTP_HOST,"smtp.gmail.com",44);
  parametersEeprom.SMTP_PORT=465;
  strncpy(parametersEeprom.AUTHOR_EMAIL,"iottest@gmail.com",39);
  strncpy(parametersEeprom.AUTHOR_PASSWORD,"iottest01",39);
  strncpy(parametersEeprom.RECIPIENT_EMAIL,"johndoe@hotmail.fr",39);
  parametersEeprom.NbOfProbe = 4; //number of probe 1-to 16
  strncpy(parametersEeprom.TypeOfDevice,"rffo",16);// F or f fridge R freezer O hot  exemple fRoFRr
  strncpy(parametersEeprom.AlertMin,"-20+0+2+23",54);//with always a sign like-10+0+2 the sign act like a separator
  strncpy(parametersEeprom.AlertMax,"-15+5+7+28",54);//with always a sign like-10+0+2 the sign act like a separator
  parametersEeprom.NbOfMinNormMail = 60 ;//time to wait in sec between 2 normal messages eg 14400 sec(4 hours)
  parametersEeprom.PowerOffMinWait = 10 ;
  parametersEeprom.TempOffLimitWait = 20;
  strncpy(parametersEeprom.AlertPowerMsg,"alerte coupure de courant ",41); //Message alerte coupure de courant
  strncpy(parametersEeprom.AlertTempMsg, "alerte temperature hors limite",41);
  strncpy(parametersEeprom.NormalTempMsg, "Tout est ok ",41);
  strncpy(parametersEeprom.DateMsg,"vide",16);
  EEPROM.put(addr, parametersEeprom);
  EEPROM.commit();

  EEPROM.get(addr,parametersEeprom);
  Serial.println("New values are: "+String(parametersEeprom.WIFI_PASSWORD)+","+String(parametersEeprom.WIFI_SSID)+","+String(parametersEeprom.SMTP_HOST));
}
void showeprom ()
{
  EEPROM.begin(sizeof(parametersEeprom));
  EEPROM.get(addr, parametersEeprom); //read data from array in ram and cast it into struct called parametersEeprom

  Serial.println("-------------------------"); //Showing the details
  Serial.print("your SSID ="); Serial.println( parametersEeprom.WIFI_SSID);
  Serial.print("your password for SSID ="); Serial.println( parametersEeprom.WIFI_PASSWORD);
  Serial.print("your SMTP_HOST ="); Serial.println( parametersEeprom.SMTP_HOST);
  Serial.print("your SMTP_PORT ="); Serial.println( parametersEeprom.SMTP_PORT);
  Serial.print("Your less secure email="); Serial.println( parametersEeprom.AUTHOR_EMAIL);
  Serial.print("Your password for not secure email="); Serial.println( parametersEeprom.AUTHOR_PASSWORD);
  Serial.print("Your email that must receive msg like MeTheBoss@MyCompany.com="); Serial.println( parametersEeprom.RECIPIENT_EMAIL);
  Serial.print("The number of thermometers probe you have is ="); Serial.println( parametersEeprom.NbOfProbe);
  Serial.print("Enter in order type of device (F)ridge f(R)ezzer (O)ven like RFFO="); Serial.println( parametersEeprom.TypeOfDevice);
  Serial.print("Enter mintemp in order per device like(suppose RFFO) -22-1+5+180="); Serial.println( parametersEeprom.AlertMin);
  Serial.print("Enter maxtemp in order per device like(suppose RFFO) -16+4+10+220="); Serial.println( parametersEeprom.AlertMax);
  Serial.print("Number of sec between 2 normal mails like(4hours) 240 ="); Serial.println( parametersEeprom.NbOfMinNormMail);
  Serial.print("Number of sec to wait before sending message Power off like 5 ="); Serial.println( parametersEeprom.PowerOffMinWait);
  Serial.print("Number of sec to wait before sending message warning temp like 5 ="); Serial.println( parametersEeprom.TempOffLimitWait);
  Serial.print("Message power down(30 char) like WARNING POWER OFF GRID="); Serial.println( parametersEeprom.AlertPowerMsg);
  Serial.print("Message temperature off min/max(30 char) like WARNING TEMPERATURE ABNORMAL="); Serial.println( parametersEeprom.AlertTempMsg);
  Serial.print("Message report state of all fridges freezer Oven like Everything is OK in the kitchen ="); Serial.println( parametersEeprom.NormalTempMsg);
  Serial.print("Enter date of the modif parameters like 08/23/21-18:25="); Serial.println( parametersEeprom.DateMsg);

}
void loop()
{
  delay(10000);
  showeprom ();

}

~
~

I hope that this experiment can be usefull
I cannot explain why it work

```

---
Tags: nodemcu
---


# Question
Title: How do I find out the maximum current through VIN on a NodeMCU board?
I read this answer https://arduino.stackexchange.com/a/51878 to a different, but related question. It seems like VIN on the NodeMCU is directly or via diode connected to the USB connector.

Image source: https://arduino.stackexchange.com/a/76119

I'm going to run my NodeMCU with a 5 V power supply connected to the USB connector. And I also need approximately 5 V for another part. So I was thinking of connecting it to VIN of the NodeMCU. So I don't want to power the NodeMCU from VIN, but I want to draw power from VIN for another part.

Is that a bad move or perfectly fine? And if it's okay, how do I find out the maximum current? Because I think the line from USB connector to VIN has some limits, so to not damage the board?

# Answer
> 2 votes
You cannot power items from the VIN pin of the NodeMCU V3.

The power circuit is like this:

simulate this circuit – Schematic created using CircuitLab

As you can see no current can flow out of the VIN pin because of diode D2.

You could, though, draw current out of the VU pin, though (situated at the top left of the board when the text is normally oriented) which is directly connected to the USB port's 5V pin. How much current can you draw? Well, there's nothing in the circuit to limit it, so whatever the USB port that the board is connected to will provide (less enough to run the ESP8266 module).

If you want to draw 1A through the VU pin and the power supply is rated for 2A there should be no problem. The traces for the VU pin are *reasonably* chunky.

A better solution though would be to power the NodeMCU board and your external components through separate power feeds from the power supply - that way there can be no interference from the board.

# Answer
> 0 votes
Just found at least a partial answer in this answer https://arduino.stackexchange.com/a/61030 to a different question:

> The component that blew up is a diode. It is designed to protect the USB from voltage being injected into the board. That diode can handle an absolute maximum of 1A. (...) the ESP8266 itself can take more than half that 1A power budget when communicating.

That sounds to me that beginning at about 500 mA, I will risk damaging the NodeMCU if I use VIN as a power supply. So to play it safe, I should probably stay below 250 mA...? Just a guess though. Not a perfect answer yet.

---
Tags: esp8266, power, nodemcu, current, voltage
---


# Question
Title: How to save sensor value in EEPROM? (ESP8266)?
I would like to save the height of a tank in case of power outage with EEPROM and every time I reboot the board. However, I could not do so after using EEPROM.commit() , EEPROM.get and EEPROM.put as the reading of the height tank changes every time I tried to reboot it . Am I using it wrongly?

I used EEPROM.get , EEPROM.put , EEPROM.commit in the void setup section so that it will save the data during boot up. However, the tank height just change whenever I changed to a different tank with different height after boot up.

How could I recalibrate the height of the tank if I would like to change to another tank one day, can I just click the RST button on the ESP8266 board?

Thank you

```
#include <LiquidCrystal_I2C.h>  //1602 LCD library
#include <Wire.h>
#include <EEPROM.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>  //NodeMCU ESP8266 library
#include <BlynkSimpleEsp8266.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

WidgetLED led1(V2);

char auth[] = ""; //Enter your Auth token
char ssid[] = ""; //Enter your WIFI name
char pass[] = ""; //Enter your WIFI password

BlynkTimer timer;
bool pinValue = 1;

long duration;
int distance;
int percentage;
int addr=0;
float tankheight, val;

#define trig D7
#define echo D8
#define relay D5

void setup() {
  Serial.begin(9600);
  EEPROM.begin(512);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(relay, OUTPUT);
  Wire.begin(D2, D1);
  lcd.init();
  lcd.backlight();
  Blynk.begin(auth, ssid, pass);
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  tankheight = duration * 0.034 / 2;
  Serial.print("Tank height");
  Serial.print(tankheight);
  EEPROM.put(addr, tankheight);
  EEPROM.commit();
  val=EEPROM.get(addr, tankheight);
  Serial.print("Addr");
  Serial.print(val);
  timer.setInterval(1L, Wlevel);
  digitalWrite(relay, HIGH);
}

BLYNK_CONNECTED(){
  Blynk.syncAll();

  }

BLYNK_WRITE(V0) {
  pinValue = param.asInt();

}

void loop() {
  Blynk.run();
  timer.run();
  WiFi.setSleepMode(WIFI_NONE_SLEEP);

}

void Wlevel(){  // Initialize detecting water level and relay)
  {
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = duration * 0.034 / 2;
  percentage= map(distance,val,10 ,0, 100);

  Blynk.virtualWrite(V1, percentage);

  if(percentage<0)
  {
    percentage = 0;
  }
  else if(percentage>100)
  {
    percentage = 100;
  }

 }

 if (pinValue == 1)
    {
       if (percentage < 100)
       {
          digitalWrite(relay, LOW);
          Serial.print("Water level:");
          Serial.print(percentage);
          Serial.print("%");
          Serial.println(" Pump is ON");
          led1.on();
          lcd.setCursor(0,0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: ON  (AUTO)");

       }

       else
       {
          digitalWrite(relay, HIGH);
          Serial.println("Water level is 100%   Pump is OFF");
          led1.off();
          lcd.setCursor(0, 0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: OFF (AUTO)");

       }
    }
   else
    {
      digitalWrite(relay, HIGH);
      Serial.print("Water level:");
      Serial.print(percentage);
      Serial.print("%");
      Serial.println("System is OFF, Check Blynk");
      lcd.setCursor(0,0);
      lcd.print("Water Lvl:");
      lcd.print(percentage);
      lcd.print("%  ");
      lcd.setCursor(0,1);
      lcd.print("System is OFF   ");
      led1.off();

    }

   }

```

# Answer
> 1 votes
Use a different button - you may have to wire something up...

In the loop, read the button and only if it is pressed should you re-calibrate and set the value to eeprom. You can do it in setup too but then you would have to reboot with the button pressed to trigger re-calibration.

You can also read a serial command in the loop. Anything external that can be triggered with a separate intent to re-calibrate would work. A power outage resembles the normal reset too much. To execute different behavior in two different scenarios, you must be able to detect which scenario you are in.

---
Tags: esp8266, nodemcu
---


title: SIM A9G: +CME ERROR: 53 failure

text:
# Question
Title: SIM A9G: +CME ERROR: 53 failure
I'm using a SIM A9G. When I send HTTP GET command from the serial monitor, it responds. But, it doesn't work when included in the code.

```
#include <SoftwareSerial.h>
SoftwareSerial myserial(8, 7); // RX: 8, TX:7

void setup()
{
//  Wire.begin(I2C_SLAVE_ADDRESS);
  Serial.begin(19200);
  myserial.begin(19200);    // 9600, 19200, 38400, 57600, 74880, 115200

//  ET.begin(details(mydata), &Wire);
  Serial.println("JSON Initializing...");
  Serial.println("GPRS Starting..........");

//  myserial.listen();
  myserial.println("AT");
  delay(500);

  myserial.println("AT+CREG=?");     //Check Network regiistration, wait a while
  delay(1000);
  ShowSerialData();

  myserial.println("AT+CCID");  //Specify the connection type
  delay(1000);
  ShowSerialData();

  myserial.println("AT+CGATT=1");
  delay(2000);
  ShowSerialData();

  myserial.println("AT+CGDCONT=1,\"IP\",\"web.gprs.mtnnigeria.net\"");//Specify the APN
  delay(2000);
  ShowSerialData();

  delay(2000);
}

void loop()
{
  myserial.println("AT+CGATT=1");
  delay(2000);
  ShowSerialData();

  myserial.println("AT+CGACT=1,1");
  delay(2000);
  ShowSerialData();

  myserial.println("AT+HTTPGET=\"https://postman-echo.com/get?foo1=bar1&foo2=bar2\"");
  delay(5000);
  ShowSerialData();

  myserial.println("AT+CCLK?");
  delay(1000);
  ShowSerialData();

  delay(3000);
}

void ShowSerialData()
{
  while (myserial.available() != 0)
  {
    Serial.write(myserial.read());
    //delay(50);
  }
}

```

The output at the serial monitor is the following:

```
+CGATT:1

OK
AT+CGACT=1,1

OK
E⸮⸮T⸮OZ⸮y:/⸮͵*⸮⸮⸮m/⸮⸮⸮⸮⸮=bar1&foo2=bar2"

+CME ERROR: 53
failure, pelase check your network or certificate!

AT+CCLK?

+CCLK: "21/02/22,18:19:43+01"

OK

```

# Answer
> 1 votes
You must use this sequence.

AT+CREG=? AT+CCID AT+CGATT=1 AT+CGDCONT=1,"IP","ba.amx" AT+CGACT=1,1

---
Tags: gsm, http
---


title: How Arduino IDE work with ESP32?

text:
# Question
Title: How Arduino IDE work with ESP32?
I understand how compiler compile our code to make binary code. Then we can use avr gcc to upload bin code to atmega chips via programer (USB ISP) or via USB serial (required bootloader). I'm using ESP32 for a while and notice they work in difference way. As far as I know

1. It not required Arduino bootloader.
2. It not reset when re-open serial monitor.
3. It use external memory chip.
4. It have boot and reset button
5. The USB Serial connect to ESP32 and we can upload bin code with it. (maybe the only way)
6. In IDE it run python scrip (esptool.py) I wonder how the process going and how each element work for its part for completely understand the process.

# Answer
> 2 votes
The ESP32 has a bootloader that uses serial embedded in its internal ROM. Whether that bootloader runs or not depends on the state of certain IO pins when the ESP32 starts up.

Those states are controlled by a small circuit that is triggered by the serial control lines (DTR and RTS).

On the Arduino there isn't that requirement, and the bootloader always runs when the chip resets, so a much simpler circuit is used to trigger a reset using just the DTR signal.

So for an Arduino whenever the serial port is opened the DTR signal resets the board. But for the ESP32 the RTS signal also has to be asserted along with the DTR signal in the right sequence to both set the correct IO pins and to reset the chip.

Whether the target device has internal flash or an external flash chip makes no difference. It is the bootloader's job to get the data into that flash. The AVR chips have a way of interfacing with the internal flash (ISP) to program it without a bootloader, but the ESP32, as it has external flash, doesn't need that (you can interface directly with the flash chip if you so wish).

The software on the PC that communicates with the bootloader has to speak the "language" the bootloader expects. Each family of chips has its own bootloader (some don't even have a bootloader, but that's another story) which speaks its own language. On the AVR chips that's usually a variant of the STK500 protocol, and the program `avrdude` is what communicates with it to send the program to flash. On the ESP32 (and the ESP8266 too) it's `esptool.py` that does the job. On chipKIT boards it's `pic32prog`. On Digipark it's `micronucleus`. There's as many upload programs as there are families of boards. Some programs, like `avrdude` and `pic32prog` are more flexible and can also talk to hardware programmers (USBASP, PICkit2 etc), but in general the upload program is written specifically for a particular bootloader.

---
Tags: esp32
---


title: Where are source files for Due?

text:
# Question
Title: Where are source files for Due?
Where are the source files containing the definitions and the HAL functions located for the Due?

I am trying to do CMSIS programming.

# Answer
The Arduino Core for supporting Arduino Due is called ArduinoCore-Sam, which can be found at https://github.com/arduino/ArduinoCore-sam, inside the `system` directory, you will find the CMSIS device driver.
> 2 votes

---
Tags: arduino-due
---


# Question
Title: LCD TFT 2.4"" changes the values of analog read of Arduino Mega
I have a Arduino Mega with LCD TFT 2.4"" with reading 5v signal on A8 pin (Arduino mega pin) from a raspberry pi (just to test). They are grounded together. When the Arduino is without the LCD, the analog reading works fine (4.8V,same from multimeter). But when I assembly the LCD, even if I just assembly VCC and ground, the analog read increasce around of 0.2V measure. I already tried to change the voltage input with a potentiometer and I still receiving a measure error of 0.2V. External energy supply to the LCD makes the things works, but I wouldn't like to have a external supply just to the screen.

What I'm doing wrong or what I can do ?

# Answer
MCUFriend went through a number of revisions of the same 2.4" TFT shield over time. I guess it depended on what TFT screens they could get hold of cheapest at any given moment. I have two versions here, neither of which are the same as yours. Both have their own voltage regulator onboard for the 3.3V power (which yours doesn't). Both of them also have resistors present on the cathode of the back light - *which yours doesn't.*

I would imagine for this revision they mistakenly though the TFT screen's back light didn't require any current limiting resistors and omitted them, with the end result that connecting the TFT screen to the Arduino drags down the 5V voltage to that of the combined forward voltage of the LEDs in the back light circuit.

In short: your TFT screen is designed badly. Fixing it would require modifying the shield on a trace-level basis. Not easy.
> 1 votes

# Answer
* The short answer is to beef up your power supply:

Don't use small batteries or power supplies. For instance use D Size Cells instead of 9 Volt Cells. Or use a 3 Amp power supply instead of a 100mAmp power supply.

* The longer answer:

Make sure you have mitigated any power problems. Like long or thin power lines. Long or thin wires have more resistance. And the more current you pull over that resistance the less voltage you will have at the far end. Remember it follows the rule:

## Voltage = Resistance * Current

* Probably the best answer:

Check the ADC specification of the processor and make sure your voltage reference is not adversely affected by power fluctuations. Some processors, like most used on Arduinos, have the ability to switch between internal references and external references. Most designers who really need a good ADC response will design an external reference and instruct the processor to use the external over the internal reference. For most Arduinos the function to call to switch references is "analogReference()". You can read more about this command and external references here.
> 0 votes

---
Tags: arduino-mega, lcd, analogread, tft
---


# Question
Title: How to restart void loop if condition is met
This should be a quick question.

I'm trying to figure out how I can restart `void loop()` if a certain condition is met. In this instance, if (s\>10), I want the loop to restart. Any help will be appreciated.

```
 void loop() {

  if (getDistance(0) == true)                   //if the car passed the first sensor
  {
    while (getDistance(0) == true && getDistance(1) == false);
    unsigned long currentMillis = millis(); //time when the passed the first sensor

    while (getDistance(1) == true && getDistance(0) == true); //wating car to pass the second sensor

    unsigned long endMillis = millis(); //time at which the car passed the second sensor

    unsigned long timeMillis = endMillis - currentMillis; //get duration in ms
    float timeSeconds = timeMillis / 1000.0; //because 1000ms = 1s

    float s = sensorDistance / timeSeconds; //speed = distance / time

    if(s>=7 && s<=10) // for red to turn on
    {
    Serial.print(s); // printing the speed magnitude
    Serial.print(" m/s");// printing the units of speed
    Serial.println(); // new line in printing

    char msg[2] = {'h','#'}; // sending some random message to indicate that speed is greater than 10
    digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, 2); // sending a message
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(led_pin, LOW); // again bringing the flash light to low

    }
    else if (s<7)
    {
    Serial.print(s); // printing the speed magnitude
    Serial.print(" m/s");// printing the units of speed
    Serial.println(); // new line in printing

    char msg[4] = {'h','e','l','#'}; // sending some random message to indicate that speed is greater than 10
    digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, 4); // sending a message
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(led_pin, LOW); // again bringing the flash light to low
    }

    delay(2000);
  }
}

```

# Answer
> 4 votes
When programming with arduino IDE, you declare 2 functions, setup() and loop().

Before compilation, arduino IDE basically expands to :

```
int main(void)
{
    /* run the Arduino setup */
    setup();
    /* and the event loop */
    while (1) {
        loop();
    }
    /* never reached */
    return 0;
}

```

So, from here you can see that setup() is called once at startup and then, loop() is called in an infinite loop. Il you return from within your loop function, it will be called again.

# Answer
> 1 votes
To expand on what jfpoilpret said setup() and loop() are called by the code you can't see in every program. `setup()` is called once and `loop()` is called in a `while(true)` loop until the program crashes or the universe ends.

To call you code while a condition is met you could either wrap it in a loop or an if, within the `loop()` function, so something like this:

```
void loop ()
{
    if (s > 10)
    {
        // Your stuff....
    }
}

```

This will only call your code IF `s > 10`. Something you need to watch for is ensuring that there is some code that can cause `s` to be greater than `10`.

You can also move `"// Your stuff..."` into a function of its own

```
void MyCode ()
{
    // Your stuff ...
}

```

and then call this function from inside the if statement. This makes you code easier to read and easier to fix.

If this answer wasn't what you meant then feel free to comment and I'll see if I can come up with a better answer.

# Answer
> 0 votes
I hate to bring this up, but I've now been programming for 58 years. One curious and often overlooked feature of the C & C++ languages is the GOTO keyword. It can be very useful. My second language was FORTRAN I. I know, now I'm relegated to the 9th circle of he|| where the miscreants are frozen into glaciers head down with their legs protruding?

---
Tags: arduino-uno
---


# Question
Title: Is it better to use #define or const int for constants?
Arduino is an odd hybrid, where some C++ functionality is used in the embedded world—traditionally a C environment. Indeed, a lot of Arduino code is very C like though.

C has traditionally used `#define`s for constants. There are a number of reasons for this:

1. You can't set array sizes using `const int`.
2. You can't use `const int` as case statement labels (though this does work in some compilers)
3. You can't initialize a `const` with another `const`.

You can check this question on StackOverflow for more reasoning.

So, what should we use for Arduino? I tend towards `#define`, but I see some code using `const` and some using a blend.

# Answer
It's important to note that `const int` does **not** behave identically in C and in C++, so in fact several of the objections against it that have been alluded to in the original question and in Peter Bloomfields's extensive answer are not valid:

* In C++, `const int` constants are compile time values and **can** be used to set array limits, as case labels, etc.
* `const int` constants do not necessarily occupy any storage. Unless you take their address or declare them extern, they will generally just have a compile time existence.

However, for integer constants, it might often be preferable to use a (named or anonymous) `enum`. I often like this because:

* It's backward compatible with C.
* It's nearly as type safe as `const int` (every bit as type safe in C++11).
* It provides a natural way of grouping related constants.
* You can even use them for some amount of namespace control.

So in an idiomatic C++ program, there is no reason whatsoever to use `#define` to define an integer constant. Even if you want to remain C compatible (because of technical requirements, because you're kickin' it old school, or because people you work with prefer it that way), you can still use `enum` and should do so, rather than use `#define`.
> 25 votes

# Answer
*EDIT: microtherion gives an excellent answer which corrects some of my points here, particularly about memory usage.*

---

As you've identified, there are certain situations where you're forced to use a `#define`, because the compiler won't allow a `const` variable. Similarly, in some situations you're forced to use variables, such as when you need an array of values (i.e. you can't have an array of `#define`).

However, there are many other situations where there isn't necessarily a single 'correct' answer. Here are some guidelines which I would follow:

**Type safety**
From a general programming point-of-view, `const` variables are usually preferable (where possible). The main reason for that is type-safety.

A `#define` (preprocessor macro) directly copies the literal value into each location in code, making every usage independent. This can hypothetically result in ambiguities, because the type may end up being resolved differently depending on how/where it's used.

A `const` variable is only ever one type, which is determined by its declaration, and resolved during initialisation. It will often require an explicit cast before it will behave differently (although there are various situations where it can safely be implicitly type-promoted). At the very least, the compiler can (if configured correctly) emit a more reliable warning when a type issue occurs.

A possible workaround for this is to include an explicit cast or a type-suffix within a `#define`. For example:

```
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f

```

That approach can potentially cause syntax problems in some cases though, depending on how it's used.

**Memory usage**
Unlike general purpose computing, memory is obviously at a premium when dealing with something like an Arduino. Using a `const` variable vs. a `#define` can affect where the data is stored in memory, which may force you to use one or the other.

* `const` variables will (usually) be stored in SRAM, along with all other variables.
* Literal values used in `#define` will often be stored in program space (Flash memory), alongside the sketch itself.

*(Note that there are various things which can affect exactly how and where something is stored, such as compiler configuration and optimisation.)*

SRAM and Flash have different limitations (e.g. 2 KB and 32 KB respectively for the Uno). For some applications, it's quite easy to run out of SRAM, so it can be helpful to shift some things into Flash. The reverse is also possible, although probably less common.

**PROGMEM**
It's possible to get the benefits of type-safety while also storing the data in program space (Flash). This is done using the `PROGMEM` keyword. It doesn't work for all types, but it's commonly used for arrays of integers or strings.

The general form given in the **documentation** is as follows:

```
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};

```

String tables are a bit more complicated, but the documentation has full details.
> 7 votes

# Answer
**For variables of a specified type which are not altered during execution, either can usually be used.**

**For Digital pin numbers contained in variables, either can work - such as:**

```
const int ledPin = 13;

```

**But there is one circumstance where I always use `#define`**

**It is to define analog pin numbers, since they are alphanumeric.**

Sure, you can hard-code the pin numbers as `a2`, `a3`, etc. all throughout the program and the compiler will know what to do with them. Then if you change pins then each use would need to be changed.

Moreover, I always like to have my pin definitions up at the top all in one place, so the question becomes which type of `const` would be appropriate for a pin defined as `A5`.

In those cases I always use `#define`

**Voltage Divider Example:**

```
//
//  read12     Reads Voltage of 12V Battery
//
//        SDsolar      8/8/18
//
#define adcInput A5    // Voltage divider output comes in on Analog A5
float R1 = 120000.0;   // R1 for voltage divider input from external 0-15V
float R2 =  20000.0;   // R2 for voltage divider output to ADC
float vRef = 4.8;      // 9V on Vcc goes through the regulator
float vTmp, vIn;
int value;
.
.
void setup() {
.
// allow ADC to stabilize
value=analogRead(adcPin); delay(50); value=analogRead(adcPin); delay(50);
value=analogRead(adcPin); delay(50); value=analogRead(adcPin); delay(50);
value=analogRead(adcPin); delay(50); value=analogRead(adcPin);
.
void loop () {
.
.
  value=analogRead(adcPin);
  vTmp = value * ( vRef / 1024.0 );
  vIn = vTmp / (R2/(R1+R2));
 .
 .

```

All the setup variables are right at the top and there is never going to be a change to the value of `adcPin` except at compile time.

No worries about what type `adcPin` is. And no extra RAM is used in the binary to store a constant.

The compiler simply replaces each instance of `adcPin` with the string `A5` before compiling.

---

There is an interesting Arduino Forum thread that discusses other ways to decide:

#define vs. const variable (Arduino forum)

Excertps:

Code substitution:

```
#define FOREVER for( ; ; )

FOREVER
 {
 if (serial.available() > 0)
   ...
 }

```

Debugging code:

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

```

Defining `true` and `false` as Boolean to save RAM

```
Instead of using `const bool true = 1;` and same for `false`

#define true (boolean)1
#define false (boolean)0

```

---

A lot of it comes down to personal preference, however it is clear that `#define` is more versatile.
> 1 votes

# Answer
1. > You can't set array sizes using `const int`.

You can with `constexpr int`:

```
constexpr auto size{ 15 };
int array[size]{};

```
2. > You can't use `const int` as case statement labels (though this does work in some compilers)

Again, you can with `constexpr int`:

```
constexpr auto zero{ 0 };
constexpr auto one{ 1 };

int number{ 1 };
switch (number)
{
case zero: Serial.println("zero!"); break;
case one:  Serial.println("one!"); break;
default:   Serial.println("neither!"); break;
}

```
3. > You can't initialize a `const` with another `const`.

You can even initialize a `constexpr` with another `constexpr`:

```
constexpr int x{ 1 };
const     int y{ x };
constexpr int z{ x };

```

Furthermore, `constexpr` guarantees that the variable gets evaluated at compile-time, unlike `const`. `constexpr` also doesn't have some of the disadvantages that preprocessor macros have<sup>(learncpp)</sup>:

1. Debuggers like Visual Studio's don't let you *watch* preprocessor macros.
2. Macros can conflict with normal code.
3. Macros don't have scope, which increases the chance of naming conflicts.
> 1 votes

---
Tags: programming, c++, coding-standards
---


# Question
Title: Adding an Interrupt to ATtiny45 with Arduino
I recently wrote a simple script to...we'll say, "flash some LED's" and uploaded it to an attiny45. In short, the script cycles through 3 LED's and turns them on for a specified frequency, in a specified direction. With a button, I can cycle through different modes. There are 7 modes (default (LED's OFF), then 3 different speeds forwards and 3 different speeds backwards).

The script works fine-ish, however I've noticed that in order to read from the button input properly, the function that turns the LED's ON and OFF must be completed, meaning that for the longer cycles, the user may have to hold the button until the function completes. This is further complicated during the shorter cycles, where the input may detect multiple button-presses (despite adding a delay following the digital read.

NOTE: I could just make the delay longer, but this doesn't fix the issue during lower frequencies, when the function may take multiple seconds to complete.

I feel the best way to sort this (though I'd be open to other ideas) is to use the attachInterrupt() function; however, it doesn't work. The button no longer works and I'm not sure why.

```
// Pin Variables
int led1 = 2;
int led2 = 3;
int led3 = 4;
int leds[] = {led1, led2, led3};
int modePin = 0; // (physical pin 5 on the IC)

// Mode Speeds and setting
int fastTime = 100;
int mediumTime = 300;
int slowTime = 1000;
int offTime = 100;
int mode = 0;

void setup() {
  for (int i=0; i<3; i++){
    pinMode(leds[i], OUTPUT);
    digitalWrite(leds[i], LOW);
  }
  attachInterrupt(modePin, callMode, RISING);
}

void loop() {
  // If we get here, reset and go back to default (all LED's OFF)
  if (mode >= 7) {
    mode = 0;
  }
}

void callMode(){
  ++mode;
  //TIME: 1000, 300, 100 (milliseconds)
   switch (mode) {
     case 0:
       // Default, OFF
       for (int i=0; i<3; i++){
         digitalWrite(leds[i], LOW);
       }
       break;
     case 1:
       // Forward, Fast
       ledMode(fastTime, offTime, true);
       break;
     case 2:
       // Forward, Medium
       ledMode(mediumTime, offTime, true);
       break;
     case 3:
       // Forward, Slow
       ledMode(slowTime, offTime, true);
       break;
     case 4:
       // Backwards, Fast
       ledMode(fastTime, offTime, false);
       break;
     case 5:
       // Backwards, Medium
       ledMode(mediumTime, offTime, false);
       break;
     case 6:
       // Backwards, Slow
       ledMode(slowTime, offTime, false);
       break;
     case 7:
       // Return to Zero
       for (int i=0; i<3; i++){
          digitalWrite(leds[i], LOW);
       }
       mode = 0;
       break;
   }
}

void ledMode(int onTime, int offTime, bool forward){
  if (forward) {
    for (int i = 0; i <= 2; i++) {
      digitalWrite(leds[i], HIGH);
      delay(onTime);
      digitalWrite(leds[i], LOW);
      delay(offTime);
    }
  }
  else {
    for (int i = 2; i >= 0; i--) {
      digitalWrite(leds[i], HIGH);
      delay(onTime);
      digitalWrite(leds[i], LOW);
      delay(offTime);
    }
  }
}

```

NOTE: callMode() and ledMode() are only split up into different functions because I know that the function passed to attachInterrupt() cannot contain any delays(). So each time the button is pressed, the mode variable should increment and then the switch-statement should cause the next mode to run. When we reach 7, let's reset to zero and enter the default/OFF mode.

I've been racking my head for a few days on this and not sure what the problem is. Perhaps I can only use the attachInterrupt() function to some other pin? Perhaps I'm not using that function correctly?

Thank you in advance for any and all help you can provide.

-Joe

# Answer
> 3 votes
Interrupts are overkill for this kind of ultra-slow problems, and they can introduce some extra complexity. Here the best solution seems (to me at least) to lie in the approach of the Blink Without Delay Arduino tutorial. Obviously, it must be adapted. In that tutorial, the system switches between only two states (LED off or on). Here the cycling of the LEDs goes through six phases:

0. all LEDs are off
1. LED\[0\] is on
2. all LEDs are off
3. LED\[1\] is on
4. all LEDs are off
5. LED\[2\] is on

The basic algorithm is the same: when `millis()` tells us it is time to move to the next phase, we do so and update the state of the LEDs.

Note that I numbered the phases in such a way that the last bit (`phase&1`) tells us whether an LED is on, and in that case the remaining bits (`phase>>1`) hold the index of the LED that is on.

Here is how to cycle the LEDs at a fixed speed:

```
if (millis() - last_change >= phase_time) {
    last_change += phase_time;

    /* If an LED is on, turn it off. */
    if (phase & 1)
        digitalWrite(leds[phase >> 1], LOW);

    /* Move to the next phase. */
    if (++phase >= 6) phase = 0;

    /* Turn on the LED if needed. */
    if (phase & 1)
        digitalWrite(leds[phase >> 1], HIGH);
}

```

On top of this you need a finite state machine that cycles between the different modes (speeds and directions). In order to avoid code repetition, I would split this mode into a “state” that can OFF, FORWARD or BACKWARDS, and an index into an array of delay times (with 0, 1, 2 meaning fast, medium and slow, respectively).

Putting it all together (warning: not tested):

```
const uint8_t leds[] = { 2, 3, 4 };
const uint32_t times[] = { 100, 300, 1000 };

void setup() {
    for (int i = 0; i < 3; i++)
        pinMode(leds[i], OUTPUT);
}

enum { OFF, FORWARD, BACKWARDS } state = OFF;  // global state
uint8_t time_idx;      // index in times[] (0 = fast)
int8_t phase;          // 0 = all off, 1 = led[0] on, 2 = all off...
uint32_t last_change;  // last time the phase changed

void loop() {

    /* Change mode on button press. */
    if (button_pressed()) {
        if (state == OFF) {
            state = FORWARD;
            time_idx = 0;  // start fast
        } else {
            time_idx++;    // slow down
            if (time_idx >= 3) {  // change direction or stop
                time_idx = 0;
                if (state == FORWARD)
                    state = BACKWARDS;
                else              // state is BACKWARDS
                    state = OFF;
            }
        }
    }

    /* Cycle the LEDs. */
    if (state != OFF && millis() - last_change >= times[time_idx]) {
        last_change += times[time_idx];

        /* If an LED is on, turn it off. */
        if (phase & 1)
            digitalWrite(leds[phase >> 1], LOW);

        /* Move to the next phase. */
        if (state == FORWARD) {
            if (++phase >= 6) phase = 0;
        } else {  // BACKWARDS
            if (--phase < 0) phase = 5;
        }

        /* Turn on the LED if needed. */
        if (phase & 1)
            digitalWrite(leds[phase >> 1], HIGH);
    }
}

```

I did not write the `button_pressed()` function, which is meant to debounce the button and detect the “just pressed” transition. It is left as an exercise to the reader (or you can just use a debouncing library).

---
Tags: arduino-nano, interrupt, attiny
---


# Question
Title: Fail upload sketches to ESP8266 only on Ubunto 20.04.3
I installed a fresh copy of Ubuntu 20.04, and Arduino IDE1.8.16. At the beginning adding user to `dialout` group enabled uploading sketch to Aruino AVR family, and ESP32, but still ESP8266 gives this error:

```
Sketch uses 260889 bytes (24%) of program storage space. Maximum is 1044464 bytes.
Global variables use 27980 bytes (34%) of dynamic memory, leaving 53940 bytes for local variables. Maximum is 81920 bytes.
esptool.py v3.0
Serial port /dev/ttyUSB0
Connecting........_____....._____....._____....._____....._____....._____....._____
Traceback (most recent call last):
  File "/home/guy/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/upload.py", line 66, in <module>
    esptool.main(cmdline)
  File "/home/guy/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool/esptool.py", line 3552, in main
    esp.connect(args.before, args.connect_attempts)
  File "/home/guy/.arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool/esptool.py", line 529, in connect
    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

```

So I tried to erase flash using `esptool.py` :

```
guy@desktop:~$ esptool --chip  auto --port /dev/ttyUSB0 erase_flash
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting........_____....._____....._____....._____....._____....._____....._____

A fatal error occurred: Failed to connect to Espressif device: Timed out waiting for packet header

```

Since AVR's and ESP32 work properly using USB's and ACM's I can guess that is is not a problem with the ability to access serial comm.

What might it be ?

# Answer
There is something wrong with some new kernels of Ubuntu 20.04 LTS, interfering with ESP8266 core uploading process

`5.4.0-88-generic #99-Ubuntu SMP Thu Sep 23 17:29:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux`

I had the same issue and downgraded the kernel to

`5.4.0-86-generic #97-Ubuntu SMP Fri Sep 17 19:19:40 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux`

solved the issue

---

---

The issue happens to ESP8266 core uploading process, with the following tested Ubuntu cores

* `linux-5.11.0-37-generic`
* `linux-5.4.0-89-generic`
* `linux-5.4.0-88-generic`

and tested OK with

* `linux-5.11.0-38-generic`
* `linux-5.11.0-36-generic`
* `linux-5.8.0-48-generic`
* `linux-5.4.0-90-generic`
* `linux-5.4.0-86-generic`

---

### Temporarily fix

To temporarily fix the issue by using working kernel, e.g. `linux-5.4.0-86-generic`

A. Select from GNU GRUB boot menu

* Advanced options for Ubuntu

+ Ubuntu, with Linux 5.4.0-86-generic
* If you don't have that kernel, install by

```
sudo apt install linux-image-5.4.0-86-generic

```
* Reboot and select `5.4.0-86-generic` from GNU GRUB boot menu

---

---

### To save the selected GRUB settings

More info **GRUB Simple-configuration**

1. Edit `/etc/default/grub` by

```
$ sudo gedit /etc/default/grub

```
2. Add to the file

```
 GRUB_DEFAULT=saved
 GRUB_SAVEDEFAULT=true

```
3. Activate the change so that last selected value is used for the next boot.

```
$ sudo update-grub

```

### Update

Just testing OK with latest kernel

* `linux-5.11.0-38-generic`
* `linux-5.4.0-90-generic`

It seems recent kernel release has fixed the issue
> 4 votes

---
Tags: serial, usb
---