Showing posts with label Standalone ESP8266. Show all posts
Showing posts with label Standalone ESP8266. Show all posts

Friday, June 16, 2017

Python run on Raspberry Pi (and PC running Ubuntu) to plot serial data from ESP8266/NodeMCU

Last post show a simple program run on ESP8266/NodeMCU to read Analog Input and send to Serial. And display the data on Raspberry Pi 3 using Arduino IDE Serial Plotted. This post show a Python example run on Raspberry Pi 3/Raspbian Jessie with PIXEL, to plot the serial data graphically using matplotlib library.



pyserialplot.py
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import platform

print("Python version: " + platform.python_version())
print("matplotlib version: " + mpl.__version__)

fig, ax = plt.subplots()
line, = ax.plot(np.random.rand(10))
ax.set_ylim(0, 1030)
xdata, ydata = [0]*100, [0]*100
SerialIn = serial.Serial("/dev/ttyUSB0",9600)

def update(data):
    line.set_ydata(data)
    return line,

def run(data):
    global xdata, ydata
    x,y = data
    if (x == 0):
        xdata = [0]*100
        ydata = [0]*100
    del xdata[0]
    del ydata[0]
    xdata.append(x)
    ydata.append(y)
    line.set_data(xdata, ydata)
    return line,

def data_gen():
    x = 9
    while True:
        if (x >= 9):
            x = 0
        else:
            x += 0.1
            
        try:
            inRaw = SerialIn.readline()
            inInt = int(inRaw)
        except:
            inInt = 0
            
        yield x, inInt

ani = animation.FuncAnimation(fig, run, data_gen, interval=0, blit=True)
plt.show()


This python example can be run on both Python 2 and 3. To run this on Raspberry Pi/Raspbian Jessie with PIXEL, matplotlib library is need.

For Python 2:
$ sudo apt-get install python-matplotlib

For Python 3:
$ sudo apt-get install python3-matplotlib

In the following code, we have to get the port connected.
SerialIn = serial.Serial("/dev/ttyUSB0",9600)

In Raspberry Pi/Raspbian Jessie with PIXEL, it is /dev/ttyUSB0 normal. We can check it with:
$ ls /dev/ttyUSB0*




Run on Ubuntu:

The Python script work on PC/Ubuntu also. This video show running on Ubuntu 17.04/Payton 3.6 (actually behind Windows 10/VirtualBox).


In order to run with newest Python 3.6 on Ubuntu 17.04, you have to install Python 3.6 and corresponding IDLE and pip.

And install packages using command:
$ sudo python3.6 -m pip install numpy
$ sudo python3.6 -m pip install matplotlib
$ sudo python3.6 -m pip install pyserial


About Saving graph of matplotlib:

Suppose I can click the Save button on matplotlib navigation toolbar to save the graph to file (reference: matplotlib - Interactive navigation).

But when I test it on Raspberry Pi with matplotlib 1.4.2, it is not work.

When test it on PC running Ubuntu 17.04/Python 3.6 with matplotlib 2.0.2, I can save the graph. But the navigation toolbar disappear after saved.



Monday, June 20, 2016

NodeMCU/ESP8266 + OLED 1.3" 128x64 SPI SH1106, using esp8266-oled-sh1106 library


It's a 1.3" 128x64 OLED of SPI interface, with SH1106 controller. The SH1106 is in general similar to the SSD1306. Main difference is a memory of 132x64 instead of 128x64.

This post show how to connect with NodeMCU and install the library of esp8266-oled-sh1106.

Connection between NodeMCU and the 1.3" 128x64 OLED SPI module with SH1106:
 D5 GPIO14   CLK         - D0 pin OLED display
 D6 GPIO12   MISO (DIN)  - not connected
 D7 GPIO13   MOSI (DOUT) - D1 pin OLED display
 D1 GPIO5    RST         - RST pin OLED display
 D2 GPIO4    DC          - DC pin OLED
 D8 GPIO15   CS / SS     - CS pin OLED display


Download and install the library as shown, and run the example:



Related:
Hello World 1.3 inch IIC/SPI 128x64 OLED x Arduino, using u8glib library
NodeMCU/ESP8266 + OLED 0.96" 128x64 I2C SSD1306 using esp8266-oled-ssd1306 library

Sunday, June 19, 2016

NodeMCU/ESP8266 + OLED 0.96" 128x64 I2C SSD1306 using esp8266-oled-ssd1306 library


esp8266-oled-ssd1306 is  a driver for the SSD1306 based 128x64 pixel OLED display running on the Arduino/ESP8266 platform. Can be used with either the I2C or SPI version of the display

You can either download this library as a zip file and unpack it to your Arduino/libraries folder or (once it has been added) choose it from the Arduino library manager.

