Project, Tutorial, NodeMCU Ab Kurk Project, Tutorial, NodeMCU Ab Kurk

Project: Creating A NodeMCU Data-Logger Using The Cloud

In this sample project we are going to build a NodeMCU data logger that uses the Adafruit cloud to store the temperature and humidity data. To make it even more exciting we are putting the NodeMCU to sleep in the periods that we are not transmitting the data to the cloud.

Please put some money in the tip jar by clicking on the donate button to support me so I can continue creating contend like this. P.S. please donate more than $1 as PayPal takes minimum $0.30 per transaction
NodeMCU_DHT11.22.sleep-configPNG.PNG

In this project we are going to build a NodeMCU data logger that uses the Adafruit cloud to store the temperature and humidity data. To make it even more exciting we are putting the NodeMCU to sleep in the periods that we are not transmitting the data to the cloud.

The basics of this project are as follows. First we are going to connect a Temperature Humidity sensor (The DHT11 or DHT22) to the NodeMCU. After getting that to work we are going to setup a feed on the Adafruit IO cloud. Then we will write the code to send the temperature data to the cloud using the MQTT protocol. Finally we add the sleep function of the ESP8266 to the mix.

This sounds like a lot, but you will actually see it is a very simple and straightforward process. If you look back a couple of weeks I build the same datalogger only using the Arduino Pro Mini, a RTC, and an SD card writer/reader breakout board. For this project we will only require A NodeMCU, a DHT11/22 sensor, and a connection to the interweb.  

Index

List Of Materials Needed For This Project

Connecting the DHT11/22 Sensor

To connect the DHT11/22 family of sensors we are going to use a library specifically designed for the ESP8266 micro controller or compatibles. The library is called DHTesp.h and needs to be installed using the Arduino IDE Library manager.

You can find the Library Manager under the Sketch menu and selecting the Include Libraries, and then the Manage Libraries option. In the search bar type dht to only show the libraries related to the DHT11/22 sensor. Click the more info link on the DHT library for the ESPx. A dropdown will appear where you select the latest version of the driver, then click the install button.

Click To Enlarge

I selected this library as it takes in consideration the slow communication speed of the DHT11/22 when running on 3.3v. Next we connect the sensor as follows (with the grid facing you)

Click Image to enlarge

Lets look at the code to make the DHT11/22 work. This is the Sample sketch is based on the sketch that comes with the Library called. You can download it from here. First lets look at the library and object deceleration.

#include "DHTesp.h"
DHTesp dht;

This is straight forward; we include the library and declare the dht object that allows us to communicate with the internal code of the library and thus communicate with the DHT hardware. Next we will look at the setup() function 

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("Status\tHumidity (%)\tTemperature (C)\t(F)\tHeatIndex (C)\t(F)");
  dht.setup(4); // data pin 4
}

Again straight forward stuff. We begin serial communication with the NodeMCU, then we print some stuff to the Serial monitor. The only thing of consequence is the dht.setup(4). This is where you tell the software what hardware pin we use. The original sketch uses Arduino digital pin 2, but because we are going to use that one later on in this project we use digital pin 4 (NodeMCU D2). Next we move to the main loop() function.

void loop()
{
  delay(dht.getMinimumSamplingPeriod());

  float humidity = dht.getHumidity();
  float temperature = dht.getTemperature();

The delay(dht.getMinimumSamplingPeriod()); is really what makes this library special. The DHT11/22 is a very slow communicator, using it on 3.3V makes it even slower. This line allows the software to communicate with the hardware by creating a moment where the software stops until the hardware is ready to communicate. The next two lines get the humidity and the temperature readings (in Celsius ) from the sensor. 

  Serial.print(dht.getStatusString());
  Serial.print("\t");
  Serial.print(humidity, 1);
  Serial.print("\t\t");
  Serial.print(temperature, 1);
  Serial.print("\t\t");
  Serial.print(dht.toFahrenheit(temperature), 1);
  Serial.print("\t\t");
  Serial.print(dht.computeHeatIndex(temperature, humidity, false), 1);
  Serial.print("\t\t");
  Serial.println(dht.computeHeatIndex(dht.toFahrenheit(temperature), humidity, true), 1);
}

In this block of code we print the temperature and humidity in different formats to the serial monitor. This code is so easy that I don't really need to say a lot about it. Upload this to your NodeMCU and see the result

The Cloud

The Cloud is just a fancy way of saying internet storage. We are going to use the Adafruit IO cloud. The Adafruit IO cloud allows you to store data for up to a month and visualize it in different ways. To get started go to this link: https://io.adafruit.com/ and create a free account.

For out project we are going to create 2 feeds. A feed is what your sketch is going to communicate with, and store your data. 

Creating a feed

To create a feed click this link: https://learn.adafruit.com/adafruit-io-basics-feeds/overview which takes you to the Adafruit tutorial how to create a feed. They did an amazing job, so why should I duplicate it. You need to create 2 feeds, one named temp (going to store the temperature) and one called humidity (to store the humidity data in). It is important that you call them exactly the same, and they are case sensitive. 

The Libraries

There are two ways of getting the libraries needed. The first one is by downloading them from github by clicking on this link: https://github.com/adafruit/Adafruit_MQTT_Library. The second one is using the Arduino IDE library manager the same way as you installed the library for the DHT 11/22 sensor. The only difference is that you type in "adafruit mqtt" in the search bar. I installed version 0.20.1 of this library.

Click TO Enlarge

The code

Before we continue I recommend you download the sketch by clicking on this link. It is always a good idea to have the code to follow along with the explanation. As usual we start with the deceleration and loading of libraries and global variables. The library section is an easy one.

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "DHTesp.h"

DHTesp dht;

