TX |
GND |
|
EN |
GPIO2 |
Antenne |
RST |
GPIO0 | (Ansicht von oben) |
Vcc |
RX |
println("INFO=selbst hallo welt esp")
ausführt.2017.12.25
13:50:23 Info: selbst hallo welt esp 2017.12.25 13:50:28 Info: selbst hallo welt esp 2017.12.25 13:50:33 Info: selbst hallo welt esp |
~/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/libraries/SoftwareSerial)
kennt einen vierten Parameter "buffSize" im Konstruktor.SoftwareSerial ser(3, 1, false,
4096);
ser.begin(19200);
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
WiFiClient sockSrv_client;
// statt HardwareSerial wird SoftwareSerial genutzt, um die Buffer-Größe hochsetzen zu können
SoftwareSerial ser(3, 1, false, 4096); // GPIO1=TX, GPIO3=RX (https://arduino.stackexchange.com/a/29940/38968)
#define REC_BUF_SIZE 2048
uint8_t rec_buf[REC_BUF_SIZE];
int bad;
/* -------------------------------------------------------------------
* Stellt eine Verbindung zum WLAN her und liefert true, wenn es
* geklappt hat.
*/
int connectWLAN(void) {
int retries;
WiFi.forceSleepWake();
WiFi.begin("FreifunkWees01.2 (http://ffw)", "");
retries=20;
while(WiFi.status()!=WL_CONNECTED && retries>0) { // 10 Sek. lang probieren
delay(500);
retries--;
}
return(WiFi.status()==WL_CONNECTED);
}
/* -------------------------------------------------------------------
* Trennt die Verbindung zum WLAN.
*/
void disconnectWLAN(void) {
WiFi.disconnect();
delay(100); // dem disconnect etwas Zeit geben, bevor abgeschatet wird
WiFi.forceSleepBegin();
}
/* -------------------------------------------------------------------
* Stellt eine Verbindung zum übergebenen SocketServer her und
* liefert true, wenn es geklappt hat.
*/
int connectSocketServer(char *ipaddr, int portnr) {
return(sockSrv_client.connect(ipaddr, portnr));
}
/* -------------------------------------------------------------------
* Liefert true, wenn die Verbindung noch steht.
*/
int isConnectedToSocketServer(void) {
return(sockSrv_client.connected());
}
/* -------------------------------------------------------------------
* Trennt die Verbindung zum SocketServer.
*/
void disconnectSocketServer(void) {
sockSrv_client.stop();
}
/* -------------------------------------------------------------------
* Liefert eine 16 Bit lange Prüfsumme für den Speicherbereich ab
* "buf" in der Länge "len".
*/
uint16_t getBinChecksum(uint8_t *buf, uint16_t len) {
uint16_t cs=0;
for(; len>0; len--) {
cs+=*buf++;
}
return(cs);
}
/* -------------------------------------------------------------------
* Sendet den Inhalt des Speicherbereiches ab "buf" in der Länge
* "len" samt einer Prüfsumme an den SocketServer.
* Die Verbindung zum SocketServer muss offen sein.
*/
void sendSocketServer(uint8_t *buf, uint32_t len) {
uint8_t *buf_ptr;
uint16_t cs=getBinChecksum(buf, len);
buf_ptr=(uint8_t *)malloc(len+2);
if(buf_ptr!=NULL) {
memcpy(buf_ptr, buf, len);
*(buf_ptr+len)=cs&0xff;
*(buf_ptr+len+1)=(cs>>8)&0xff;
sockSrv_client.write((const uint8_t *)buf_ptr, len+2);
free(buf_ptr);
}
}
/* -------------------------------------------------------------------
* Empfängt bis zu "maxlen" Byte vom SocketServer und legt sie ab
* "buf" im Speicher ab. Passt die Checksum gemäß der letzten zwei
* Byte zu den davor liegenden Byte, wird die Länge der empfangenen
* Daten (ohne die letzten zwei Byte für die Checksum)
* zurückgeliefert. Ansonsten wird 0 geliefert.
* Die Verbindung zum SocketServer muss offen sein.
*/
uint32_t receiveSocketServer(uint8_t *buf, uint32_t maxlen, uint32_t timeout_ms=2000) {
uint32_t start_ms=millis();
uint32_t idx, len;
uint16_t cs;
while(sockSrv_client.available()==0 && (millis()-start_ms)<timeout_ms) {
delay(10);
}
idx=0;
while(sockSrv_client.available()>0 && idx<maxlen && (millis()-start_ms)<timeout_ms) {
buf[idx++]=sockSrv_client.read();
}
if(idx>=3 && (millis()-start_ms)<timeout_ms) {
// Mindestens ein Byte Nutzdaten empfangen und kein Timeout aufgetreten
len=idx-2;
cs=getBinChecksum(buf, len);
if(buf[len]==(uint8_t)cs&0xff && buf[len+1]==(uint8_t)(cs>>8)&0xff) {
buf[len]='\0'; // String draus machen...falls es keiner sein sollte
return(len);
} else {
#if DEBUG==1
// Serial.println("checksum fehler");
// Serial.println(len);
#endif
}
}
return(0);
}
/* -------------------------------------------------------------------
* Liefert true, wenn eine Verbindung zum SocketServer steht.
*/
int reconnectIfNeeded(char *host, int port) {
if(isConnectedToSocketServer()) { // wenn die Verbindung zum SocketServer steht
return(true); // ist alles gut
}
if(WiFi.status()!=WL_CONNECTED) { // wenn WLAN-Connect nicht mehr steht
if(connectWLAN()) { // im WLAN anmelden und wenns geklappt hat
return(connectSocketServer(host, port)); // beim SocketServer anmelden und Erfolgsstatus liefern
}
} else { // wenn WLAN-Connect steht
return(connectSocketServer(host, port)); // beim SocketServer anmelden und Erfolgsstatus liefern
}
return(false);
}
/* -------------------------------------------------------------------
*
*/
int receiveBlock(char *buf, int maxlen) {
unsigned int adr=0, len1, len2, cs;
unsigned char b, state=0;
char *ptr;
ptr=buf;
if(ser.available()>0) {
while(state!=7) {
while(ser.available()==0) { delay(1); }
b=ser.read();
if(state==6) { state=7; cs+=b; }
if(state==5) { state=6; cs=(b<<8); }
if(state==4) {
*ptr=b;
len2--;
maxlen--;
if(maxlen>=0) { maxlen--; ptr++; }
if(len2==0) { state=5; }
}
if(state==3) { state=4; len1+=b; len2=len1; }
if(state==2) { state=3; len1=(b<<8); }
if(state==1) { if(b==23) { state=2; } else { state=0; bad=1; } }
if(state==0 && b==42) { state=1; }
}
if(cs==getBinChecksum((uint8_t*)buf, len1)) {
return(len1);
} else {
bad=2;
}
}
return(0);
}
/* -------------------------------------------------------------------
*
*/
void setup() {
ser.begin(19200);
}
/* -------------------------------------------------------------------
*
*/
void loop() {
static int len;
bad=0;
len=receiveBlock((char*)rec_buf, REC_BUF_SIZE);
if(len>0) {
if(reconnectIfNeeded("192.168.42.99", 2627)) {
sendSocketServer(rec_buf, len);
receiveSocketServer(rec_buf, REC_BUF_SIZE, 2000);
}
}
if(bad>0) {
if(reconnectIfNeeded("192.168.42.99", 2627)) {
snprintf((char*)rec_buf, 100, "INFO=BAD=%d", bad);
sendSocketServer(rec_buf, len);
receiveSocketServer(rec_buf, REC_BUF_SIZE, 2000);
}
}
delay(1);
}
#ifndef LoggingDevice_h
#define LoggingDevice_h
#include <Arduino.h>
#include <SoftwareSerial.h>
class LoggingDevice {
public:
LoggingDevice(uint8_t rx, uint8_t tx, uint8_t power, uint8_t enable, long spd) : esp(rx, tx) {
rx_pin=rx;
tx_pin=tx;
power_pin=power;
enable_pin=enable;
speed=spd;
enabled=0;
pinMode(power_pin, OUTPUT);
pinMode(enable_pin, OUTPUT);
digitalWrite(power_pin, HIGH); // ESP ausschalten
};
void enable(void);
void disable(void);
void sendBuffer(char *buf, int len);
void sendString(char *buf);
private:
uint8_t power_pin;
uint8_t enable_pin;
uint8_t rx_pin;
uint8_t tx_pin;
long speed;
uint8_t enabled;
SoftwareSerial esp;
uint16_t getBinChecksum(uint8_t *buf, uint16_t len);
};
#endif
#include "LoggingDevice.h"
/* -------------------------------------------------------------------
* ESP-01 power on und enable
*/
void LoggingDevice::enable(void) {
if(!enabled) {
digitalWrite(power_pin, LOW); // ESP mit Strom versorgen
delay(10);
digitalWrite(enable_pin, HIGH); // ESP aktivieren
esp.begin(speed);
enabled=1;
esp.setTimeout(1000);
}
}
/* -------------------------------------------------------------------
* ESP-01 disable und power off
*/
void LoggingDevice::disable(void) {
digitalWrite(tx_pin, LOW); // keine Spannung am abgeschalteten ESP
digitalWrite(enable_pin, LOW); // ESP deaktivieren
delay(10);
digitalWrite(power_pin, HIGH); // Strom für ESP abschalten
enabled=0;
}
/* -------------------------------------------------------------------
* Sendet den Null-terminierten String "buf" an den ESP-01.
*/
void LoggingDevice::sendString(char *buf) {
sendBuffer(buf, strlen(buf)+1);
}
/* -------------------------------------------------------------------
*
*/
void LoggingDevice::sendBuffer(char *buf, int len) {
unsigned int i, cs;
cs=getBinChecksum((uint8_t*)buf, len);
esp.write(42);
esp.write(23);
esp.write((len>>8)&0xff);
esp.write(len&0xff);
for(i=0; i<len; i++) {
esp.write(*buf++);
}
esp.write((cs>>8)&0xff);
esp.write(cs&0xff);
}
/* -------------------------------------------------------------------
* Liefert eine 16 Bit lange Prüfsumme für den Speicherbereich ab
* "buf" in der Länge "len".
*/
uint16_t LoggingDevice::getBinChecksum(uint8_t *buf, uint16_t len) {
uint16_t cs=0;
for(; len>0; len--) {
cs+=*buf++;
}
return(cs);
}
#include <SoftwareSerial.h>
#include "LoggingDevice.h"
#define ESP_POWER_PIN 7 // Stromversorgung für den 3.3V-Regler
#define ESP_EN_PIN 8 // Chip-Enable des ESP
#define RX_PIN_TO_ESP 9 // an diesem Pin wird vom ESP empfangen - also mit ESP-TX verbinden
#define TX_PIN_TO_ESP 10 // an diesem Pin wird zum ESP gesendet - also mit ESP-RX verbinden
#define ESP_SPEED 19200L // Baudrate zwischen ATmega328 und ESP-01
LoggingDevice log_dev(RX_PIN_TO_ESP, TX_PIN_TO_ESP, ESP_POWER_PIN, ESP_EN_PIN, ESP_SPEED);
char buf[100];
void setup() {
Serial.begin(115200);
log_dev.enable();
}
void loop() {
for(int i=0; i<40; i++) {
snprintf(buf, 100, "INFO=hallo %2d **********************************************************************", i);
log_dev.sendString(buf);
}
while(true) {
delay(100);
}
}