UoK Shed IOT Crossing

Dependencies:   EthernetInterface MQTT mbed-dsp mbed-rtos mbed

Fork of KL25Z_FFT_Demo_tony by Leicester Hackspace

main.cpp

Committer:
Condo2k4
Date:
2016-01-14
Revision:
6:78106c78e577
Parent:
5:4152530c0cf5

File content as of revision 6:78106c78e577:

// Audio Spectrum Display
// Copyright 2013 Tony DiCola (tony@tonydicola.com)
// Code ported from the guide at http://learn.adafruit.com/fft-fun-with-fourier-transforms?view=all
// mods by Tony Abbey to simplify code to drive tri-colour LED as a "colour organ"

#include "mbed.h"

#include "EthernetInterface.h"
#include "MQTTEthernet.h"
#include "MQTTClient.h"

#define IP_RETRIES 2
#define HOSTNAME "192.168.0.1"
//#define HOSTNAME "doughnut.kent.ac.uk"
#define PORT 1883

enum Mode {RESPONSIVE, OVERRIDE};

//timer
Ticker timer;

//buffers
char mqtt_buffer[100];
MQTT::Message message;

//topics
char personTopic[] = "shed/masterclass/iot/crossing/person";
char modeTopic[] = "shed/masterclass/iot/crossing/mode";

//io
AnalogIn sensor(A0);
DigitalOut GND(A2);
DigitalOut pelican(D0);
Ticker presenceTimer;

//state
bool personPresent = false;
volatile Mode mode = RESPONSIVE;
volatile bool checkPresence = false;

volatile bool turnLightsOn = false;
volatile bool turnLightsOff = false;

void presenceTick() {
    checkPresence = true;
}

void timeout() {
    if(mode==RESPONSIVE) {
        turnLightsOff = true;
    }
    timer.detach();
}

void messageArrived(MQTT::MessageData& md) {
    MQTT::Message &msg = md.message;
    
    char mode;
    if(sscanf((char*)msg.payload, "{\"mode\":\"%c\"}", &mode)) {
        switch(mode) {
            case 'r': case 'R': mode = RESPONSIVE; if(!personPresent) timer.attach(&timeout,3.0f); break;
            case 'o': case 'O': mode = OVERRIDE; turnLightsOn=true; break;
        }
    }
}

int main() {

    MQTTEthernet ipstack;
    MQTT::Client<MQTTEthernet, Countdown> m_client(ipstack);
    
    int ip_result;
    for(int i=0; i<IP_RETRIES; i++) {
        int ip_result = ipstack.connect(HOSTNAME, PORT);
        if(ip_result==0) break;
    }
    if (ip_result != 0) {
        error("IP stack failed");
    }
    if(m_client.connect()!=MQTT::SUCCESS) {
        error("MQTT connection failed");
    }
    if(m_client.subscribe(modeTopic, MQTT::QOS0, messageArrived)!=MQTT::SUCCESS) {
        error("MQTT subscribe failed");
    }
    
    GND = 0; //provide sensor with ground
    
    presenceTimer.attach_us(&presenceTick,50000);
    
    while(1) {
        
        sleep();
        
        if(checkPresence) {
            float s = sensor;
            if((s<0.5f)!=personPresent) { //state changed
                personPresent = s<0.5f;
                
                if(mode==RESPONSIVE && personPresent) {
                    sprintf(mqtt_buffer, "{\"personPresent\":1, \"lightState\":1}");
                } else {
                    sprintf(mqtt_buffer, "{\"personPresent\":%d}", personPresent);
                }
                message.qos = MQTT::QOS0;   // Send at least once
                // Do not null terminate -- we have a length field, and it will piss off the JS front end
                message.payloadlen = strlen(mqtt_buffer);
                message.payload = (void*)mqtt_buffer;
                m_client.publish(personTopic, message);
                
                if(personPresent) {
                    timer.attach(&timeout,3.0f);
                    pelican = true;
                }
            }
            checkPresence = false;
        }
        if(turnLightsOn) {
            pelican = true;
            sprintf(mqtt_buffer, "{\"lightState\":1}");
            message.qos = MQTT::QOS0;   // Send at least once
            // Do not null terminate -- we have a length field, and it will piss off the JS front end
            message.payloadlen = strlen(mqtt_buffer);
            message.payload = (void*)mqtt_buffer;
            m_client.publish(personTopic, message);
            turnLightsOn = false;
        }
        if(turnLightsOff) {
            pelican = false;
            sprintf(mqtt_buffer, "{\"lightState\":0}");
            message.qos = MQTT::QOS0;   // Send at least once
            // Do not null terminate -- we have a length field, and it will piss off the JS front end
            message.payloadlen = strlen(mqtt_buffer);
            message.payload = (void*)mqtt_buffer;
            m_client.publish(personTopic, message);
            turnLightsOff = false;
        }
        
        m_client.yield(100);
    }
    
    
    /*    
    */
}