Student project, Faculty of Electrical Engineering, University of Belgrade

Dependencies:   SSD1308_128x64_I2C Adafruit_GFX 19E042PIM_MB_PINS

Files at this revision

API Documentation at this revision

Comitter:
oljakovljevic
Date:
Wed Jul 13 15:07:00 2022 +0000
Parent:
1:c994530bdb3d
Commit message:
Student project, Faculty of Electrical Engineering, University of Belgrade

Changed in this revision

Adafruit_GFX.lib Show annotated file Show diff for this revision Revisions of this file
SSD1308_128x64_I2C.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mb_pins.h Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
diff -r c994530bdb3d -r 4c2c7c8d608b Adafruit_GFX.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_GFX.lib	Wed Jul 13 15:07:00 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/jportela/code/Adafruit_GFX/#e97cd4d2a37b
diff -r c994530bdb3d -r 4c2c7c8d608b SSD1308_128x64_I2C.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SSD1308_128x64_I2C.lib	Wed Jul 13 15:07:00 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/oljakovljevic/code/SSD1308_128x64_I2C/#9a4a9da4e801
diff -r c994530bdb3d -r 4c2c7c8d608b main.cpp
--- a/main.cpp	Sat Nov 27 20:33:49 2021 +0000
+++ b/main.cpp	Wed Jul 13 15:07:00 2022 +0000
@@ -1,58 +1,103 @@
 /*
- * Program implements MQTT client on a NUCLEO-L476RG board
- * using arm mbed-mqtt library and ESP-WROOM-02 WiFi modem.
- *
- * University of Belgrade - School of Electrical Engineering
- * Department of Electronics
- * Bulevar Kralja Aleksandra 73, 11120 Belgrade, Serbia
- *
- * November 2021.
- *
- */
+
+This code implements MQTT broker for Smart Industry system.
+The system sorts plastic caps based on their color (red, green or blue). 
+Proximity sensors detect the presence of the cup, color sensor determines the color and
+servo motors drive the sorting mechanism.
+
+Faculty of Electrical Engineering, University of Belgrade.
+Version (1), July 2022.
+
+*/
+
+// Include the libraries
 
 #include "mbed.h"
 #include "mb_pins.h"
 #include "platform/mbed_thread.h"
 #include "MQTTClientMbedOs.h"
-
+#include "SSD1308.h"
+#include "Adafruit_GFX.h"
+#include "Adafruit_GFX_Config.h"
+#include "Adafruit_SSD1306.h"
 
-// LED2 blinking rate:
-#define BLINKING_RATE_MS                                                     250
-// Scaler to 3v3L
-#define VOLTAGE_SCALER                                                      3.3f
-// Client yield timeout in miliseconds:
+// 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
+#define I2C_FREQUENCY                                                     400000
+
+// Client yield timeout in miliseconds
 #define YIELD_TIMEOUT_MS                                                    1000
-// Maximum number of networks to scan for:
-#define MAX_NETWORKS                                                          15
-// Small delay for network information printing:
+
+// Maximum number of networks to scan for
+#define MAX_NETWORKS                                                          10
+
+// Small delay for network information printing
 #define PRINTF_DELAY_MS                                                       10
 
+// Set OLED width and heigth [pixel]
+#define OLED_WIDTH_PX                                                        128
+#define OLED_HEIGHT_PX                                                        64
 
-// Left potentiometer:
-AnalogIn pot1(MB_POT1);
-// Left button on the motherboard:
-InterruptIn sw1(MB_SW1);
-// Right LED on the motherboard:
-DigitalOut led2(MB_LED2);
-// Pointer to a WiFi network object:
+// Initialize I2C for OLED display
+I2C i2c(D_SDA, D_SCL);
+
+// Initialize OLED
+Adafruit_SSD1306_I2c myOled(i2c,PB_5,I2C_ADDRESS,OLED_HEIGHT_PX,OLED_WIDTH_PX);
+
+// Variables that count the number of caps for every color
+int red;
+int green;
+int blue;
+
+// Variables used in broker decision algorithm
+int flagColor = 0;
+int flagProx1 = 0;
+int flagProx2 = 0;
+int flagStage1 = 1;
+int flagStage2 = 1;
+int notAvailable = 0;
+int poximityTreshold1 = 300;
+int poximityTreshold2 = 280;
+int currentColor = 0;
+
+// Define start button
+DigitalIn buttonStart(MB_SW1); 
+int flagStart = 0;
+
+// Pointer to a WiFi network object
 WiFiInterface *wifi;
-// Creating TCP socket:
+
+// Creating TCP socket
 TCPSocket socket;
