19E042PIM 2021/22 T3 Key

Dependencies:   Adafruit_GFX 19E042PIM_MB_PINS

Committer:
tzwell
Date:
Wed Dec 15 22:31:26 2021 +0000
Revision:
0:e60b621e14a5
Test 3 key, first commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tzwell 0:e60b621e14a5 1 /*
tzwell 0:e60b621e14a5 2 * Upon receiving 'start' mcu starts sending voltage values stampled from POT1.
tzwell 0:e60b621e14a5 3 * When 'stop' is received, sending is stopped, while after receving 'oled',
tzwell 0:e60b621e14a5 4 * message transaction is displayed on OLED display.
tzwell 0:e60b621e14a5 5 *
tzwell 0:e60b621e14a5 6 * University of Belgrade - School of Electrical Engineering
tzwell 0:e60b621e14a5 7 * Department of Electronics
tzwell 0:e60b621e14a5 8 * Bulevar Kralja Aleksandra 73, 11120 Belgrade, Serbia
tzwell 0:e60b621e14a5 9 *
tzwell 0:e60b621e14a5 10 * December 2021.
tzwell 0:e60b621e14a5 11 *
tzwell 0:e60b621e14a5 12 */
tzwell 0:e60b621e14a5 13
tzwell 0:e60b621e14a5 14 /*
tzwell 0:e60b621e14a5 15 * Includes:
tzwell 0:e60b621e14a5 16 */
tzwell 0:e60b621e14a5 17 #include "mbed.h"
tzwell 0:e60b621e14a5 18 #include "mb_pins.h"
tzwell 0:e60b621e14a5 19 #include "platform/mbed_thread.h"
tzwell 0:e60b621e14a5 20 #include "MQTTClientMbedOs.h"
tzwell 0:e60b621e14a5 21 #include "Adafruit_GFX.h"
tzwell 0:e60b621e14a5 22 #include "Adafruit_GFX_Config.h"
tzwell 0:e60b621e14a5 23 #include "Adafruit_SSD1306.h"
tzwell 0:e60b621e14a5 24
tzwell 0:e60b621e14a5 25 /*
tzwell 0:e60b621e14a5 26 * User defines:
tzwell 0:e60b621e14a5 27 */
tzwell 0:e60b621e14a5 28 // Scaler to 3v3L
tzwell 0:e60b621e14a5 29 #define VOLTAGE_SCALER 3.3f
tzwell 0:e60b621e14a5 30 // Client yield timeout in miliseconds:
tzwell 0:e60b621e14a5 31 #define YIELD_TIMEOUT_MS 500
tzwell 0:e60b621e14a5 32 // MQTT message buffer length:
tzwell 0:e60b621e14a5 33 #define BUFF_LEN 15
tzwell 0:e60b621e14a5 34 // Sampling period:
tzwell 0:e60b621e14a5 35 #define SAMPLE_PERIOD 10
tzwell 0:e60b621e14a5 36 // Sampling period scaler:
tzwell 0:e60b621e14a5 37 #define SAMPLE_SCALER SAMPLE_PERIOD*1000/YIELD_TIMEOUT_MS
tzwell 0:e60b621e14a5 38 // I2C bus pins:
tzwell 0:e60b621e14a5 39 #define D_SDA PB_14
tzwell 0:e60b621e14a5 40 #define D_SCL PB_13
tzwell 0:e60b621e14a5 41 // I2C address, 60d or 0x3c:
tzwell 0:e60b621e14a5 42 #define I2C_REAL_ADD 0x3c
tzwell 0:e60b621e14a5 43 #define I2C_ADDRESS I2C_REAL_ADD << 1
tzwell 0:e60b621e14a5 44 // Set OLED width and heigth [pixel]:
tzwell 0:e60b621e14a5 45 #define OLED_WIDTH_PX 128
tzwell 0:e60b621e14a5 46 #define OLED_HEIGHT_PX 64
tzwell 0:e60b621e14a5 47 // State machine conditions (list of commands):
tzwell 0:e60b621e14a5 48 #define START_COND "start"
tzwell 0:e60b621e14a5 49 #define STOP_COND "stop"
tzwell 0:e60b621e14a5 50 #define OLED_COND "oled"
tzwell 0:e60b621e14a5 51
tzwell 0:e60b621e14a5 52
tzwell 0:e60b621e14a5 53 /*
tzwell 0:e60b621e14a5 54 * Global user variables/objects:
tzwell 0:e60b621e14a5 55 */
tzwell 0:e60b621e14a5 56 // Left potentiometer:
tzwell 0:e60b621e14a5 57 AnalogIn pot1(MB_POT1);
tzwell 0:e60b621e14a5 58 // Right LED on the motherboard:
tzwell 0:e60b621e14a5 59 DigitalOut led2(MB_LED2);
tzwell 0:e60b621e14a5 60 // Pointer to a WiFi network object:
tzwell 0:e60b621e14a5 61 WiFiInterface *wifi;
tzwell 0:e60b621e14a5 62 // Creating TCP socket:
tzwell 0:e60b621e14a5 63 TCPSocket socket;
tzwell 0:e60b621e14a5 64 // Creating MQTT client using the TCP socket;
tzwell 0:e60b621e14a5 65 MQTTClient client(&socket);
tzwell 0:e60b621e14a5 66 // Sent message handler:
tzwell 0:e60b621e14a5 67 MQTT::Message message_sent;
tzwell 0:e60b621e14a5 68 // Received message handler:
tzwell 0:e60b621e14a5 69 MQTT::Message message_received;
tzwell 0:e60b621e14a5 70 // Initialize I2C:
tzwell 0:e60b621e14a5 71 I2C i2c(D_SDA,D_SCL);
tzwell 0:e60b621e14a5 72 // Initialize OLED display:
tzwell 0:e60b621e14a5 73 Adafruit_SSD1306_I2c myOled(i2c,PB_5,I2C_ADDRESS,OLED_HEIGHT_PX,OLED_WIDTH_PX);
tzwell 0:e60b621e14a5 74 // MQTT topics:
tzwell 0:e60b621e14a5 75 char* topic_pub = "pubpim";
tzwell 0:e60b621e14a5 76 char* topic_sub = "subpim";
tzwell 0:e60b621e14a5 77 // HiveMQ broker connectivity information:
tzwell 0:e60b621e14a5 78 const char* hostname = "broker.hivemq.com";
tzwell 0:e60b621e14a5 79 int port = 1883;
tzwell 0:e60b621e14a5 80 // Flag indicating that pot values should be sent:
tzwell 0:e60b621e14a5 81 char sending_allowed = 0;
tzwell 0:e60b621e14a5 82 // Flag indicating that OLED display preview is enabled:
tzwell 0:e60b621e14a5 83 char oled_allowed = 0;
tzwell 0:e60b621e14a5 84 //Pseudo-timer for avoiding long CPU idle periods:
tzwell 0:e60b621e14a5 85 int pseudo_timer = 0;
tzwell 0:e60b621e14a5 86 // Message buffer to be sent:
tzwell 0:e60b621e14a5 87 char buf[BUFF_LEN];
tzwell 0:e60b621e14a5 88 // Message processing status:
tzwell 0:e60b621e14a5 89 char msgrcv = 0;
tzwell 0:e60b621e14a5 90
tzwell 0:e60b621e14a5 91 /*
tzwell 0:e60b621e14a5 92 * Publish pot value:
tzwell 0:e60b621e14a5 93 */
tzwell 0:e60b621e14a5 94 void publishPot()
tzwell 0:e60b621e14a5 95 {
tzwell 0:e60b621e14a5 96 sprintf(buf, "V = %1.2f\r\n", pot1*VOLTAGE_SCALER);
tzwell 0:e60b621e14a5 97 message_sent.qos = MQTT::QOS0;
tzwell 0:e60b621e14a5 98 message_sent.retained = false;
tzwell 0:e60b621e14a5 99 message_sent.dup = false;
tzwell 0:e60b621e14a5 100 message_sent.payload = (void*)buf;
tzwell 0:e60b621e14a5 101 message_sent.payloadlen = strlen(buf);
tzwell 0:e60b621e14a5 102 client.publish(topic_pub, message_sent);
tzwell 0:e60b621e14a5 103 }
tzwell 0:e60b621e14a5 104
tzwell 0:e60b621e14a5 105 /*
tzwell 0:e60b621e14a5 106 * MQTT traffic previewed on OLED:
tzwell 0:e60b621e14a5 107 */
tzwell 0:e60b621e14a5 108 void oledPreview()
tzwell 0:e60b621e14a5 109 {
tzwell 0:e60b621e14a5 110 myOled.clearDisplay();
tzwell 0:e60b621e14a5 111 myOled.setTextCursor(0, 0);
tzwell 0:e60b621e14a5 112 myOled.printf("Sent: %.*s\n", strlen(buf), buf);
tzwell 0:e60b621e14a5 113 myOled.printf("Received: %.*s\n", message_received.payloadlen, (char*)message_received.payload);
tzwell 0:e60b621e14a5 114 myOled.display();
tzwell 0:e60b621e14a5 115 }
tzwell 0:e60b621e14a5 116
tzwell 0:e60b621e14a5 117 /*
tzwell 0:e60b621e14a5 118 * Check if payload satisfies any of the state machine conditions:
tzwell 0:e60b621e14a5 119 */
tzwell 0:e60b621e14a5 120 int checkCondition (char* payload, int payloadlen, char* condition)
tzwell 0:e60b621e14a5 121 {
tzwell 0:e60b621e14a5 122 char not_satisfied = 0;
tzwell 0:e60b621e14a5 123 char cnt = 0;
tzwell 0:e60b621e14a5 124 while(cnt != payloadlen)
tzwell 0:e60b621e14a5 125 {
tzwell 0:e60b621e14a5 126 if (payload[cnt] != condition[cnt])
tzwell 0:e60b621e14a5 127 not_satisfied = 1;
tzwell 0:e60b621e14a5 128 cnt++;
tzwell 0:e60b621e14a5 129 }
tzwell 0:e60b621e14a5 130 return not_satisfied;
tzwell 0:e60b621e14a5 131 }
tzwell 0:e60b621e14a5 132
tzwell 0:e60b621e14a5 133 /*
tzwell 0:e60b621e14a5 134 * MQTT message received function:
tzwell 0:e60b621e14a5 135 */
tzwell 0:e60b621e14a5 136 void messageArrived(MQTT::MessageData& md)
tzwell 0:e60b621e14a5 137 {
tzwell 0:e60b621e14a5 138 MQTT::Message &message = md.message;
tzwell 0:e60b621e14a5 139 message_received = md.message;
tzwell 0:e60b621e14a5 140 msgrcv = 1;
tzwell 0:e60b621e14a5 141 printf("Message from the browser: %.*s\r\n", message.payloadlen, (char*)message.payload);
tzwell 0:e60b621e14a5 142 }
tzwell 0:e60b621e14a5 143
tzwell 0:e60b621e14a5 144 /*
tzwell 0:e60b621e14a5 145 * State machine update upon receiving a message:
tzwell 0:e60b621e14a5 146 */
tzwell 0:e60b621e14a5 147 void stateCheck()
tzwell 0:e60b621e14a5 148 {
tzwell 0:e60b621e14a5 149 char message_buff[BUFF_LEN];
tzwell 0:e60b621e14a5 150
tzwell 0:e60b621e14a5 151 // Copy payload into a char arrray:
tzwell 0:e60b621e14a5 152 sprintf(message_buff, "%.*s",message_received.payloadlen, (char*)message_received.payload);
tzwell 0:e60b621e14a5 153
tzwell 0:e60b621e14a5 154 // State machine:
tzwell 0:e60b621e14a5 155 if(!checkCondition(message_buff, strlen(message_buff), START_COND))
tzwell 0:e60b621e14a5 156 {
tzwell 0:e60b621e14a5 157 sending_allowed = 1;
tzwell 0:e60b621e14a5 158 }
tzwell 0:e60b621e14a5 159 else if (!checkCondition(message_buff, strlen(message_buff), STOP_COND))
tzwell 0:e60b621e14a5 160 {
tzwell 0:e60b621e14a5 161 sending_allowed = 0;
tzwell 0:e60b621e14a5 162 }
tzwell 0:e60b621e14a5 163 else if (!checkCondition(message_buff, strlen(message_buff), OLED_COND))
tzwell 0:e60b621e14a5 164 {
tzwell 0:e60b621e14a5 165 oled_allowed = 1;
tzwell 0:e60b621e14a5 166 myOled.begin();
tzwell 0:e60b621e14a5 167 oledPreview();
tzwell 0:e60b621e14a5 168 }
tzwell 0:e60b621e14a5 169 // Mark the end of message processing:
tzwell 0:e60b621e14a5 170 msgrcv = 0;
tzwell 0:e60b621e14a5 171 }
tzwell 0:e60b621e14a5 172
tzwell 0:e60b621e14a5 173
tzwell 0:e60b621e14a5 174 /*
tzwell 0:e60b621e14a5 175 * Main:
tzwell 0:e60b621e14a5 176 */
tzwell 0:e60b621e14a5 177 int main()
tzwell 0:e60b621e14a5 178 {
tzwell 0:e60b621e14a5 179 // Create a default network interface:
tzwell 0:e60b621e14a5 180 wifi = WiFiInterface::get_default_instance();
tzwell 0:e60b621e14a5 181
tzwell 0:e60b621e14a5 182 // Connect to the network with the parameters specified in 'mbed_app.json':
tzwell 0:e60b621e14a5 183 printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID);
tzwell 0:e60b621e14a5 184 wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
tzwell 0:e60b621e14a5 185 // Mark connection done:
tzwell 0:e60b621e14a5 186 printf("\nConnected.\r\n");
tzwell 0:e60b621e14a5 187
tzwell 0:e60b621e14a5 188 // Open TCP socket using WiFi network interface:
tzwell 0:e60b621e14a5 189 socket.open(wifi);
tzwell 0:e60b621e14a5 190 // Connect to the HiveMQ broker over the internet:
tzwell 0:e60b621e14a5 191 socket.connect(hostname, port);
tzwell 0:e60b621e14a5 192 // Fill connect data with default values:
tzwell 0:e60b621e14a5 193 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
tzwell 0:e60b621e14a5 194 // Change only ID and protocol version:
tzwell 0:e60b621e14a5 195 data.MQTTVersion = 3;
tzwell 0:e60b621e14a5 196 data.clientID.cstring = "pim-60";
tzwell 0:e60b621e14a5 197
tzwell 0:e60b621e14a5 198 // Establish MQTT connection:
tzwell 0:e60b621e14a5 199 client.connect(data);
tzwell 0:e60b621e14a5 200 // Subscribe to the topic specified by topic_sub:
tzwell 0:e60b621e14a5 201 client.subscribe(topic_sub, MQTT::QOS2, messageArrived);
tzwell 0:e60b621e14a5 202
tzwell 0:e60b621e14a5 203 while (true)
tzwell 0:e60b621e14a5 204 {
tzwell 0:e60b621e14a5 205 // Show that the loop is running by switching motherboard LED2:
tzwell 0:e60b621e14a5 206 led2 = !led2;
tzwell 0:e60b621e14a5 207
tzwell 0:e60b621e14a5 208 // If the message is received, check state machine current state:
tzwell 0:e60b621e14a5 209 if (msgrcv)
tzwell 0:e60b621e14a5 210 stateCheck();
tzwell 0:e60b621e14a5 211
tzwell 0:e60b621e14a5 212 // If 'oled' was received:
tzwell 0:e60b621e14a5 213 if (oled_allowed)
tzwell 0:e60b621e14a5 214 oledPreview();
tzwell 0:e60b621e14a5 215
tzwell 0:e60b621e14a5 216 // If the pseudo-timer has counted 10s:
tzwell 0:e60b621e14a5 217 if( pseudo_timer == (SAMPLE_SCALER))
tzwell 0:e60b621e14a5 218 {
tzwell 0:e60b621e14a5 219 // If 'start' was received:
tzwell 0:e60b621e14a5 220 if(sending_allowed == 1)
tzwell 0:e60b621e14a5 221 publishPot();
tzwell 0:e60b621e14a5 222 // Reset pseudo-timer:
tzwell 0:e60b621e14a5 223 pseudo_timer = 0;
tzwell 0:e60b621e14a5 224 }
tzwell 0:e60b621e14a5 225 //Increment pseudo-timer:
tzwell 0:e60b621e14a5 226 pseudo_timer++;
tzwell 0:e60b621e14a5 227 // Need to call yield API to maintain connection:
tzwell 0:e60b621e14a5 228 client.yield(YIELD_TIMEOUT_MS);
tzwell 0:e60b621e14a5 229 }
tzwell 0:e60b621e14a5 230 }