NIKOLA ANICIC 2019/0099

Dependencies:   Adafruit_GFX_PIM 19E042PIM_MB_PINS

main.cpp

Committer:
an_thanik
Date:
2021-12-11
Revision:
0:32862e9c3b40

File content as of revision 0:32862e9c3b40:

/*
 * Nikola Anicic
 * 2019/0099
 *
 * ETF Beograd
 * napisano 11/12/2021
 *
 * 15:22 - 17:22
 */
 
/* Libraries & Definitions */
// Pin out diagram for motherboard
#include "mb_pins.h"

// Standard needed for most functions - Moved to version 5.15.4 for compatibility through Revisions
#include "mbed.h"

/* Headers needed for MQTT protocol communication */
#include "platform/mbed_thread.h"
#include "MQTTClientMbedOs.h"

/* Headers & Definitions needed for communication with OLED display */
 #include "Adafruit_GFX.h"
 #include "Adafruit_GFX_Config.h"                                                
 #include "Adafruit_SSD1306.h"    
 // I2C bus                  
 #define SCL                 PB_13
 #define SDA                 PB_14
 // I2C address
 #define I2C_ADDRESS         0x3C
 #define I2C_ADDRESS_MBED    I2C_ADDRESS << 1
 // I2C frequency
 #define FREQ                400000 // 400 kHz
 // OLED dimensions
 #define OLED_HEIGHT      64
 #define OLED_WIDTH       128

 #define RESET_PIN           PB_5                                               /* Needed for initializing the display */
 
 I2C                         i2c_obj(SDA, SCL); 
 Adafruit_SSD1306_I2c        myOLED(i2c_obj,                                    /* Adafruit_SSD1306.cpp documentation */
                                    RESET_PIN, 
                                    I2C_ADDRESS_MBED, 
                                    OLED_HEIGHT, 
                                    OLED_WIDTH
                                    );

/* Standard Definitions */
#define WAIT_PERIOD_SEC                                                       10 // s
#define YIELD_TIMEOUT_MS                                                    1000 // ms
#define BLINK_PERIOD                                                         250 // ms
#define SMALL_WAIT_MS                                                         10 // ms

DigitalOut LED (MB_LED2);
InterruptIn SW1(MB_SW1);
AnalogIn POT1 (MB_POT1);

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

/* Variables */
bool active = 0;

// Wifi information
WiFiInterface *wifi;
// .json for network information
const char* hostname = "broker.hivemq.com";
int port = 1883;

char* topic_pub = "pubpim"; // Publication // Za potrebe testiranja broj hardvera, obrisi kada zavrsis
char* topic_sub = "subpim"; // Subscription

/* Functions */
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(WiFiInterface *wifi)
{
    WiFiAccessPoint *access_point;
    printf("Scan:\n");
    
    int counter = wifi->scan(NULL, 0);
    if (counter <= 0)
    {
        printf("Function 'scan()' failed.");
        return 0;   
    }   
    
    counter = counter < 10 ? counter : 10;
    
    access_point = new WiFiAccessPoint[counter];
    counter = wifi->scan(access_point, counter);
    
    if (counter <= 0)
    {
        printf("Second 'scan()' failed");
        return 0;   
    }
    
    for (int i = 0; i < counter; i++)
    {
        printf(
            "Network: %s secured: %s BSSID: %hhX:%hhX:%hhX:%hhx:%hhx:%hhx RSSI: %hhd Ch: %hhd\n", 
            access_point[i].get_ssid(),
            sec2str(access_point[i].get_security()), 
            access_point[i].get_bssid()[0], 
            access_point[i].get_bssid()[1], 
            access_point[i].get_bssid()[2],
            access_point[i].get_bssid()[3], 
            access_point[i].get_bssid()[4], 
            access_point[i].get_bssid()[5], 
            access_point[i].get_rssi(), 
            access_point[i].get_channel()
        );   
        thread_sleep_for(SMALL_WAIT_MS);
    }
    printf("%d networks found.\n", counter);
    
    delete[] access_point;
    return counter;
}

void messageArrived(MQTT::MessageData &md)
{
    MQTT::Message &message = md.message;
    printf("%.*s \r\n", message.payloadlen, (char*) message.payload);
    // Browser message:  izbaceno radi poredjenja
}

int button_pressed = 0;
void ISR_SW1()
{
    active = !active;   
}

/* Main program */
int main ()
{   
    
    /* Initialization */
    SW1.fall(&ISR_SW1); // Debugging
    
    // Initializing the display
    i2c_obj.frequency(FREQ);
    myOLED.begin();
    
    wifi = WiFiInterface::get_default_instance();   
    
    if(!wifi)
    {
        printf("ERROR 000: Connection not established.\n");   
        return -1;
    }
    
    int count = scan(wifi);
    if (count == 0)
    {
        printf("ERROR 001: No Wifi access points found.\n");
        return -1;   
    }
    
    printf("\n Connecting 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("Error 002: Connection error.\n");
        return 1;
    }
    printf("Success!\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());
    
    int rc = 0;
    
    socket.open(wifi);
    socket.connect(hostname, port);
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 3;
    data.clientID.cstring = "pim-06";
        
    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)
    {
        printf("rc from MQTT subscribe is %d\r\n", rc);
    }
    
    while (true) 
    {
        LED = !LED;
        thread_sleep_for(BLINK_PERIOD); 
        
        if ( strcmp((char *) message.payload, "start") == 0 )
            active = 1;
            
        if ( strcmp((char *) message.payload, "stop") == 0 )
            active = 0;
            
        if ( active == 1 ) 
        {
            char buffer[100];
            int bufferlen = strlen(buffer) + 1;
            sprintf(buffer, "V(POT1) = %1.2f \r\n", POT1 * 3.3); // Where 3.3V is Vcc
            
            message.qos = MQTT::QOS0; 
            message.retained = false;
            message.dup = false;
            message.payload = (void*) buffer;
            message.payloadlen = bufferlen;
            client.publish(topic_pub, message); // Sending 'Message' to 'Topic for publishing'
            thread_sleep_for(WAIT_PERIOD_SEC * 1000);    
        }
        
        client.yield(YIELD_TIMEOUT_MS);   
    }
}

/* Debug code */
/*
        if ( button_pressed == 1 )
        {
            button_pressed = 0;
            char buffer[100];
            sprintf(buffer, "V(POT1) = %1.2f \r\n", POT1 * 3.3); // Where 3.3V is Vcc
            
            message.qos = MQTT::QOS0; 
            message.retained = false;
            message.dup = false;
            message.payload = (void*) buffer;
            message.payloadlen = strlen(buffer) + 1;
            client.publish(topic_pub, message); // Sending 'Message' to 'Topic for publishing'
        }
 */