This video show how to install on Arduino IDE using Library Manager, and run the example.


Connection between NodeMCU and OLED 0.96" 128x64 I2C SSD1306:
NodeMCU 3V3 - OLED VCC
NodeMCU GND - OLED GND
NodeMCU D3 - OLED SDA
NodeMCU D5 - OLED SCL

(The Fritzing parts of both nodemcu-v1.0 and OLED_SSD1306_I2C_128x64 can be download here:
https://github.com/squix78/esp8266-fritzing-parts)


Related:
NodeMCU/ESP8266 display on 1.3" 128x64 OLED SPI with SH1106, using esp8266-oled-sh1106 library
Raspberry Pi display on 128x64 I2C OLED with SSD1306, using Python

Other libraries to run on NodeMCU/ESP8266 with I2C OLED SSD1306:
NodeMCU (ESP8266) to display on 128x64 I2C OLED, using Adafruit SSD1306 library
esp8266-OLED, esp8266-Arduino library for I2C-OLED displays

For ESP32 WiFi/Bluetooth Module:
Connect I2C 128X64 OLED (SSD1306) to ESP32, using esp8266-oled-ssd1306

Tuesday, May 10, 2016

NodeMCU/ESP8266 WebSocketsServer, load html from separate file in flash file system


This example have the same function of "NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED", but the html is saved in separate file in flash file system instead of hard code in ino.


Prepare the html in data directory under sketch directory:

data/home.html
<html>
<head>
<script>
var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);
connection.onopen = function(){
    connection.send('Connect ' + new Date()); 
};

connection.onerror = function(error){
    console.log('WebSocket Error ', error);
};

connection.onmessage = function(e){
    console.log('Server: ', e.data);
};

function sendRGB(){
    var r = parseInt(document.getElementById('r').value).toString(16);
    var g = parseInt(document.getElementById('g').value).toString(16);
    var b = parseInt(document.getElementById('b').value).toString(16);
    
    if(r.length < 2){
        r = '0' + r;
    }   
    
    if(g.length < 2){
        g = '0' + g;
    }   
    
    if(b.length < 2){
        b = '0' + b;
    }   
    
    var rgb = '#'+r+g+b;    
    console.log('RGB: ' + rgb); 
    connection.send(rgb);
}
</script>
</head>
<body>
<b>LED Control 2:</b><br/>
<i>Load html from separate file</i><br/>
<br/>
R: <input id="r" type="range" min="0" max="255" step="1" onchange="sendRGB();" /><br/>
G: <input id="g" type="range" min="0" max="255" step="1" onchange="sendRGB();" /><br/>
B: <input id="b" type="range" min="0" max="255" step="1" onchange="sendRGB();" /><br/>
<br/>
http://arduino-er.blogspot.com/
</body>
</html>

To upload this sketch data of html, refer last post "NodeMCU/ESP8266 read from separate file in Flash File System".

Modify the ino to load String of html from external file.

WebSocketServer_LEDcontrol.ino
//NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED
//arduino-er.blogspot.com

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>

#include "FS.h"

#define LED_RED     15
#define LED_GREEN   12
#define LED_BLUE    13

ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server = ESP8266WebServer(80);
WebSocketsServer webSocket = WebSocketsServer(81);

String html_home;

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {

    switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[%u] Disconnected!\n", num);
            break;
        case WStype_CONNECTED: {
            IPAddress ip = webSocket.remoteIP(num);
            Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);

            // send message to client
            webSocket.sendTXT(num, "Connected");
        }
            break;
        case WStype_TEXT:
            Serial.printf("[%u] get Text: %s\n", num, payload);

            if(payload[0] == '#') {
                // we get RGB data

                // decode rgb data
                uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);

                analogWrite(LED_RED,    ((rgb >> 16) & 0xFF));
                analogWrite(LED_GREEN,  ((rgb >> 8) & 0xFF));
                analogWrite(LED_BLUE,   ((rgb >> 0) & 0xFF));
            }

            break;
    }

}

void prepareFile(){
  
  Serial.println("Prepare file system");
  SPIFFS.begin();
  
  File file = SPIFFS.open("/home.html", "r");
  if (!file) {
    Serial.println("file open failed");  
  } else{
    Serial.println("file open success");

    html_home = "";
    while (file.available()) {
      //Serial.write(file.read());
      String line = file.readStringUntil('\n');
      html_home += line + "\n";
    }
    file.close();

    Serial.print(html_home);
  }
}