-// Creating MQTT client using the TCP socket;
+
+// Creating MQTT client using the TCP socket
 MQTTClient client(&socket);
-// Message handler:
+
+// Message handler
 MQTT::Message message;
 
-char* topic = "mbed-sample-pub";
-char* topic_sub = "mbed-sample-sub";
-// Counter of arrived messages:
+// MQTT topics
+char* topic_pub_servo1 = "PMK_industry/micro/servo1";
+char* topic_pub_servo2 = "PMK_industry/micro/servo2";
+char* topic_sub_color = "PMK_industry/micro/color";
+char* topic_sub_proximity1 = "PMK_industry/micro/proximity1";
+char* topic_sub_proximity2 = "PMK_industry/micro/proximity2";
+
+char* receavedMessage;
+
+// Counter of arrived messages
 int arrivedcount = 0;
-// Flag indicating that button is not pressed:
-int button_pressed=0;
-// HiveMQ broker connectivity information:
+
+// HiveMQ broker connectivity information
 const char* hostname = "broker.hivemq.com";
 int port = 1883;
-// Returning a string for a provided network encryption: 
+
+// Returning a string for a provided network encryption
 const char *sec2str(nsapi_security_t sec)
 {
     switch (sec) 
@@ -73,12 +118,14 @@
     }
 }
 
