IoT sensor/controller using STM32, W5500 ethernet, MQTT
Dependencies: mbed WIZnet_Library Watchdog DHT MQTT DS1820
Diff: main.cpp
- Revision:
- 4:ebaf1973d008
- Parent:
- 3:de9611d75590
- Child:
- 5:b2ae1ed8a30e
diff -r de9611d75590 -r ebaf1973d008 main.cpp --- a/main.cpp Sun Feb 23 10:17:06 2020 +0000 +++ b/main.cpp Sun Feb 23 18:36:18 2020 +0000 @@ -1,15 +1,16 @@ #include "mbed.h" //#include "rtos.h" //#include "pins.h" -#include "networking.h" - +#include "WIZnetInterface.h" +#include "MQTTSocket.h" +#include "MQTTClient.h" // ========== PIN DEFINITIONS ============ #define NUM_OF_OUTPUTS 11 #define NUM_OF_INPUTS 12 -#define GREENLEDPIN PA5 -#define ORANGELEDPIN PA_1 +#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 @@ -53,48 +54,162 @@ // ================= *************** ================== #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) -Serial pc(USART3_TX, NC); // serial output on D26 -DigitalIn BTN(BUTTON); -DigitalOut LED(LED_GREEN); +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(actuator_name, "led") == 0) - LED = atoi(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 readInputs() + +void messageArrived(MQTT::MessageData& md) { - inputs[0] = digitalRead(INPUTPIN0); - inputs[1] = digitalRead(INPUTPIN1); - inputs[2] = digitalRead(INPUTPIN2); - inputs[3] = digitalRead(INPUTPIN3); - inputs[4] = digitalRead(INPUTPIN4); - inputs[5] = digitalRead(INPUTPIN5); - inputs[6] = digitalRead(INPUTPIN6); - inputs[7] = digitalRead(INPUTPIN7); - inputs[8] = digitalRead(INPUTPIN8); - inputs[9] = digitalRead(INPUTPIN9); - inputs[10] = digitalRead(INPUTPIN10); - inputs[11] = digitalRead(INPUTPIN11); + 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; } -void setOutputs() + +int publish_value(MClient &client, const char *topic, const char *buf) { - digitalWrite(OUTPUTPIN0,!outputs[0]); - digitalWrite(OUTPUTPIN1,!outputs[1]); - digitalWrite(OUTPUTPIN2,!outputs[2]); - digitalWrite(OUTPUTPIN3,!outputs[3]); - digitalWrite(OUTPUTPIN4,!outputs[4]); - digitalWrite(OUTPUTPIN5,!outputs[5]); - digitalWrite(OUTPUTPIN6,!outputs[6]); - digitalWrite(OUTPUTPIN7,!outputs[7]); - digitalWrite(OUTPUTPIN8,!outputs[8]); - digitalWrite(OUTPUTPIN9,!outputs[9]); - digitalWrite(OUTPUTPIN10,!outputs[10]); + 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; } @@ -103,43 +218,25 @@ MQTTSocket sock; MClient client(sock); - // Declare sensors (name, unit) - const char* sensors[][8] = { - "test", " ", - "button", "V", - NULL, NULL - }; - - // Declare all actuators (name and parameter) - const char* actuators[][8] = { - "led", "int", - NULL, NULL - }; - - int connected = networking_init(sock, client, sensors, actuators, on_control_cmd); + int connected = networking_init(sock, client); bool btn = 0; while(1) { - setOutputs(); - readInputs(); + set_outputs(); + read_inputs(); - - bool newBTN = BTN; + // replace this hacky mess with read_inputs! + bool newBTN = button; if(newBTN != btn) { - char buf[16]; - int value = (bool)newBTN; - - sprintf(buf, "%d mV", value); - publish_value(client,"button",buf); - + 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, sensors, actuators, on_control_cmd); + networking_init(sock, client); } } }