The ESP8266WiFi.h library is used to create a connection to your WiFi router. The Adafruit_MQTT.h, and the Adafruit_MQTT_Client.h are used to communicate with their cloud service. And the rest of this code is already explained as it is used for the DHT type sensor. 

Next we will setup the configuration needed to connect to your WiFi router.

#define R_SSID       "...your SSID..."
#define PASS       "...your password..."

The R_SSID is the name of your router, replace the text between the "" with the name of your WiFi router, the PASS is your routers password. Replace the text between the "" with your routers password. The next section we are setting up the Adafruit IO cloud variables.

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "...your AIO username (see https://accounts.adafruit.com)..."
#define AIO_KEY         "...your AIO key..."

The naming of the variables are self explanatory. The only thing you have to supply is your username. Type it between the quotation marks behind the AIO_USERNAME  You created this when you created the 2 feeds earlier on, and the AIO_KEY, which you can generate or copy by clicking on this link: https://io.adafruit.com/  logging in to your account and clicking on the View AIO Key link. Here you can either copy the key, or if you have not done so generate a key. Place the key between the quotation marks .

Next we are going to look at the code to create the feed objects. As explained in the Adafruit tutorial, the feeds is where you publish your data to. The code for the feed objects looks like this

Adafruit_MQTT_Publish Temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/temp");
Adafruit_MQTT_Publish Humidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/humidity");

The names we use to communicate with the objects are "Temperature" to communicate with the temp feed, and the "Humidity" object to communicate with the humidity feed. The function used works like this;

Adafruit_MQTT_Publish(mqtt object, AIO_USERNAME "/feeds/name of the feed") . If you have named your feeds different or want to name them different this is the part of the code you alter to make that happen, but be aware that the name of the feed needs to be the same as the name you used in the cloud.

Next we create the WiFi client object we are going to use to connect to the Adafruit MQTT server  with this line of code:

WiFiClient client;

Now we are going to create the MQTT object used to connect and communicate  with the Adafruit MQTT server. We do this with this line of code:

Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

If you noticed all previously created variables are used in this line. the mqtt object created is used to further communicate to the MQTT server and feeds throughout the sketch. 

Next we are looking at the setup() function. Here we are going to connect to your WiFi router.

  WiFi.begin(R_SSID, PASS);
  int counter=10;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter--;
    if(counter==0){
      // reset me
        ESP.reset();
    }
  }

The Wifi.begin() starts the connection to your WiFi router. It uses the R_SSID and PASS variables to connect to your WiFi router. This can take a bit of time, this is why we have a while() loop that checks the status of the WiFi connection with the WiFi.status() function. This function can have these states:

  •     WL_IDLE_STATUS      
  •     WL_NO_SSID_AVAIL   
  •     WL_SCAN_COMPLETED  
  •     WL_CONNECTED        
  •     WL_CONNECT_FAILED   
  •     WL_CONNECTION_LOST  
  •     WL_DISCONNECTED    

I am not sure if this is an all inclusive list, but these are the most common ones. The loop will run as long as the WiFi.status() function doesn't returns  the value  WL_CONNECTED. Now sometimes this can be forever even when your WiFi SSID and password are correct.

To prevent this from happening I have put in the int counter=10; variable. With the counter--; we subtract 1 of the value of this variable. Next we have the if(counter==0) statement that lets the loop run for about 10 cycles. When the counter variable has a value of 0 the if() statement is true and the ESP.reset() will reset  your NodeMCU and restart the connection process. This basically prevents you from entering the loop of no return.

When the connection to the WiFi router is successful we are passed on to the main loop() of the sketch. The first line of consequence is the MQTT_connect(); . This send us to the function that will connect us to the MQTT server.

  if (mqtt.connected()) {
    return;
  }

The first thing we do is to see if we are still connected from a previous loop with the if() statement. If mqtt.connected() is true the return; command will exit us from the function back to the main loop preventing us from unnecessarily taxing the MQTT server.

If we are not connected we end up here;

  uint8_t retries = 5;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // reset me
        ESP.reset();
       }
  }

Here we end up in another loop to facilitate the connection to the MQTT server. The while() loop will continue until mqtt.connect() returns a value of 0. In the loop the mqtt.disconnect(); resets the connection to the MQTT server to prevent it from being in a weird state. We wait 5 seconds to give everything a rest period with delay(5000);. The retries counter value is reduced by 1. As with the connection to the WiFi router this could become an endless loop. So by the time we have gone through this process 5 times and we are still not connected the  ESP.reset() will reset the NodeMCU and we start the whole process again.

After we are successful connecting to the MQTT we are send back to the main loop and we are ready to finally upload some data to that cloud.

  delay(dht.getMinimumSamplingPeriod());//waits for the DHT sensor to respond

  float humidity = dht.getHumidity();  //Gets the humidity from the sensor
  float temperature = dht.getTemperature();//gets the temperature in celsius from the sensor

First we get the temperature and humidity data with the above code. We explained the function of this already. Now we have the data we can send it to the cloud.

  if (! Temperature.publish(temperature)) { 
    Serial.println(F("Temperature Failed"));
  } else {
    Serial.println("Temperature: "+String(temperature)+"C");
  }
  if (! Humidity.publish(humidity)) {
    Serial.println(F("Humidity Failed"));
  } else {
    Serial.println("Humidity: "+String(humidity)+"%");
  }

The actual important parts of this code are Temperature.publish(temperature) and Temperature.publish(humidity) statements. If you notice we use the feed object we created in the declaration section of the code and use the .publish() to send it so the cloud. The if() statement is only there to do error checking.  The .publish() returns a value of 0 when it is successful, if not we just write a error statement to the serial monitor. The final line in the main loop() is a delay(30000); which makes the sketch wait 30 seconds before continueing for another go. 

Sleep Mode

