-
Notifications
You must be signed in to change notification settings - Fork 4
/
wifi-s8-thingspeak.ino
136 lines (111 loc) · 3.34 KB
/
wifi-s8-thingspeak.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
/*
MIT License.
Tested on NodeMCU 1.0 (ESP12E)
*/
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
const char* ssid = "MozTW";
const char* password = "fox-mosa";
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); // RX, TX
byte buf[10];
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();
}
void loop() {
uint16_t co2;
char url[200];
co2 = readco2();
snprintf(url, sizeof(url), "https://api.thingspeak.com/update?api_key=PUT_API_KEY_HERE&field1=%d", co2);
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
if(https.begin(*client, url)) { // HTTPS
int httpCode = https.GET();
if (httpCode > 0) {
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
}
delay(15 * 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;
}