Melbourne specific temperature/humidity sensor

Dependencies:   EALib EthernetInterface SHTx mbed-rtos mbed

main.cpp

Committer:
BPPearson
Date:
2016-05-06
Revision:
0:4bbf12d35a8c

File content as of revision 0:4bbf12d35a8c:

#include "mbed.h"
#include "EthernetInterface.h"
#include "QSPIFileSystem.h"
#include "SHTx/sht15.hpp"
 
 
#define ECHO_SERVER_PORT   7
#define on 0
#define off 1
#define DESIRED_SIZE_IN_MB  (1)

// devices 
Serial pc(USBTX, USBRX); // tx, rx
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalIn ipReset(p23,PullUp);
QSPIFileSystem qspifs("qspi");
SHTx::SHT15 sensor(p32, p31);
EthernetInterface eth;
TCPSocketServer server;
TCPSocketConnection client;
Ticker oneSecondTick;
DigitalOut hostQueryLED(p24);
DigitalOut timingPulse(p25);

// variables
char ipStr[20];
char subnetStr[20];
char gatewayStr[20]; 
char inBuff[256];
char outBuff[256];
float currTemperature = 25.4;
float currHumidity = 78.3;
int flashLedCnt = 4;
int cnt = 0;
bool sensorCommsFault;
int ipResetCount = 0;
 
// procedure declarations
void initSensor();
void readSensor();
void oneSecondTimer();
bool readConfigFile();
void writeConfigFile();
void processRcvBuffer(char *inBuff);

 
 
int main() 
{
    char *macAddr;
    //char *hello = "Hello\n";
    
    // get mac address and print it to PC
    //macAddr = eth.getMACAddress();
    //pc.printf("MAC address %s\n", macAddr);
    
    // check if file system already formatted
    if (!qspifs.isformatted()) 
    {        pc.printf("Format qspi file system\n");
        qspifs.format(DESIRED_SIZE_IN_MB);
    }
 
    // try to read config file which contains the IP address, subnet and gateway
/*    if (readConfigFile())
    {
        pc.printf("Config file ethernet details\n %s\n %s\n %s\n", ipStr, subnetStr, gatewayStr);
        // set IP address from config file    
        eth.init(ipStr, subnetStr, gatewayStr);
    }
    else
    {
        pc.printf("default ethernet address\n");
        // set to a default IP address, subnet and gateway
        strcpy(ipStr, "10.39.123.123");
        strcpy(subnetStr, "255.255.0.0");
        strcpy(gatewayStr,"10.39.1.1");

        // initialise the IP stack to these defaults
        eth.init(ipStr, subnetStr, gatewayStr); 
        
        // save default settings as working config
        writeConfigFile();
    }
*/

    eth.init(); //Use DHCP
    eth.connect();

    // get mac address and print it to PC
    macAddr = eth.getMACAddress();
    pc.printf("MAC address %s\n", macAddr);

    pc.printf("IP Address is %s\n", eth.getIPAddress());

    // turn off all the leds on the chip
    led1 = 1;
    led2 = 1;
    led3 = 0;
    led4 = 0;
  
    // bind to the required port      
    server.bind(ECHO_SERVER_PORT);
    
    // put into listen mode
    server.listen();
    
    // initialise the sensor
    initSensor();
    
    // start the one second tick that does periodic tasks such as read the sensor and toggle the activity LED
    oneSecondTick.attach(&oneSecondTimer, 1);
    
    // do forever
    while (1)
    {
        // configure stack ready to accept a client connection        
        server.accept(client);
 
        // wait for a connection request from the client (receipt of a packet)
        client.set_blocking(true, 0);
        
        // get received packet from client
        int n = client.receive(inBuff, sizeof(inBuff));

        // process the request from the client
        processRcvBuffer(inBuff);
        
        // close the client connection        
        client.close();

        // pulse LED 4 to show ethernet activity
        hostQueryLED = 0;
        wait(0.1);
        hostQueryLED = 1;

        //pc.printf("Sensor update\n");
        //pc.printf("Temp %5.1f, Humidity %5.1f\n", currTemperature, currHumidity );
    }}