void setup() {
    //Serial.begin(921600);
    Serial.begin(115200);

    //Serial.setDebugOutput(true);

    Serial.println();
    Serial.println();
    Serial.println();

    for(uint8_t t = 4; t > 0; t--) {
        Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
        Serial.flush();
        delay(1000);
    }

    pinMode(LED_RED, OUTPUT);
    pinMode(LED_GREEN, OUTPUT);
    pinMode(LED_BLUE, OUTPUT);

    digitalWrite(LED_RED, 1);
    digitalWrite(LED_GREEN, 1);
    digitalWrite(LED_BLUE, 1);

    
    prepareFile();

    WiFi.softAP("arduino-er", "12345678");
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);

    // start webSocket server
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);

    if(MDNS.begin("esp8266")) {
        Serial.println("MDNS responder started");
    }

    // handle index
    server.on("/", []() {
        // send home.html
        server.send(200, "text/html", html_home);
    });

    server.begin();

    // Add service to MDNS
    MDNS.addService("http", "tcp", 80);
    MDNS.addService("ws", "tcp", 81);

    digitalWrite(LED_RED, 0);
    digitalWrite(LED_GREEN, 0);
    digitalWrite(LED_BLUE, 0);

    Serial.printf("Server Start\n");

}

void loop() {
    webSocket.loop();
    server.handleClient();
}



- more example of "ESP8266 core for Arduino".

NodeMCU/ESP8266 read from separate file in Flash File System


This example show how NodeMCU/ESP8266 read separate file in Flash File System.

In order to upload extra files to NodeMCU/ESP8266, a tool "ESP8266FS" is needed:

ESP8266FS is a tool which integrates into the Arduino IDE. It adds a menu item to Tools menu for uploading the contents of sketch data directory into ESP8266 flash file system.
  • Download the tool: https://github.com/esp8266/arduino-esp8266fs-plugin/releases/download/0.2.0/ESP8266FS-0.2.0.zip.
  • In your Arduino sketchbook directory, create tools directory if it doesn't exist yet
  • Unpack the tool into tools directory (the path will look like <home_dir>/Arduino/tools/ESP8266FS/tool/esp8266fs.jar)
  • Restart Arduino IDE
  • Open a sketch (or create a new one and save it)
  • Go to sketch directory (choose Sketch > Show Sketch Folder)
  • Create a directory named data and any files you want in the file system there
  • Make sure you have selected a board, port, and closed Serial Monitor
  • Select Tools > ESP8266 Sketch Data Upload. This should start uploading the files into ESP8266 flash file system. When done, IDE status bar will display SPIFFS Image Uploaded message.
ref: https://esp8266.github.io/Arduino/versions/2.1.0/doc/filesystem.html

This video show how to:


Example to read text file, test.txt, from Flash File System:

ESP_ext_file.ino
//arduino-er.blogspot.com
//To read separate file in file system
#include "FS.h"

void prepareFile(){
  
  Serial.println("Prepare file system");
  SPIFFS.begin();
  
  File file = SPIFFS.open("/test.txt", "r");
  if (!file) {
    Serial.println("file open failed!");  
  } else{
    Serial.println("file open success:)");

    while (file.available()) {
      Serial.write(file.read());
    }
    file.close();
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("To read separate file in file system");
  prepareFile();
}

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

}


Saturday, May 7, 2016

NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED


In the previous example "NodeMCU/ESP8266 act as AP (Access Point) and web server to control GPIO", every time user click to change GPIO the page will be reloaded. This example use WebSocket, such that no need reload page.


Add WebSockets library to Arduino Software. To run on ESP devices, add version 2.x.x.
reference: https://github.com/Links2004/arduinoWebSockets


Open WebSockets example WebSocketServer_LEDcontrol. It's a WebSocketServer example to control RGB LED.


In my case, it cannot connect to my HotSpot shared by ASUS Zenfone 2 running Android 5.0! So I modify it to act as Access Point (AP).

WebSocketServer_LEDcontrol.ino
/*
 * WebSocketServer_LEDcontrol.ino
 *
 *  Created on: 26.11.2015
 *
 */
//Modified to act as AP
//arduino-er.blogspot.com

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>

#define LED_RED     15
#define LED_GREEN   12
#define LED_BLUE    13

#define USE_SERIAL Serial


ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server = ESP8266WebServer(80);
WebSocketsServer webSocket = WebSocketsServer(81);

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {

    switch(type) {
        case WStype_DISCONNECTED:
            USE_SERIAL.printf("[%u] Disconnected!\n", num);
            break;
        case WStype_CONNECTED: {
            IPAddress ip = webSocket.remoteIP(num);
            USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);

            // send message to client
            webSocket.sendTXT(num, "Connected");
        }
            break;
        case WStype_TEXT:
            USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);

            if(payload[0] == '#') {
                // we get RGB data

                // decode rgb data
                uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);

                analogWrite(LED_RED,    ((rgb >> 16) & 0xFF));
                analogWrite(LED_GREEN,  ((rgb >> 8) & 0xFF));
                analogWrite(LED_BLUE,   ((rgb >> 0) & 0xFF));
            }

            break;
    }

}

