Untitled
unknown
plain_text
3 years ago
6.8 kB
3
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...