Project for course Appliance of MCU, School of Electrical engineering, Uni of Belgrade

Dependencies:   19E042PIM_MB_PINS Adafruit_GFX MAX44000 mbed-mqtt

Committer:
pavleradojkovic
Date:
Mon Jun 20 17:28:54 2022 +0000
Revision:
0:cd8f25aaf6d7
Child:
1:dbf4e2903500
When the button is not pressed sends data to MQTT broker

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pavleradojkovic 0:cd8f25aaf6d7 1
pavleradojkovic 0:cd8f25aaf6d7 2 #include "mbed.h"
pavleradojkovic 0:cd8f25aaf6d7 3 #include "mb_pins.h"
pavleradojkovic 0:cd8f25aaf6d7 4 #include "platform/mbed_thread.h"
pavleradojkovic 0:cd8f25aaf6d7 5 #include "MQTTClientMbedOs.h"
pavleradojkovic 0:cd8f25aaf6d7 6
pavleradojkovic 0:cd8f25aaf6d7 7
pavleradojkovic 0:cd8f25aaf6d7 8 // LED2 blinking rate:
pavleradojkovic 0:cd8f25aaf6d7 9 #define BLINKING_RATE_MS 250
pavleradojkovic 0:cd8f25aaf6d7 10 // Scaler to 3v3L
pavleradojkovic 0:cd8f25aaf6d7 11 #define VOLTAGE_SCALER 3.3f
pavleradojkovic 0:cd8f25aaf6d7 12 // Client yield timeout in miliseconds:
pavleradojkovic 0:cd8f25aaf6d7 13 #define YIELD_TIMEOUT_MS 1000
pavleradojkovic 0:cd8f25aaf6d7 14 // Maximum number of networks to scan for:
pavleradojkovic 0:cd8f25aaf6d7 15 #define MAX_NETWORKS 15
pavleradojkovic 0:cd8f25aaf6d7 16 // Small delay for network information printing:
pavleradojkovic 0:cd8f25aaf6d7 17 #define PRINTF_DELAY_MS 10
pavleradojkovic 0:cd8f25aaf6d7 18
pavleradojkovic 0:cd8f25aaf6d7 19
pavleradojkovic 0:cd8f25aaf6d7 20 // Left potentiometer:
pavleradojkovic 0:cd8f25aaf6d7 21 AnalogIn pot1(MB_POT1);
pavleradojkovic 0:cd8f25aaf6d7 22 // Left button on the motherboard:
pavleradojkovic 0:cd8f25aaf6d7 23 InterruptIn sw1(MB_SW1);
pavleradojkovic 0:cd8f25aaf6d7 24 // Right LED on the motherboard:
pavleradojkovic 0:cd8f25aaf6d7 25 DigitalOut led2(MB_LED2);
pavleradojkovic 0:cd8f25aaf6d7 26 // Pointer to a WiFi network object:
pavleradojkovic 0:cd8f25aaf6d7 27 WiFiInterface *wifi;
pavleradojkovic 0:cd8f25aaf6d7 28 // Creating TCP socket: - not in use
pavleradojkovic 0:cd8f25aaf6d7 29 TCPSocket socket;
pavleradojkovic 0:cd8f25aaf6d7 30 // Creating TLS socket:
pavleradojkovic 0:cd8f25aaf6d7 31 TLSSocket tlsSocket;
pavleradojkovic 0:cd8f25aaf6d7 32 // Creating MQTT client using the TCP socket;
pavleradojkovic 0:cd8f25aaf6d7 33 MQTTClient client(&socket);
pavleradojkovic 0:cd8f25aaf6d7 34 // Message handler:
pavleradojkovic 0:cd8f25aaf6d7 35 MQTT::Message message;
pavleradojkovic 0:cd8f25aaf6d7 36
pavleradojkovic 0:cd8f25aaf6d7 37 char* topic = "mbed-sample-pub";
pavleradojkovic 0:cd8f25aaf6d7 38 char* topic_sub = "mbed-sample-sub";
pavleradojkovic 0:cd8f25aaf6d7 39 // Counter of arrived messages:
pavleradojkovic 0:cd8f25aaf6d7 40 int arrivedcount = 0;
pavleradojkovic 0:cd8f25aaf6d7 41 // Flag indicating that button is not pressed:
pavleradojkovic 0:cd8f25aaf6d7 42 int button_pressed=0;
pavleradojkovic 0:cd8f25aaf6d7 43 // HiveMQ broker connectivity information:
pavleradojkovic 0:cd8f25aaf6d7 44 const char* hostname = "broker.mqttdashboard.com";
pavleradojkovic 0:cd8f25aaf6d7 45 int port = 1883;
pavleradojkovic 0:cd8f25aaf6d7 46 // Returning a string for a provided network encryption:
pavleradojkovic 0:cd8f25aaf6d7 47 const char *sec2str(nsapi_security_t sec)
pavleradojkovic 0:cd8f25aaf6d7 48 {
pavleradojkovic 0:cd8f25aaf6d7 49 switch (sec)
pavleradojkovic 0:cd8f25aaf6d7 50 {
pavleradojkovic 0:cd8f25aaf6d7 51 case NSAPI_SECURITY_NONE:
pavleradojkovic 0:cd8f25aaf6d7 52 return "None";
pavleradojkovic 0:cd8f25aaf6d7 53 case NSAPI_SECURITY_WEP:
pavleradojkovic 0:cd8f25aaf6d7 54 return "WEP";
pavleradojkovic 0:cd8f25aaf6d7 55 case NSAPI_SECURITY_WPA:
pavleradojkovic 0:cd8f25aaf6d7 56 return "WPA";
pavleradojkovic 0:cd8f25aaf6d7 57 case NSAPI_SECURITY_WPA2:
pavleradojkovic 0:cd8f25aaf6d7 58 return "WPA2";
pavleradojkovic 0:cd8f25aaf6d7 59 case NSAPI_SECURITY_WPA_WPA2:
pavleradojkovic 0:cd8f25aaf6d7 60 return "WPA/WPA2";
pavleradojkovic 0:cd8f25aaf6d7 61 case NSAPI_SECURITY_UNKNOWN:
pavleradojkovic 0:cd8f25aaf6d7 62 default:
pavleradojkovic 0:cd8f25aaf6d7 63 return "Unknown";
pavleradojkovic 0:cd8f25aaf6d7 64 }
pavleradojkovic 0:cd8f25aaf6d7 65 }
pavleradojkovic 0:cd8f25aaf6d7 66
pavleradojkovic 0:cd8f25aaf6d7 67 int scan_networks(WiFiInterface *wifi)
pavleradojkovic 0:cd8f25aaf6d7 68 {
pavleradojkovic 0:cd8f25aaf6d7 69 printf("Scan:\n");
pavleradojkovic 0:cd8f25aaf6d7 70
pavleradojkovic 0:cd8f25aaf6d7 71 // Scan only for the number of networks, first parameter is NULL:
pavleradojkovic 0:cd8f25aaf6d7 72 int count = wifi->scan(NULL, 0);
pavleradojkovic 0:cd8f25aaf6d7 73 // If there are no networks, count == 0, if there is an error, counter < 0:
pavleradojkovic 0:cd8f25aaf6d7 74 if (count <= 0)
pavleradojkovic 0:cd8f25aaf6d7 75 {
pavleradojkovic 0:cd8f25aaf6d7 76 printf("scan() failed with return value: %d\n", count);
pavleradojkovic 0:cd8f25aaf6d7 77 return 0;
pavleradojkovic 0:cd8f25aaf6d7 78 }
pavleradojkovic 0:cd8f25aaf6d7 79
pavleradojkovic 0:cd8f25aaf6d7 80 // Limit number of network arbitrary to some reasonable number:
pavleradojkovic 0:cd8f25aaf6d7 81 count = count < MAX_NETWORKS ? count : MAX_NETWORKS;
pavleradojkovic 0:cd8f25aaf6d7 82
pavleradojkovic 0:cd8f25aaf6d7 83 // Create a local pointer to an object, which is an array of WiFi APs:
pavleradojkovic 0:cd8f25aaf6d7 84 WiFiAccessPoint *ap = new WiFiAccessPoint[count];
pavleradojkovic 0:cd8f25aaf6d7 85 // Now scan again for 'count' networks and populate the array of APs:
pavleradojkovic 0:cd8f25aaf6d7 86 count = wifi->scan(ap, count);
pavleradojkovic 0:cd8f25aaf6d7 87
pavleradojkovic 0:cd8f25aaf6d7 88 // This time, the number of entries to 'ap' is returned:
pavleradojkovic 0:cd8f25aaf6d7 89 if (count <= 0)
pavleradojkovic 0:cd8f25aaf6d7 90 {
pavleradojkovic 0:cd8f25aaf6d7 91 printf("scan() failed with return value: %d\n", count);
pavleradojkovic 0:cd8f25aaf6d7 92 return 0;
pavleradojkovic 0:cd8f25aaf6d7 93 }
pavleradojkovic 0:cd8f25aaf6d7 94
pavleradojkovic 0:cd8f25aaf6d7 95 // Print out the parameters of each AP:
pavleradojkovic 0:cd8f25aaf6d7 96 for (int i = 0; i < count; i++)
pavleradojkovic 0:cd8f25aaf6d7 97 {
pavleradojkovic 0:cd8f25aaf6d7 98 printf("Network: %s secured: %s BSSID: %hhX:%hhX:%hhX:%hhx:%hhx:%hhx RSSI: %hhd Ch: %hhd\n", ap[i].get_ssid(),
pavleradojkovic 0:cd8f25aaf6d7 99 sec2str(ap[i].get_security()), ap[i].get_bssid()[0], ap[i].get_bssid()[1], ap[i].get_bssid()[2],
pavleradojkovic 0:cd8f25aaf6d7 100 ap[i].get_bssid()[3], ap[i].get_bssid()[4], ap[i].get_bssid()[5], ap[i].get_rssi(), ap[i].get_channel());
pavleradojkovic 0:cd8f25aaf6d7 101 thread_sleep_for(PRINTF_DELAY_MS);
pavleradojkovic 0:cd8f25aaf6d7 102 }
pavleradojkovic 0:cd8f25aaf6d7 103 printf("%d networks available.\n", count);
pavleradojkovic 0:cd8f25aaf6d7 104
pavleradojkovic 0:cd8f25aaf6d7 105 // Since 'ap' is dynamically allocated pointer to the array of objects, it
pavleradojkovic 0:cd8f25aaf6d7 106 // needs to be deleted:
pavleradojkovic 0:cd8f25aaf6d7 107 delete[] ap;
pavleradojkovic 0:cd8f25aaf6d7 108 return count;
pavleradojkovic 0:cd8f25aaf6d7 109 }
pavleradojkovic 0:cd8f25aaf6d7 110
pavleradojkovic 0:cd8f25aaf6d7 111 void messageArrived(MQTT::MessageData& md)
pavleradojkovic 0:cd8f25aaf6d7 112 {
pavleradojkovic 0:cd8f25aaf6d7 113 MQTT::Message &message = md.message;
pavleradojkovic 0:cd8f25aaf6d7 114 //printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
pavleradojkovic 0:cd8f25aaf6d7 115 printf("Message from the browser: %.*s\r\n", message.payloadlen, (char*)message.payload);
pavleradojkovic 0:cd8f25aaf6d7 116 ++arrivedcount;
pavleradojkovic 0:cd8f25aaf6d7 117 }
pavleradojkovic 0:cd8f25aaf6d7 118
pavleradojkovic 0:cd8f25aaf6d7 119 void buttonFunction() {
pavleradojkovic 0:cd8f25aaf6d7 120
pavleradojkovic 0:cd8f25aaf6d7 121 button_pressed=1;
pavleradojkovic 0:cd8f25aaf6d7 122
pavleradojkovic 0:cd8f25aaf6d7 123 }
pavleradojkovic 0:cd8f25aaf6d7 124
pavleradojkovic 0:cd8f25aaf6d7 125 int main()
pavleradojkovic 0:cd8f25aaf6d7 126 {
pavleradojkovic 0:cd8f25aaf6d7 127 // Set the interrupt event:
pavleradojkovic 0:cd8f25aaf6d7 128 sw1.rise(&buttonFunction);
pavleradojkovic 0:cd8f25aaf6d7 129
pavleradojkovic 0:cd8f25aaf6d7 130 // Create a default network interface:
pavleradojkovic 0:cd8f25aaf6d7 131 wifi = WiFiInterface::get_default_instance();
pavleradojkovic 0:cd8f25aaf6d7 132 if (!wifi) {
pavleradojkovic 0:cd8f25aaf6d7 133 printf("ERROR: No WiFiInterface found.\n");
pavleradojkovic 0:cd8f25aaf6d7 134 return -1;
pavleradojkovic 0:cd8f25aaf6d7 135 }
pavleradojkovic 0:cd8f25aaf6d7 136
pavleradojkovic 0:cd8f25aaf6d7 137 // Scan for available networks and aquire information about Access Points:
pavleradojkovic 0:cd8f25aaf6d7 138 int count = scan_networks(wifi);
pavleradojkovic 0:cd8f25aaf6d7 139 if (count == 0) {
pavleradojkovic 0:cd8f25aaf6d7 140 printf("No WIFI APs found - can't continue further.\n");
pavleradojkovic 0:cd8f25aaf6d7 141 return -1;
pavleradojkovic 0:cd8f25aaf6d7 142 }
pavleradojkovic 0:cd8f25aaf6d7 143
pavleradojkovic 0:cd8f25aaf6d7 144 // Connect to the network with the parameters specified in 'mbed_app.json':
pavleradojkovic 0:cd8f25aaf6d7 145 printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID);
pavleradojkovic 0:cd8f25aaf6d7 146 int ret = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
pavleradojkovic 0:cd8f25aaf6d7 147 if (ret != 0) {
pavleradojkovic 0:cd8f25aaf6d7 148 printf("\nConnection error: %d\n", ret);
pavleradojkovic 0:cd8f25aaf6d7 149 return -1;
pavleradojkovic 0:cd8f25aaf6d7 150 }
pavleradojkovic 0:cd8f25aaf6d7 151
pavleradojkovic 0:cd8f25aaf6d7 152 // Print out the information aquired:
pavleradojkovic 0:cd8f25aaf6d7 153 printf("Success\n\n");
pavleradojkovic 0:cd8f25aaf6d7 154 printf("MAC: %s\n", wifi->get_mac_address());
pavleradojkovic 0:cd8f25aaf6d7 155 printf("IP: %s\n", wifi->get_ip_address());
pavleradojkovic 0:cd8f25aaf6d7 156 printf("Netmask: %s\n", wifi->get_netmask());
pavleradojkovic 0:cd8f25aaf6d7 157 printf("Gateway: %s\n", wifi->get_gateway());
pavleradojkovic 0:cd8f25aaf6d7 158 printf("RSSI: %d\n\n", wifi->get_rssi());
pavleradojkovic 0:cd8f25aaf6d7 159
pavleradojkovic 0:cd8f25aaf6d7 160 // Open TCP socket using WiFi network interface:
pavleradojkovic 0:cd8f25aaf6d7 161 socket.open(wifi);
pavleradojkovic 0:cd8f25aaf6d7 162 // Connect to the HiveMQ broker:
pavleradojkovic 0:cd8f25aaf6d7 163 socket.connect(hostname, port);
pavleradojkovic 0:cd8f25aaf6d7 164 // Fill connect data with default values:
pavleradojkovic 0:cd8f25aaf6d7 165 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
pavleradojkovic 0:cd8f25aaf6d7 166 // Change only ID and protocol version:
pavleradojkovic 0:cd8f25aaf6d7 167 data.MQTTVersion = 3;
pavleradojkovic 0:cd8f25aaf6d7 168 data.clientID.cstring = "NUCLEO-L476RG-64";
pavleradojkovic 0:cd8f25aaf6d7 169 // Connect the
pavleradojkovic 0:cd8f25aaf6d7 170 int rc = 0;
pavleradojkovic 0:cd8f25aaf6d7 171 if ((rc = client.connect(data)) != 0)
pavleradojkovic 0:cd8f25aaf6d7 172 printf("rc from MQTT connect is %d\n", rc);
pavleradojkovic 0:cd8f25aaf6d7 173
pavleradojkovic 0:cd8f25aaf6d7 174 if ((rc = client.subscribe(topic_sub, MQTT::QOS2, messageArrived)) != 0)
pavleradojkovic 0:cd8f25aaf6d7 175 printf("rc from MQTT subscribe is %d\n", rc);
pavleradojkovic 0:cd8f25aaf6d7 176
pavleradojkovic 0:cd8f25aaf6d7 177 while (true) {
pavleradojkovic 0:cd8f25aaf6d7 178 // Show that the loop is running by switching motherboard LED2:
pavleradojkovic 0:cd8f25aaf6d7 179 led2 = !led2;
pavleradojkovic 0:cd8f25aaf6d7 180 thread_sleep_for(BLINKING_RATE_MS);
pavleradojkovic 0:cd8f25aaf6d7 181 if (button_pressed==1) {
pavleradojkovic 0:cd8f25aaf6d7 182 button_pressed=0;
pavleradojkovic 0:cd8f25aaf6d7 183 // QoS 0
pavleradojkovic 0:cd8f25aaf6d7 184 char buf[100];
pavleradojkovic 0:cd8f25aaf6d7 185 sprintf(buf, "V(POT1) = %1.2f\r\n", pot1*VOLTAGE_SCALER);
pavleradojkovic 0:cd8f25aaf6d7 186 message.qos = MQTT::QOS0;
pavleradojkovic 0:cd8f25aaf6d7 187 message.retained = false;
pavleradojkovic 0:cd8f25aaf6d7 188 message.dup = false;
pavleradojkovic 0:cd8f25aaf6d7 189 message.payload = (void*)buf;
pavleradojkovic 0:cd8f25aaf6d7 190 message.payloadlen = strlen(buf)+1;
pavleradojkovic 0:cd8f25aaf6d7 191 client.publish(topic, message);
pavleradojkovic 0:cd8f25aaf6d7 192 }
pavleradojkovic 0:cd8f25aaf6d7 193 // Need to call yield API to maintain connection:
pavleradojkovic 0:cd8f25aaf6d7 194 client.yield(YIELD_TIMEOUT_MS);
pavleradojkovic 0:cd8f25aaf6d7 195 }
pavleradojkovic 0:cd8f25aaf6d7 196 }
pavleradojkovic 0:cd8f25aaf6d7 197