void setup() {
    //USE_SERIAL.begin(921600);
    USE_SERIAL.begin(115200);

    //USE_SERIAL.setDebugOutput(true);

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    pinMode(LED_RED, OUTPUT);
    pinMode(LED_GREEN, OUTPUT);
    pinMode(LED_BLUE, OUTPUT);

    digitalWrite(LED_RED, 1);
    digitalWrite(LED_GREEN, 1);
    digitalWrite(LED_BLUE, 1);

    /*
    WiFiMulti.addAP("SSID", "passpasspass");

    while(WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
    }
    */

    WiFi.softAP("arduino-er", "12345678");
    IPAddress myIP = WiFi.softAPIP();
    USE_SERIAL.print("AP IP address: ");
    USE_SERIAL.println(myIP);

    // start webSocket server
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);

    if(MDNS.begin("esp8266")) {
        USE_SERIAL.println("MDNS responder started");
    }

    // handle index
    server.on("/", []() {
        // send index.html
        // replace for better looking
        server.send(200, "text/html", 
        "<html><head><script>"
        "var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);"
        "connection.onopen = function () {  connection.send('Connect ' + new Date()); };"
        "connection.onerror = function (error) {    console.log('WebSocket Error ', error);};"
        "connection.onmessage = function (e) {  console.log('Server: ', e.data);};"
        "function sendRGB() {  "
        "var r = parseInt(document.getElementById('r').value).toString(16);  "
        "var g = parseInt(document.getElementById('g').value).toString(16);  "
        "var b = parseInt(document.getElementById('b').value).toString(16);  "
        "if(r.length < 2) { r = '0' + r; }   "
        "if(g.length < 2) { g = '0' + g; }   "
        "if(b.length < 2) { b = '0' + b; }   "
        "var rgb = '#'+r+g+b;    "
        "console.log('RGB: ' + rgb); "
        "connection.send(rgb); }"
        "</script></head><body>"
        "LED Control:<br/><br/>"
        "R: ""<input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" onchange=\"sendRGB();\" /><br/>"
        "G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" onchange=\"sendRGB();\" /><br/>"
        "B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" onchange=\"sendRGB();\" /><br/>"
        "</body></html>");
    });

    server.begin();

    // Add service to MDNS
    MDNS.addService("http", "tcp", 80);
    MDNS.addService("ws", "tcp", 81);

    digitalWrite(LED_RED, 0);
    digitalWrite(LED_GREEN, 0);
    digitalWrite(LED_BLUE, 0);

}

void loop() {
    webSocket.loop();
    server.handleClient();
}


Connection:


Connect your mobile to the AP "arduino-er" with password "12345678", open browser and visit IP 192.168.4.1. Then you can control the RGB LED in web page. As shown in the video, more than one device can connect to and control the RGB LED at the same time.

This example hard-code the html inside ino. The next example show how to "load html from separate file in flash file system".

- more example of "ESP8266 core for Arduino".



Updated@2017-06-18:
What is WStype_t (WStype_DISCONNECTED, WStype_CONNECTED...)?

WStype_t is:
typedef enum {
    WStype_ERROR,
    WStype_DISCONNECTED,
    WStype_CONNECTED,
    WStype_TEXT,
    WStype_BIN
} WStype_t;

Should be defined at your Documents\Arduino\libraries\WebSockets\src\WebSockets.h

You should have a example at File > Examples > WebSockets > WebSocketClient to show how to use it.


Tuesday, May 3, 2016

NodeMCU/ESP8266 act as AP (Access Point) and web server to control GPIO

Further works on previous exercise "NodeMCU/ESP8266 act as AP (Access Point) and simplest Web Server"; this example of NodeMCU/ESP8266 act as AP and implement a web server to control GPIO (on-board LED) using HTML interface.


ESP_AP_WebServer.ino
/*
 * NodeMCU/ESP8266 act as AP (Access Point) and simplest Web Server
 * to control GPIO (on-board LED)
 * Connect to AP "arduino-er", password = "password"
 * Open browser, visit 192.168.4.1
 */
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <ESP8266WebServer.h>

const char *ssid = "arduino-er";
const char *password = "password";
int stateLED = LOW;

ESP8266WebServer server(80);

void handleRoot() {
    response();
}

void handleLedOn() {
  stateLED = LOW;
  digitalWrite(LED_BUILTIN, stateLED);
  response();
}

void handleLedOff() {
  stateLED = HIGH;
  digitalWrite(LED_BUILTIN, stateLED);
  response();
}

