GithubHelp home page GithubHelp logo

esp8266's Introduction

ESP8266 Library and Demo

Author: Steven Sokol [email protected]

Created: November 6, 2014

Table of Contents

  1. Overview
  2. Usage
  3. Reference a. Enumerated Values b. Constructor c. initializeWifi() d. connectWifi() e. startServer() f. startClient() g. enableBeacon() h. send() i. run() j. ip()
  4. Limitations
  5. License

Overview

The project consists of the ESP8266 library and a sample application that demonstrates the use of the library to create a generic serial <=> wifi bridge.

The library handles the configuration of the connection between the module and an access point. It begins by checking for and initializing the module with a reset. If the reset succeeds, the module can then be connected to an access point. Once the connection is established, the module starts a TCP server.

The library can inform the application when a client connection occurs using a callback. Data that arrives from a connected client is also delivered to the application via a callback.

The library supports a primitive sort of discovery for situations where the module's IP address is unknown: it can broadcast a JSON-formatted UDP "beacon" containing the IP address assigned by DHCP, the port on which the server is listening and an arbitrary device identifier. By default the beacon is sent out on port 34807.

Usage

The library assumes that the ESP8266 is connected to the hardware Serial pins (or, in the case of a Mega, UART0).

WARNING: If you are using the library to go "serial-to-serial" on an Arduino with only a single hardware serial port, do NOT use the default SoftwareSerial library or NewSoftSerial. Both result in maddening timing issues. Instead, use AltSoftSerial which can be found here.

To use the library, simply add a reference to the header file and create a single ESP8266 object passing in the connection mode and the baudrate for the connection to the module:

#include "ESP8266.h"

ESP8266 wifi(WIFI_MODE_STATION, 38400);

Next, initialize the library, passing in callbacks for data and connection events:

void dataCallback(char *data) {
	// do something with the data
}

void connectCallback() {
	// do something in response to the connection
}

int ret = wifi.initializeWifi(&dataCallback, &connectCallback);
if (ret != WIFI_ERR_NONE) {
	// your module was either not found or is using a different baud rate
}

If that worked out (you received WIFI_ERR_NONE) then start the connection by passing in the SSID and password:

int ret = wifi.connectWifi("myssid", "mypassword");
if (ret != WIFI_ERR_NONE) {
	// connection failed for some reason. could be that the ssid or password are
	// incorrect. could be out of range. could be hardware issues (you only paid $5)
}

If the module connects, you're ready to start a server. The server will listen on the assigned port for connections. If you're using the module purely as a client, you can skip over this.

int myPort = 80;
long myTimeout = 25000;
bool ret = wifi.startServer(myPort, timeout);

If the function returns true, you should be able to create a TCP connection on the assigned port. When you do, your connectCallback() should be called, letting your app know that it has a connection. When data arrives, it will result in a callback to your dataCallback() function. To send data to connected client, use the send() method.