void initSensor()
{
    
    // reset sensor just to check if it can be communicated with (returns true)
    if (sensor.reset())
    {
        sensorCommsFault = false;
        pc.printf("Sensor reset\n");
        
        // set temperature in celcius
        sensor.setScale(false);

        // optimise speed of sensor
        if (!sensor.setOTPReload(false))
        {
            sensorCommsFault = true;
            pc.printf("Set OTP reload\n");
        }
                    
        // set resolution to high (14 bits for temperature, 12 bits for humidity)
        if (!sensor.setResolution(false))
        {
            sensorCommsFault = true;
            pc.printf("Set resolution\n");
        }
    }
    else
    {
        sensorCommsFault = true;
        pc.printf("Sensor comms fault\n");
    }
}
    

void readSensor() 
{
    bool goodRead = false;
    
    if (!sensorCommsFault)
    {
        timingPulse = 1;
        
        goodRead = sensor.update();
    
        timingPulse = 0;

        // trigger a measurement
        if (goodRead == true)
        {
            // get temperature in celcius
            currTemperature = sensor.getTemperature();
        
            // get relative humidity
            currHumidity = sensor.getHumidity();
        }
        else
        {
            currTemperature = -1.0F;
                
            currHumidity = -1.0F;
        }    
            
    }
    else            // return error values
    {    
        currTemperature = -1.0F;
            
        currHumidity = -1.0F;
    }        
}



void oneSecondTimer()
{
    
    // if end of pulse sequence and LED still lit
    if (flashLedCnt == 0 && led4 == 1)
    {
        // turn off LED
        led4 = 0;
    }
        
    // if location LED still requires pulsing
    if (flashLedCnt > 0)
    {
        // toggle the LED indicator
        led4 = flashLedCnt & 1;
        
        // decrement the count
        flashLedCnt--;
    }

    // check if user pushbutton pressed (low)
    if (ipReset == 0)
    {
        // increment the counter
        ipResetCount++;

        // turn on a LED for seconds 1 to 4
        switch (ipResetCount)
        {
            case 1:
                led1 = 0;
                break;
            case 2:
                led2 = 0;
                break;
            case 3:
                led3 = 1;
                break;
            case 4:
                led4 = 1;
                break;
            case 5:
                // turn off all the leds on the chip to indicate change of IP address
                led1 = 1;
                led2 = 1;
                led3 = 0;
                led4 = 0;
                break;
            default: ;
        }
        
        // if button pressed for 5 seconds
        if (ipResetCount >= 5)
        {
            // initialise the IP address back to the default value
            strcpy(ipStr, "10.39.123.123");
            strcpy(subnetStr, "255.255.0.0");
            strcpy(gatewayStr,"10.39.1.1");
            
            // save to config file
            writeConfigFile();
        }
    }
    else
    {
        // reset the counter
        ipResetCount = 0;

        // turn off all the leds on the chip
        led1 = 1;
        led2 = 1;
        led3 = 0;
        led4 = 0;
    }
}


