![](/media/cache/profiles/nikki.png.50x50_q85.jpg)
19E042PIM 2021/22 T3 Key
Dependencies: Adafruit_GFX 19E042PIM_MB_PINS
main.cpp
- Committer:
- tzwell
- Date:
- 2021-12-15
- Revision:
- 0:e60b621e14a5
File content as of revision 0:e60b621e14a5:
/* * Upon receiving 'start' mcu starts sending voltage values stampled from POT1. * When 'stop' is received, sending is stopped, while after receving 'oled', * message transaction is displayed on OLED display. * * University of Belgrade - School of Electrical Engineering * Department of Electronics * Bulevar Kralja Aleksandra 73, 11120 Belgrade, Serbia * * December 2021. * */ /* * Includes: */ #include "mbed.h" #include "mb_pins.h" #include "platform/mbed_thread.h" #include "MQTTClientMbedOs.h" #include "Adafruit_GFX.h" #include "Adafruit_GFX_Config.h" #include "Adafruit_SSD1306.h" /* * User defines: */ // Scaler to 3v3L #define VOLTAGE_SCALER 3.3f // Client yield timeout in miliseconds: #define YIELD_TIMEOUT_MS 500 // MQTT message buffer length: #define BUFF_LEN 15 // Sampling period: #define SAMPLE_PERIOD 10 // Sampling period scaler: #define SAMPLE_SCALER SAMPLE_PERIOD*1000/YIELD_TIMEOUT_MS // I2C bus pins: #define D_SDA PB_14 #define D_SCL PB_13 // I2C address, 60d or 0x3c: #define I2C_REAL_ADD 0x3c #define I2C_ADDRESS I2C_REAL_ADD << 1 // Set OLED width and heigth [pixel]: #define OLED_WIDTH_PX 128 #define OLED_HEIGHT_PX 64 // State machine conditions (list of commands): #define START_COND "start" #define STOP_COND "stop" #define OLED_COND "oled" /* * Global user variables/objects: */ // Left potentiometer: AnalogIn pot1(MB_POT1); // Right LED on the motherboard: DigitalOut led2(MB_LED2); // Pointer to a WiFi network object: WiFiInterface *wifi; // Creating TCP socket: TCPSocket socket; // Creating MQTT client using the TCP socket; MQTTClient client(&socket); // Sent message handler: MQTT::Message message_sent; // Received message handler: MQTT::Message message_received; // Initialize I2C: I2C i2c(D_SDA,D_SCL); // Initialize OLED display: Adafruit_SSD1306_I2c myOled(i2c,PB_5,I2C_ADDRESS,OLED_HEIGHT_PX,OLED_WIDTH_PX); // MQTT topics: char* topic_pub = "pubpim"; char* topic_sub = "subpim"; // HiveMQ broker connectivity information: const char* hostname = "broker.hivemq.com"; int port = 1883; // Flag indicating that pot values should be sent: char sending_allowed = 0; // Flag indicating that OLED display preview is enabled: char oled_allowed = 0; //Pseudo-timer for avoiding long CPU idle periods: int pseudo_timer = 0; // Message buffer to be sent: char buf[BUFF_LEN]; // Message processing status: char msgrcv = 0; /* * Publish pot value: */ void publishPot() { sprintf(buf, "V = %1.2f\r\n", pot1*VOLTAGE_SCALER); message_sent.qos = MQTT::QOS0; message_sent.retained = false; message_sent.dup = false; message_sent.payload = (void*)buf; message_sent.payloadlen = strlen(buf); client.publish(topic_pub, message_sent); } /* * MQTT traffic previewed on OLED: */ void oledPreview() { myOled.clearDisplay(); myOled.setTextCursor(0, 0); myOled.printf("Sent: %.*s\n", strlen(buf), buf); myOled.printf("Received: %.*s\n", message_received.payloadlen, (char*)message_received.payload); myOled.display(); } /* * Check if payload satisfies any of the state machine conditions: */ int checkCondition (char* payload, int payloadlen, char* condition) { char not_satisfied = 0; char cnt = 0; while(cnt != payloadlen) { if (payload[cnt] != condition[cnt]) not_satisfied = 1; cnt++; } return not_satisfied; } /* * MQTT message received function: */ void messageArrived(MQTT::MessageData& md) { MQTT::Message &message = md.message; message_received = md.message; msgrcv = 1; printf("Message from the browser: %.*s\r\n", message.payloadlen, (char*)message.payload); } /* * State machine update upon receiving a message: */ void stateCheck() { char message_buff[BUFF_LEN]; // Copy payload into a char arrray: sprintf(message_buff, "%.*s",message_received.payloadlen, (char*)message_received.payload); // State machine: if(!checkCondition(message_buff, strlen(message_buff), START_COND)) { sending_allowed = 1; } else if (!checkCondition(message_buff, strlen(message_buff), STOP_COND)) { sending_allowed = 0; } else if (!checkCondition(message_buff, strlen(message_buff), OLED_COND)) { oled_allowed = 1; myOled.begin(); oledPreview(); } // Mark the end of message processing: msgrcv = 0; } /* * Main: */ int main() { // Create a default network interface: wifi = WiFiInterface::get_default_instance(); // Connect to the network with the parameters specified in 'mbed_app.json': printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID); wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2); // Mark connection done: printf("\nConnected.\r\n"); // Open TCP socket using WiFi network interface: socket.open(wifi); // Connect to the HiveMQ broker over the internet: socket.connect(hostname, port); // Fill connect data with default values: MQTTPacket_connectData data = MQTTPacket_connectData_initializer; // Change only ID and protocol version: data.MQTTVersion = 3; data.clientID.cstring = "pim-60"; // Establish MQTT connection: client.connect(data); // Subscribe to the topic specified by topic_sub: client.subscribe(topic_sub, MQTT::QOS2, messageArrived); while (true) { // Show that the loop is running by switching motherboard LED2: led2 = !led2; // If the message is received, check state machine current state: if (msgrcv) stateCheck(); // If 'oled' was received: if (oled_allowed) oledPreview(); // If the pseudo-timer has counted 10s: if( pseudo_timer == (SAMPLE_SCALER)) { // If 'start' was received: if(sending_allowed == 1) publishPot(); // Reset pseudo-timer: pseudo_timer = 0; } //Increment pseudo-timer: pseudo_timer++; // Need to call yield API to maintain connection: client.yield(YIELD_TIMEOUT_MS); } }