Sometimes the logging projects get put in an area where no power outlets are available. If you are running the project on a battery pack you need to put your NodeMCU to sleep when not in use. If you look back a couple of weeks back you see that I created a data logger very similar to this project only we used an Arduino Pro mini. It is a lot harder to wake up an Arduino Pro Mini.

To wake up the NodeMCU only one jumper wire is required, after that no additional hardware is required. All we do is run a jumper wire from pin D0 to the RST pin

NodeMCU_DHT11.22.sleep-configPNG.PNG

You can download the sketch mqtt_NodeMCU_sleep_v1_0b.ino from here. The only difference to the code is that we alter the delay(30000); in the main loop to delay(1000); and add this line just below it; ESP.deepSleep(30e6);

The ESP.deepSleep(microseconds) function puts the NodeMCU into a deep sleep for the time you entered between the brackets in microseconds. We want to put the NodeMCU to sleep for 30 seconds, that is 30000000 microseconds or a 30 with 6 zeros or 30e6.

The process is simple the ESP.deepSleep() function switches off all functions of the NodeMCU except for its internal clock. You basically set an alarm, and when the time is up it pulls the D0 pin low and doing this also pulling pin RST low. This will reset the NodeMCU and the process will start over as if you just plugged in the power to the controller. 

In Closing

I wanted to quickly compare the NodeMCU with the Adafruit Huzzah. If you are going to connect your project to a power supply the NodeMCU is a good solution as you don't have to buy special cables, you could even power it with a USB charger/cable.

If you are going to connect your project to a battery pack the Adafruit Huzzah is your board. While in sleep mode the NodeMCU uses almost 21mA more then the Adafruit Huzzah. Check out the diagram below for the info

Compare.PNG

 

This is the end of this project. I will go deeper into the sleep modes available for the NodeMCU on a later date. This is a sample project so the code can certainly be refind with better error checking. Also the DHT11 can sometimes give false readings when used in this way. Putting a for() loop where you read the data out of the sensor a couple of times before you use it can make it more accurate. 

DHT 11/22 NodeMCU Arduino equivalant
Pin 1 VCC In 3.3V 3.3V
Data Out Pin D2 Digital Pin 4
GND GND GND
GND GND GND
Please put some money in the tip jar by clicking on the donate button to support me so I can continue creating contend like this. P.S. please donate more than $1 as PayPal takes minimum $0.30 per transaction

If you like this sample project and want to see more of this type of content, consider putting some money in the tip jar by clicking the Donate button. If you want to see more of this content subscribe to my newsletter with the form below or follow me on Facebook. This link will take you to my Facebook page. Hope to see you soon, have a great day and bye for now

Subscribe to our mailing list

* indicates required
Email Format
Read More
Tutorial, NodeMCU Ab Kurk Tutorial, NodeMCU Ab Kurk

Tutorial: Intro to the NodeMCU

This tutorial is a simple guide to get started with the NodeMCU one of the most popular forms of the ESP8266 on the market right now. The NodeMCU is a powerful board that is good on the pocket book, but has its drawbacks. We are going to explore how to set this board up with the Arduino IDE, and some other simple tips and trick to get you started.

Please put some money in the tip jar by clicking on the donate button to support me so I can continue creating contend like this. P.S. please donate more than $1 as PayPal takes minimum $0.30 per transaction
New-Wireless-Module-CH340-NodeMcu-V3-Lua-WIFI-Internet-of-Things-Development-Board-Based-ESP8266.jpg

This tutorial is a simple guide to get started with the NodeMCU one of the most popular forms of the ESP8266 on the market right now. The NodeMCU is a powerful board that is good on the pocket book, but has its drawbacks. We are going to explore how to set this board up with the Arduino IDE, and some other simple tips and trick to get you started.

 

Material Needed For This Tutorial

Driver Installation

One of the drawbacks of this board is that you have to install a usb drivers to communicate with this board. You can download the driver from here. Before you try to install the driver be sure you have Administrator privileges on your computer.

After you have downloaded the driver installation package, and you have Administrator privileges you can start the installation. Use a Micro USB Type-B cable that is rated for data transfer.  Follow these steps to install your Driver

install.PNG
  1. Download Driver
  2. Connect your NodeMCU to your computer using the USB cable.
  3. Run the driver installation package  you downloaded as Administrator
  4. Click the install button

 

The driver should install without any problems. The main issue that people have is either not connecting the NodeMCU to the computer before starting the install, or not having the right cable, or not having the correct privileges on your computer. If your driver install fails first make sure all the above mentioned requirements have been met. If it still doesn’t work you have entered the realm of unsupported freeware, and sadly are on a journey of exploration that can be painful. I have not seen it fail when all the requirements have been met.

 

Preparing the Arduino IDE

If you have never worked with an ESP8266 type of board you need to install the drivers and libraries for this in your Arduino IDE. . The people at Sparkfun have a nice tutorial for this. You go there by clicking on this link: https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/installing-the-esp8266-arduino-addon

The NodeMCU form factor

IMG_5031.JPG

You might have noticed by now that the NodeMCU is a bit large. It won’t fit on a regular size breadboard (well it does but you have no room to connect anything to it). What I have done to make it fit is use a dremel tool and cut a normal breadboard in two along the spine (See picture) Now it will fit perfectly.

 

 

 

Pinouts

This is one of the greatest drawbacks of the NodeMCU for beginner users. The labels on the NodeMCU don’t correspond to the digital pins (GPIO pins) we know and love when working with Arduino compatibles. You need image ? to make sense of it.

For example pin D1 on the board corresponds with GPIO 5 (Digital pin 5 on your Arduino). The best thing to do is keep that image handy as a guide to find out what pin does what, and how they correspond to the Arduino world.

Specs

