Wouter Van den Bogaert
/
PGO6_VoteController_template
PGO6
main.cpp@6:754d3e8f9ae9, 2019-11-14 (annotated)
- Committer:
- s0130594
- Date:
- Thu Nov 14 15:07:12 2019 +0100
- Revision:
- 6:754d3e8f9ae9
- Parent:
- 4:15e7cac255da
Added MQTT functionality
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jensdehoog | 0:fd29cd85e75e | 1 | #define APP_VERSION 0.6f |
jensdehoog | 0:fd29cd85e75e | 2 | #define MQTT_VERSION 3 |
jensdehoog | 0:fd29cd85e75e | 3 | #define BROKER_NAME "broker.hivemq.com" |
jensdehoog | 0:fd29cd85e75e | 4 | #define BROKER_PORT 1883 |
jensdehoog | 0:fd29cd85e75e | 5 | |
jensdehoog | 0:fd29cd85e75e | 6 | #include "debounce_button.h" |
jensdehoog | 0:fd29cd85e75e | 7 | #include "EthernetInterface.h" |
jensdehoog | 0:fd29cd85e75e | 8 | #include "MQTTNetwork.h" |
jensdehoog | 0:fd29cd85e75e | 9 | #include "MQTTmbed.h" |
jensdehoog | 0:fd29cd85e75e | 10 | #include "MQTTClient.h" |
s0130594 | 3:14b20a4f36d0 | 11 | #include "mbed.h" |
s0130594 | 4:15e7cac255da | 12 | #include "easy-connect/easy-connect.h" |
jensdehoog | 0:fd29cd85e75e | 13 | |
jensdehoog | 0:fd29cd85e75e | 14 | char* topic; |
s0130594 | 3:14b20a4f36d0 | 15 | Serial pc(USBTX, USBRX); |
s0130594 | 4:15e7cac255da | 16 | |
s0130594 | 4:15e7cac255da | 17 | /** hier copy */ |
s0130594 | 4:15e7cac255da | 18 | volatile bool button1_pressed = false; // Used in the main loop |
s0130594 | 4:15e7cac255da | 19 | volatile bool button1_enabled = true; // Used for debouncing |
s0130594 | 4:15e7cac255da | 20 | volatile int multiclick_state =0 ; // Counts how many clicks occured in the time slot, used in main loop |
s0130594 | 4:15e7cac255da | 21 | volatile bool button1_busy = false; // Informs the mainloop that the user is clicking the button |
s0130594 | 4:15e7cac255da | 22 | volatile int button_count =0; // counter for number of clicks within 1 second |
s0130594 | 4:15e7cac255da | 23 | volatile bool disp = false; // show eindtotaal |
s0130594 | 4:15e7cac255da | 24 | |
s0130594 | 4:15e7cac255da | 25 | void button1_multiclick_reset_cb(void); // Resets the amount of clicks, but stores this value for the usage in the main loop |
s0130594 | 4:15e7cac255da | 26 | void button1_enabled_cb(void); // Enables the button again after a timeout, used for debouncing the button |
s0130594 | 4:15e7cac255da | 27 | void button1_onpressed_cb(void); // Callback which is called when the user presses the button |
s0130594 | 4:15e7cac255da | 28 | |
s0130594 | 4:15e7cac255da | 29 | DigitalOut led1(LED1); |
s0130594 | 4:15e7cac255da | 30 | DigitalOut led2(LED2); |
s0130594 | 4:15e7cac255da | 31 | DigitalOut led3(LED3); |
s0130594 | 4:15e7cac255da | 32 | Timeout someTimeout; |
s0130594 | 4:15e7cac255da | 33 | Timeout someTimeout2; |
s0130594 | 4:15e7cac255da | 34 | |
s0130594 | 4:15e7cac255da | 35 | int arrivedcount = 0; |
s0130594 | 4:15e7cac255da | 36 | |
s0130594 | 4:15e7cac255da | 37 | |
s0130594 | 4:15e7cac255da | 38 | /** end copy */ |
s0130594 | 4:15e7cac255da | 39 | |
s0130594 | 4:15e7cac255da | 40 | #include "debounce_button.h" |
s0130594 | 4:15e7cac255da | 41 | |
s0130594 | 4:15e7cac255da | 42 | /** |
s0130594 | 4:15e7cac255da | 43 | Some tips and tricks: |
s0130594 | 4:15e7cac255da | 44 | - To use the built-in LED: |
s0130594 | 4:15e7cac255da | 45 | DigitalOut led1(LED1); |
s0130594 | 4:15e7cac255da | 46 | ... |
s0130594 | 4:15e7cac255da | 47 | led1 = 1; |
s0130594 | 4:15e7cac255da | 48 | - To delay the call of a function: |
s0130594 | 4:15e7cac255da | 49 | Timeout someTimeout; |
s0130594 | 4:15e7cac255da | 50 | ... |
s0130594 | 4:15e7cac255da | 51 | someTimeout.attach(callback(&someFunction), 0.5) with 0.5 as 500 milliseconds |
s0130594 | 4:15e7cac255da | 52 | - The variables that are used in interrupt callbacks have to be volatile, |
s0130594 | 4:15e7cac255da | 53 | because these variables can change at any time. Therefore, the compiler is not |
s0130594 | 4:15e7cac255da | 54 | going to make optimisations. |
s0130594 | 4:15e7cac255da | 55 | */ |
s0130594 | 4:15e7cac255da | 56 | |
s0130594 | 4:15e7cac255da | 57 | /** |
s0130594 | 4:15e7cac255da | 58 | TODO |
s0130594 | 4:15e7cac255da | 59 | ---- |
s0130594 | 4:15e7cac255da | 60 | This function: |
s0130594 | 4:15e7cac255da | 61 | - stores the amount of clicks in a variable which is read by the main loop. |
s0130594 | 4:15e7cac255da | 62 | - resets the click counter which is used inside this file. |
s0130594 | 4:15e7cac255da | 63 | - lowers a flag which tells the main loop that the user stopped pressing the button |
s0130594 | 4:15e7cac255da | 64 | such that it can proceed its program. |
s0130594 | 4:15e7cac255da | 65 | - turns the built-in LED off. Therefore, the user gets informed that the program stopped counting the clicks. |
s0130594 | 4:15e7cac255da | 66 | */ |
s0130594 | 4:15e7cac255da | 67 | void button1_multiclick_reset_cb(void) { |
s0130594 | 4:15e7cac255da | 68 | led3=1; |
s0130594 | 4:15e7cac255da | 69 | //pc.printf("Time to reset alles"); |
s0130594 | 4:15e7cac255da | 70 | button_count = multiclick_state; |
s0130594 | 4:15e7cac255da | 71 | multiclick_state =0; |
s0130594 | 4:15e7cac255da | 72 | disp=true; |
s0130594 | 4:15e7cac255da | 73 | |
s0130594 | 4:15e7cac255da | 74 | button1_busy = false; |
s0130594 | 4:15e7cac255da | 75 | button1_pressed = false; |
s0130594 | 4:15e7cac255da | 76 | |
s0130594 | 4:15e7cac255da | 77 | DigitalOut led1(LED1); |
s0130594 | 4:15e7cac255da | 78 | led1 = 0; |
s0130594 | 4:15e7cac255da | 79 | |
s0130594 | 4:15e7cac255da | 80 | } |
s0130594 | 4:15e7cac255da | 81 | |
s0130594 | 4:15e7cac255da | 82 | /** |
s0130594 | 4:15e7cac255da | 83 | TODO |
s0130594 | 4:15e7cac255da | 84 | ---- |
s0130594 | 4:15e7cac255da | 85 | This function enables the button again, such that unwanted clicks of the bouncing button get ignored. |
s0130594 | 4:15e7cac255da | 86 | */ |
s0130594 | 4:15e7cac255da | 87 | void button1_enabled_cb(void) |
s0130594 | 4:15e7cac255da | 88 | { |
s0130594 | 4:15e7cac255da | 89 | button1_enabled = true; |
s0130594 | 4:15e7cac255da | 90 | led2=0; |
s0130594 | 4:15e7cac255da | 91 | |
s0130594 | 4:15e7cac255da | 92 | } |
s0130594 | 4:15e7cac255da | 93 | |
s0130594 | 4:15e7cac255da | 94 | /** |
s0130594 | 4:15e7cac255da | 95 | TODO |
s0130594 | 4:15e7cac255da | 96 | ---- |
s0130594 | 4:15e7cac255da | 97 | This function: |
s0130594 | 4:15e7cac255da | 98 | - turns the built-in LED on, so the user gets informed that the program has started with counting clicks |
s0130594 | 4:15e7cac255da | 99 | - disables the button such that the debouncer is active |
s0130594 | 4:15e7cac255da | 100 | - enables the button again after a certain amount of time |
s0130594 | 4:15e7cac255da | 101 | (use interrupts with "button1_enabled_cb()" as callback. |
s0130594 | 4:15e7cac255da | 102 | - counts the amount of clicks within a period of 1 second |
s0130594 | 4:15e7cac255da | 103 | - informs the main loop that the button has been pressed |
s0130594 | 4:15e7cac255da | 104 | - informs the main loop that the user is clicking the button. |
s0130594 | 4:15e7cac255da | 105 | Therefore, this main loop cannot continue its procedure until the clicks within 1 second have been counted. |
s0130594 | 4:15e7cac255da | 106 | */ |
s0130594 | 4:15e7cac255da | 107 | void button1_onpressed_cb(void) |
s0130594 | 4:15e7cac255da | 108 | { |
s0130594 | 4:15e7cac255da | 109 | // Turn led on |
s0130594 | 4:15e7cac255da | 110 | led1 = 1; |
s0130594 | 4:15e7cac255da | 111 | led2= 0; |
s0130594 | 4:15e7cac255da | 112 | // Set button disabled |
s0130594 | 4:15e7cac255da | 113 | if(button1_enabled){ |
s0130594 | 4:15e7cac255da | 114 | multiclick_state++; |
s0130594 | 4:15e7cac255da | 115 | button1_enabled = false; |
s0130594 | 4:15e7cac255da | 116 | led2=1; |
s0130594 | 4:15e7cac255da | 117 | //pc.printf("Nu is de button1_enabled false"); |
s0130594 | 4:15e7cac255da | 118 | //pc.printf("Multiclickstate is nu: %d", multiclick_state); |
s0130594 | 4:15e7cac255da | 119 | someTimeout.attach(callback(button1_enabled_cb), 0.2); |
s0130594 | 4:15e7cac255da | 120 | } |
s0130594 | 4:15e7cac255da | 121 | |
s0130594 | 4:15e7cac255da | 122 | |
s0130594 | 4:15e7cac255da | 123 | // Inform main loop that user is clicking the button |
s0130594 | 4:15e7cac255da | 124 | button1_busy = true; |
s0130594 | 4:15e7cac255da | 125 | |
s0130594 | 4:15e7cac255da | 126 | // Do a count after 1 second |
s0130594 | 4:15e7cac255da | 127 | if(!button1_pressed){ |
s0130594 | 4:15e7cac255da | 128 | // Inform main loop that button has been pressed |
s0130594 | 4:15e7cac255da | 129 | //pc.printf("Registering callback for within 1 second"); |
s0130594 | 4:15e7cac255da | 130 | button1_pressed = true; |
s0130594 | 4:15e7cac255da | 131 | led3=0; |
s0130594 | 4:15e7cac255da | 132 | someTimeout2.attach(callback(button1_multiclick_reset_cb), 1); |
s0130594 | 4:15e7cac255da | 133 | } |
s0130594 | 4:15e7cac255da | 134 | |
s0130594 | 4:15e7cac255da | 135 | } |
s0130594 | 4:15e7cac255da | 136 | |
jensdehoog | 0:fd29cd85e75e | 137 | /** |
jensdehoog | 0:fd29cd85e75e | 138 | TODO |
jensdehoog | 0:fd29cd85e75e | 139 | ---- |
jensdehoog | 0:fd29cd85e75e | 140 | - Check if the button has been pressed. If so, print the amount of clicks to a serial terminal. |
jensdehoog | 0:fd29cd85e75e | 141 | - Make an MQTT-service which: |
jensdehoog | 0:fd29cd85e75e | 142 | - starts up a network using EthernetInterface. Make sure the development board requests its address via DHCP. |
jensdehoog | 0:fd29cd85e75e | 143 | - makes a client and connects it to the broker using a client ID and credentials (username & password). |
jensdehoog | 0:fd29cd85e75e | 144 | - sends messages at the same topic as the smartphone app from PGO 2. Feel free to choose which Quality of Service |
jensdehoog | 0:fd29cd85e75e | 145 | you are going to use. Make a separate function which handles the sending procedure. Therefore, this function |
jensdehoog | 0:fd29cd85e75e | 146 | can be called each time we want to send a certain message. |
jensdehoog | 0:fd29cd85e75e | 147 | - When the button is pressed once, we send an upvote. When pressed twice, a downvote is sent. By pressing 4 times, |
jensdehoog | 0:fd29cd85e75e | 148 | the program disconnects from the broker and terminates. |
jensdehoog | 0:fd29cd85e75e | 149 | |
jensdehoog | 0:fd29cd85e75e | 150 | Extra |
jensdehoog | 0:fd29cd85e75e | 151 | ----- |
jensdehoog | 0:fd29cd85e75e | 152 | - Subscribe to the topic on which the song data is published. Display this received message on the serial terminal. |
jensdehoog | 0:fd29cd85e75e | 153 | - Test this controller in the complete system of PGO 2. Use these controllers instead of the smartphones. |
jensdehoog | 0:fd29cd85e75e | 154 | |
jensdehoog | 0:fd29cd85e75e | 155 | Tips & tricks |
jensdehoog | 0:fd29cd85e75e | 156 | ------------- |
jensdehoog | 0:fd29cd85e75e | 157 | - To generate an interrupt on the press of a button, use: |
jensdehoog | 0:fd29cd85e75e | 158 | InterruptIn button(USER_BUTTON); |
jensdehoog | 0:fd29cd85e75e | 159 | ... |
jensdehoog | 0:fd29cd85e75e | 160 | button.fall(callback(someFunction)); |
jensdehoog | 0:fd29cd85e75e | 161 | - Before implementing MQTT, test the multiclick feature first. |
jensdehoog | 0:fd29cd85e75e | 162 | - Have a look at the MQTT-library for Mbed and the HelloMQTT-example. |
jensdehoog | 0:fd29cd85e75e | 163 | - To have a uniform message sending procedure, use the following function usage: |
jensdehoog | 0:fd29cd85e75e | 164 | sendMessage(&client, topic, buf, qos, retained, duplicate) |
jensdehoog | 0:fd29cd85e75e | 165 | */ |
jensdehoog | 0:fd29cd85e75e | 166 | |
jensdehoog | 0:fd29cd85e75e | 167 | int main(int argc, char* argv[]) |
jensdehoog | 0:fd29cd85e75e | 168 | { |
s0130594 | 4:15e7cac255da | 169 | led3=1; |
s0130594 | 3:14b20a4f36d0 | 170 | InterruptIn button(USER_BUTTON); |
s0130594 | 4:15e7cac255da | 171 | button.fall(callback(&button1_onpressed_cb)); |
s0130594 | 3:14b20a4f36d0 | 172 | pc.printf("Print print \n"); |
s0130594 | 6:754d3e8f9ae9 | 173 | topic = "IGNISVOTESPOSTINGBETA"; |
s0130594 | 4:15e7cac255da | 174 | NetworkInterface* network = easy_connect(true); |
s0130594 | 4:15e7cac255da | 175 | if (!network) { |
s0130594 | 4:15e7cac255da | 176 | pc.printf("Je netwerk is kapot"); |
s0130594 | 4:15e7cac255da | 177 | return -1; |
s0130594 | 4:15e7cac255da | 178 | } |
s0130594 | 4:15e7cac255da | 179 | |
s0130594 | 4:15e7cac255da | 180 | MQTTNetwork mqttNetwork(network); |
s0130594 | 4:15e7cac255da | 181 | MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork); |
s0130594 | 4:15e7cac255da | 182 | |
s0130594 | 4:15e7cac255da | 183 | const char* hostname = BROKER_NAME; |
s0130594 | 4:15e7cac255da | 184 | int port = BROKER_PORT; |
s0130594 | 4:15e7cac255da | 185 | |
s0130594 | 4:15e7cac255da | 186 | pc.printf("Connecting to %s:%d\r\n", hostname, port); |
s0130594 | 4:15e7cac255da | 187 | int rc = mqttNetwork.connect(hostname, port); |
s0130594 | 4:15e7cac255da | 188 | if (rc != 0) |
s0130594 | 4:15e7cac255da | 189 | pc.printf("rc from TCP connect is %d\r\n", rc); |
s0130594 | 6:754d3e8f9ae9 | 190 | pc.printf("result van connecten %d\r\n", rc); |
s0130594 | 4:15e7cac255da | 191 | |
s0130594 | 6:754d3e8f9ae9 | 192 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
s0130594 | 6:754d3e8f9ae9 | 193 | data.MQTTVersion = 3; |
s0130594 | 6:754d3e8f9ae9 | 194 | data.clientID.cstring = "mbed-sample"; |
s0130594 | 6:754d3e8f9ae9 | 195 | data.username.cstring = "testuser"; |
s0130594 | 6:754d3e8f9ae9 | 196 | data.password.cstring = "testpassword"; |
s0130594 | 6:754d3e8f9ae9 | 197 | if ((rc = client.connect(data)) != 0) |
s0130594 | 6:754d3e8f9ae9 | 198 | pc.printf("rc from MQTT connect is %d\r\n", rc); |
s0130594 | 4:15e7cac255da | 199 | |
s0130594 | 6:754d3e8f9ae9 | 200 | pc.printf("rc from MQTT connect is %d\r\n", rc); |
s0130594 | 4:15e7cac255da | 201 | |
s0130594 | 3:14b20a4f36d0 | 202 | while(true){ |
s0130594 | 4:15e7cac255da | 203 | if(disp){ |
s0130594 | 3:14b20a4f36d0 | 204 | // Toon eindtotaal |
s0130594 | 4:15e7cac255da | 205 | pc.printf("Er is zoveel keer geklikt: %d \n",button_count); |
s0130594 | 4:15e7cac255da | 206 | disp=false; |
s0130594 | 6:754d3e8f9ae9 | 207 | |
s0130594 | 6:754d3e8f9ae9 | 208 | // QoS 2 |
s0130594 | 6:754d3e8f9ae9 | 209 | MQTT::Message message; |
s0130594 | 6:754d3e8f9ae9 | 210 | char buf[100]; |
s0130594 | 6:754d3e8f9ae9 | 211 | sprintf(buf, "Er is %d keer geklikt",button_count); |
s0130594 | 6:754d3e8f9ae9 | 212 | message.qos = MQTT::QOS1; |
s0130594 | 6:754d3e8f9ae9 | 213 | message.retained = false; |
s0130594 | 6:754d3e8f9ae9 | 214 | message.dup = false; |
s0130594 | 6:754d3e8f9ae9 | 215 | message.payload = (void*)buf; |
s0130594 | 6:754d3e8f9ae9 | 216 | message.payloadlen = strlen(buf)+1; |
s0130594 | 6:754d3e8f9ae9 | 217 | pc.printf("ik ga nu publishen"); |
s0130594 | 6:754d3e8f9ae9 | 218 | rc = client.publish(topic, message); |
s0130594 | 3:14b20a4f36d0 | 219 | } |
s0130594 | 3:14b20a4f36d0 | 220 | } |
s0130594 | 6:754d3e8f9ae9 | 221 | |
s0130594 | 6:754d3e8f9ae9 | 222 | pc.printf("result van publishen %d\r\n", rc); |
s0130594 | 6:754d3e8f9ae9 | 223 | if ((rc = client.unsubscribe(topic)) != 0) |
s0130594 | 6:754d3e8f9ae9 | 224 | pc.printf("rc from unsubscribe was %d\r\n", rc); |
s0130594 | 6:754d3e8f9ae9 | 225 | |
s0130594 | 6:754d3e8f9ae9 | 226 | if ((rc = client.disconnect()) != 0) |
s0130594 | 6:754d3e8f9ae9 | 227 | pc.printf("rc from disconnect was %d\r\n", rc); |
s0130594 | 6:754d3e8f9ae9 | 228 | pc.printf("Version %.2f: finish %d msgs\r\n", 1111, arrivedcount); |
s0130594 | 6:754d3e8f9ae9 | 229 | mqttNetwork.disconnect(); |
jensdehoog | 0:fd29cd85e75e | 230 | return 0; |
jensdehoog | 0:fd29cd85e75e | 231 | } |