const String HtmlHtml = "<html><head>"
    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /></head>";
const String HtmlHtmlClose = "</html>";
const String HtmlTitle = "<h1>Arduino-er: ESP8266 AP WebServer exercise</h1><br/>\n";
const String HtmlLedStateLow = "<big>LED is now <b>ON</b></big><br/>\n";
const String HtmlLedStateHigh = "<big>LED is now <b>OFF</b></big><br/>\n";
const String HtmlButtons = 
    "<a href=\"LEDOn\"><button style=\"display: block; width: 100%;\">ON</button></a><br/>"
    "<a href=\"LEDOff\"><button style=\"display: block; width: 100%;\">OFF</button></a><br/>";

void response(){
  String htmlRes = HtmlHtml + HtmlTitle;
  if(stateLED == LOW){
    htmlRes += HtmlLedStateLow;
  }else{
    htmlRes += HtmlLedStateHigh;
  }

  htmlRes += HtmlButtons;
  htmlRes += HtmlHtmlClose;

  server.send(200, "text/html", htmlRes);
}

void setup() {
    delay(1000);
    Serial.begin(9600);
    Serial.println();

    WiFi.softAP(ssid, password);

    IPAddress apip = WiFi.softAPIP();
    Serial.print("visit: \n");
    Serial.println(apip);
    server.on("/", handleRoot);
    server.on("/LEDOn", handleLedOn);
    server.on("/LEDOff", handleLedOff);
    server.begin();
    Serial.println("HTTP server beginned");
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, stateLED);
}

void loop() {
    server.handleClient();
}


Next:
NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED


- more example of "ESP8266 core for Arduino".

Monday, May 2, 2016

NodeMCU/ESP8266 act as AP (Access Point) and simplest Web Server


NodeMCU/ESP8266 example act as AP (Access Point) and simplest Web Server:


ESP_AP_WebServer.ino
/*
 * NodeMCU/ESP8266 act as AP (Access Point) and simplest Web Server
 * Connect to AP "arduino-er", password = "password"
 * Open browser, visit 192.168.4.1
 */
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <ESP8266WebServer.h>

const char *ssid = "arduino-er";
const char *password = "password";

ESP8266WebServer server(80);

void handleRoot() {
    server.send(200, "text/html", "<h1>Hello! from arduino-er!</h1>");
}

char* htmlBody_help = "<h1>Help</h1><br/>\n"
  "Visit http://192.168.4.1/ to access web server.<br/>\n"
  "Visit http://192.168.4.1/help to access this page.<br/>\n";

void handleHelp(){
  server.send(200, "text/html", htmlBody_help);
}

void setup() {
    delay(1000);
    Serial.begin(9600);
    Serial.println();

    WiFi.softAP(ssid, password);

    IPAddress apip = WiFi.softAPIP();
    Serial.print("visit: \n");
    Serial.println(apip);
    server.on("/", handleRoot);
    server.on("/help", handleHelp);
    server.begin();
    Serial.println("HTTP server beginned");
}

void loop() {
    server.handleClient();
}

Next:
NodeMCU/ESP8266 act as AP (Access Point) and web server to control GPIO

- more example of "ESP8266 core for Arduino".

Sunday, April 24, 2016

NodeMCU/ESP8266: get ESP chip and flash info

Simple sketch run on NodeMCU/ESP8266 to get chip and flash info.

ESP_GetFlashSize.ino
//reference: 
//http://esp8266.github.io/Arduino/versions/2.1.0/doc/libraries.html

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

  Serial.println("http://arduino-er.blogspot.com/");
  Serial.println("ESP chip and flash info");
  Serial.printf("The ESP8266 chip ID as a 32-bit integer:\t%08X\n", ESP.getChipId());
  Serial.printf("The flash chip ID as a 32-bit integer:\t\t%08X\n", ESP.getFlashChipId());
  Serial.printf("Flash chip frequency:\t\t\t\t%d (Hz)\n", ESP.getFlashChipSpeed());

  /* ESP.getFlashChipSize() returns the flash chip size, in bytes, 
   * as seen by the SDK (may be less than actual size).
   */
  Serial.printf("Flash chip size:\t\t\t\t%d (bytes)\n", ESP.getFlashChipSize());

  Serial.printf("Free heap size:\t\t\t\t\t%d (bytes)\n", ESP.getFreeHeap());

  
}

void loop() {
  

}

Tested on NodeMCU 1.0:


Tuesday, April 19, 2016

NodeMCU (ESP8266) call function repeatedly in fixed interval, with Ticker.

Ticker is a library of ESP8266 Arduino Core for calling functions repeatedly with a certain period.

It is currently not recommended to do blocking IO operations (network, serial, file) from Ticker callback functions. Instead, set a flag inside the ticker callback and check for that flag inside the loop function.