The board runs at 3.3v, and all pins can have a max load of 12mA and a 3.3v logic. When buying breakout boards or other components make sure they run on those specs. It also means you have to be careful when using the pins from the NodeMCU to power components. 12mA is not a lot and this makes it easy for you to overload a pin and fry your board. The board also has only one analog port A0, and it is for input only (like all other ESP8266).

You can power the board with an external power supply no greater than 12V. The documentation is spars, but what I have found is that it can handle 20V but the volt regulator will get dangerously hot. This is why I recommend having a power supply that supplies no more than 12V.

Onboard LED

Often we use an onboard LED in the development phase to error check. This board does not have the LED connected to pin/gpio13, instead it has it connected on pin/gpio 2.

Uploading a Sketch

Next we are going to upload the blink sketch to the NodeMCU. If you have followed the above steps you should have installed the hardware driver (driver name) and the Arduino IDE drivers and libraries we are ready to upload a blink sketch.

Configuration for the NodeMCU

Configuration for the NodeMCU

We start by selecting the NodeMCU 1.0 (ESP-12 Module) under the board options in the Tools menu (See Image for the complete configuration). See Image ? . The only thing that could be different on your computer is the COM port. You just need to select the COM port available to you under the Tools menu Port option.

Below you find the sample sketch to make the onboard LED flash on the NodeMCU

int LED_PIN= 2;

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_PIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_PIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_PIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

In Closing

Check back in about 14 days when I build a more elaborate project with the NodeMCU to see what you can do with this board. But for now if you enjoyed this tutorial please subscribe to my newsletter by filling out the form below, or go to my Facebook page by clicking on the link and follow and like the page. By doing his you will get an alert every time I post a new article. If you have questions or suggestions please email at akurk@thearduinomakerman.info me or leave it in the comments below. Have a great day and see you next time. 

 

Subscribe to our mailing list

* indicates required
Email Format
Read More
Tutorial, Arduino Ab Kurk Tutorial, Arduino Ab Kurk

Tutorial: How to measure current consumption and why should you do it?

A lot of makers don't know how important it is to know the current draw of your project, or why you need to know this. In this tutorial I will explain to you how to measure the current draw of your project, and why it is so important to know this.

I often get asked the question of what type of power supply to use for projects. Most of us know the voltage required, but how much current it draws and why you need to know this is a mystery to many beginner makers. To start with what is this current thing?  "In comes the analogy that uses the flow of water to explain these things".  

Please put some money in the tip jar by clicking on the donate button to support me so I can continue creating contend like this. P.S. please donate more than $1 as PayPal takes minimum $0.30 per transaction
20180102_074627.jpg

A lot of makers don't know how important it is to know the current draw of your project, or why you need to know this. In this tutorial I will explain to you how to measure the current draw of your project, and why it is so important to know this.

I often get asked the question of what type of power supply to use for projects. Most of us know the voltage required, but how much current it draws and why you need to know this is a mystery to many beginner makers. To start with what is this current thing?  "In comes the analogy that uses the flow of water to explain these things".  

 

 

Let’s say that a battery that we use to power our project is a bucket of water with a hose attached to it. The water pressure at the end of the hose is what we consider the voltage. The speed the water runs through the hose is the current and that is measured in Amps.

Yes this never made sense to me either. It comes down to this if your project consumes more current then your power supply has to offer it won’t run, and can even damage your power supply. We measure current in Amperes or Amps for short (Symbol used is A). 

One way to roughly figure out what power supply to use is by reading the documentation of all the components used in your project, and see their current draw (how much Amp(A) or milliamp(mA)). Add these numbers up and you roughly know what the amperage your power supply needs to be.

Note of caution: If you use your laptop USB to power your project you could damage your USB port if the current draw is too high. This is why it is a good practice to have an external power supply to power your project, even when you have a USB cable connected to your Arduino.

MATERIALS NEEDED IN THIS TUTORIAL

 

The other way to find out the current draw is by using a multimeter. Follow the these steps to setup your multimeter for this exercise:

20180102_074627.jpg

Step 1) Look at the bottom of your multimeter you will notice 3 or 4 ports where you plug your probes in to. The black probe plugs into the COM port (COM stands for common ground). The red probe for this exercise should be plugged into the port with the A symbol (or 10A or something similar).  

Note of caution: Multimeters have a limit on how much Amperage a port they can handle. Most likely your multimeter also has a port that measures the current in mA. I normally don’t use this one as it is so easy to damage if you don’t watch it, and you still get enough precision through the A port.

20180102_074627.jpg

Step 2) Turn the dial of your multimeter to A and use the DC mode. Some multimeters will have multiple A options on the dial. We are using DC (direct current), look for an A with this symbol behind it .

 

Click To Enlarge

Step 3) Next using the adapter we connect the red probe  from your multimeter to the plus (+) terminal of your power supply. Connect the black probe to the Vin on your Arduino Uno. Finally connect the GND on your Arduino Uno to your power supply minus (-) terminal. This is called  putting your multimeter in in series, or in line with your power supply.

 

Figure 1

 

Your setup should look a little like figure 1. You should now see how much current your project requires.

 

 

 

 

 

 

 

 

 

Note: Some components require a start-up current (DC motors are bad for this). Your multimeter might not be fast enough to register this, and might not notice this if the power supply can handle this. This happened to me when I started using my desktop power supply. I had a DC motor that needed 3A current to start, after it was running the current use dropped back to under 1A.

Another good reason for knowing how much current your project uses is when you try to run it of a battery pack. Most USB battery packs are graded (the Capacity ) in milliamp hours (mAh). To figure out how long it will last all you need to know is its capacity and how much current your project draws. All you have to do nexts is following this simple formula:

formula.PNG

Divide the battery pack capacity in mAh by the projects current draw in mA. If you have a battery back that provides 16750mAh and your project consumes 32 mA just  divide 16750mAh by 32mA

formula with numbers.PNG

