Untitled
unknown
plain_text
3 years ago
6.8 kB
4
Indexable
/**
* A mqtt wrapper for ESP01(ESP8266) using serial ports.
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Dictionary.h>
#define DEBUG false
#define DEBUG_SERIAL if(DEBUG)Serial
#define BUFFER_SIZE 30
// WiFi
const char *ssid = "mqtt8266"; // Enter your WiFi name
const char *password = "espesp8266"; // Enter WiFi password
// MQTT Broker 配置mosquitto.org公共服务
bool mqtt_is_ready = false;
const char *mqtt_broker = "test.mosquitto.org";
const char *topic_log = "Boiler/log";
const char *topic_power = "Boiler/power";
const char *topic_switch = "Boiler/switch";
const char *topic_soakset = "Boiler/soaktime";
const char *topic_firstset = "Boiler/firstTime";
const char *topic_secondset = "Boiler/secondTime";
const char *mqtt_username = "smart_pot";
const char *mqtt_password = "smart_pot";
const int mqtt_port = 1883;
// For embedded C, a fixed-length buffer will be good.
// 对于嵌入式C, 固定长度的缓冲区比较合适
byte uart_send[BUFFER_SIZE];
byte uart_in[BUFFER_SIZE];
bool new_from_server = false;
bool new_from_device = false;
Dictionary *dict;
WiFiClient espClient;
PubSubClient client(espClient);
void blink(int times, int gap)
{
for(int i = 0; i < times; i++)
{
digitalWrite(LED_BUILTIN, LOW); // Turn the LED on
delay(gap);
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off
delay(gap * 2);
}
}
void serialEvent() {
if (Serial.available() > 0) {
// read the incoming byte:
int incomingByte = Serial.readBytes(uart_in, BUFFER_SIZE);
// say what you got:
if (uart_in[0] == 0xAB && uart_in[1] == 0xCD) {
if (mqtt_is_ready) {
uart_send[0] = 0xAB;
uart_send[1] = 0xCD;
Serial.write(uart_send, BUFFER_SIZE);
Serial.flush();
}
else {
uart_send[0] = 0xFF;
uart_send[1] = 0xFF;
Serial.write(uart_send, BUFFER_SIZE);
Serial.flush();
}
}
DEBUG_SERIAL.print("I received: ");
DEBUG_SERIAL.print(incomingByte, DEC);
DEBUG_SERIAL.print(" bytes: ");
for(int i=0; i < incomingByte; i++){
DEBUG_SERIAL.print(uart_in[i], HEX);
}
DEBUG_SERIAL.println("");
new_from_device = true;
}
}
byte checksum(const byte *uart_buf, uint len){
uint sum = 0;
for(byte i = 0; i < len; i++){
sum += uart_buf[i];
}
byte result = sum & 0xFF;
return result;
}
void uart_pack_msg(char *topic, byte *msg, byte *uart_buf, unsigned int length)
{
uint len = length + 3;
for (uint i = 0; i <= dict->size(); i++)
{
if (i == dict->size()) break;
if (dict->key(i) == String(topic)) uart_buf[0] = dict->value(i).toInt();
}
// if (strcmp(topic,"esp8266/msg")==0)
// {
// uart_buf[0]=MSG;
// }
// else if (strcmp(topic,"esp8266/led")==0)
// {
// uart_buf[0]=LED;
// }
uart_buf[1] = len;
for(uint i = 0; i < length; i++)
{
uart_buf[i+2] = msg[i];
}
uart_buf[len-1] = checksum(uart_buf, len - 1);
}
void parse_and_publish(byte *msg)
{
// default topic
String topic_s = "esp8266/log";
// msg[1] holds the length of whole msg with payload from msg[2] ~ msg[msg[1] - 1]
if ( checksum(msg, msg[1] - 1 ) == msg[msg[1] - 1])
{
DEBUG_SERIAL.print("msg[0]: ");
DEBUG_SERIAL.println(String(msg[0]));
for (uint i = 0; i <= dict->size(); i++)
{
if (i == dict->size()) break;
if (dict->value(i) == String(msg[0])) topic_s = dict->key(i);
}
const uint plen = msg[1] - 3;
if( client.publish( topic_s.c_str(), &msg[2], plen))
{
DEBUG_SERIAL.println("msg published");
blink(2, 100);
}
else
{
DEBUG_SERIAL.println("error in publish");
blink(4, 50);
}
}
else
{
DEBUG_SERIAL.println("wrong sum check!");
}
}
void callback(char *topic, byte *payload, unsigned int length) {
DEBUG_SERIAL.print("\nMessage arrived in topic: ");
DEBUG_SERIAL.println(topic);
DEBUG_SERIAL.print("Message with: ");
DEBUG_SERIAL.print(length, DEC);
DEBUG_SERIAL.print(" bytes: ");
for (int i = 0; i < length; i++) {
DEBUG_SERIAL.print((char) payload[i]);
}
DEBUG_SERIAL.println();
DEBUG_SERIAL.println("-----------------------");
uart_pack_msg(topic, payload, uart_send, length);
new_from_server = true;
}
void setup() {
dict = new Dictionary();
dict->insert("Boiler/log", String(0xA0));
dict->insert("Boiler/temper", String(0xA1));
dict->insert("Boiler/switch", String(0xA2));
dict->insert("Boiler/soaktime", String(0xA3));
dict->insert("Boiler/firstTime", String(0xA4));
dict->insert("Boiler/secondTime", String(0xA5));
dict->insert("Boiler/soakprogress", String(0xA6));
dict->insert("Boiler/firstboil", String(0xA6));
dict->insert("Boiler/secondboil", String(0xA7));
dict->insert("Boiler/dryalarm", String(0xA8));
dict->insert("Boiler/finish", String(0xA9));
dict->insert("Boiler/power", String(0xAA));
// Set software serial baud to 115200;
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
// connecting to a WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
//delay(500);
blink(1, 1000);
DEBUG_SERIAL.println("Connecting to WiFi..");
}
blink(3, 100);
DEBUG_SERIAL.println("Connected to the WiFi network");
//connecting to a mqtt broker
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
while (!client.connected()) {
String client_id = "esp8266-client-";
client_id += String(WiFi.macAddress());
DEBUG_SERIAL.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
DEBUG_SERIAL.println("Public mosquitto mqtt broker connected");
mqtt_is_ready = true;
blink(4, 50);
} else {
DEBUG_SERIAL.print("failed with state ");
DEBUG_SERIAL.print(client.state());
delay(2000);
}
}
// publish and subscribe
client.publish(topic_log, "hello mqtt");
client.subscribe(topic_power);
client.subscribe(topic_firstset);
client.subscribe(topic_secondset);
client.subscribe(topic_switch);
client.subscribe(topic_soakset);
}
void loop() {
client.loop();
if(new_from_server)
{
Serial.write(uart_send, BUFFER_SIZE);
Serial.flush();
blink(1, 100);
new_from_server = false;
}
if(new_from_device)
{
parse_and_publish(uart_in);
new_from_device = false;
}
delay(50);
}
Editor is loading...