227 lines
4.8 KiB
C++
227 lines
4.8 KiB
C++
#include "ESP8266.h"
|
|
|
|
ESP8266::ESP8266(Module* module) {
|
|
_mod = module;
|
|
}
|
|
|
|
int16_t ESP8266::begin(long speed) {
|
|
// set module properties
|
|
_mod->AtLineFeed = "\r\n";
|
|
_mod->baudrate = speed;
|
|
_mod->init(USE_UART, INT_NONE);
|
|
|
|
// empty UART buffer (garbage data)
|
|
_mod->ATemptyBuffer();
|
|
|
|
// test AT setup
|
|
if(!_mod->ATsendCommand("AT")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
int16_t ESP8266::reset() {
|
|
// send the reset command
|
|
if(!_mod->ATsendCommand("AT+RST")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// wait for the module to start
|
|
delay(2000);
|
|
|
|
// test AT setup
|
|
uint32_t start = millis();
|
|
while (millis() - start < 3000) {
|
|
if(!_mod->ATsendCommand("AT")) {
|
|
delay(100);
|
|
} else {
|
|
return(ERR_NONE);
|
|
}
|
|
}
|
|
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
int16_t ESP8266::join(const char* ssid, const char* password) {
|
|
// set mode to station + soft AP
|
|
if(!_mod->ATsendCommand("AT+CWMODE_CUR=3")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// reset the module
|
|
int16_t state = reset();
|
|
if(state != ERR_NONE) {
|
|
return(state);
|
|
}
|
|
|
|
// build AT command
|
|
const char* atStr = "AT+CWJAP_CUR=\"";
|
|
uint8_t cmdLen = strlen(atStr) + strlen(ssid) + strlen(password) + 4;
|
|
char* cmd = new char[cmdLen];
|
|
strcpy(cmd, atStr);
|
|
strcat(cmd, ssid);
|
|
strcat(cmd, "\",\"");
|
|
strcat(cmd, password);
|
|
strcat(cmd, "\"");
|
|
|
|
// send command
|
|
bool res = _mod->ATsendCommand(cmd);
|
|
delete[] cmd;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// disable multiple connection mode
|
|
if(!_mod->ATsendCommand("AT+CIPMUX=0")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
int16_t ESP8266::openTransportConnection(const char* host, const char* protocol, uint16_t port, uint16_t tcpKeepAlive) {
|
|
char portStr[6];
|
|
itoa(port, portStr, 10);
|
|
char tcpKeepAliveStr[6];
|
|
itoa(tcpKeepAlive, tcpKeepAliveStr, 10);
|
|
|
|
// build AT command
|
|
const char* atStr = "AT+CIPSTART=\"";
|
|
uint8_t cmdLen = strlen(atStr) + strlen(protocol) + strlen(host) + strlen(portStr) + 5;
|
|
if((strcmp(protocol, "TCP") == 0) && (tcpKeepAlive > 0)) {
|
|
cmdLen += strlen(tcpKeepAliveStr) + 1;
|
|
}
|
|
char* cmd = new char[cmdLen];
|
|
strcpy(cmd, atStr);
|
|
strcat(cmd, protocol);
|
|
strcat(cmd, "\",\"");
|
|
strcat(cmd, host);
|
|
strcat(cmd, "\",");
|
|
strcat(cmd, portStr);
|
|
if((strcmp(protocol, "TCP") == 0) && (tcpKeepAlive > 0)) {
|
|
strcat(cmd, ",");
|
|
strcat(cmd, tcpKeepAliveStr);
|
|
}
|
|
|
|
// send command
|
|
bool res = _mod->ATsendCommand(cmd);
|
|
delete[] cmd;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
int16_t ESP8266::closeTransportConnection() {
|
|
// send AT command
|
|
if(!_mod->ATsendCommand("AT+CIPCLOSE")) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
int16_t ESP8266::send(const char* data) {
|
|
// build AT command
|
|
char lenStr[8];
|
|
itoa(strlen(data), lenStr, 10);
|
|
const char* atStr = "AT+CIPSEND=";
|
|
char* cmd = new char[strlen(atStr) + strlen(lenStr)];
|
|
strcpy(cmd, atStr);
|
|
strcat(cmd, lenStr);
|
|
|
|
// send command
|
|
bool res = _mod->ATsendCommand(cmd);
|
|
delete[] cmd;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// send data
|
|
if(!_mod->ATsendCommand(data)) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
int16_t ESP8266::send(uint8_t* data, uint32_t len) {
|
|
// build AT command
|
|
char lenStr[8];
|
|
itoa(len, lenStr, 10);
|
|
const char atStr[] = "AT+CIPSEND=";
|
|
char* cmd = new char[strlen(atStr) + strlen(lenStr)];
|
|
strcpy(cmd, atStr);
|
|
strcat(cmd, lenStr);
|
|
|
|
// send command
|
|
bool res = _mod->ATsendCommand(cmd);
|
|
delete[] cmd;
|
|
if(!res) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
// send data
|
|
if(!_mod->ATsendData(data, len)) {
|
|
return(ERR_AT_FAILED);
|
|
}
|
|
|
|
return(ERR_NONE);
|
|
}
|
|
|
|
size_t ESP8266::receive(uint8_t* data, size_t len, uint32_t timeout) {
|
|
size_t i = 0;
|
|
uint32_t start = millis();
|
|
|
|
// wait until the required number of bytes is received or until timeout
|
|
while((millis() - start < timeout) && (i < len)) {
|
|
while(_mod->ModuleSerial->available() > 0) {
|
|
uint8_t b = _mod->ModuleSerial->read();
|
|
DEBUG_PRINT(b);
|
|
data[i] = b;
|
|
i++;
|
|
}
|
|
}
|
|
return(i);
|
|
}
|
|
|
|
uint16_t ESP8266::getNumBytes(uint32_t timeout, size_t minBytes) {
|
|
// wait for available data
|
|
uint32_t start = millis();
|
|
while(_mod->ModuleSerial->available() < minBytes) {
|
|
if(millis() - start >= timeout) {
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
// read response
|
|
char rawStr[20];
|
|
uint8_t i = 0;
|
|
start = millis();
|
|
while(_mod->ModuleSerial->available() > 0) {
|
|
char c = _mod->ModuleSerial->read();
|
|
rawStr[i++] = c;
|
|
if(c == ':') {
|
|
rawStr[i++] = 0;
|
|
break;
|
|
}
|
|
if(millis() - start >= timeout) {
|
|
rawStr[i++] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// get the number of bytes in response
|
|
char* pch = strtok(rawStr, ",:");
|
|
if(pch == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
pch = strtok(NULL, ",:");
|
|
if(pch == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
return(atoi(pch));
|
|
}
|