With a battery pack with a capacity of 16750mAh and a project consuming 32mA has a runtime of about 523 hours. Just a disclaimer; this is not precise in anyway. Environmental factors like temperature have a big impact on the actual run time. Another factor is the quality of the power cells used in your battery pack. All battery packs will start to discharge quicker as it loses charge, some might also have voltage drop. So the moral of this story is that you have to run a test to see the actual run time, the calculation will give you a proximate value only.

In Closing

Knowing your projects current consumption can make sure you get the right power supply for your project, reducing the chance of power supply failure or unexplained freeze ups of your project. It can also help you figure out what battery pack you need for your project.

If you like this tutorial and would like to see more of the same type, please subscribe to my newsletter using the form below or like my Facebook page. This way you get notified when a new post is available.  If you have questions or suggestions please email me or leave it in the comments below. Have a great day and see you next time.

     

Subscribe to our mailing list

* indicates required
Email Format
Read More
Arduino, Tutorial, Huzzah ESP8266 Ab Kurk Arduino, Tutorial, Huzzah ESP8266 Ab Kurk

Tutorial:Storing WiFi Configuration On Your ESP8266 Using The EEPROM Library Made Simple Part 2

This is Part 2 of a 2 part tutorial that will simplify the way you can store your WiFi configuration on an ESP8266 using the EEPROM library. With this knowledge you can then build Internet Of Things (IOT) projects that can be configured by web form. This will enable to change passwords or IP configuration when needed without having to recompile your sketch.

In part 2 you will learn howto read information "your stored in memory in part one" out of memory. How to use it to configure your IOT device to connect to your WiFi network, and make it user configurable by combining Part 1 and 2 in one sketch

Please put some money in the tip jar by clicking on the donate button to support me so I can continue creating contend like this. P.S. please donate more than $1 as PayPal takes minimum $0.30 per transaction

This is Part 2 of a tutorial Storing WiFi Configuration On Your ESP8266 Using The EEPROM Library Made Simple. If you have not read Part 1 I would recommend you do. Here is the link to Part 1.  In this tutorial (Part 1/Part 2) I explain how to build a user configurable Internet Of Things devide

In Part 2 we are going to look at how to read the data we stored in Part 1 from memory. We are going to use this to configure your IOT device and connect to your local WiFi network. The end result of this tutorial will be an IOT device that will turn the on board LED on and off through a web browser, and enable you to alter your WiFi configuration through a web form all in one device.

This Tutorial will have three sections. In Section One: Read data out of memory using the EEPROM Library; you will see how to read data out of memory using the EEPROM library. In Section Two: Connecting your IOT device to your WiFi network using the credentials stored in memory; you will learn how to connect your IOT device with the data stored in memory to your local WIFI network, and be able to connect to it with a web browser. In Section 3: Creating your user configurable IOT device ; you will see how to combine what you have learned in Part 1 and Part 2 of this tutorial to create a final project with a WiFi Access Point to configure your WiFi credentials, and an Internet Of Things device that allows you to turn the on-board LED on and off using a web browser

MATERIALS NEEDED IN THIS TUTORIAL

  • Adafruit Huzzah Breakout 
  • 5v FTDI cable
  • bread board
  • On/OFF switch ( SPST Toggle Switch)
  • Some jumper wires
  • 10K ohm resistor

Sample Sketches

Section One: Read data out of memory using the EEPROM Library

Download the eeprom_read_1_0.ino sketch from this link. This sketch is going to read the SSID out of memory that you wrote to the ESP8266 in the last example (WifiAccessPoint_Write_1_0.ino) in Part 1 of this tutorial. If you recall that our SSID was stored in memory location 0, and had a max length of 30 characters. We used the ';' character as the end of string character.

Looking at the sketch we see that only one part has changed in this sketch compared to the writing sketch in Part 1. Instead of writing we are reading from memory. On line 21 in the if statement we are reading data with this command:

eeprom_read_char.PNG

If you notice we are reading it in as a char. On line 22 we convert this char back to a string and append it to a string variable named string_Value with this command.

eeprom_read_string_convert.PNG

Notice how we use the String() to convert it. Also we use the += operator to append. It does the same as if you would use this code: string_Value=string_Value+ "some string". As I said in the title "Simple". Now you know the basics how to read your data out of memory.

Section Two: Connecting your IOT device to your WiFi network using the credentials stored in memory

Before you continue with this section first make sure you have entered your WiFi credentials in the ESP8266 huzzah breakout memory using the sketch in section 3 of Part 1 of this tutorial. We are building on top of that data. 

Download sketch IOTdevice_read_Config_1_0.ino from this link. At first glance the sketch might look complicated, but that is only because we need to read information out of memory and then convert it to whatever format it needs to be in. If you look past the amount of code everything is straight forward  

Near the top of the sketch (starting at line 24) we declare the following variables:

Notice that we declare 2 char arrays; ssid[30] and password[30]. This is needed because the code below (which is needed to connect to your WiFi router) needs this data type to work.

wifibegin.PNG

 I'll explain this in more in detail in a bit. Next you see the integer ip_group. We use this variable to help parse the IP data out  of memory. Each ip address is made up out of 4 groups of numbers, and we need a fifth one to store the last 3 digits of the gateway address. The last variable (string_IP) is used to  temporarily store the ip info while we parse the data.

Reading Credentials out of Memory (ssid, Password)

Next we jump to the top of the setup() function.  Lest look at the code starting at line 62;

reading_ssidpassword_out_of_Memory.PNG

This block of code reads the WiFi routers ssid, and password out of memory. First two Strings() are declare to temporarily store the ssid, and password in. Then the function read_string(int Size,int Location) is called. You pass this function the location (in memory) of the data you want to read out of memory, and the size (in characters) of the data. It returns a String() containing the data you were looking for. Next the Strings  gets converted into an Char Array. Remember that a Char Array variable had to use for the ssid and password, well here they are populate them with this command;