NodeMCU/ESP8266 example to toggle built-in LED in 0.5 second, using Ticker.
#include <Ticker.h>

Ticker ticker;

boolean ticker_reached;
boolean LED_state;

void ticker_handler(){
  ticker_reached = true;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  
  ticker_reached = false;
  LED_state = HIGH;

  //call ticker_handler() in 0.5 second
  ticker.attach(0.5, ticker_handler);
  
}

void loop() {

  if(ticker_reached){
    ticker_reached = false;
    digitalWrite(LED_BUILTIN, LED_state);
    LED_state = !LED_state;
  }

}


esp8266-OLED, esp8266-Arduino library for I2C-OLED displays


esp8266-OLED is an esp8266-Arduino library for I2C-OLED displays. This post show how to download and install to Arduino IDE, and test with example.

- It's assumed you are programming NodeMCU on Arduino Software, with ESP8266 core for Arduino installed.

- Connect I2C OLED to NodeMCU.


OLED VCC - NodeMCU 3v3
OLED GND - NodeMCU GND
OLED SCL - NodeMCU D1
OLED SDA - NodeMCU D2

(reamrk: the Fritzing parts of can OLED_SSD1306_I2C_128x64 can be download HERE)


- Add esp8266-OLED library to Arduino Software:
visit https://github.com/klarsys/esp8266-OLED, follow the steps to install the library:
  • Click on the Download ZIP button in the top right corner.
  • Uncompress it.
  • Rename the uncompressed folder to OLED.
  • Check that the OLED folder contains OLED.cpp and OLED.h files.
  • Place the OLED folder in your <arduinosketchfolder>/libraries/ folder - you may need to create the libraries subfolder if it is your first library.
  • Restart the IDE.

Open the example,
File > Examples > ESP8266-OLED Display Library > example

In order to match with our connection, we have to modify it to correct SDA and SCL pins:
change the code:
OLED display(2, 14);

to
OLED display(4, 5);

where 4, 5 correspond to NodeMCU D2 and D1. Refer to the "The pin definition" in NodeMCU - ESP8266/CP2102.

// Example sketch for testing OLED display

// We need to include Wire.h for I2C communication
#include <Wire.h>
#include "OLED.h"

// Declare OLED display
// display(SDA, SCL);
// SDA and SCL are the GPIO pins of ESP8266 that are connected to respective pins of display.
OLED display(4, 5);

void setup() {
  Serial.begin(9600);
  Serial.println("OLED test!");

  // Initialize display
  display.begin();

  // Test message
  display.print("Hello World");
  delay(3*1000);

  // Test long message
  display.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
  delay(3*1000);

  // Test display clear
  display.clear();
  delay(3*1000);

  // Test message postioning
  display.print("TOP-LEFT");
  display.print("4th row", 4);
  display.print("RIGHT-BOTTOM", 7, 4);
  delay(3*1000);

  // Test display OFF
  display.off();
  display.print("3rd row", 3, 8);
  delay(3*1000);

  // Test display ON
  display.on();
  delay(3*1000);
}

int r = 0, c = 0;

void loop() {
  r = r % 8;
  c = micros() % 6;

  if (r == 0)
    display.clear();

  display.print("Hello World", r++, c++);

  delay(500);
}

Result:




Related:
- Another library of I2C OLED for ESP8266 core for Arduino - Adafruit SSD1306 library
- esp8266-oled-ssd1306 library

Monday, April 18, 2016

Hello World NodeMCU (ESP8266) + 128x64 I2C OLED, using Adafruit SSD1306 library

Minimum "Hello World" run on NodeMCU (ESP8266) + 128x64 I2C OLED:


To setup libraries for 128x64 I2C OLED, refer last post "NodeMCU (ESP8266) to display on 128x64 I2C OLED".

NodeMCU_OLED_helloworld.ino
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET LED_BUILTIN  //4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  // Clear the buffer.
  display.clearDisplay();
  display.display();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello from:");
  display.println("http://arduino-er.blogspot.com/");
  display.display();

}

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

}

Sunday, April 17, 2016

NodeMCU (ESP8266) to display on 128x64 I2C OLED, using Adafruit SSD1306 library




This post show how to program NodeMCU (ESP8266) on Arduino IDE (with ESP8266 core for Arduino), to display on  0.96 inch 128X64 I2C OLED (base on SSD1306), using Adafruit SSD1306 and Adafruit GFX Libraries.

- It's assumed you are programming NodeMCU on Arduino Software, with ESP8266 core for Arduino installed.

- Connect I2C OLED to NodeMCU.


