-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathwifi-s8-mqtt.ino
154 lines (128 loc) · 3.74 KB
/
wifi-s8-mqtt.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
MIT License.
Install MQTT lib to ESP8266.
Tested on NodeMCU 1.0 (ESP12E)
*/
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#define AIO_SERVER "mqtt-server.org"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "mqtt-username"
#define AIO_KEY "mqtt-password"
const char* ssid = "SSID";
const char* password = "WiFi-password";
const byte s8_co2[8] = {0xfe, 0x04, 0x00, 0x03, 0x00, 0x01, 0xd5, 0xc5};
const byte s8_fwver[8] = {0xfe, 0x04, 0x00, 0x1c, 0x00, 0x01, 0xe4, 0x03};
const byte s8_id_hi[8] = {0xfe, 0x04, 0x00, 0x1d, 0x00, 0x01, 0xb5, 0xc3};
const byte s8_id_lo[8] = {0xfe, 0x04, 0x00, 0x1e, 0x00, 0x01, 0x45, 0xc3};
SoftwareSerial swSer(13, 15, false, 256); // RX, TX
byte buf[10];
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish senseair = Adafruit_MQTT_Publish(&mqtt, "/feeds/co2");
void MQTT_connect();
void myread(int n) {
int i;
memset(buf, 0, sizeof(buf));
for(i = 0; i < n; ) {
if(swSer.available() > 0) {
buf[i] = swSer.read();
i++;
}
yield();
delay(10);
}
}
// Compute the MODBUS RTU CRC
uint16_t ModRTU_CRC(byte* buf, int len){
uint16_t crc = 0xFFFF;
for (int pos = 0; pos < len; pos++) {
crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
return crc;
}
void setup() {
Serial.begin(9600);
swSer.begin(9600);
delay(10);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("Sensor ID: ");
swSer.write(s8_id_hi, 8);
myread(7);
Serial.printf("%02x%02x", buf[3], buf[4]);
swSer.write(s8_id_lo, 8);
myread(7);
Serial.printf("%02x%02x", buf[3], buf[4]);
Serial.println("");
swSer.write(s8_fwver, 8);
myread(7);
Serial.printf("Firmware: %d.%d", buf[3], buf[4]);
Serial.println();
}
int value = 0;
void loop() {
uint16_t co2;
MQTT_connect();
co2 = readco2();
senseair.publish(co2);
delay(10 * 1000L);
}
uint16_t readco2() {
uint16_t crc, got, co2;
swSer.write(s8_co2, 8);
myread(7);
co2 = (uint16_t)buf[3] * 256 + (uint16_t)buf[4];
crc = ModRTU_CRC(buf, 5);
got = (uint16_t)buf[5] + (uint16_t)buf[6] * 256;
if(crc != got) {
Serial.print("Invalid checksum. Expect: ");
Serial.print(crc, HEX);
Serial.print(" Got: ");
Serial.println(got, HEX);
} else {
Serial.print("CO2: ");
Serial.println(co2);
// Serial.printf("%02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
}
return co2;
}
void MQTT_connect() {
int8_t ret;
if(mqtt.connected()) return;
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while((ret = mqtt.connect()) != 0) {
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if(retries == 0) {
Serial.println("Cannot connect to MQTT. System hangs.");
while(1);
}
}
Serial.println("MQTT Connected!");
}