IoT sensor/controller using STM32, W5500 ethernet, MQTT

Dependencies:   mbed WIZnet_Library Watchdog DHT MQTT DS1820

Committer:
Geekshow
Date:
Mon Feb 24 00:40:29 2020 +0000
Revision:
5:b2ae1ed8a30e
Parent:
4:ebaf1973d008
Child:
6:4d30bc5a8076
All in main.cpp, Tickers added!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zhangyx 0:1170747a672f 1 #include "mbed.h"
Geekshow 3:de9611d75590 2 //#include "rtos.h"
Geekshow 3:de9611d75590 3 //#include "pins.h"
Geekshow 4:ebaf1973d008 4 #include "WIZnetInterface.h"
Geekshow 4:ebaf1973d008 5 #include "MQTTSocket.h"
Geekshow 4:ebaf1973d008 6 #include "MQTTClient.h"
Geekshow 3:de9611d75590 7
Geekshow 3:de9611d75590 8 // ========== PIN DEFINITIONS ============
Geekshow 3:de9611d75590 9 #define NUM_OF_OUTPUTS 11
Geekshow 3:de9611d75590 10 #define NUM_OF_INPUTS 12
Geekshow 3:de9611d75590 11
Geekshow 4:ebaf1973d008 12 #define LED_GREEN PA_5
Geekshow 4:ebaf1973d008 13 #define LED_ORANGE PA_1 // Don't use! Shared with D3
Geekshow 3:de9611d75590 14 #define BUTTON PC_9
Geekshow 3:de9611d75590 15
Geekshow 3:de9611d75590 16 #define ANALOGPIN0 PC_0 // Analogue Input 0
Geekshow 3:de9611d75590 17 #define ANALOGPIN1 PC_1 // Analogue Input 1
Geekshow 3:de9611d75590 18 #define ANALOGPIN2 PC_2 // Analogue Input 2
Geekshow 3:de9611d75590 19 #define ANALOGPIN3 PC_3 // Analogue Input 3
Geekshow 3:de9611d75590 20 #define ANALOGPIN4 PC_4 // Analogue Input 4
Geekshow 3:de9611d75590 21 #define ANALOGPIN5 PC_5 // Analogue Input 5
Geekshow 3:de9611d75590 22
Geekshow 3:de9611d75590 23 //#define INPUTPINx PC_15 // Don't use D23
Geekshow 3:de9611d75590 24 #define INPUTPIN0 PB_9 // DHT22 digital pin (D24)
Geekshow 3:de9611d75590 25 #define INPUTPIN1 PD_2 // DHT22 digital pin (D25)
Geekshow 3:de9611d75590 26 #define INPUTPIN2 PC_10 // DHT22 digital pin (D26)
Geekshow 3:de9611d75590 27 //#define INPUTPINx PB_0 // Don't use D27
Geekshow 3:de9611d75590 28 //#define INPUTPINx PB_1 // Don't use D28
Geekshow 3:de9611d75590 29 #define INPUTPIN3 PB_10 // digital pin (D29)
Geekshow 3:de9611d75590 30 #define INPUTPIN4 PB_11 // digital pin (D30)
Geekshow 3:de9611d75590 31 #define INPUTPIN5 PB_12 // digital pin (D31)
Geekshow 3:de9611d75590 32 #define INPUTPIN6 PB_13 // digital pin (D32)
Geekshow 3:de9611d75590 33 #define INPUTPIN7 PB_14 // digital pin (D33)
Geekshow 3:de9611d75590 34 #define INPUTPIN8 PB_15 // digital pin (D34)
Geekshow 3:de9611d75590 35 #define INPUTPIN9 PC_6 // digital pin (D35)
Geekshow 3:de9611d75590 36 #define INPUTPIN10 PC_7 // digital pin (D36)
Geekshow 3:de9611d75590 37 #define INPUTPIN11 PC_8 // digital pin (D37)
Geekshow 3:de9611d75590 38
Geekshow 3:de9611d75590 39 #define OUTPUTPIN0 PA_3 // digital output D0
Geekshow 3:de9611d75590 40 #define OUTPUTPIN1 PA_2 // digital output D1
Geekshow 3:de9611d75590 41 #define OUTPUTPIN2 PA_0 // digital output D2
Geekshow 3:de9611d75590 42 #define OUTPUTPIN3 PA_1 // digital output D3
Geekshow 3:de9611d75590 43 #define OUTPUTPIN4 PB_5 // digital output D4
Geekshow 3:de9611d75590 44 #define OUTPUTPIN5 PB_6 // digital output D5
Geekshow 3:de9611d75590 45 #define OUTPUTPIN6 PA_8 // digital output D6
Geekshow 3:de9611d75590 46 #define OUTPUTPIN7 PA_9 // digital output D7
Geekshow 3:de9611d75590 47 #define OUTPUTPIN8 PA_10 // digital output D8
Geekshow 3:de9611d75590 48 #define OUTPUTPIN9 PB_7 // digital output D9
Geekshow 3:de9611d75590 49 //#define OUTPUTPINx PA_4 // digital output D10 - SPI1 SS
Geekshow 3:de9611d75590 50 //#define OUTPUTPINx PA_4 // digital output D11 - SPI1 MOSI
Geekshow 3:de9611d75590 51 //#define OUTPUTPINx PA_4 // digital output D12 - SPI1 MISO
Geekshow 3:de9611d75590 52 //#define OUTPUTPINx PA_4 // digital output D13 - SPI1 CLK
Geekshow 3:de9611d75590 53 #define OUTPUTPIN10 PB_8 // digital output D14
Geekshow 3:de9611d75590 54 // ================= *************** ==================
Geekshow 3:de9611d75590 55 #define USART3_TX PC_10
Geekshow 3:de9611d75590 56 // ================= *************** ==================
Geekshow 4:ebaf1973d008 57 #define NODE_NAME "controller03" // TODO just define node number
Geekshow 3:de9611d75590 58
Geekshow 5:b2ae1ed8a30e 59 Ticker tick_5sec;
Geekshow 5:b2ae1ed8a30e 60 Ticker tick_1sec;
Geekshow 4:ebaf1973d008 61
Geekshow 4:ebaf1973d008 62 typedef MQTT::Client<MQTTSocket,Countdown> MClient;
Geekshow 4:ebaf1973d008 63
Geekshow 4:ebaf1973d008 64 const char* ONOFF[] = {"OFF", "ON"};
Geekshow 4:ebaf1973d008 65 const char* OPENCLOSED[] = {"CLOSED", "OPEN"};
Geekshow 4:ebaf1973d008 66
Geekshow 4:ebaf1973d008 67 Serial pc(USART3_TX, NC); // serial debug output on D26 (pin 4 of Extension)
Geekshow 3:de9611d75590 68
Geekshow 4:ebaf1973d008 69 DigitalIn button(BUTTON);
Geekshow 4:ebaf1973d008 70 DigitalOut led(LED_GREEN);
Geekshow 4:ebaf1973d008 71 DigitalOut output0(OUTPUTPIN0);
Geekshow 4:ebaf1973d008 72
Geekshow 5:b2ae1ed8a30e 73 uint8_t mac_addr[6]={0x00, 0x00, 0x00, 0xBE, 0xEF, 0x03}; // TODO make last byte dynamic
Geekshow 5:b2ae1ed8a30e 74 const char* mqtt_broker = "192.168.1.99";
Geekshow 5:b2ae1ed8a30e 75 const int mqtt_port = 1883;
Geekshow 5:b2ae1ed8a30e 76 unsigned long uptime_sec = 0;
Geekshow 5:b2ae1ed8a30e 77
Geekshow 5:b2ae1ed8a30e 78
Geekshow 4:ebaf1973d008 79 const char* inputs[2] = {
Geekshow 4:ebaf1973d008 80 "button",
Geekshow 4:ebaf1973d008 81 NULL
Geekshow 4:ebaf1973d008 82 };
Geekshow 4:ebaf1973d008 83
Geekshow 4:ebaf1973d008 84 const char* outputs[2] = {
Geekshow 4:ebaf1973d008 85 "output0",
Geekshow 4:ebaf1973d008 86 NULL
Geekshow 4:ebaf1973d008 87 };
Geekshow 4:ebaf1973d008 88
zhangyx 0:1170747a672f 89
zhangyx 2:a50b794b8ede 90 void on_control_cmd(const char* actuator_name, const char* control_value)
zhangyx 0:1170747a672f 91 {
Geekshow 4:ebaf1973d008 92 int new_state = 0;
zhangyx 2:a50b794b8ede 93 pc.printf("Received CMD %s %s\r\n", actuator_name, control_value);
Geekshow 4:ebaf1973d008 94 if(strcmp(control_value, "ON") == 0) {
Geekshow 4:ebaf1973d008 95 pc.printf("ON value requested!\r\n");
Geekshow 4:ebaf1973d008 96 new_state = 1;
Geekshow 4:ebaf1973d008 97 }
Geekshow 4:ebaf1973d008 98 else if(strcmp(control_value, "OFF") == 0) {
Geekshow 4:ebaf1973d008 99 pc.printf("OFF value requested!\r\n");
Geekshow 4:ebaf1973d008 100 new_state = 0;
Geekshow 4:ebaf1973d008 101 }
Geekshow 4:ebaf1973d008 102 else {
Geekshow 4:ebaf1973d008 103 pc.printf("No value specified! In future return the current value...\r\n");
Geekshow 4:ebaf1973d008 104 return;
Geekshow 4:ebaf1973d008 105 }
Geekshow 4:ebaf1973d008 106
Geekshow 4:ebaf1973d008 107 if(strcmp(actuator_name, "output0") == 0) {
Geekshow 4:ebaf1973d008 108 pc.printf("Output: %s updated to %d\r\n", actuator_name, new_state);
Geekshow 4:ebaf1973d008 109 led = new_state;
Geekshow 4:ebaf1973d008 110 output0 = new_state;
Geekshow 4:ebaf1973d008 111 }
Geekshow 4:ebaf1973d008 112 }
Geekshow 4:ebaf1973d008 113
Geekshow 4:ebaf1973d008 114 void read_inputs()
Geekshow 4:ebaf1973d008 115 {
Geekshow 5:b2ae1ed8a30e 116
Geekshow 4:ebaf1973d008 117 }
Geekshow 4:ebaf1973d008 118
Geekshow 4:ebaf1973d008 119
Geekshow 4:ebaf1973d008 120 void set_outputs()
Geekshow 4:ebaf1973d008 121 {
Geekshow 4:ebaf1973d008 122 }
Geekshow 4:ebaf1973d008 123
Geekshow 4:ebaf1973d008 124
Geekshow 4:ebaf1973d008 125 int publish(MClient& client, const char* msg_type, const char* point,
Geekshow 4:ebaf1973d008 126 const char* payload = NULL, size_t payload_len = 0,
Geekshow 4:ebaf1973d008 127 bool retain = false, MQTT::QoS qos = MQTT::QOS1){
Geekshow 4:ebaf1973d008 128 char topic[64];
Geekshow 4:ebaf1973d008 129 sprintf(topic, "%s/" NODE_NAME "/%s", msg_type, point);
Geekshow 4:ebaf1973d008 130 int ret = client.publish(topic, (void*)payload, payload_len, qos, retain);
Geekshow 4:ebaf1973d008 131 if(ret == -1) {
Geekshow 4:ebaf1973d008 132 pc.printf("ERROR during client.publish() = %d\r\n",ret);
Geekshow 4:ebaf1973d008 133 }
Geekshow 4:ebaf1973d008 134 return ret;
zhangyx 0:1170747a672f 135 }
zhangyx 2:a50b794b8ede 136
Geekshow 4:ebaf1973d008 137
Geekshow 4:ebaf1973d008 138 void messageArrived(MQTT::MessageData& md)
Geekshow 3:de9611d75590 139 {
Geekshow 4:ebaf1973d008 140 MQTT::Message &message = md.message;
Geekshow 4:ebaf1973d008 141
Geekshow 4:ebaf1973d008 142 // copy message payload into local char array IMPROVE ME!
Geekshow 4:ebaf1973d008 143 char* payload = new char[message.payloadlen+1];
Geekshow 4:ebaf1973d008 144 if(!payload)
Geekshow 4:ebaf1973d008 145 return;
Geekshow 4:ebaf1973d008 146 memcpy(payload, message.payload, message.payloadlen);
Geekshow 4:ebaf1973d008 147 payload[message.payloadlen]='\0';
Geekshow 4:ebaf1973d008 148
Geekshow 4:ebaf1973d008 149 // copy topic payload into local char array IMPROVE ME!
Geekshow 4:ebaf1973d008 150 char* topic = new char[md.topicName.lenstring.len+1];
Geekshow 4:ebaf1973d008 151 if(!topic){
Geekshow 4:ebaf1973d008 152 delete[] payload;
Geekshow 4:ebaf1973d008 153 return;
Geekshow 4:ebaf1973d008 154 }
Geekshow 4:ebaf1973d008 155 memcpy(topic, md.topicName.lenstring.data, md.topicName.lenstring.len);
Geekshow 4:ebaf1973d008 156 topic[md.topicName.lenstring.len]='\0';
Geekshow 4:ebaf1973d008 157
Geekshow 4:ebaf1973d008 158 pc.printf("Rcvd: %s : %s\r\n", topic, payload);
Geekshow 4:ebaf1973d008 159
Geekshow 4:ebaf1973d008 160 // split up topic string
Geekshow 4:ebaf1973d008 161 char *topics = strtok (topic,"/");
Geekshow 4:ebaf1973d008 162 for (int tok=0; tok<2 && topics != NULL; tok++) // WARNING! hard coded 2 layer topic!
Geekshow 4:ebaf1973d008 163 {
Geekshow 4:ebaf1973d008 164 // pc.printf ("%s\r\n",topics);
Geekshow 4:ebaf1973d008 165 topics = strtok (NULL, "/");
Geekshow 4:ebaf1973d008 166 }
Geekshow 4:ebaf1973d008 167 on_control_cmd(topics, payload);
Geekshow 4:ebaf1973d008 168 delete[] topic;
Geekshow 4:ebaf1973d008 169 delete[] payload;
Geekshow 3:de9611d75590 170 }
Geekshow 3:de9611d75590 171
Geekshow 4:ebaf1973d008 172
Geekshow 4:ebaf1973d008 173 int publish_value(MClient &client, const char *topic, const char *buf)
Geekshow 3:de9611d75590 174 {
Geekshow 4:ebaf1973d008 175 return publish(client, "stat", topic, buf, strlen(buf), true);
Geekshow 4:ebaf1973d008 176 }
Geekshow 4:ebaf1973d008 177
Geekshow 5:b2ae1ed8a30e 178 WIZnetInterface wiz(PA_7, PA_6, PA_5, PA_4, PB_10); // SPI1 with D29 (reset)
Geekshow 5:b2ae1ed8a30e 179 MQTTSocket sock;
Geekshow 5:b2ae1ed8a30e 180 MClient client(sock);
Geekshow 5:b2ae1ed8a30e 181 int connected = -1;
Geekshow 5:b2ae1ed8a30e 182
Geekshow 5:b2ae1ed8a30e 183 int networking_init(MQTTSocket &sock, MClient &client, WIZnetInterface &wiz) {
Geekshow 4:ebaf1973d008 184 int ret = 0;
Geekshow 4:ebaf1973d008 185 pc.printf("\n\nNode: %s\r\n", NODE_NAME);
Geekshow 4:ebaf1973d008 186 pc.printf("%s attempting ethernet connection...\r\n", NODE_NAME);
Geekshow 4:ebaf1973d008 187 wiz.init(mac_addr); // resets the w5500
Geekshow 4:ebaf1973d008 188 if (wiz.connect() == (-1)) {
Geekshow 4:ebaf1973d008 189 pc.printf("Error getting DHCP address!!\r\n");
Geekshow 4:ebaf1973d008 190 }
Geekshow 4:ebaf1973d008 191
Geekshow 4:ebaf1973d008 192 pc.printf("IP: %s\r\n", wiz.getIPAddress());
Geekshow 5:b2ae1ed8a30e 193
Geekshow 4:ebaf1973d008 194 ret = sock.connect((char*)mqtt_broker,mqtt_port);
Geekshow 4:ebaf1973d008 195 if(ret != 0){
Geekshow 4:ebaf1973d008 196 pc.printf("failed to connect to TCP server\r\n");
Geekshow 4:ebaf1973d008 197 return 1;
Geekshow 4:ebaf1973d008 198 }
Geekshow 4:ebaf1973d008 199 pc.printf("sock.connect()=%d\r\n",ret);
Geekshow 5:b2ae1ed8a30e 200
Geekshow 4:ebaf1973d008 201 if(client.connect() != 0){
Geekshow 4:ebaf1973d008 202 pc.printf("MQTT connect failed\r\n");
Geekshow 4:ebaf1973d008 203 return -1;
Geekshow 4:ebaf1973d008 204 }
Geekshow 4:ebaf1973d008 205 pc.printf("client.connect()=%d\r\n",ret);
Geekshow 4:ebaf1973d008 206
Geekshow 4:ebaf1973d008 207
Geekshow 4:ebaf1973d008 208 ret = client.subscribe("cmnd/" NODE_NAME "/+", MQTT::QOS1, messageArrived);
Geekshow 4:ebaf1973d008 209 pc.printf("client.subscribe()=%d\r\n", ret);
Geekshow 4:ebaf1973d008 210
Geekshow 4:ebaf1973d008 211 // Node online message
Geekshow 5:b2ae1ed8a30e 212 publish_value(client, "alive","ON");
Geekshow 5:b2ae1ed8a30e 213 publish_value(client, "IPAddress", wiz.getIPAddress());
Geekshow 4:ebaf1973d008 214 pc.printf("Initialization done.\r\n");
Geekshow 4:ebaf1973d008 215
Geekshow 4:ebaf1973d008 216 return 0;
Geekshow 5:b2ae1ed8a30e 217 }
Geekshow 5:b2ae1ed8a30e 218
Geekshow 5:b2ae1ed8a30e 219 void periodic_announcement() {
Geekshow 5:b2ae1ed8a30e 220 // announce statuses
Geekshow 5:b2ae1ed8a30e 221 char uptime_sec_str[12];
Geekshow 5:b2ae1ed8a30e 222 sprintf(uptime_sec_str, "%d", uptime_sec);
Geekshow 5:b2ae1ed8a30e 223 connected = publish_value(client,"uptime",uptime_sec_str);
Geekshow 3:de9611d75590 224 }
Geekshow 3:de9611d75590 225
Geekshow 5:b2ae1ed8a30e 226 void every_second() {
Geekshow 5:b2ae1ed8a30e 227 uptime_sec++;
Geekshow 5:b2ae1ed8a30e 228 }
Geekshow 3:de9611d75590 229
Geekshow 3:de9611d75590 230 int main()
Geekshow 3:de9611d75590 231 {
Geekshow 5:b2ae1ed8a30e 232 tick_1sec.attach(&every_second, 1.0);
Geekshow 5:b2ae1ed8a30e 233 pc.printf("\n\nNode: %s\r\n", NODE_NAME);
Geekshow 3:de9611d75590 234
Geekshow 5:b2ae1ed8a30e 235 connected = networking_init(sock, client, wiz);
Geekshow 5:b2ae1ed8a30e 236
Geekshow 5:b2ae1ed8a30e 237 tick_5sec.attach(&periodic_announcement, 5.0);
Geekshow 3:de9611d75590 238
Geekshow 3:de9611d75590 239 while(1) {
Geekshow 4:ebaf1973d008 240 set_outputs();
Geekshow 4:ebaf1973d008 241 read_inputs();
Geekshow 3:de9611d75590 242
Geekshow 5:b2ae1ed8a30e 243
Geekshow 5:b2ae1ed8a30e 244 if(connected != 0) {
Geekshow 5:b2ae1ed8a30e 245 pc.printf("Restarting network....\r\n");
Geekshow 5:b2ae1ed8a30e 246 networking_init(sock, client, wiz);
zhangyx 0:1170747a672f 247 }
Geekshow 5:b2ae1ed8a30e 248 // pause a while, yawn......
Geekshow 5:b2ae1ed8a30e 249 // client.yield(1000);
zhangyx 0:1170747a672f 250 }
zhangyx 0:1170747a672f 251 }