STM32 + W5500 + MQTT
Dependencies: MQTT WIZnet_Library mbed
Revision 2:a50b794b8ede, committed 2018-06-04
- Comitter:
- zhangyx
- Date:
- Mon Jun 04 15:16:05 2018 +0000
- Parent:
- 1:9689429a0a29
- Commit message:
- better API
Changed in this revision
--- a/WIZnet_Library.lib Fri Aug 25 15:46:28 2017 +0000 +++ b/WIZnet_Library.lib Mon Jun 04 15:16:05 2018 +0000 @@ -1,1 +1,1 @@ -https://mbed.org/teams/WIZnet/code/WIZnet_Library/#cb8808b47e69 +https://os.mbed.com/users/zhangyx/code/WIZnet_Library/#f390679a0468
--- a/main.cpp Fri Aug 25 15:46:28 2017 +0000 +++ b/main.cpp Mon Jun 04 15:16:05 2018 +0000 @@ -1,86 +1,50 @@ #include "mbed.h" -#include "WIZnetInterface.h" -#include "MQTTSocket.h" -#include "MQTTClient.h" +#include "networking.h" +Serial pc(PA_9,PA_10); DigitalIn BTN(PC_13); - //W5500接线 mosi,miso,sclk,cs,reset -WIZnetInterface wiz(PA_7,PA_6,PA_5,PB_6,PC_7); -//节点名称任取 -#define NODE_NAME "n_12345" - //接在同一子网下的设备MAC地址必须不同 -uint8_t mac_addr[6]={0x50,0x51,0x50,0x00,0x00,0x01}; +DigitalOut LED(PB_8); -typedef MQTT::Client<MQTTSocket,Countdown> MClient; -void meta_report(MClient& client, const char* ns, const char* type, - 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", ns, type); - int ret = client.publish(topic, (void*)payload, payload_len, qos, retain); - printf("client.publish()=%d\r\n",ret); -} -void messageArrived(MQTT::MessageData& md) +void on_control_cmd(const char* actuator_name, const char* control_value) { - MQTT::Message &message = md.message; - char buf[64]; - int value, len = sizeof(buf)-1; - if(message.payloadlen < len) - len = message.payloadlen; - memcpy(buf, message.payload, len); - buf[len] = '\0'; - sscanf(buf, "%d", &value); - printf("received %d\r\n", value); + pc.printf("Received CMD %s %s\r\n", actuator_name, control_value); + if(strcmp(actuator_name, "led") == 0) + LED = atoi(control_value); } - + int main() { - int ret; - wiz.init(mac_addr); - printf("DHCP...\r\n"); - wiz.connect(); - printf("IP: %s\r\n", wiz.getIPAddress()); MQTTSocket sock; MClient client(sock); - ret = sock.connect("tdxls-iot.xicp.net",1883); - if(ret != 0){ - printf("failed to connect to TCP server\r\n"); - return 1; - } - printf("sock.connect()=%d\r\n",ret); - - ret = client.connect(); - if(ret != 0){ - printf("MQTT connect failed\r\n"); - return 1; - } - printf("client.connect()=%d\r\n",ret); - - const char* actuators = "switch,int\n"; - const char* sensors = "analog,mV\n"; + //声明所有的传感器,每行一个,每个由名字、单位两部分组成,最后一行必须为空指针作为结尾 + const char* sensors[][2] = { + "test", " ", + "button", "V", + NULL, NULL //最后一行以空指针作为结束标记 + }; - ret = client.subscribe("/control/" NODE_NAME "/switch", MQTT::QOS1, messageArrived); - printf("sock.subscribe()=%d\r\n",ret); + //声明所有的执行器,每行一个,每个由名字、参数类型两部分组成,最后一行必须为空指针作为结尾 + const char* actuators[][2] = { + "led", "int", + NULL, NULL //最后一行以空指针作为结束标记 + }; + networking_init(sock, client, "tdxls-iot.xicp.net", sensors, actuators, on_control_cmd); - //节点上线消息 - meta_report(client, "events","online"); - //报告所有可接受的控制指令 - meta_report(client, "capability","control", actuators, strlen(actuators), true); - //报告所有的传感器 - meta_report(client, "capability","values", sensors, strlen(sensors), true); - bool btn = 0; while(1){ bool newBTN = BTN; if(newBTN != btn){ char buf[16]; - int value = newBTN ? 3300 : 0; + int value = (bool)newBTN; + sprintf(buf, "%d mV", value); - meta_report(client, "values","analog",buf,strlen(buf),true); + publish_value(client,"button",buf); + btn = newBTN; }else{ - client.yield(100); + client.yield(1000); + publish_value(client,"test","hello world"); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networking.cpp Mon Jun 04 15:16:05 2018 +0000 @@ -0,0 +1,165 @@ +#include "mbed.h" +#include "WIZnetInterface.h" +#include "MQTTSocket.h" +#include "MQTTClient.h" +#include "networking.h" + +extern Serial pc; + //W5500接线 mosi,miso,sclk,cs,reset +WIZnetInterface wiz(PB_5,PB_4,PB_3,PC_14,NC); +//节点名称任取 +#define NODE_NAME "n_12345" + //接在同一子网下的设备MAC地址必须不同 +uint8_t mac_addr[6]={0x50,0x51,0x50,0x00,0x00,0x01}; + +recv_ctl_cb g_recv_cb; +const char* (*g_actuators)[2]; +static Timer g_timer; + +void disable_LSE() //调用此函数将 PC_14, PC_15 用作普通I/O +{ + RCC_OscInitTypeDef OscInitStruct; + HAL_RCC_GetOscConfig(&OscInitStruct); +// pc.printf("%u %u %u %u\r\n",OscInitStruct.HSEState,OscInitStruct.LSEState,OscInitStruct.HSIState,OscInitStruct.LSIState); + + // Enable access to Backup domain + HAL_PWR_EnableBkUpAccess(); + // Reset Backup domain + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + // Disable access to Backup domain + HAL_PWR_DisableBkUpAccess(); + + OscInitStruct.LSEState=RCC_LSE_OFF; + HAL_RCC_OscConfig(&OscInitStruct); + + HAL_RCC_GetOscConfig(&OscInitStruct); +// pc.printf("%u %u %u %u\r\n",OscInitStruct.HSEState,OscInitStruct.LSEState,OscInitStruct.HSIState,OscInitStruct.LSIState); +} + + +void meta_report(MClient& client, const char* ns, const char* type, + 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", ns, type); + int ret = client.publish(topic, (void*)payload, payload_len, qos, retain); + //pc.printf("client.publish()=%d\r\n",ret); +} +void messageArrived(MQTT::MessageData& md) +{ + MQTT::Message &message = md.message; +// pc.printf("messageArrived '%s' %d,%d\r\n", md.topicName.cstring, md.topicName.lenstring.len, message.payloadlen); + +// char buf[64]; +// int value, len = sizeof(buf)-1; +// if(message.payloadlen < len) +// len = message.payloadlen; +// memcpy(buf, message.payload, len); +// buf[len] = '\0'; +// sscanf(buf, "%d", &value); +// pc.printf("received %d\r\n", value); + + char* payload = new char[message.payloadlen+1]; + if(!payload) + return; + memcpy(payload, message.payload, message.payloadlen); + payload[message.payloadlen]='\0'; + + 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'; + + char *pch = strtok (topic,"/"); + for (int tok=0; tok<2 && pch != NULL; tok++) + { +// pc.printf ("%s\r\n",pch); + pch = strtok (NULL, "/"); + } + if(pch) + g_recv_cb(pch, payload); + delete[] topic; + delete[] payload; +} + +void publish_value(MClient &client, const char *topic, const char *buf) +{ + meta_report(client, "values",topic,buf,strlen(buf),true); +} + +void buildCapability(char *out, const char* infoList[][2]) +{ + out[0] = '\0'; + for (int i = 0; infoList[i][0]; ++i) + { + strcat(out, infoList[i][0]); + strcat(out, ","); + strcat(out, infoList[i][1]); + strcat(out, "\\n"); + } +} + +int networking_init(MQTTSocket &sock, MClient &client, const char *broker,const char* sensors[][2], const char* actuators[][2], recv_ctl_cb cb) { + int ret; + g_timer.start(); + disable_LSE(); //free LSE pins + wiz.init(mac_addr); + pc.printf("DHCP...\r\n"); + wiz.connect(); + pc.printf("IP: %s\r\n", wiz.getIPAddress()); + + srand(rand()^g_timer.read_us()); + + ret = sock.connect((char*)broker,1883); + 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()); + + ret = client.connect(); + if(ret != 0){ + pc.printf("MQTT connect failed\r\n"); + return 1; + } + pc.printf("client.connect()=%d\r\n",ret); + + + ret = client.subscribe("/control/" NODE_NAME "/+", MQTT::QOS1, messageArrived); + pc.printf("sock.subscribe()=%d\r\n", ret); + + g_recv_cb = cb; + g_actuators = actuators; + + char * capabilities = new char[128]; + if(!capabilities){ + pc.printf("failed to alloc memory\r\n"); + return 1; + } + //for (int i = 0; actuators[i][0]; ++i){ +// sprintf(capabilities,"/control/" NODE_NAME "/+",actuators[i][0]); +// ret = client.subscribe(capabilities, MQTT::QOS1, messageArrived); +// pc.printf("sock.subscribe(%s)=%d\r\n", capabilities, ret); +// } + + //节点上线消息 + meta_report(client, "events","online"); + + //报告所有可接受的控制指令 + buildCapability(capabilities, actuators); + meta_report(client, "capability","control", capabilities, strlen(capabilities), true); + //报告所有的传感器 + buildCapability(capabilities, sensors); + meta_report(client, "capability","values", capabilities, strlen(capabilities), true); + delete[] capabilities; + + pc.printf("Initialization done.\r\n"); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networking.h Mon Jun 04 15:16:05 2018 +0000 @@ -0,0 +1,10 @@ +#pragma once + +#include "MQTTSocket.h" +#include "MQTTClient.h" + +typedef MQTT::Client<MQTTSocket,Countdown> MClient; +typedef void (*recv_ctl_cb)(const char*, const char*); + +int networking_init(MQTTSocket &sock, MClient &client, const char *broker,const char* sensors[][2], const char* actuators[][2], recv_ctl_cb cb); +void publish_value(MClient &client, const char *topic, const char *buf);