ESP-12E running the sample LED Blink Lua script |
Alternatively we can directly program the 80MHz 32-bit Tensilica CPU inside the ESP8266. After all, the NodeMCU folks wrote ESP8266 firmware so that we can run Lua programs directly on the ESP8266.
If you are new to all this, don't be fazed- all this new stuff is really easy to learn and use. They are designed like that. This is also my first experience of NodeMCU, Lua and ESP8266.
We program the ESP-12E using the Arduino IDE. It supports much more than the ESP8266, which is just a tiny part of the Arduino ecosystem.
Screenshot of Arduino IDE on Slackware 14.2 (bottom left). and the Arduino IDE Serial Port Monitor (top left). Henry's Bench website (right) |
I would have preferred a smaller program, the command line-based nodemcu-uploader would have been perfect, but it was unable to work with my ESP-12E. I suspect I would first have to change the firmware.
Since I am running Linux Slackware 14.2, we first need to install Arduino IDE. I got the source files arduino-1.8.5-linux64.tar.xz from here. Using my root account, I simply ran the install script:
$./install.sh
Still as root (otherwise you need to give yourself the permissions to access the USB device /dev/ttyUSB0), and still using the same directory you unpacked your source files:
$arduino-1.8.5/arduino
Henry's Bench does a great job explaining how to set up Arduino IDE for the ESP8266. I would just add that you need a working Internet connection to get it done. His sample program, which I copied and pasted into my Arduino IDE worked right out of the box.
To program and run the stock sample Blink sketch (Lua programs are called sketches), again please refer to the excellent example in Henry's Bench.
While you are setting up the LED circuit, it is sometimes helpful to have an idea how the Blink program is running. I have modified the Blink sketch slightly so that it outputs messages to the Arduino Serial Monitor as well:
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
Serial.begin(115200);
Serial.print("Setup done on ");
Serial.println(LED_BUILTIN);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is active low on the ESP-01)
Serial.println("Low");
delay(1000); // Wait for a second
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
Serial.println("High");
delay(2000); // Wait for two seconds (to demonstrate the active low LED)
}
Rather than going to the trouble of building another 3.3V power module for this test, I have simply directly connected the LED to pin D0 of the ESP-12E. The circuit in Henry's Corner is a much better one; it results in a bright light and will work reliably without over-stressing the ESP8266's GPIO output pin.
Often modern CPUs have short-circuit protection for their IO pins, and often the output pins are strong enough to light up an LED dimly. It helps to chose a red LED (they are the oldest and most efficient). Luckily, in this case I got away with it; the LED was just bright enough to be seen, although I had to turn off my study lights for it to come out in the photo.
One possible pitfall with this method is the LED will take up precious mA of power from your ESP-12E PCB. The ESP8266 is effifcient enough but it seems to have trouble powering up from many laptops' USB ports and most USB hubs.
I am powering my ESP-12E from a D-Link USB 3.0 hub with 4A of external power. If your system gets all flakey, you are probably better off using the method in Henry's Bench. The current draw of the ESP-12E is normally about 60mA. When the LED turns on this increased to 80mA. This means the ESP8266 IC is putting out 20mA to the LED which is very close to its maximum running current.
The Blink sketch LED circuit from Henry's Corner |
You now have an ESP8266 running a native (ie stored onboard) Lua program on NodeMCU firmware. If you now exit from Arduino IDE, the ESP-12E program should continue to run on its own. In fact the program will now start up every time you turn the device on.
ESP8266 as IoT Digital Output controlling an LED |
Next to make it an IoT application, navigate thus:
File->Examples->ESP8266->ESP8266WiFi->WiFiWebServer
to the sketch WiFiWebServer.
/*
* This sketch demonstrates how to set up a simple HTTP-like server.
* The server will set a GPIO pin depending on the request
* http://server_ip/gpio/0 will set the GPIO2 low,
* http://server_ip/gpio/1 will set the GPIO2 high
* server_ip is the IP address of the ESP8266 module, will be
* printed to Serial when the module is connected.
*/
#include <ESP8266WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// prepare GPIO2
pinMode(16, OUTPUT);
digitalWrite(16, 0);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();
// Match the request
int val;
if (req.indexOf("/gpio/0") != -1)
val = 0;
else if (req.indexOf("/gpio/1") != -1)
val = 1;
else {
Serial.println("invalid request");
client.stop();
return;
}
// Set GPIO2 according to the request
digitalWrite(16, val);
client.flush();
// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
s += (val)?"high":"low";
s += "</html>\n";
// Send the response to the client
client.print(s);
delay(1);
Serial.println("Client disonnected");
// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}
// prepare GPIO2
pinMode(16, OUTPUT);
digitalWrite(16, 0);
And further down, near the bottom:
// Set GPIO2 according to the request
digitalWrite(16, val);
digitalWrite(16, val);
Compile and upload the sketch to the ESP-12E. Over at a convenient browser in your phone, laptop or desktop type out:
http://IPaddress:8080/gpio/1
And the LED turns on, as before. You might notice I use the webserver port 8080, whereas the normal port to use is 80. This is because my website www.cmheong.com is already using port 80, and I reconfigured my modem router to map port 8080 in the browser to port 80 in the ESP-12E.
There you have it: a simple IoT control of an LED. Add a cheap Arduino relay PCB, and you should be able to switch useful things like light bulbs.
Until the next post then, Happy Trails.
No comments:
Post a Comment