IoT sensor/controller using STM32, W5500 ethernet, MQTT
Dependencies: mbed WIZnet_Library Watchdog DHT MQTT DS1820
main.cpp
- Committer:
- Geekshow
- Date:
- 2020-02-23
- Revision:
- 4:ebaf1973d008
- Parent:
- 3:de9611d75590
- Child:
- 5:b2ae1ed8a30e
File content as of revision 4:ebaf1973d008:
#include "mbed.h" //#include "rtos.h" //#include "pins.h" #include "WIZnetInterface.h" #include "MQTTSocket.h" #include "MQTTClient.h" // ========== PIN DEFINITIONS ============ #define NUM_OF_OUTPUTS 11 #define NUM_OF_INPUTS 12 #define LED_GREEN PA_5 #define LED_ORANGE PA_1 // Don't use! Shared with D3 #define BUTTON PC_9 #define ANALOGPIN0 PC_0 // Analogue Input 0 #define ANALOGPIN1 PC_1 // Analogue Input 1 #define ANALOGPIN2 PC_2 // Analogue Input 2 #define ANALOGPIN3 PC_3 // Analogue Input 3 #define ANALOGPIN4 PC_4 // Analogue Input 4 #define ANALOGPIN5 PC_5 // Analogue Input 5 //#define INPUTPINx PC_15 // Don't use D23 #define INPUTPIN0 PB_9 // DHT22 digital pin (D24) #define INPUTPIN1 PD_2 // DHT22 digital pin (D25) #define INPUTPIN2 PC_10 // DHT22 digital pin (D26) //#define INPUTPINx PB_0 // Don't use D27 //#define INPUTPINx PB_1 // Don't use D28 #define INPUTPIN3 PB_10 // digital pin (D29) #define INPUTPIN4 PB_11 // digital pin (D30) #define INPUTPIN5 PB_12 // digital pin (D31) #define INPUTPIN6 PB_13 // digital pin (D32) #define INPUTPIN7 PB_14 // digital pin (D33) #define INPUTPIN8 PB_15 // digital pin (D34) #define INPUTPIN9 PC_6 // digital pin (D35) #define INPUTPIN10 PC_7 // digital pin (D36) #define INPUTPIN11 PC_8 // digital pin (D37) #define OUTPUTPIN0 PA_3 // digital output D0 #define OUTPUTPIN1 PA_2 // digital output D1 #define OUTPUTPIN2 PA_0 // digital output D2 #define OUTPUTPIN3 PA_1 // digital output D3 #define OUTPUTPIN4 PB_5 // digital output D4 #define OUTPUTPIN5 PB_6 // digital output D5 #define OUTPUTPIN6 PA_8 // digital output D6 #define OUTPUTPIN7 PA_9 // digital output D7 #define OUTPUTPIN8 PA_10 // digital output D8 #define OUTPUTPIN9 PB_7 // digital output D9 //#define OUTPUTPINx PA_4 // digital output D10 - SPI1 SS //#define OUTPUTPINx PA_4 // digital output D11 - SPI1 MOSI //#define OUTPUTPINx PA_4 // digital output D12 - SPI1 MISO //#define OUTPUTPINx PA_4 // digital output D13 - SPI1 CLK #define OUTPUTPIN10 PB_8 // digital output D14 // ================= *************** ================== #define USART3_TX PC_10 // ================= *************** ================== #define NODE_NAME "controller03" // TODO just define node number uint8_t mac_addr[6]={0x00, 0x00, 0x00, 0xBE, 0xEF, 0x03}; // TODO make last byte dynamic const char* mqtt_broker = "192.168.1.99"; const int mqtt_port = 1883; static Timer g_timer; // TODO remove me WIZnetInterface wiz(PA_7, PA_6, PA_5, PA_4, PB_10); // SPI1 with D29 (reset) typedef MQTT::Client<MQTTSocket,Countdown> MClient; const char* ONOFF[] = {"OFF", "ON"}; const char* OPENCLOSED[] = {"CLOSED", "OPEN"}; Serial pc(USART3_TX, NC); // serial debug output on D26 (pin 4 of Extension) DigitalIn button(BUTTON); DigitalOut led(LED_GREEN); DigitalOut output0(OUTPUTPIN0); const char* inputs[2] = { "button", NULL }; const char* outputs[2] = { "output0", NULL }; void on_control_cmd(const char* actuator_name, const char* control_value) { int new_state = 0; pc.printf("Received CMD %s %s\r\n", actuator_name, control_value); if(strcmp(control_value, "ON") == 0) { pc.printf("ON value requested!\r\n"); new_state = 1; } else if(strcmp(control_value, "OFF") == 0) { pc.printf("OFF value requested!\r\n"); new_state = 0; } else { pc.printf("No value specified! In future return the current value...\r\n"); return; } if(strcmp(actuator_name, "output0") == 0) { pc.printf("Output: %s updated to %d\r\n", actuator_name, new_state); led = new_state; output0 = new_state; } } void read_inputs() { } void set_outputs() { } int publish(MClient& client, const char* msg_type, const char* point, const char* payload = NULL, size_t payload_len = 0, bool retain = false, MQTT::QoS qos = MQTT::QOS1){ char topic[64]; sprintf(topic, "%s/" NODE_NAME "/%s", msg_type, point); int ret = client.publish(topic, (void*)payload, payload_len, qos, retain); if(ret == -1) { pc.printf("ERROR during client.publish() = %d\r\n",ret); } return ret; } void messageArrived(MQTT::MessageData& md) { MQTT::Message &message = md.message; // copy message payload into local char array IMPROVE ME! char* payload = new char[message.payloadlen+1]; if(!payload) return; memcpy(payload, message.payload, message.payloadlen); payload[message.payloadlen]='\0'; // copy topic payload into local char array IMPROVE ME! char* topic = new char[md.topicName.lenstring.len+1]; if(!topic){ delete[] payload; return; } memcpy(topic, md.topicName.lenstring.data, md.topicName.lenstring.len); topic[md.topicName.lenstring.len]='\0'; pc.printf("Rcvd: %s : %s\r\n", topic, payload); // split up topic string char *topics = strtok (topic,"/"); for (int tok=0; tok<2 && topics != NULL; tok++) // WARNING! hard coded 2 layer topic! { // pc.printf ("%s\r\n",topics); topics = strtok (NULL, "/"); } on_control_cmd(topics, payload); delete[] topic; delete[] payload; } int publish_value(MClient &client, const char *topic, const char *buf) { return publish(client, "stat", topic, buf, strlen(buf), true); } int networking_init(MQTTSocket &sock, MClient &client) { int ret = 0; g_timer.start(); pc.printf("\n\nNode: %s\r\n", NODE_NAME); pc.printf("%s attempting ethernet connection...\r\n", NODE_NAME); wiz.init(mac_addr); // resets the w5500 if (wiz.connect() == (-1)) { pc.printf("Error getting DHCP address!!\r\n"); } pc.printf("IP: %s\r\n", wiz.getIPAddress()); srand(rand()^g_timer.read_us()); // what is this doing? ret = sock.connect((char*)mqtt_broker,mqtt_port); if(ret != 0){ pc.printf("failed to connect to TCP server\r\n"); return 1; } pc.printf("sock.connect()=%d\r\n",ret); srand(rand()^g_timer.read_us()); // what is this doing? if(client.connect() != 0){ pc.printf("MQTT connect failed\r\n"); return -1; } pc.printf("client.connect()=%d\r\n",ret); ret = client.subscribe("cmnd/" NODE_NAME "/+", MQTT::QOS1, messageArrived); pc.printf("client.subscribe()=%d\r\n", ret); // Node online message publish(client, "stat","online"); pc.printf("Initialization done.\r\n"); return 0; } int main() { MQTTSocket sock; MClient client(sock); int connected = networking_init(sock, client); bool btn = 0; while(1) { set_outputs(); read_inputs(); // replace this hacky mess with read_inputs! bool newBTN = button; if(newBTN != btn) { publish_value(client,"input0",OPENCLOSED[newBTN]); btn = newBTN; } else { client.yield(1000); connected = publish_value(client,"stat","hello world"); if(connected != 0) { pc.printf("Restarting network....\r\n"); networking_init(sock, client); } } } }