+// Scan available WiFi networks
 int scan_networks(WiFiInterface *wifi)
 {
     printf("Scan:\n");
     
-    // Scan only for the number of networks, first parameter is NULL:
+    // Scan only for the number of networks, first parameter is NULL
     int count = wifi->scan(NULL, 0);
+    
     // If there are no networks, count == 0, if there is an error, counter < 0:
     if (count <= 0)
     {
@@ -86,22 +133,23 @@
         return 0;
     }
 
-    // Limit number of network arbitrary to some reasonable number:
+    // Limit number of network arbitrary to some reasonable number
     count = count < MAX_NETWORKS ? count : MAX_NETWORKS;
     
-    // Create a local pointer to an object, which is an array of WiFi APs:
+    // Create a local pointer to an object, which is an array of WiFi APs
     WiFiAccessPoint *ap = new WiFiAccessPoint[count];
-    // Now scan again for 'count' networks and populate the array of APs:
+    
+    // Now scan again for 'count' networks and populate the array of APs
     count = wifi->scan(ap, count);
     
-    // This time, the number of entries to 'ap' is returned:
+    // This time, the number of entries to 'ap' is returned
     if (count <= 0) 
     {
         printf("scan() failed with return value: %d\n", count);
         return 0;
     }
     
-    // Print out the parameters of each AP:
+    // Print out the parameters of each AP
     for (int i = 0; i < count; i++) 
     {
         printf("Network: %s secured: %s BSSID: %hhX:%hhX:%hhX:%hhx:%hhx:%hhx RSSI: %hhd Ch: %hhd\n", ap[i].get_ssid(),
@@ -117,25 +165,45 @@
     return count;
 }
 
-void messageArrived(MQTT::MessageData& md)
+// MQTT message handlers for certain topics
+void messageArrivedColor(MQTT::MessageData& md)
+{
+    MQTT::Message &message = md.message;
+    receavedMessage = (char*)message.payload;
+    
+    if (strcmp(receavedMessage,"Red") == 0 ){ flagColor = 1; }
+    else if (strcmp(receavedMessage,"Green") == 0 ) { flagColor = 2; }
+    else if (strcmp(receavedMessage, "Blue") == 0 ) { flagColor = 3; }
+    printf("Color: %.*s\r\n", message.payloadlen, (char*)message.payload);
+    
+}
+
+void messageArrivedProximity1(MQTT::MessageData& md)
 {
     MQTT::Message &message = md.message;
-    //printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
-    printf("Message from the browser: %.*s\r\n", message.payloadlen, (char*)message.payload);
-    ++arrivedcount;
+    int receavedMessage = atoi((char*)message.payload);
+
+    if (receavedMessage > poximityTreshold1){ flagProx1 = 1;}
+    else { flagProx1 = 0;}
+    printf("Prox1 = %d\t", receavedMessage);
+    printf("flag = %d\r\n", flagProx1);
+    
 }
 
-void buttonFunction() {
+void messageArrivedProximity2(MQTT::MessageData& md)
+{
+    MQTT::Message &message = md.message;
+    int receavedMessage = atoi((char*)message.payload);
     
-    button_pressed=1;
-   
+    if (receavedMessage > poximityTreshold2){ flagProx2 = 1;}
+    else { flagProx2 = 0;}
+    printf("Prox2 = %d\t", receavedMessage);
+    printf("flag = %d\r\n", flagProx2);
+    
 }
 
 int main()
 {
-    // Set the interrupt event:
-    sw1.fall(&buttonFunction); 
-    
     // Create a default network interface:
     wifi = WiFiInterface::get_default_instance();
     if (!wifi) {
@@ -168,39 +236,192 @@
     
     // Open TCP socket using WiFi network interface:
     socket.open(wifi);
+    
     // Connect to the HiveMQ broker:
     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 = "NUCLEO-L476RG-60";
+    data.clientID.cstring = "Broker";
     
-    // Connect the 
+    // Connect to the mqtt broker
     int rc = 0;
     if ((rc = client.connect(data)) != 0)
         printf("rc from MQTT connect is %d\r\n", rc);
 
-    if ((rc = client.subscribe(topic_sub, MQTT::QOS2, messageArrived)) != 0)
+    // Subscribe to topics
+    if ((rc = client.subscribe(topic_sub_color, MQTT::QOS2, messageArrivedColor)) != 0)
+        printf("rc from MQTT subscribe is %d\r\n", rc);
+        
+    if ((rc = client.subscribe(topic_sub_proximity1, MQTT::QOS2, messageArrivedProximity1)) != 0)
+        printf("rc from MQTT subscribe is %d\r\n", rc);
+        
+    if ((rc = client.subscribe(topic_sub_proximity2, MQTT::QOS2, messageArrivedProximity2)) != 0)
         printf("rc from MQTT subscribe is %d\r\n", rc);
-      
+    
+    red = 0;
+    green = 0;
+    blue = 0;
+    
+    char bufRed[15];   
+    char bufGreen[15];
+    char bufBlue[15];
+    
+    myOled.begin(); 
+    myOled.setTextSize(2);
+    myOled.setTextColor(WHITE);
+    myOled.setTextCursor(25,0);
+    myOled.printf("Press");
+    myOled.setTextCursor(25,25);
+    myOled.printf("START");
+    myOled.display();
+ 
     while (true) {
-        // Show that the loop is running by switching motherboard LED2:
-        led2 = !led2;
-        thread_sleep_for(BLINKING_RATE_MS);
-        if (button_pressed==1) {
-            button_pressed=0;      
-            // QoS 0
-            char buf[100];
-            sprintf(buf, "V(POT1) = %1.2f\r\n", pot1*VOLTAGE_SCALER);
-            message.qos = MQTT::QOS0;
-            message.retained = false;
-            message.dup = false;
-            message.payload = (void*)buf;
-            message.payloadlen = strlen(buf)+1;
-            client.publish(topic, message);
+        
+        if (!flagStart){
+        flagStart = !buttonStart;
+        thread_sleep_for(50);
+        
         }
-        // Need to call yield API to maintain connection:
-        client.yield(YIELD_TIMEOUT_MS);
+        
+        if (flagStart) {
+        
+        sprintf(bufRed, "%s %d", "Red:", red);
+        sprintf(bufGreen, "%s %d", "Green:", green);
+        sprintf(bufBlue, "%s %d", "Blue:", blue);
+        
+        myOled.clearDisplay();
+        myOled.setTextSize(2);
+        myOled.setTextColor(WHITE);
+        myOled.setTextCursor(0,0);
+        myOled.printf(bufRed);
+        myOled.setTextCursor(0,25);
+        myOled.printf(bufGreen);
+        myOled.setTextCursor(0,50);
+        myOled.printf(bufBlue);
+        myOled.display();
+        
+        // If a cap is detected at the first stage, send a command
+        // for servo1 based on the color of the cap
+        if(flagStage1 && flagProx1)
+        {
+            
+            if (flagColor == 1)
+            {
+                char buf[100];
+                sprintf(buf, "right");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo1, message);
+                flagStage1 = 0;
+                red++;
+                
+                }
+                
+                else if (flagColor == 2)
+            {
+                char buf[100];
+                sprintf(buf, "left");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo1, message);
+                flagStage1 = 0;
+                green++;
+                
+                }
+                
+                else if (flagColor == 3)
+            {
+                char buf[100];
+                sprintf(buf, "left");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo1, message);
+                flagStage1 = 0;
+                blue++;
+                
+                }
+                
+                currentColor = flagColor;
+            }
+        
+            else if(!flagStage1 && !flagProx1)
+            {
+                char buf[100];
+                sprintf(buf, "zero");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo1, message);
+                flagStage1 = 1;
+                
+                }
+        
+        // If a cap is detected at the second stage, send a command
+        // for servo2 based on the color of the cap
+        if(flagStage2 && flagProx2)
+        {
+            
+            if (currentColor == 2)
+            {
+                char buf[100];
+                sprintf(buf, "right");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo2, message);
+                flagStage2 = 0;
+                
+                }
+                
+                else if (currentColor  == 3)
+            {
+                char buf[100];
+                sprintf(buf, "left");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo2, message);
+                flagStage2 = 0;
+                
+                }
+                
+            }
+        
+            else if(!flagStage2 && !flagProx2)
+            {
+                char buf[100];
+                sprintf(buf, "zero");
+                message.qos = MQTT::QOS0;
+                message.retained = false;
+                message.dup = false;
+                message.payload = (void*)buf;
+                message.payloadlen = strlen(buf)+1;
+                client.publish(topic_pub_servo2, message);
+                flagStage2 = 1;
+                currentColor = 0;
+                
+                }
+                
+        client.yield(YIELD_TIMEOUT_MS); // Need to call yield API to maintain connection
+    }
     }
 }
