#include
"ESP8266_PowerSave.h"
/*
-------------------------------------------------------------------
* Setup des ATmega zur Kommunikation mit dem
ESP8266.
*/
void ESP8266_PowerSave::setup(uint8_t power, uint8_t
enable, long spd, char *buf, uint8_t blen) {
enabled=0;
power_pin=power;
enable_pin=enable;
speed=spd;
buf_ptr=buf;
buf_len=blen;
pinMode(power_pin, OUTPUT);
pinMode(enable_pin, OUTPUT);
digitalWrite(power_pin, HIGH); // ESP
ausschalten
delay(200);
}
/*
-------------------------------------------------------------------
* ESP8266 power on und enable
*/
void ESP8266_PowerSave::enable(void) {
if(!enabled) {
digitalWrite(power_pin,
LOW); // ESP8266 mit Strom
versorgen
delay(10);
digitalWrite(enable_pin,
HIGH); // ESP8266 aktivieren
esp.begin(speed);
enabled=1;
}
}
/*
-------------------------------------------------------------------
* ESP8266 disable und power off
*/
void ESP8266_PowerSave::disable(void) {
digitalWrite(tx_pin,
LOW); // keine Spannung
am abgeschalteten ESP8266
digitalWrite(enable_pin, LOW); // ESP8266
deaktivieren
delay(10);
digitalWrite(power_pin, HIGH); // Strom
für ESP8266 abschalten
enabled=0;
}
/*
-------------------------------------------------------------------
* Stellt den ESP8266 auf
* "station mode",
* "single connection" und
* connect to AP
"FreifunkWees01.2 (http://ffw)"
* ein.
*/
void ESP8266_PowerSave::init(void) {
esp.println(F("AT+CWMODE_CUR=1"));
esp.println(F("AT+CIPMUX=0"));
esp.println(F("AT+CWAUTOCONN=1"));
esp.println(F("AT+CWJAP_CUR=\"FreifunkWees01.2
(http://ffw)\",\"\""));
}
/*
-------------------------------------------------------------------
* Wartet (bis zu "timeout_seconds" Sekunden)
darauf, dass der ESP8266
* mit "OK" auf einen "AT"-Befehl reagiert.
* Liefert 1, wenn der ESP8266 korrekt reagiert
hat. Sonst 0.
*/
char ESP8266_PowerSave::wait_until_responsive(uint8_t
timeout_seconds) {
for(uint8_t i=0; i<timeout_seconds;
i++) {
esp.println(F("AT"));
if(esp.find((char*)"\r\nOK\r\n")) { // wartet
den Default-Timeout von einer Sekunde
emptyBuffer();
return(1);
}
}
return(0);
}
/*
-------------------------------------------------------------------
* Receive-Buffer leerlesen
*/
void ESP8266_PowerSave::emptyBuffer(void) {
char c;
unsigned long timeout;
if(esp.available()==0) {
return;
}
timeout=millis()+100; // maximal 1/10
Sekunde lang leerlesen
while(esp.available() &&
millis()<timeout) {
c=esp.read();
}
}
/*
-------------------------------------------------------------------
* Liefert den Status des ESP8266 als Zahl.
* 0 : Fehler
* 2 : Got IP
* 3 : Connected
(via TCP/IP)
* 4 : Disconnected (from TCP/IP)
*/
uint8_t ESP8266_PowerSave::get_TCPIP_status(void) {
uint8_t state=0;
esp.println(F("AT+CIPSTATUS"));
if(esp.find((char*)"\r\nSTATUS:")) {
state=esp.parseInt();
}
esp.find((char*)"\r\nOK\r\n"); // Rest weglesen
return(state);
}
/*
-------------------------------------------------------------------
* Daten ("data") via IP senden und Antwort (in
buf_ptr) empfangen.
* Für die Gut-Meldung der Funktion muss auch die
empfangene Checksum
* zu den empfangenen Daten passen.
* Liefert 1, wenn alles geklappt hat. Sonst 0.
*/
uint8_t ESP8266_PowerSave::TCPIP_send(char *data) {
int len;
char *ptr, *ptr_cs, rc=0;
unsigned long timeout;
esp.print(F("AT+CIPSEND="));
esp.println(strlen(data)+5); // +5 ->
',' + 4 Byte Checksum
delay(20); // etwas warten zwischen
Kommando und Daten - sonst klappts nicht
esp.print(data);
esp.print(",");
esp.println(getChecksum(data));
// Antwort: "+IPD,nn:<nn Byte Daten>"
(bei CIPMUX=0 = "single connection")
if(!esp.find((char*)"+IPD,")) { // wartet gemäß
Stream.timeout (Default=1Sek) auf Daten
return(0);
}
len=esp.parseInt();
if(len>=buf_len) {
return(0); // da kommen mehr
Daten, als in buf_ptr passen
}
esp.find(':');
esp.readBytes(buf_ptr, len);
*(buf_ptr+len)='\0';
// String-Ende setzen
*(buf_ptr+len-5)='\0';
// Checksum abtrennen
ptr_cs=buf_ptr+len-4; //
Pointer auf den Checksum-String
ptr=getChecksum(buf_ptr); //
Checksum-String für Daten (ohne Checksum) bilden
if(strcmp(ptr, ptr_cs)==0) {
// beide Checksummen vergleichen
rc=1;
} else {
rc=0;
}
delay(100); // mit etwas Wartezeit
zwischen TCPIP_send()'s ist es sicherer
emptyBuffer();
return(rc);
}
/*
-------------------------------------------------------------------
* Liefert eine [primitive] Prüfsumme für den
Null-terminierten
* String "strg" als Pointer auf einen String (4
Byte + '\0').
*/
char *ESP8266_PowerSave::getChecksum(char *strg) {
static char buf[5];
int cs=0;
for(char *ptr=strg; *ptr!='\0'; ptr++) {
cs+=*ptr;
}
snprintf(buf, 5, "%04x", cs);
return(buf);
}
/*
-------------------------------------------------------------------
* "connect_retries" mal versuchen, die
Verbindung zum
* Python-Script herstellen.
* Liefert 1, wenn verbunden. Sonst 0.
*/
uint8_t ESP8266_PowerSave::connect_TCPIP(uint8_t
connect_retries) {
for(uint8_t i=0; i<connect_retries; i++) {
esp.println(F("AT+CIPSTART=\"TCP\",\"192.168.42.80\",2626"));
if(esp.find((char*)"\r\nOK\r\n")) {
delay(50); // den
braucht er....
if(is_connected_via_TCPIP()) {
return(1);
}
}
}
return(0);
}
/*
-------------------------------------------------------------------
* Verbindungs-Status abfragen (3 = connected via
TCP/IP).
* Liefert 1, wenn der ESP8266 via TCP/IP
verbunden ist. Sonst 0.
*/
uint8_t
ESP8266_PowerSave::is_connected_via_TCPIP(void) {
return(get_TCPIP_status()==3);
}
|