OLED VCC - NodeMCU 3v3
OLED GND - NodeMCU GND
OLED SCL - NodeMCU D1
OLED SDA - NodeMCU D2

(reamrk: the Fritzing parts of can OLED_SSD1306_I2C_128x64 can be download HERE)


- Add OLED library to Arduino Software:
* Open Library Manager in Arduino IDE, search SSD1306. You can find Adafruit SSD1306 library, SSD1306 OLED driver library for 'monochrome' 128x64 and 128x32 OLEDs. Install it.
* Install Adafruit GFX Library also.

- Open SSD1306 example:
File > Examples > Adafruit SSD1306 > ssd1306_128x64_i2c.

If you get error of "Height incorrect, please fix Adafruit_SSD1306.h!":
Open Adafruit_SSD1306.h file, in the path like "C:\Users\user\Documents\Arduino\libraries\Adafruit_SSD1306\Adafruit_SSD1306.h". Un-comment "#define SSD1306_128_64", and comment "#define SSD1306_128_32".


- Return to the Adafruit SSD1306 library again. Visit the web site of the library, https://github.com/adafruit/Adafruit_SSD1306. It's Tested Works on ESP8266 (Adafruit Huzzah), but have to change OLED_RESET to different pin if using default I2C pins D4/D5.

There are no RESET signal on my I2C OLED, so I assign it to any pin, LED_BUILTIN (the on-board LED).


- Make sure the I2C address is correct:
My I2C OLED have address 3C, correct the code display.begin(SSD1306_SWITCHCAPVCC, 0x3C);


- Finished.


more:
- Hello World NodeMCU (ESP8266) + 128x64 I2C OLED


Related:
- Another library of I2C OLED for ESP8266 core for Arduino - esp8266-OLED
esp8266-oled-ssd1306 library

Monday, April 4, 2016

NodeMCU act as WiFi client to update dweet.io



dweet.io is simple publishing and subscribing for machines, sensors, devices, robots, and gadgets (we just call them things). We call published messages ‘dweets’. It’s helpful to think of dweet.io as a Twitter for things, in fact.

I have a old example to show how to "Arduino Uno + Ethernet Shield send data to dweet.io and freeboard.io". It's a NodeMCU (with ESP8266 core for Arduino) version to update dweet.io.

You can visit following link on web browser to update dweet.io manually to test your url:
www.dweet.io/dweet/for/test_NodeMCU?A0=123

And check your thing at:
http://dweet.io/follow/test_NodeMCU

where testNodeMCU is the id of your thing in dweet.io, 123 is the value to update.