Sending data is easy (as long as you're sending text - this library does not support binary data transfer at this point). You can send data when connected in either client or server mode.

wifi.send("hello world!");

Because the module gets its IP from DHCP, it can be difficult to use it for server applications. To work around this, the library provides a very primitive discovery and autoconfiguration method: it broadcasts UDP datagrams with a JSON-encoded blob of text that tells you the IP address, port and device name. The beacon fires every 10 seconds when no client is connected, and every 30 seconds after a connection has been made.

wifi.enableBeacon("MyWackyDevice");

That's all there is to it. The call will return false if you don't have a server running.

Client mode allows you to establish a TCP connection to a remote server. Once connected, you can send data to the server using the send() method. Data sent to you will arrive on the data callback established when you initialized the library.

if (wifi.connectServer("10.0.8.22", 80)) {
	wifi.send("hello, world!");
}

IMPORTANT: Your app must call the 'run()' function in your loop or the library won't work!!!

Finally, your app must call the 'run()' function in the library. This allows the library to process messages on the module.

loop() {
	// run all wifi stuff
	wifi.run();
	
	// now do your stuff...
}

Reference

Enumerated Values

Here are some enumerations from the library and what the various values mean:

Wifi Mode Values

  • WIFI_MODE_STA = 1 - station mode
  • WIFI_MODE_AP = 2 - access point mode
  • WIFI_MODE_APSTA = 3 - dual station / access point mode (untested)

Wifi Error Values

  • WIFI_ERR_NONE = 0 - no error returned
  • WIFI_ERR_AT = 1 - no response to 'AT' command (module connected?)
  • WIFI_ERR_RESET = 2 - reset failed (adequate power supply?)
  • WIFI_ERR_CONNECT = 3 - access point associate failed (bad ssid or password?)
  • WIFI_ERR_LINK = 4 - error enabling multi-link mode

ESP826 (constructor)

Arguments:

  • Wireless mode
    • optional
    • WIFI_MODE_STA, WIFI_MODE_AP, WIFI_MODE_APSTA
    • defaults to STA
  • baud rate
    • optional
    • any baud rate supported by the module + your Arduino
    • defaults to 9600
    • does NOT change the modules baud rate (see setBaudRate for that)
  • debug level
    • optional
    • defaults to 0 (off)
    • valid values 0 - 2
    • causes debug data to be called back to your app through the dataCallback set in the constructor (could probably be done more legantly with a dedicated debug callback)

Returns:

void (nothing)

Example:

ESP8266 myWifi(WIFI_MODE_STA, 80, 115400);

initializeWifi()

Initialize the library and set callbacks.

Arguments:

  • data callback
    • address of a function to call when data arrives
    • must have a single char * parameter that receives the data
    • must return nothing
  • connect callback
    • address of a function to call when a connection occurs
    • must have no parameters
    • must return nothing

Returns:

An integer value that maps to the wifi errors enumeration above.

Example:

int ret = myWifi.initializeWifi(&myDataCallback, &myConnectionCallback);

connectWifi()

Connect to an access point.

Arguments:

  • ssid
    • char * or string literal
    • name of the access point with which to associate
  • password
    • char * or string literal
    • password value
    • use empty string "" for unsecured networks

Returns:

An integer value that maps to the wifi error enumeration above.

Example:

int ret = myWifi.connectWifi("accesspoint", "password");

startServer()

Create a TCP server to which clients may connect.

Arguments:

  • port
    • integer port number (1 - 65534) on which to listen
    • defaults to 8000
  • timeout
    • time in seconds after which inactive clients are disconnected
    • minimum useful value appear to be ~10 seconds
    • defaults to 300 (5 minutes)

Returns:

Boolean. True = success. False = failure.

Example:

bool ret = myWifi.startServer(80, 500)

startClient()

Create a client TCP connection to a remote server.

Arguments:

  • ip
    • ip address to which the client should connect
  • port
    • integer port number (1 - 65534) on which to connect
  • timeout
    • time in seconds to wait for the connection to succeed

Returns:

Boolean. True = success. False = failure.

Example:

bool ret = myWifi.startServer(80, 500)

enableBeacon()

Enable the UDP beacon which posts a JSON datagram to the broadcast address (see limitations below for caveats) every 10 seconds. JSON datagrams include the IP address and port of the server and the device name provided when the beacon is enabled.

NOTE: the beacon is currently hard-coded to use UDP port 34807. If you want/need to change this, you will need to edit the library code. At some point in the future I will update to make the beacon port configurable.

Beacon frequency is every 10 seconds when no server connections are active. Once a server connection occurrs, the frequency goes to ever 30 seconds.

The beacon makes the assumption that your broadcast address is the same as the IP the module received with the last octet set to 255. This sucks, but since there's no way to get the actual broadcast from the module, that's the best I could do. At some point it should probably be made configurable as well.

Arguments:

  • device
    • char * or string literal identifing the device
    • use something unique if you will have muliple devices on your network
    • see the sample app for an example of how this can be stored in EEPROM

Returns:

Boolean. True = success - beacon enabled. False = failure.

Example:

bool ret = myWifi.enableBeacon("MyWeatherStation");

// sample beacon packet:
{"event": "beacon", "ip": "10.0.1.85", "port": 80, "device": "foobar123"}

send()

Send character data from your application to device connected via the wifi module.

Arguments:

  • data
    • char * or string literal identifing the data to send

Returns:

Boolean. True = success - beacon enabled. False = failure.

Example:

boot ret = myWifi.send("{timestamp: '3:14:18 9-NOV-2014', temperature: '14'}");

run()

Causes the library to process incoming messages. This must be called from the loop() function of your application. If you don't you'll never receive any incoming data.

Arguments:

  • none

Returns:

nothing

Example:

loop() {
	wifi.run();
}

ip()

Returns the current IP address. Only valid after connection is established.

Arguments:

  • none

Returns:

char * referencing a buffer containing the IP address.

Example:

// print the IP address 
Serial2.println(wifi.ip());

Limitations

The beacon feature presumes the broadcast address for the network consists of the initial three octets of the assigned IP address plus "255". This is obviously not going to work in cases where the network is not using that address for broadcast purposes.

No support for DNS. In client mode you can only use IPs, not addresses. (Anyone have a VERY tiny getHostByName we can toss in here?)

I'm not sure how the module deals with "glare" - incoming and outgoing data at the same time. Perhaps it internally locks / buffers when sending? I've been able to trip it up by sending from both the serial and wifi sides at the same time.

License

Copyright (c) 2014 Steven Sokol

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

esp8266's People

Contributors

ssokol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp8266's Issues

"Ready" detection

You must search "ready", not "Ready" at line 81 of ESP8266.cpp.

Ramón

i have problem with WiFiClientSecure :(

hi
i am thanks for your help to peaple for publishin your good project
in this code i want give data from google Sheet and send data in telegram bot,
i use this project to give data from google sheet:
https://github.com/lorol/Googlesheet_DHT_simple
and use this project for recive and send data from telegram robat:
https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
i use esp8266
i merge two above project but i cant compile because i give error , because two project use WiFiClientSecure.h library , and same client :(

i changed the client name , and code ha been compiled, but in serial monitor , program crashed
i changed "HTTPSRedirect* client= nullptr;" to "HTTPSRedirect* test= nullptr;" and change every client in the code to test,
i also change below code, in the next change

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

to :

WiFiClientSecure test;
UniversalTelegramBot bot(BOTtoken, test);

and you can see my Serial monitor in both time:

Starting ...
Connecting to hooshmandsazan3
.

WiFi connected

Exception (29):
epc1=0x4000e1cc epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000204 depc=0x00000000

ctx: cont 
sp: 3fff0fd0 end: 3fff18e0 offset: 01a0

>>>stack>>>
3fff1170:  00410000 3fffb59c 3fffb75c 40224e3f  
3fff1180:  3fffb63c 3fffb87c 00000081 40225aa1  

i add Serial.println() in the code for debugging
this is my code:

#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include "HTTPSRedirect.h"




//======================From Telegram===============================
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

#define BOTtoken "339475786:AAH7IjXu51xPom_sMx8IRnvQbcTD5FfO2Wc"  // your Bot Token (Get from Botfather)
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

int Bot_mtbs = 1000; //mean time between scan messages
long Bot_lasttime;   //last time messages' scan has been done
bool Start = false;

const int ledPin = 2;
int ledStatus = 0;

void handleNewMessages(int numNewMessages) {
  //Serial.println(F("handleNewMessages"));
  //Serial.println(String(numNewMessages));

  for (int i=0; i<numNewMessages; i++) {
    String chat_id = String(bot.messages[i].chat_id);
    String text = bot.messages[i].text;

    String from_name = bot.messages[i].from_name;
    if (from_name == "") from_name = "Guest";

    if (text == "/ledon") {
      digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
      ledStatus = 1;
      bot.sendMessage(chat_id, "Led is ON", "");
    }

    if (text == "/ledoff") {
      ledStatus = 0;
      digitalWrite(ledPin, LOW);    // turn the LED off (LOW is the voltage level)
      bot.sendMessage(chat_id, "Led is OFF", "");
    }

    if (text == "/status") {
      if(ledStatus){
        bot.sendMessage(chat_id, "Led is ON", "");
      } else {
        bot.sendMessage(chat_id, "Led is OFF", "");
      }
    }

    if (text == "/start") {
      String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n";
      welcome += "This is Flash Led Bot example.\n\n";
      welcome += "/ledon : to switch the Led ON\n";
      welcome += "/ledoff : to switch the Led OFF\n";
      welcome += "/status : Returns current status of LED\n";
      bot.sendMessage(chat_id, welcome, "Markdown");
    }
  }
}
//***************************************************************************




#define WRITE_INTERVAL_MINITES 1

#define MAX_CONNECT 200 //reuse 2 times same clent
#define MAX_ERROR 100 //restart everything

const char *ssid =  "sajjad";
const char *pass =  "1q2w3e4r5t6y";

const char* host = "script.google.com";
const int httpsPort = 443;

int seconds = (WRITE_INTERVAL_MINITES * 60) - 20; // schedule first sending to TS in 20 sec after start

char *GScriptId = "AKfycbxRzkMt87iyiyU9EDY6REoRDpl5C9oHdjVyCSF6A4QN7jkNMGHD";   // Put your  GScriptId   here

// Access to Google Spreadsheet
String url = String("/macros/s/") + GScriptId + "/exec?";


HTTPSRedirect* test = nullptr;


float hum;
float tem;

void setup() {
  Serial.begin(115200);
  Serial.println();
  delay(200);
  Serial.println(F("Starting ..."));

  delay(200);
 
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  if (WiFi.status() != WL_CONNECTED) WiFi.begin(ssid, pass);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); 
    Serial.println(F("."));
  }
  Serial.println("");
  Serial.println("WiFi connected");
  pinMode(ledPin, OUTPUT); // initialize digital ledPin as an output.
  delay(10);
  digitalWrite(ledPin, LOW); // initialize pin as off
}

void loop() {
  Serial.println("1");
  
  //==============================From telegram=========================================
  if (millis() > Bot_lasttime + Bot_mtbs)  {
    Serial.println("2");
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    
    while(numNewMessages) {
      Serial.println("3");
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
    Serial.println("4");
    Bot_lasttime = millis();
  }
  //***********************************************************************
  Serial.println("5");
  static int error_count = 0;
  static int connect_count = 0;
  static bool flag = false;

  if (!flag){
    Serial.println("6");
    test = new HTTPSRedirect(httpsPort);
    flag = true;
    test->setPrintResponseBody(true); // or false and use String getResponseBody();
    Serial.println("6a");
    test->setContentTypeHeader("application/json");  
    Serial.println("6b");
    if (!test->connected()) test->connect(host, httpsPort);
    Serial.println("6c");
    ++connect_count;
    Serial.println("6d");
  }

   // 30 sec after writing 
  

    if (test != nullptr){
      Serial.println("7");
      if (!test->connected()){
        test->connect(host, httpsPort);
      }
    }
    else{
      Serial.println(F("Error2 creating client object!"));
      error_count = -10;
      Serial.println("7a");
    }
    Serial.println("7b");
    Serial.println(F("========================="));
    if (test->GET(url + String("readrow=last"), host)){
      Serial.println("8");
      DynamicJsonBuffer jsonBuffer;
      JsonObject& json = jsonBuffer.parseObject(test->getResponseBody());
      //json.printTo(Serial);
      String Timestamp = json["values"][0];
      int MaxT0        = json["values"][1];
      int minT0        = json["values"][2];
      String Con0      = json["values"][3];
      int Hu0          = json["values"][4];
      String WS0       = json["values"][5];
      String WD0       = json["values"][6];

      int MaxT1        = json["values"][7];
      int minT1        = json["values"][8];
      String Con1      = json["values"][9];
      int Hu1          = json["values"][10];
      String WS1       = json["values"][11];
      String WD1       = json["values"][12];

      int MaxT2        = json["values"][13];
      int minT2        = json["values"][14];
      String Con2      = json["values"][15];
      int Hu2          = json["values"][16];
      String WS2       = json["values"][17];
      String WD2       = json["values"][18];

      int MaxT3        = json["values"][19];
      int minT3        = json["values"][20];
      String Con3      = json["values"][21];
      int Hu3          = json["values"][22];
      String WS3       = json["values"][23];
      String WD3       = json["values"][24];
      
      float TEMP       = json["values"][25];
      float Hu         = json["values"][26];
      
      Serial.println(Timestamp);
      Serial.println(MaxT0);
      Serial.println(minT0);
      Serial.println(Con0);
      Serial.println(Hu0);
      Serial.println(WS0);
      Serial.println(WD0);

      Serial.println("");
      Serial.println(MaxT1);
      Serial.println(minT1);
      Serial.println(Con1);
      Serial.println(Hu1);
      Serial.println(WS1);
      Serial.println(WD1);

      Serial.println("");
      Serial.println(MaxT2);
      Serial.println(minT2);
      Serial.println(Con2);
      Serial.println(Hu2);
      Serial.println(WS2);
      Serial.println(WD2);

      Serial.println("");
      Serial.println(MaxT3);
      Serial.println(minT3);
      Serial.println(Con3);
      Serial.println(Hu3);
      Serial.println(WS3);
      Serial.println(WD3);

      Serial.println("");
      Serial.println(TEMP);
      Serial.println(Hu);      
      ++connect_count;
    } else {
      Serial.println("9");
      ++error_count;
      Serial.println(F("GET Last row val failed!"));
      seconds = 10; // stage again in 10 sec
    }


   if (error_count > MAX_ERROR){
    Serial.println("10");
     Serial.println(F("Errors > MAX_ERROR...")); 
     //delete client;
     //client = nullptr;
     //connect_count = -1;
     //error_count = 0;
     //flag = false;
     ESP.restart(); 
   }

   if (connect_count > MAX_CONNECT){
      Serial.println("11");
      Serial.println(F("Connects > MAX_CONNECT... rebuild"));
      connect_count = -1;
      flag = false;
      delete test;
     
      //return;  //where?
   }
   
   seconds++;
   delay(1000); //1 sec loop
}

when the code arive to "6b" program go to hang,
when arive to :
if (!test->connected()) test->connect(host, httpsPort);
this is my output:

Starting ...
Connecting to sajjad
.
.
.
.
.
.
.
.

WiFi connected
1
2
4
5
6
6a
6b

Exception (29):
epc1=0x4000dfd9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont 
sp: 3fff1000 end: 3fff1850 offset: 01a0

>>>stack>>>
3fff11a0:  3fff073c 000011c9 000011c9 4022ab8c  
3fff11b0:  3fff1584 00000012 00000003 00000000  

Hardware

Hardware: NodeMcu Lua WIFI Board Based on ESP8266 CP2102 Module (ESP-12E)

Description

Problem description

Settings in IDE

Module: Adafruit HUZZAH esp8266
Flash Size: 4MB(3MB SPIFFS)
CPU Frequency: 80Mhz
Upload Using: SERIAL 115200

please help me please :(

FW in ESP8266

Which version of AT commands firmware of ESP this code support?

busy when beacon event

Is that normal?

AT+RST

OK
L(����ZN�bZS����DLJK�l�
[Vendor:www.ai-thinker.com Version:0.9.2.4]

ready
Wifi initialized
AT+CWMODE=1
no change
AT+CWJAP="none","xxxxx"

OK

AT+CIPMUX=1

OK
Wifi connected
192.168.31.243
AT+CIPSERVER=1,80

OK

AT+CIPSTO=300

OK

AT+CIPSTART=2,"UDP","192.168.31.255",-30729

OK
AT+CIPSEND=2,82
> {"event": "beacon", "ip": "192.168.31.243",": "wifi-serial"}
busy s...

SEND OK
AT+CIPSEND=2,82
> {"event": "beacon", "ip": "192.168.31.243",": "wifi-serial"}
busy s...

SEND OK
AT+CIPSEND=2,82
> {"event": "beacon", "ip": "192.168.31.243",": "wifi-serial"}
busy s...

SEND OK

Method getIP() buffer overflow

The private method getIP() keeps writing into buf[ptr] even if ptr is > 15, so it goes out of the bounds of the array.

curios?

what is EEPROMAnything.h used for? and when i type passwrd in, it doesn't reconize the function

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.