\ No newline at end of file
diff -r c994530bdb3d -r 4c2c7c8d608b mb_pins.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mb_pins.h	Wed Jul 13 15:07:00 2022 +0000
@@ -0,0 +1,60 @@
+/*
+ * This file contains all the pin names neccessary
+ * for easy interaction with the EDS-MB for NUCLEOL476RG.
+ *
+ * University of Belgrade - School of Electrical Engineering
+ * Department of Electronics
+ * Bulevar Kralja Aleksandra 73, 11120 Belgrade, Serbia
+ *
+ * November 2021.
+ *
+ */
+
+// LEDs, 560R in series, cathode to GND; left - red LED1;  right - blue LED2:
+#define MB_LED1                                                            PA_11
+#define MB_LED2                                                            PB_15
+// Switches, DPST, pulled up with 10k resistor; left SW1, right SW2:
+// SW_EXT connector, from left to right:
+
+#define MB_SW1                                                             PC_9
+#define MB_SW2                                                             PC_8
+// Potentiometers; left POT1, right POT2:
+#define MB_POT1                                                            PA_0
+#define MB_POT2                                                            PA_1
+// Common anode, two digit seven-segment display. All signals active at '0':
+#define MB_SEL1                                                            PB_6
+#define MB_SEL2                                                            PC_7
+#define MB_A                                                               PA_10
+#define MB_B                                                               PA_9
+#define MB_C                                                               PA_8
+#define MB_D                                                               PB_10
+#define MB_E                                                               PB_5
+#define MB_F                                                               PB_4
+#define MB_G                                                               PB_3
+// Piezoelectric buzzer, 10k in parallel; Active at '0':
+#define MB_BUZZ                                                            PA_11
+// SDD1306-based OLED display; Uses I2C_2 to communicate with NUCLEO:
+#define MB_OLED_SDA                                                        PB_14
+#define MB_OLED_SCL                                                        PB_13
+// ESP8266 WiFi microcontroller; Uses UART_3 to communicate with NUCLEO:
+#define MB_ESP_RST                                                         PA_12
+#define MB_ESP_TX                                                          PC_4
+#define MB_ESP_RX                                                          PC_5
+#define MB_ESP_EN                                                          RESET
+// mikroBUS pinout, upper leftmost pin is no. 1:
+#define MB_MIKRO_AN                                                        PB_1
+#define MB_MIKRO_RST                                                       PB_12
+#define MB_MIKRO_CS                                                        PD_2
+#define MB_MIKRO_SCK                                                       PC_10
+#define MB_MIKRO_MISO                                                      PC_11
+#define MB_MIKRO_MOSI                                                      PC_12
+#define MB_MIKRO_SDA                                                       PB_14
+#define MB_MIKRO_SCL                                                       PB_13
+#define MB_MIKRO_TX                                                        PB_11
+#define MB_MIKRO_RX                                                        PB_7
+#define MB_MIKRO_INT                                                       PB_2
+#define MB_MIKRO_PWM                                                       PC_6
+// ANALOG_EXT connector, from left to right:
+#define MB_AI1                                                             PC_3
+#define MB_AI2                                                             PC_2
+#define MB_A0                                                              PA_4
\ No newline at end of file
diff -r c994530bdb3d -r 4c2c7c8d608b mbed_app.json
--- a/mbed_app.json	Sat Nov 27 20:33:49 2021 +0000
+++ b/mbed_app.json	Wed Jul 13 15:07:00 2022 +0000
@@ -2,11 +2,11 @@
     "config": {
         "wifi-ssid": {
             "help": "WIFI SSID",
-            "value": "\"testing1\""
+            "value": "\"oljko\""
         },
         "wifi-password": {
             "help": "Wifi Password",
-            "value": "\"testing1\""
+            "value": "\"oljaolja\""
         }
     },
     "target_overrides": {