Student project, Faculty of Electrical Engineering, University of Belgrade

Dependencies:   mbed Servo

main.cpp

Committer:
oljakovljevic
Date:
2022-07-13
Revision:
0:0093b6d26596

File content as of revision 0:0093b6d26596:

/*

This code implements MQTT client for Smart Industry system.
Proximity sensor detects the presence of the cup and
the information is sent to the broker. 
If the cap is on the second stage, command for the servo motor, calculated by the broker,
is sent to the client.

Faculty of Electrical Engineering, University of Belgrade.
Version (1), July 2022.

*/

// Include the libraries
#include "mbed.h"
#include "platform/mbed_thread.h"
#include <string>
#include <algorithm>
#include "Servo.h"
#include "MQTTClientMbedOs.h"

#define MAX_NETWORKS                                                          10
#define PRINTF_DELAY_MS                                                       10
#define YIELD_TIMEOUT_MS                                                    1000

#define PSAdress (0x38<<1)

Servo myservo(D7);  // servo motor control signal pin
Serial pc(USBTX,USBRX);

// Proximity sensor parameters 
I2C i2c(PB_14,PB_13);

int PSresult = 0; 
char modeControlRegister[2] = {0x41, 0xC6}; // Mode Control Register - {Adress,  Value}
char PSregadRegister [2] = {0x44, 0x45}; // PS register values - {PSLSB Adress, PSMSB Adress}
char PSReading [2];
int poximityTreshold = 280;

TCPSocket socket;
MQTTClient client(&socket);
MQTT::Message message;

char* topic_pub_proximity2 = "PMK_industry/micro/proximity2";
char* topic_sub_servo2 = "PMK_industry/micro/servo2";

char* receavedMessage;

WiFiInterface *wifi;
volatile int mems_event = 0;
uint32_t previous_tick = 0;
uint32_t current_tick = 0;
uint8_t high = 0, low = 0;
float temperature = 0.0f;
char buffer[32];

int flag = 0;

const char *sec2str(nsapi_security_t sec)
{
    switch (sec) 
    {
        case NSAPI_SECURITY_NONE:
            return "None";
        case NSAPI_SECURITY_WEP:
            return "WEP";
        case NSAPI_SECURITY_WPA:
            return "WPA";
        case NSAPI_SECURITY_WPA2:
            return "WPA2";
        case NSAPI_SECURITY_WPA_WPA2:
            return "WPA/WPA2";
        case NSAPI_SECURITY_UNKNOWN:
        default:
            return "Unknown";
    }
}

int scan_networks(WiFiInterface *wifi)
{
    printf("Scan:\n");
    
    // 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)
    {
        printf("scan() failed with return value: %d\n", count);
        return 0;
    }

    // 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
    WiFiAccessPoint *ap = new WiFiAccessPoint[count];
    
    // 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
    if (count <= 0) 
    {
        printf("scan() failed with return value: %d\n", count);
        return 0;
    }
    
    // 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(),
               sec2str(ap[i].get_security()), ap[i].get_bssid()[0], ap[i].get_bssid()[1], ap[i].get_bssid()[2],
               ap[i].get_bssid()[3], ap[i].get_bssid()[4], ap[i].get_bssid()[5], ap[i].get_rssi(), ap[i].get_channel());
        thread_sleep_for(PRINTF_DELAY_MS);
    }
    printf("%d networks available.\n", count);
    
    // Since 'ap' is dynamically allocated pointer to the array of objects, it
    // needs to be deleted:
    delete[] ap;
    return count;
}

void messageArrivedServo2(MQTT::MessageData& md)
{   
    MQTT::Message &message = md.message;
    receavedMessage = (char*)message.payload;
    
    if (strcmp(receavedMessage,"zero") == 0){ flag = 0;}
    else if (strcmp(receavedMessage,"left") == 0){ flag = 1;}
    else if (strcmp(receavedMessage,"right") == 0) { flag = 2;}
    
}


int main()

{   
    const char* hostname = "broker.hivemq.com";
    int port = 1883;    
    
    // Create a default network interface
    wifi = WiFiInterface::get_default_instance();
    if (!wifi) {
        printf("ERROR: No WiFiInterface found.\n");
        return -1;
    }
    
    // Scan for available networks and aquire information about Access Points
    int count = scan_networks(wifi);
    if (count == 0) {
        printf("No WIFI APs found - can't continue further.\n");
        return -1;
    }
    
    // Connect to the network with the parameters specified in 'mbed_app.json'
    printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID);
    int ret = wifi->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
    if (ret != 0) {
        printf("\nConnection error: %d\n", ret);
        return -1;
    }
    
    // Print out the information aquired:
    printf("Success\n\n");
    printf("MAC: %s\n", wifi->get_mac_address());
    printf("IP: %s\n", wifi->get_ip_address());
    printf("Netmask: %s\n", wifi->get_netmask());
    printf("Gateway: %s\n", wifi->get_gateway());
    printf("RSSI: %d\n\n", wifi->get_rssi());   

    socket.open(wifi);
    socket.connect(hostname, port);
    
    int rc=0;
    
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 3;
    data.clientID.cstring = "Client2";
    
    if ((rc = client.connect(data)) != 0)
        printf("rc from MQTT connect is %d\r\n", rc);

    
    if ((rc = client.subscribe(topic_sub_servo2, MQTT::QOS2, messageArrivedServo2)) != 0)
        printf("rc from MQTT subscribe is %d\r\n", rc); 

    // Start I2C communication
    i2c.start();
    
    // Set the Mode Control Register, so the sensor is waken up from the standby mode (default)
    i2c.write(PSAdress, modeControlRegister, 2, 1);
    
    myservo.position(0);
    
    while (true) {
            
            i2c.write(PSAdress, PSregadRegister, 2, 1);  // Select the registers to read from, no I2C Stop 
            i2c.read(PSAdress, PSReading, 2, 0); // Read data from register
            PSresult = (int) ((int)PSReading[1] << 8) | PSReading[0];
            
            char buf[100];
            sprintf(buf, "%d", PSresult);
            message.qos = MQTT::QOS0;
            message.retained = false;
            message.dup = false;
            message.payload = (void*)buf;
            message.payloadlen = strlen(buf)+1;
            client.publish(topic_pub_proximity2, message);
            
            // Servo commands
            
            if (flag == 0)
            {
                myservo.position(0); 
                
                }
                
            else if (flag == 1) 
            {
                myservo.position(25); 
                
                }
                
            else if (flag == 2) 
            {
                myservo.position(-25); 
                
                }
            
        client.yield(YIELD_TIMEOUT_MS); // Need to call yield API to maintain connection
    }
}