tochararray.PNG

String.toCharArray(Char,Size) function converts a String into an Char Array. All you need is the String you want to convert, a Char Array and the size of Array. On line 69, and 70 we convert the temporary strings into the arrays that are going to be used to provide the SSID and Password credentials.

Next lets look at the read_string() function:

read_string.PNG

The read_string() function is strait forward. A for() loop that reads one character at a time out of memory. When it encounters the end of data string ';' character it exits the loop and returns the string as an result.

Configuring the IP information

The difficulty with configuring the IP information is that a string containing 4 groups of numbers needs to converted into 4 integers. Lets look at the code and see how it is done;  

read_ip_information.PNG

On line 73 a Array is declared of the integer type (ip_Info[5]. It can hold 5 groups of integers (The 4 from the IP, and one group for the gateway. Now remember when using Arrays, the first position always starts at 0. The ip_group variable is used to handle what IP group we are dealing with.

A simple for loop is used to read a string out of memory one character at a time. The if ()/else statement in the  loop looks for the '.' and ';' characters (The '.' divides the 4 sets of IP numbers, and the';' is the end of string character)  .  When one of those characters is found it sends the string_IP string to the ip_convert(String) function. The ip_convert() function converts the string to an integer and returns it. The integer gets store in the ip_Info[] variable using the ip_group variable to determine what slot it gets stored in. 

Lets explore the code for the ip_convert() function ;

ip_convert.PNG

The ip_convert() function starts on line 34 of the sketch. It converts the string send to it to an integer. The syntax  to convert a string into an integer is simple String.toInt(). We check if the string actually can be converted to an integer with the in statement on line 35. If it is possible to convert the string,  the string_IP variable gets reset to empty and then returns the converted integer containing your IP information. If the string can't be converted to an integer it returns a value of 400 (You can use this for error checking, which I have not implemented).

Next the gateway information is read out of memory with the following code;

read_GW_info.PNG

It uses the functions described above, saving me time and code size,  and making things more streamlined :). Now it is time to put this all together and link the IP information (IP Stack) and credentials (ssid,password) to the ESP8266 and connecting it to your WiFi network. We do this with the following code;

click to enlarge

The IPAddress data type requires 4 integers divided by commas. The IP information stored in the ip_Info[] array gets use  to populate the IP variables. Next we bind them to the development board using the WiFi.config() command, and it is time to connect to your WiFi router with the WiFi.begin() code.

The following code checks if the connection is working;

check_connection.PNG

The While() loop uses the WiFi.status() function to check if it is connected. This does not check if the IP information is correct, it only checks that your credentials (ssid,password) are correct. The loop keeps cycling until it connects. I added the blinking onboard LED that blinks until connected.

Configuring the Web Server

I am not going to go deep into the webserver configuration as we have discussed it in detail in Part 1 of this tutorial. All I have done is created /on, and /off functions. The code for this can be found starting on line 113 of the sketch and the actual functions can be found starting on line 127 . 

Compile this code and try to type http://insert your ip/on to turn the on board light on, and http://insert your ip/on to turn it off.

Section 3: Creating your user configurable IOT device

Download  the completed sketch: complete_IOT_solution_1_0_2.ino here. I have also created a pdf with all functions in this sketch, their short descriptions and the line in the code where to find them. You can download it from here.

This is the final sketch of the tutorial. This sketch is basically WiFiAccessPoint_Write1_0.ino  sketch(from Part 1), and the IOTdevice_read_Config_1_0.ino from the previous section mashed together to make one coherent sketch.

As a disclaimer I would like to say that this final sketch is not to be used without you doing thorough testing in a real world environment. I have done testing on it under controlled environment, but it has not had a monkey test done. 

To make the two above mentioned sketches work I had to rework some of the variables used to deal with naming conflicts, but all the main functions and parts of the two parent sketches are there and intact.

To make the integration readable and understandable, I moved most of the code located in the setup() function of the parent sketches, and put them in their own functions (WAP(), and IOT()). I only left  the shared items, like the setup of the webserver in the setup function.

The biggest change is really that I have altered the hardware configuration by adding a (spst) switch. This is basically a On and Off  switch. The connection diagram can be found below. I have created the #define button_Pin 13 variable for the define the switch digital port.

hardware diagram.PNG

I have set it up so that when the switch is in the On position you go into setup mode, and when it is Off to be in normal mode.

Another big change is part of the error checking. I have added some more comprehensive but still basic error checking with these functions:

  • int ssid_error_Check(String content) on line 306
  • int password_error_Check(String content) on line 321
  • int ip_error_Check(String content) on line 344
  • int gw_error_Check(String content) on line 382

These are very simple error check routines. They basically check if the string containing the data is the correct length, and if it contain characters that not allowed in the ssid, password, IP, and gateway. In the case of the IP I check for non alphanumeric characters with isAlpha(). This function returns a true when it contains non numeric characters. I do this with the following code:

It basically creates an error message that gets displayed in the input form if the IP address contains non Alphanumeric characters. A great place to see how to evaluate and analyse strings is this tutorial from the Arduino.cc people; link: https://www.arduino.cc/en/Tutorial/CharacterAnalysis

The creation of the input web form also has seen some changes. I create a function called create_form(String ssidr,String passwordr,String ipr, String gwr) (on line 218). When you call it you pass it the ssid, password, ip, and the gw address. This is done in the error checking process. If one of the error checking function return a 1 (indicating an error)  the input form is returned to the web browser with previously entered values and the appropriate error message. We use the following global error messages variables (declared on line 38).

String ssid_Arg;// Error message for ssid input
String password_Arg;// Error message for password input
String ip_Arg;// Error message for ip input
String gw_Arg;// Error message for gateway input

Compile and upload the sketch and take it for a run. First set the switch into the setup configuration and type in your WiFi credentials. See how the error checking works (remember it is really basic, you might want to add some more checks to it). Then throw the switch into normal operation mode and see how it connects to your WiFi router. Go to the root / of your device with your web browser and how to turn the onboard led on and off.

This completes this tutorial. If you have further questions leave them in the comment section below and I'll try to answer them as quick as possible. I hope you enjoyed this tutorial and it increased your knowledge base so you can become a more accomplished maker.

If you like this tutorial and want to see more of this please subscribe to my periodical Newsletter by filling out the form below, or follow me on Facebook by clicking on this link, and click the Like button on my Facebook page. 

Subscribe to our mailing list

* indicates required
Email Format

  

Read More
Arduino, Tutorial Ab Kurk Arduino, Tutorial Ab Kurk

Tutorial:Storing WiFi Configuration On Your ESP8266 Using The EEPROM Library Made Simple Part 1

This tutorial is part 1 of 2 that will simplify the way you can store your WiFi configuration on an ESP8266 using the EEPROM library. With this knowledge you can then build Internet Of Things (IOT) projects that can be configured by web form. This will enable to change passwords or IP configuration when needed without having to recompile your sketch.

In part 1 we learn how to write the information to your IOT project, part 2 will teach you how to read this information out of memory and configure your IOT project so it can connect to your WiFi router

Please put some money in the tip jar by clicking on the donate button to support me so I can continue creating contend like this. P.S. please donate more than $1 as PayPal takes minimum $0.30 per transaction
IOT Symbol.png

In this tutorial we are going to build an IOT device, using the ESP8266, that allows you to setup the network configuration (e.g. SSID, and password of a WiFi router ) through a form and store it in it’s memory. This is a bit harder to do then for instance using  an Arduino UNO as the ESP8266 does not really have an EEPROM like all the  real Arduino boards have. This is why most of us struggle to use the EEPROM library with the ESP8266 development board.

This is the first tutorial out of a 2 part series. In part 1 I will teach you how to write the data to the ESP8266. In part 2 we will teach you how to read it back out of memory to configure your IOT device to connect to your home network.

Part one has 3 sections. In section One (The EEPROM Conundrum)  we will look at how to write data to the ESP8266 memory. Section Two (Setting up a basic WAP) will explain how to set up an WiFi Access Point.

"An access point is a device that creates a wireless local area network. or WLAN, usually in an office or large building. An access point sometimes connects to a wired router, switch, or hub via an Ethernet cable, and projects a Wi-Fi signal to a designated area. It is also used for users to configure IOT devices for first time use, or password changes"

In Section Three ( Adding a form to the WAP, and write data to huzzah memory )  we will put it all together to create a functional WiFi access point that writes configuration data to your ESP8266 memory

Below is a You Tube video accompanying this tutorial. For best result download the example sketches within this tutorial before watching this video.

Materials Needed in this tutorial

  • The Adafruit ESP8266 Huzzah Breakout board
  •  5v ftdi cable
  • Access  to the the SSID and password of your WiFi router you want to connect to, to get configuration data

 

Section One:The EEPROM Conundrum

Because many makers want to build cheap IOT solution, the ESP8266 has become a favourite to a lot of us. But writing values other than integers to its memory can be problematic. The main reason is that the standard EEPROM library does not work, because the ESP8266 does not have an EEPROM. The library we use simply emulates an EEPROM but in real life we are writing to the FLASH Memory.

Writing to the ESP8266 memory

The trick is simple; anything we write to the ESP8266 memory will have to be a string, and we can write them one character as a time.  Download the sample sketch from this link:

#include <EEPROM.h> //The EEPROM libray 
String string_Value;
float float_Value=111.2222;


void setup() {
string_Value=String(float_Value,4);
string_Value=string_Value+";";
EEPROM.begin(512);
for(int n=0; n< string_Value.length();n++){
  EEPROM.write(n,string_Value[n]);
}
EEPROM.commit();
}

void loop() {
  // put your main code here, to run repeatedly:

}

As you can see the code is very simple. Let me explain what we do. First we declare a String variable called string_Value and a float variable float_Value with a value of 111.2222

String string_Value;
float float_Value=111.2222;

Next in the setup() function I convert the float variable into a string. I do this using the String object. If you notice  the "4" in the String(float_Value,4), this signifies the precision of the float value that gets stored in the string_Value variable. If you notice I added the "; "character  to the string value.

string_Value=String(float_Value,4);
string_Value=string_Value+";";
string.PNG

I add the ; character as an end of string symbol. When you read data one character at a time you need to know when you have reached the end of the data. The easiest way to do this is by adding a predetermined character that symbolizes the end of data stream. I chose the ; character as you are not allowed to use them in most passwords, or URL's.

Now comes the writing process,  I first initiate the EEPROM function with EEPROM.begin(512);, and I also set the size of the storage as well. Next I cycle through the string value string_Value one character at a time using a for() loop.  I start writing these characters to the ESP8622 memory starting at position 0 with this command EEPROM.write(n,string_Value[n]).

Eeprom_write.PNG
cabinet-with-many-small-drawers.jpg
"If you look at the memory we defined as a chest of drawers with 512 drawer. The first drawer has an address of 0, and the last drawer has a address of 511. As the sketch walk's through the string one character at a time, it opens the drawer with the corresponding address and deposits the character in that drawer. "  

The write position in the ESP8622's memory get determined by the value n which I set to 0 in the initialization section of the for loop. I use the string.Value.length() to set how many times we go through the for loop. After the loop terminates I commit the data written to memory with EEPROM.commit() 

As you see it is quite easy. You can write any value you want to the ESP8266 memory this way as long as you first convert it to a String. 

Section TWO: setting up a basic WAP

Access Points are fun little things that allow you to connect to your Arduino  projects to do interesting things like, get or store data that is password protected, create your own WiFi router, or for our purpose to let the user configure your project.

In this section we are setting up a basic WAP. It will allow you to give your WAP a name like a WiFi router( the SSID), require a password for authentication and security purposes, and provide you with a static IP address so you can access the web server to get information. 

Download the sample sketch "WiFiAccesspoint1_0.ino" from here. I will walk through it and highlight the important bits. 

At the top of the sketch you see the following section near line 20 in your sketch

/* Configuration Variables for the AP name and IP. */
const char *ssid = "Test";
const char *password = "Password";
IPAddress ap_local_IP(192,168,1,1);
IPAddress ap_gateway(192,168,1,254);
IPAddress ap_subnet(255,255,255,0);

These variables set up the WAP environment. The ssid variable gives your WAP its name, and the password provides you with a password. You can change this to whatever your heart desires. Here you can also find 3 variables that define the IP information. If you understand a little bit about the  IP configuration you can alter this to your liking. The IP, Gateway, and subnet get  bound to the board with the following commands you can find in the setup() function roughly at line 33 in the sketch and write below it we set the name and password for the AP ;

WiFi.softAPConfig(ap_local_IP, ap_gateway, ap_subnet)
WiFi.softAP(ssid, password);

You are now ready to connect to the WAP. It still would not do anything as we have to add a service to provide. We are going to add a web-server. We do this with the following line found in your sketch on line 19;

ESP8266WebServer server(80);

This line adds a webserver listening on port 80. Now it is time to add some content to the webserver. We do this by adding the following lines to the setup() function near line 41.

server.on("/", handleRoot);  
server.onNotFound(handleNotFound);
server.begin();

The first line tells the server to execute function handleRoot() when somebody accesses the root of the server. In our case if somebody would type http://192.168.1.1/. The next line will execute function handleNotFound() if somebody would try to access anything else other then the root of the server.

If you look at the bottom end of the sketch you actually see both functions handleRoot() and handleNotFound(). The handleRoot() function has this line of code in it;

server.send(200, "text/html", "<h1>You are connected</h1>");

This line basically sends a response to the request for data when you type  http://192.168.1.1/ into your web browser and press enter.  The send() function basically is made up like this; send(code,content type,content).

The code parameter is basically the type of response the webserver gives. The two most common are 200 (which means this is success full response and here is what you requested), or the 404 (which means the data requested does not exist). The next parameter is content type. For us it is plain html (text/html), and the next parameter is the actual content. In our case it is;

"<h1>You are connected</h1>"

This can also be a string variable that contains html code. If you look at the handleNotFound() function you see that we first create a string called message where we store the html response of the server not finding the requested page. Then in the send() function we give a code of 404 (page not found), a content type of text/plain, and the content is the message string.

The final component in setting up the webserver is the line server.handleClient(); in the loop() function of the sketch. The server.handleClient(); listens to the IP address provided and will call the appropriate function declared in the setup() function. Now your webserver is ready. Compile your sketch and upload it to your huzzah breakout and see what happens.

Section Three: Adding a form to the WAP, and write data to huzzah memory 

In this section we combine Section one and two of this tutorial to get a WAP that writes information you enter into a form to memory.  I am not going to rehash all the points explained in the previous sections, I am just going over the new stuff. Start with downloading the sketch "WiFiAccesspoint_Write1_0.ino" by clicking on this link.

The first major difference is that we create a constant char near line 17 of the sketch named INDEX_HTML. This contains the form html data that we are going to display.

The next big change you can find is near the bottom of the sketch in the handleRoot() function(on line 79 of your sketch). It has a if() statement that checks if the data received by the web server contains the input field information of the form created on line 17 of the sketch. This is done by checking for the names assigned to the input fields on the html form. See the example of  an html input field below.

<input maxlength="30" name="ssid">

The following code checks if the input field name "ssid" is one of the parameters received by the webserver when you submitted it. If it did it returns a value of true, if not it returns a value of false;  

serverhash.png

The if() statement below makes sure that all field name parameters are present. 

ifhashcheck.PNG

If this is true we call the handleSubmit() function. If this is not true we display the html input form.

In this sketch we don't check if the data entered is correct. If this would be a completed sketch to be used in the field it would be imperative to check this.

If the input field names exists  and the if statement returns as true, we call the handleSubmit() function (on line 87 of your sketch). In this function we create an html page displaying the data the user just entered, and we call the write_to_Memory() function (on line 108 of your sketch).

We pass this function the content of each input field found in the html form. You get the content of the form input field named "ssid" with the code below; 

server.arg.PNG

This code returns the value of the form input field as a String. 

In the write_to_Memory() function the end of data symbol ";"  is added to each fields data and call the write_EEPROM( ) function to write it to memory. At the end of the write_to_Memory() function we commit the data to memory using the EEPROM.commit() code.

Webform.PNG

Compile your sketch and upload it to your ESP8266. Now use a laptop or other device to connect to your WAP. If you did not change the ssid name look for the name Test in your available WiFi connection point. Use Password as the password. After it completes connecting to your IOT device start up a web browser and type 192.168.1.1 in your URL bar and press enter. A form pops up, and you are ready to type in your WiFi router credentials and press enter. Your information is now written to your ESP8266.

This completes this tutorial , check back in a week or two for Part 2 of this tutorial where we will learn how to read the data back and how to put these two sections together. If you have further questions leave them in the comments below.  

If you like this tutorial and want to see more of this please subscribe to my periodical Newsletter by filling out the form below, or follow me on Facebook by clicking on this link, and click the Like button on my Facebook page. 

Subscribe to our mailing list

* indicates required
Email Format
Read More