bool readConfigFile()
{
    int digits;
    int octet1, octet2, octet3, octet4;
    bool ipOk = false;
    bool subnetOk = false;
    bool gatewayOk = false;

    // open file pointer to config data    
    FILE *fp = fopen("/qspi/config.dat", "r");

    // if open successful
    if (fp != NULL)
    {
        // read 20 byte blocks for each parameter
        fread(ipStr, 20, 1, fp);
        fread(subnetStr, 20, 1, fp); 
        fread(gatewayStr, 20, 1, fp); 
        
        // close the file pointer
        fclose(fp);

        // break the IP address down to individual octets and return number of octets read
        digits = sscanf(ipStr, "%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4);

        // check if 4 octets and all within range
        if (digits == 4 && octet1 >=0 && octet1 < 256 && octet2 >=0 && octet2 < 256 && octet3 >=0 && octet3 < 256 && octet4 >=0 && octet4 < 256)
            ipOk = true;

        // break the subnet down to individual octets and return number of octets read
        digits = sscanf(subnetStr, "%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4);
        
        // check if 4 octets and all within range
        if (digits == 4 && octet1 >=0 && octet1 < 256 && octet2 >=0 && octet2 < 256 && octet3 >=0 && octet3 < 256 && octet4 >=0 && octet4 < 256)
            subnetOk = true;
            
        // break the gateway down to individual octets and return number of octets read
        digits = sscanf(gatewayStr, "%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4);
        
        // check if 4 octets and all within range
        if (digits == 4 && octet1 >=0 && octet1 < 256 && octet2 >=0 && octet2 < 256 && octet3 >=0 && octet3 < 256 && octet4 >=0 && octet4 < 256)
            gatewayOk = true;
            
        // if IP address, subnet and gateway valid
        if (ipOk && subnetOk && gatewayOk)
            return true;
        else
            return false;
    }
    return false;
}



void writeConfigFile()
{

    // open file pointer to config data file
    FILE *fp = fopen("/qspi/config.dat", "w");

    // if valid handle returned
    if (fp != NULL)
    {
        // write the IP address, subnet and gateway as 3 twenty byte blocks
        fwrite(ipStr, 20, 1, fp);
        fwrite(subnetStr, 20, 1, fp); 
        fwrite(gatewayStr, 20, 1, fp); 

        // close the file handle
        fclose(fp);
    }
}


    
    

                
void processRcvBuffer(char *inBuff)
{
    int digits;
    int octet1, octet2, octet3, octet4;
    bool ipOk = false;
    bool subnetOk = false;
    bool gatewayOk = false;
    char *cPtr = outBuff;
    
    switch (inBuff[0])
    {
        case 'r':                 // return temperature and humidity readings
            
            readSensor();
            
            // get temperature and humidity in a string            
            sprintf( cPtr, "%5.1f\n%5.1f\n", currTemperature, currHumidity );

            // send readings back to client
            client.send_all(outBuff, strlen(outBuff));       
            break;
        case 'i':                 // could be id or ip
            switch (inBuff[1])
            {
                case 'd':                         // flash a led to identify this device
                    flashLedCnt = 10;
                    break;
                case 'p':                         // set the IP address to that contained in this packet
                    // split packet up into seperate strings - ip add, subnet and gateway
                    sscanf(inBuff, "ip %s\n%s\n%s", ipStr, subnetStr, gatewayStr);
                    
                    //pc.printf("ip %s\nSubnet %s\ngateway %s\n", ipStr, subnetStr, gatewayStr);
                    
                    // check if ip address valid
                    digits = sscanf(ipStr, "%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4);
        
                    if (digits == 4 && octet1 >=0 && octet1 < 256 && octet2 >=0 && octet2 < 256 && octet3 >=0 && octet3 < 256 && octet4 >=0 && octet4 < 256)
                        ipOk = true;

                    //pc.printf("ip %d.%d.%d.%d\n", octet1, octet2, octet3, octet4 );
                    
                    // check if subnet valid
                    digits = sscanf(subnetStr, "%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4);
        
                    //pc.printf("subnet %d.%d.%d.%d\n", octet1, octet2, octet3, octet4 );

                    if (digits == 4 && octet1 >=0 && octet1 < 256 && octet2 >=0 && octet2 < 256 && octet3 >=0 && octet3 < 256 && octet4 >=0 && octet4 < 256)
                        subnetOk = true;
                    
                    // check if gateway valid
                    digits = sscanf(gatewayStr, "%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4);
        
                    //pc.printf("gateway %d.%d.%d.%d\n", octet1, octet2, octet3, octet4 );

                    if (digits == 4 && octet1 >=0 && octet1 < 256 && octet2 >=0 && octet2 < 256 && octet3 >=0 && octet3 < 256 && octet4 >=0 && octet4 < 256)
                        gatewayOk = true;

                    // if all valid
                    if (ipOk && subnetOk && gatewayOk)
                    {
                        //pc.printf("Changing IP settings\n");
                        
                        // save to config file
                        writeConfigFile();
                    }
                    break;
                default: ;
            }
            break;
        default: 
            break;
    }
}