This code run on NodeMCU (suppose other standalone ESP8266 also), to connect to WiFi as client, read analog input from A0, and update dweet.io. (It's modified from Examples > ESP8266WiFi > WiFiClient,)


Connect analog input to A0, connection refer to last post "NodeMCU to read analog input, A0".

NodeMCU_WiFiClient_dweetio.ino
/*
 * reference: Examples > ESP8266WiFi > WiFiClient 
 */

#include <ESP8266WiFi.h>
const int AnalogIn  = A0;

const char* ssid     = "myssid";
const char* password = "password";

const char* host = "www.dweet.io";
const char* thing  = "test_NodeMCU";
const char* thing_content = "A0";

void setup() {
  Serial.begin(115200);
  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {
  delay(1000);
  value = analogRead(AnalogIn);

  Serial.print("connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
  
  // We now create a URI for the request
  String url = "/dweet/for/";
  url += thing;
  url += "?";
  url += thing_content;
  url += "=";
  url += value;
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  int timeout = millis() + 5000;
  while (client.available() == 0) {
    if (timeout - millis() < 0) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }
  
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  
  Serial.println();
  Serial.println("closing connection");
}


NodeMCU to read analog input, A0.


Last post introduced "Serial Plotter in Arduino IDE" with Arduino Uno example to read analog input and println to Serial Port, to display on Arduino Software's Serial Plotter. The example can direct re-compile and run target NodeMCU/ESP8266.



remark: Fritzing part of NodeMCU can be found HERE.

Example code, same as in last post.
const int AnalogIn  = A0;

int readingIn = 0;

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

void loop() {
  readingIn = analogRead(AnalogIn);
  Serial.println(readingIn);
}


Wednesday, March 30, 2016

Run diagnosis of NodeMCU/ESP8266


To run diagnosis of NodeMCU/ESP8266, we can call the function WiFi.printDiag(Serial), pass with Serial port as the parameter, it will send the diagnostic info to Serial port.

remark: this apply on NodeMCU (suppose on other standalone ESP8266 also) with ESP8266 core for Arduino.

Example:
#include <ESP8266WiFi.h>

const char* ssid = "arduino-er";
const char* password = "12345678";
byte mac[6];

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

  Serial.print("\nRun diagnostic...\n");
  WiFi.printDiag(Serial);
  Serial.println();
  
  Serial.print("\nStart...\n");
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  Serial.print(mac[0],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.println(mac[5],HEX);
  Serial.println();

  WiFi.begin(ssid, password);
  Serial.print("Connecting WIFI ");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("connected");  
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

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

}

sample output:

Thursday, March 24, 2016

NodeMCU exercise: get my IP address

NodeMCU (ESP8266) + ESP8266 core for Arduino example to get my IP address after connected to WiFi.


#include <ESP8266WiFi.h>

const char* ssid = "your WiFi ssid";
const char* password = "xxxxxxxx";
byte mac[6];

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

  Serial.print("\nStart...\n");
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  Serial.print(mac[0],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.println(mac[5],HEX);
  Serial.println();
  
  WiFi.begin(ssid, password);
  Serial.print("Connecting WIFI ");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("connected");  
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

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

}

Tuesday, March 22, 2016

Read NodeMCU MAC address using Arduino IDE with esp8266 library

With esp8266 board installed to Arduino IDE, we can program NodeMCU using Arduino IDE directly.

Here is a example to read the MAC address of NodeMCU. Because we are going to read MAC only, so no need to begin WiFi and connect to any network actually.

NodeMCU_getMAC.ino
#include <ESP8266WiFi.h>

//const char* ssid = "ssid";
//const char* password = "password";
byte mac[6];

void setup() {
  Serial.begin(9600);
  //WiFi.begin(ssid, password);

  Serial.print("\nStart...\n");
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  Serial.print(mac[0],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.println(mac[5],HEX);
}

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

}


Next:
- Get my IP address

Sunday, March 20, 2016

Blink NodeMCU on-board LED using Arduino IDE with ESP8266 core for Arduino, and more examples


To program NodeMCU in Arduino IDE, we have to install esp8266 board (ESP8266 core for Arduino) to Arduino IDE.

Add Additional Board Manager URL for ESP8266 board:
> File > Preference

Add "http://arduino.esp8266.com/stable/package_esp8266com_index.json" in Additional Board Manager URLs.


Add ESP8266 board to Arduino IDE:
- Open Boards Manager in Arduino IDE
- Search "esp8266" or "NodeMCU", you will find "esp8266 by ESP8266 Community". Install it.


Test:
Once esp8266 board installed, you can find an example to blink the on-board LED.
File > Examples > ESP8266 > Blink

/*
 ESP8266 Blink by Simon Peter
 Blink the blue LED on the ESP-01 module
 This example code is in the public domain
 
 The blue LED on the ESP-01 module is connected to GPIO1 
 (which is also the TXD pin; so we cannot use Serial.print() at the same time)
 
 Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
*/

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// 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 acive low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}

You can upload it to NodeMCU, to toggle the on-board LED.


notice:
- Once the ModeMCU programmed, the original firmware will be erased. To restore the original firmware with Lua shell, you have to flash the firmware again.

Control GPIO (external IO pins) of NodeMCU (ESP8266) with ESP8266 core for Arduino

Next:
Read NodeMCU MAC address using Arduino IDE with esp8266 library
Get my IP address
Run diagnosis
NodeMCU to read analog input, A0
NodeMCU act as WiFi client to update dweet.io
Display on 128x64 I2C OLED, using Adafruit SSD1306 and GFX libraries
esp8266-OLED, another esp8266-Arduino library for I2C-OLED displays
NodeMCU/ESP8266 act as AP (Access Point) and simplest Web Server
NodeMCU/ESP8266 act as AP (Access Point) and web server to control GPIO
NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED
NodeMCU/ESP8266 WebSocketsServer, load html from separate file in flash file system
Read Buttons and write LEDs
NodeMCU/ESP8266 Arduino Core analog output PWM
Simple http server to output PWM, to set color/brightness of RGB LED
Install Arduino IDE on Raspberry Pi/Raspbian Jessie with PIXEL and Add Arduino core for ESP8266 to Arduino IDE (run on Raspberry Pi/Raspbian Jessie with PIXEL)

Saturday, March 19, 2016

Test NodeMCU onboard LED in Lua shell

Once flashed update firmware to NodeMCU, we can test the onboard LED in Lua shell.


- Connect NodeMCU and run PuTTY to enter its Lua shell.
- Enter this code (in red) to test the onboard LED:

NodeMCU 0.9.6 build 20150704  powered by Lua 5.1.4
lua: cannot open init.lua
> gpio.mode(0, gpio.OUTPUT)
> gpio.write(0, gpio.HIGH)
> print(gpio.read(0))
1
> gpio.write(0, gpio.LOW)
> print(gpio.read(0))
0
>



This video show how to: