temp

Files at this revision

API Documentation at this revision

Comitter:
BenRJG
Date:
Thu Dec 06 15:38:09 2018 +0000
Commit message:
Imported Code from Kiel; Added button functionality; Added set DateTime Functionality

Changed in this revision

Button.cpp Show annotated file Show diff for this revision Revisions of this file
Button.hpp Show annotated file Show diff for this revision Revisions of this file
General.hpp Show annotated file Show diff for this revision Revisions of this file
LCD.cpp Show annotated file Show diff for this revision Revisions of this file
LCD.hpp Show annotated file Show diff for this revision Revisions of this file
NetWorking.cpp Show annotated file Show diff for this revision Revisions of this file
NetWorking.hpp Show annotated file Show diff for this revision Revisions of this file
Pages.cpp Show annotated file Show diff for this revision Revisions of this file
Pages.hpp Show annotated file Show diff for this revision Revisions of this file
SDReader.cpp Show annotated file Show diff for this revision Revisions of this file
SDReader.hpp Show annotated file Show diff for this revision Revisions of this file
Terminal.cpp Show annotated file Show diff for this revision Revisions of this file
Terminal.hpp Show annotated file Show diff for this revision Revisions of this file
dateTime.hpp Show annotated file Show diff for this revision Revisions of this file
displayThread.cpp Show annotated file Show diff for this revision Revisions of this file
displayThread.h 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
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
sample_buffer.cpp Show annotated file Show diff for this revision Revisions of this file
sample_buffer.hpp Show annotated file Show diff for this revision Revisions of this file
sd-driver.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Button.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,77 @@
+#include "Button.hpp"
+
+BYTE BUTTON::poll(void)
+{
+    switch(state)
+    {
+        case FALLEN :
+            OUTPUT = 0;
+            if(IN != 0){
+                OUTPUT = 1;
+                state = RISING;
+                timer.reset();
+                timer.start();
+            }
+        break;
+        
+        case RISING :
+            OUTPUT = 0;
+            if(timer.read_ms() > 100){
+                timer.stop();
+                state = RISEN;
+            }
+        break;
+        
+        case RISEN :
+            OUTPUT = 0;
+            if(IN != 0){
+                OUTPUT = 2;
+                state = FALLING;
+                timer.reset();
+                timer.start();
+            }
+        break;
+        
+        case FALLING :
+            OUTPUT = 0;
+            if(timer.read_ms() > 100){
+                timer.stop();
+                state = FALLEN;
+            }
+        break;
+    }
+    
+    return OUTPUT;
+}
+
+BYTE BUTTON::rise(void)
+{
+    switch(state)
+    {
+        case FALLEN :
+            OUTPUT = 0;
+            if(IN != 0){
+                OUTPUT = 1;
+                state = RISING;
+                timer.reset();
+                timer.start();
+            }
+        break;
+        
+        case RISING :
+            OUTPUT = 0;
+            if(timer.read_ms() > 100){
+                timer.stop();
+                state = FALLEN;
+            }
+        break;
+    }
+    
+    return OUTPUT;
+}
+
+/*BYTE BUTTON::fall(void)
+{
+    
+    return OUTPUT;
+}*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Button.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,18 @@
+#include "mbed.h"
+#include "General.hpp"
+
+// Class BUTTON polls a button for detection of edge
+class BUTTON {
+    public:
+        BUTTON(PinName pin) : IN(pin){state = FALLEN;}
+        BYTE poll(void);
+				BYTE rise(void);
+				//BYTE fall(void);
+    private:
+        enum State {FALLEN, RISING, RISEN, FALLING};
+        State state;
+        DigitalIn IN;
+        INT_16 OUTPUT; //Output is 1 if button is rising and 2 if button is falling
+        Timer timer;
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/General.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+
+// Define Needed values for SD reader
+#define Signal_UnMount 1
+
+// define all datatypes to make data sizes more understandable
+#define     S_BYTE      signed char
+#define     BYTE        char
+#define     U_BYTE      unsigned char
+#define     INT_16      short int
+#define     UINT_16     unsigned short int
+#define     INT_32      int
+#define     UINT_32     unsigned int
+#define     INT_64      long int
+#define     UINT_64     unsigned long int
+#define     FLOAT_32    float
+#define     FLOAT_64    double
+#define     FLOAT_96    long double
+
+extern Thread SDcard_THREAD, Terminal_THREAD, NetWorking_THREAD;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LCD.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,98 @@
+#include "LCD.hpp"
+#include "General.hpp"
+
+//LCD data sheet: https://www.rapidonline.com/pdf/57-2224.pdf
+
+void LCD::INIT()
+{
+    //All lines default low
+    _LCD_RS = 0;
+    _LCD_E  = 0;
+    
+    //LCD Initialise
+    wait_ms(45); //Wait for LCD startup
+    /*Step 1*/
+        wait_us(40);      //Wait whilst LCD busy
+        _LCD_RS = control;   
+        LCD_DDRAM = 0;  //Clear data line
+        LCD_DDRAM = (FUNC|bit8)>>4;  //Put data on line
+        LCD_strobe();
+    
+    /*Step 2*/ cmdLCD(FUNC|lines2);  //Function Set 0x20|0x08 = 0x28
+    /*Step 3*/ cmdLCD(FUNC|lines2);  //Function Set 0x20|0x08 = 0x28
+    /*Step 4*/ cmdLCD(DISPLAY|on);    //Display Control 0x08|0x0x04 = 0x0c
+    /*Step 5*/ cmdLCD(CLEAR);         //Clear Display 0x01
+    /*Step 6*/ cmdLCD(ENTRYMODE|I);   //Set entry mode 0x04|0x02 = 0x06
+
+    cmdLCD(RETURN); //return home location
+}
+
+void LCD::clear()
+{
+    cmdLCD(CLEAR);   
+}
+
+void LCD::display(BYTE* str, UINT_16 location)
+{
+    if(location != NULL)
+    {
+        pos(location);
+    }
+    U_BYTE p = 0;
+    while((str[p]!= NULL)&&(p<16))
+    {
+        putt(str[p]);
+        p++; 
+    }
+}
+
+void LCD::pos(UINT_16 location)
+{
+    cmdLCD(0x80|location);   
+}
+
+void LCD::putt(U_BYTE c)
+{
+    wait_us(3000);
+    _LCD_RS = text;
+    set_LCD_data(c);
+}
+
+void LCD::cmdLCD(U_BYTE cmd)
+{
+    wait_us(3000);      //Wait whilst LCD busy
+    _LCD_RS = control;   
+    set_LCD_data(cmd);  //set data on bus
+}
+
+void LCD::LCD_strobe(void)
+{
+    wait_us(10);
+    _LCD_E = 1;
+    wait_us(10);
+    _LCD_E = 0;
+}
+
+void LCD::set_LCD_data(U_BYTE d)
+{
+    // Send upper 4 bits then lower for bits
+    // e.g. 11110000 => 1111 -> 0000
+    
+    LCD_DDRAM = 0;  //Clear data line
+    LCD_DDRAM = d>>4;  //Put data on line
+    LCD_strobe();
+    wait_us(1000);
+    LCD_DDRAM = 0;  //Clear
+    LCD_DDRAM = d; //Put remaining data on line
+    LCD_strobe();   
+}
+
+void LCD::enableCursor()
+{
+    cmdLCD(DISPLAY|on|cursor);
+}
+
+void LCD::disableCursor()
+{
+    cmdLCD(DISPLAY|on);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LCD.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,55 @@
+#ifndef _LCD_HPP
+#define _LCD_HPP
+    
+    #include "mbed.h"
+    #include "General.hpp"
+    
+    #define CLEAR   0x01
+    #define RETURN  0x02
+    
+    #define ENTRYMODE 0x04
+    #define I 0x02
+    #define shift 0x01    
+    
+    #define DISPLAY 0x08
+    #define on 0x04
+    #define cursor  0x02
+    #define blink   0x01    
+    
+    #define FUNC 0x20
+    #define bit8  0x10
+    #define lines2 0x08
+    #define dots11 0x04
+    
+    #define control 0
+    #define text 1
+    
+    #define write 0
+    #define read 1
+    
+    #define LINE1 0x00
+    #define LINE2 0x40
+    
+    class LCD{
+        public:
+            LCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7) : _LCD_RS(rs), _LCD_E(e), LCD_DDRAM(d4,d5,d6,d7) {} 
+            void INIT();
+            void clear();
+            void display(BYTE* str, UINT_16 location=NULL);
+            void putt(U_BYTE c);
+            void pos(UINT_16 location);
+            
+            void enableCursor();
+            void disableCursor();
+        private:
+            DigitalOut _LCD_RS;
+            DigitalOut _LCD_E;
+            BusOut LCD_DDRAM;   
+        private:
+            void cmdLCD(U_BYTE cmd);
+            void LCD_strobe(void);
+            void set_LCD_data(U_BYTE d);
+            UINT_32 findSpace(U_BYTE* str);
+    };
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NetWorking.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,59 @@
+#include "NetWorking.hpp"
+
+// Thread handels networking and updates a conected PC whenever the webpage is refreshed
+void NetWorkingThread(void)
+{    
+    // Configure an ethernet connection
+    EthernetInterface eth;
+    eth.set_network(IP, NETMASK, GATEWAY);
+    eth.connect();
+    
+    // Now setup a web server
+    TCPServer srv;           // TCP/IP Server
+    TCPSocket clt_sock;      // Socket for communication
+    SocketAddress clt_addr;  // Address of incoming connection
+    
+    // Open the server on ethernet stack
+    srv.open(&eth);
+    
+    // Bind the HTTP port (TCP 80) to the server
+    srv.bind(eth.get_ip_address(), 80);
+    
+    // Set maximum simultanious conections
+    srv.listen(5);
+    
+    while (true) {
+        using namespace std;
+        
+        // Block and wait on an incoming connection (if page is accessed)
+        srv.accept(&clt_sock, &clt_addr);
+        
+        // Get most up to date enviromental values
+        float LIGHT = 0.0f;
+        float TEMP = 0.0f;
+        float PRES = 0.0f;
+        
+        // Convert to a C String
+        char Light_str[8];
+        char Temp_str[8];
+        char Pres_str[8];
+        sprintf(Light_str, "%5.3f", LIGHT );
+        sprintf(Temp_str, "%5.3f", TEMP );
+        sprintf(Pres_str, "%5.3f", PRES );
+        
+        string response;
+
+        // Build the C++ string response
+        response = HTTP_MESSAGE_BODY1;
+        response += Light_str;
+        response += HTTP_MESSAGE_BODY2;
+        response += Temp_str;
+        response += HTTP_MESSAGE_BODY3;
+        response += Pres_str;
+        response += HTTP_CLOSE;
+        
+        // Send static HTML response (as a C string)
+        int debug = clt_sock.send(response.c_str(), strlen(response.c_str())+6);   
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NetWorking.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,50 @@
+#if !FEATURE_LWIP
+    #error [NOT_SUPPORTED] LWIP not supported for this target
+#endif
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "TCPServer.h"
+#include "TCPSocket.h"
+#include <iostream>
+#include <string> 
+
+#define HTTP_STATUS_LINE "HTTP/1.0 200 OK"
+#define HTTP_HEADER_FIELDS "Content-Type: text/html; charset=utf-8"
+#define HTTP_MESSAGE_BODY1 ""                                           \
+"<html>" "\n\r"                                                         \
+"<head>" "\n\r"                                                         \
+"  <meta charset=\"utf-8\">" "\n\r"                                     \
+"  <title> ELEC 351 </title>" "\n\r"                                    \
+"  <meta http-equiv=\"refresh\" content=\"10\">" "\n\r"                 \
+"</head>" "\n\r"                                                        \
+"<body style=\"display:flex;text-align:center\" bgcolor=\"black\" text=\"white\">" "\n\r"  \
+"  <div style=\"margin:auto\">" "\n\r"                                  \
+"    <h1> Low Power Enviromental Sensor : Network Conection </h1>" "\n\r"\
+"    <p>  The Light value is "                                        
+
+#define HTTP_MESSAGE_BODY2 ""                                           \
+"    </p>" "\n\r"                                                       \
+"    <p>  The Temp value is "                                        
+
+#define HTTP_MESSAGE_BODY3 ""                                           \
+"    </p>" "\n\r"                                                       \
+"    <p>  The Pressure value is "                                        
+
+#define HTTP_CLOSE ""                                                   \
+"    </p>" "\n\r"                                                       \
+"  </div>" "\n\r"                                                       \
+"</body>" "\n\r"                                                        \
+"</html>"                                                        
+
+#define HTTP_RESPONSE HTTP_STATUS_LINE "\r\n"   \
+                      HTTP_HEADER_FIELDS "\r\n" \
+                      "\r\n"                    \
+                      HTTP_MESSAGE_BODY "\r\n"
+
+#define IP        "10.0.0.10"
+#define NETMASK   "255.0.0.0"
+#define GATEWAY   "10.0.0.1"
+
+void NetWorkingThread(void);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pages.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,91 @@
+#include "Pages.hpp"
+
+    //d.setTime();
+    //printf("Info Start -------\n\r");
+    //printf("Time -> %s\n\r",d.getTime());
+    //printf("Info End ---------\n\r");
+
+void Pages::INIT()
+{
+    setTemperature(0);
+    setLightLevel(0);
+    setPressure(0);
+    _lcd.INIT();
+    
+}
+
+void Pages::pageOne()
+{
+    _lcd.clear();
+   // _lcd.disableCursor();
+    
+    //Temperature Page
+    _lcd.display("T: ",LINE1);
+    _lcd.display(_temperature);
+    _lcd.putt(223);
+    _lcd.display("C");
+    
+    //LightLevel Page
+    _lcd.display("L: ",LINE1+9);
+    _lcd.display(_lightLevel);
+
+    //Pressure Page
+    _lcd.display("P: ",LINE2+2);
+    _lcd.display(_pressure);
+    _lcd.display(" mbar");
+    _lcd.enableCursor();
+}
+
+void Pages::pageTwo()
+{
+    _lcd.clear();
+  //  _lcd.enableCursor();
+    
+    _lcd.display("00/00/0000 00:00",LINE1);
+    _lcd.display("dd/mm/yyyy hh:mm",LINE2);
+    
+    _lcd.pos(LINE1);
+}
+
+void Pages::pageThree()
+{
+    _lcd.clear();
+  //  _lcd.enableCursor();
+    
+    _lcd.display("Life? don't talk",LINE1);
+    _lcd.display("to me about life",LINE2);
+    
+    _lcd.pos(LINE1);
+}
+
+void Pages::setTemperature(S_BYTE temp)
+{
+    sprintf(_temperature,"%d",temp);
+}
+
+void Pages::setLightLevel(U_BYTE light)
+{
+    sprintf(_lightLevel,"%u",light);
+}
+
+void Pages::setPressure(U_BYTE pres)
+{
+    sprintf(_pressure,"%u",pres);
+}
+
+void Pages::setDateTime(char* dateTime)
+{
+       _lcd.pos(LINE1);
+       _lcd.display(dateTime,LINE1);
+}
+
+void Pages::cursorPos(UINT_16 location)
+{
+    _lcd.pos(location);
+}
+
+void Pages::clear()
+{
+	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pages.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,30 @@
+#ifndef _DISPLAY_HPP
+#define _DISPLAY_HPP
+    #include "mbed.h"
+    #include "General.hpp"
+    #include "LCD.hpp"
+    
+    class Pages{
+        public:
+            Pages(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7) : _lcd(rs,e,d4,d5,d6,d7) {} 
+            void INIT();
+            void clear();
+            void pageOne();
+            void pageTwo();
+            void pageThree();
+						void cursorPos(UINT_16 location);
+            
+            void setTemperature(S_BYTE temp);
+            void setLightLevel(U_BYTE light);
+            void setPressure(U_BYTE pres);
+            
+            void setDateTime(char* dateTime);
+        private:
+            char _temperature[4];
+            char _lightLevel[5];
+            char _pressure[6];
+        private:
+            LCD _lcd;
+    };
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDReader.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,133 @@
+#include "SDReader.hpp"
+#include "Button.hpp"
+
+// Thread for saving DATA to the SD card
+void SDThread(void)
+{
+    // Create object SD of the SDReader class with set SPI pins
+    SDReader SD(PB_5, D12, D13, D10); // mosi, miso, sclk, cs   
+    
+    // Create switch to dismount the SD card
+    BUTTON onBoardSwitch(USER_BUTTON);
+    
+    // Create variable to store state of SD card
+    enum State {MOUNTED, UNMOUNTED, MOUNTING, UNMOUNTING};
+    State Mounted = MOUNTING;
+    
+    while(1)
+    {
+        // FSM for each state of SD card
+        switch(Mounted)
+        {
+            case UNMOUNTED :
+                wait_ms(100);
+                if(onBoardSwitch.poll() == 1)
+                {
+                    Mounted = MOUNTING;
+                }
+            break;
+                
+            case MOUNTED :
+                //SD.UPLOAD(1.404f,0.303f,0.124f);
+                wait_ms(100);
+                if(onBoardSwitch.poll() == 1)
+                {
+                    Mounted = UNMOUNTING;
+                }
+            break;
+                
+            case UNMOUNTING :
+                SD.unmount();
+                Terminal_THREAD.signal_set(Signal_UnMount);
+                Mounted = UNMOUNTED;
+            break;
+            
+            case MOUNTING :
+                if(SD.INIT() == 0){
+                    Mounted = UNMOUNTED;
+                    Terminal_THREAD.signal_set(Signal_UnMount);
+                } else {
+                    Mounted = MOUNTED;  
+                }                
+            break;
+        }
+    }
+}
+
+BYTE SDReader::INIT(void)
+{
+    BYTE Mount;
+    
+    // call the SDBlockDevice instance initialisation method.
+    if(sd.init() != 0){
+        Mount = 0;
+    } else {
+        Mount = 1;
+    }
+    
+    if(Mount == 0){
+        return Mount;
+    } else {           
+        //Remove existing file
+        remove( "/sd/ELEC351.csv" );
+        
+        FILE* fp = fopen("/sd/ELEC351.csv","a+");
+        //Check file handle (stream)
+        if (fp == NULL) {
+            return Mount;
+        }
+            
+        //Put some text in the file...
+        fprintf(fp, " TIME STAMP, light, temperature, pressure\n");
+        
+        //Close the file
+        fclose(fp);
+        
+        return Mount;
+    }
+}
+
+void SDReader::UPLOAD(FLOAT_32 LIGHT, FLOAT_32 TEMP, FLOAT_32 PRESS)
+{   
+    FILE* fp = fopen("/sd/ELEC351.csv","a+");
+    //Check file handle (stream)
+    if (fp == NULL) {
+        return;
+    }
+    
+    //Put some text in the file...
+    fprintf(fp, " TIME STAMP, %1.4f, %1.4f, %1.4f\n", LIGHT, TEMP, PRESS);
+    
+    //Close the file
+    fclose(fp);
+}
+
+BYTE* SDReader::DOWNLOAD(void)
+{   
+    FILE* fp = fopen("/sd/ELEC351.csv","r");
+    if (fp == NULL) {
+
+    }   
+    
+    //Read back all strings
+    BYTE* s1 = new BYTE;
+    
+    //while (fscanf(fp, "%s", s1) == 1) 
+    //{
+    //
+    //}
+    
+    fgets(s1, sizeof(s1), fp);
+    
+    //Close File
+    fclose(fp);
+    
+    return s1;
+}
+
+void SDReader::unmount(void)
+{
+    sd.deinit();
+    return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDReader.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+#include "SDBlockDevice.h"
+#include "FATFileSystem.h"
+#include "General.hpp"
+#include "rtos.h"
+
+// Class SDReader expects mosi miso sclk and cs pins and is used for controlling a spi connected sd reader
+class SDReader {
+    public:
+        SDReader(PinName mosi, PinName miso, PinName sclk, PinName cs) : sd(mosi, miso, sclk, cs), fs("sd", &sd){}
+        BYTE INIT(void);
+        void UPLOAD(FLOAT_32 LIGHT, FLOAT_32 TEMP, FLOAT_32 PRESS);
+        BYTE* DOWNLOAD(void);
+        void unmount(void);
+    private:
+        SDBlockDevice sd;
+        FATFileSystem fs;
+};
+
+void SDThread(void); // Thread for terminal to run in
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Terminal.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,89 @@
+/*******************************************************************************
+This cpp defines the functions for the terminal class which are used to 
+control the terminal, it also defines the TerminalThread function which
+is ran in its own thread and controls the printing of DATA to the Terminal
+*******************************************************************************/
+#include "Terminal.hpp"
+
+// Thread for handiling the terminal
+void TerminalThread(void)
+{
+    // Create Object PC of class Terminal with Set SERIAL_TX and SERIAL_RX pins
+    Terminal PC(SERIAL_TX, SERIAL_RX);
+    PC.init();
+    PC.DisplayCellIndex();
+    // Enter Forever loop
+    while(1)
+    {
+        // If signal from SD thread recieved print message to terminal
+        Thread::signal_wait(Signal_UnMount);
+        PC.PrintMSGS("UNMOUNTED SD");
+    }   
+}
+
+void Terminal::init(void)
+{
+    // Set baud rate for serial object pc
+    pc.baud (115200);   
+     
+    // Hide cursor, move to x 0 y 0 and change print colour to green
+    pc.printf("\x1b[?25l"); // Hides cursor
+    //pc.printf("\x1b[3j"); // Clear screen
+    Cursor(0,0);
+    Colour(ColourGREEN);
+ 
+    // Print DATA table to present data
+    pc.printf("* ELEC351 : Low Power Enviromental Sensor *   Date and Time Here    *\n\r"
+              "*********************************************************************\n\r"
+              "*      TIME      *    TEMP (C)    * PRESSURE (mbar)*   LIGHT (LUX)  *\n\r"
+              "*********************************************************************\n\r");
+    for(BYTE idx = 0; idx < Rows; idx++)
+    {
+        pc.printf("*                *                *                *                *\n\r");
+    }
+    pc.printf("*********************************************************************\n\r"
+              "* Debug *                                                           *");
+    
+    // Position cursor in first cell of table
+    Cursor(3,3);
+    Colour(ColourRED);
+}
+
+// Move cursor of pc terminal to co-ordinates 'X' and 'Y' (between 0 and 255)
+void Terminal::Cursor(BYTE X, BYTE Y)
+{
+    pc.printf("\x1b[%d;%dH",Y,X);
+}
+
+// Change pc terminal print colour (8 bit colour) to colour defined by "COLOUR"
+void Terminal::Colour(BYTE COLOUR)
+{
+    pc.printf("\x1b[38;5;%dm",COLOUR);
+}
+
+// Prints data(STRING) to cell in table defined by IDX
+void Terminal::PrintDATA(BYTE* STRING, BYTE IDX)
+{
+    BYTE Y = (IDX/4)+5;
+    BYTE X = ((IDX%4)*17)+3;
+    Cursor(X,Y);
+    pc.printf("%s",STRING);  
+}
+
+// Prints index of cells into each cell for debug purpose
+void Terminal::DisplayCellIndex(void){
+    for(BYTE IDX = 0; IDX < MaxDATA; IDX++){
+        BYTE Y = (IDX/4)+5;
+        BYTE X = ((IDX%4)*17)+3;
+        Cursor(X,Y);
+        pc.printf("%d",IDX);
+    }        
+}
+
+// Prints MSGS (String) to debug line of terminal
+void Terminal::PrintMSGS(BYTE* STRING)
+{    
+    Cursor((11),(Rows+6));
+    pc.printf("%s",STRING);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Terminal.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,37 @@
+/*******************************************************************************
+This header defines Terminal class which has all the functions for controlling a 
+terminal, the serial object is kept private and therefore can only be accessed
+through function of the terminal class.
+*******************************************************************************/
+
+#include "mbed.h"
+#include "rtos.h"
+#include "General.hpp"
+
+// Use generic to set number of rows in table
+#define Rows 15
+#define MaxDATA (Rows*4)
+
+// Define 8 bit colours for printing to terminal 
+#define ColourRED    9
+#define ColourGREEN  118
+#define ColourBLUE   12
+#define ColourWhite  255
+#define ColourPurple 5
+
+// Class Terminal expects tx and rx pins and is used for controlling a serialy conected terminal
+class Terminal {
+    public:
+        Terminal(PinName tx, PinName rx) : pc(tx, rx){}
+        void init(void);
+        void PrintDATA(BYTE* STRING, BYTE IDX);
+        void PrintMSGS(BYTE* STRING);
+        void DisplayCellIndex(void); // Prints index of cells into each cell for debug purpose
+    private:
+        Serial pc;
+        void Cursor(BYTE X, BYTE Y); // Function moves cursor to position defined by co-ordinates x,y
+        void Colour(BYTE COLOUR);    // Function changes terminal print colour to 8 bit colour defined by COLOUR
+};
+
+void TerminalThread(void); // Thread for terminal to run in
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dateTime.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,90 @@
+#ifndef _dateTime_HPP
+#define _dateTime_HPP
+    #include "mbed.h"
+    #include "General.hpp"
+    
+    class dateTime{
+        public:
+            dateTime()
+						{
+							getSystemTime();
+							time_t check = -1;
+							if(mktime(&_currentTime_struct) == check)
+							{
+								_currentTime_struct.tm_year = 70;
+								_currentTime_struct.tm_mon = 0;
+								_currentTime_struct.tm_mday = 1;
+								_currentTime_struct.tm_hour = 0;
+								_currentTime_struct.tm_min = 0;
+								_currentTime_struct.tm_sec = 0;
+								printf("THIS HAS BEEN RUN TOO\n\r");
+							}
+							
+							printf("THIS HAS BEEN RUN %d\n\r",check);
+						}
+            
+            
+						void updateStruct()
+						{	
+							time_t _newTime_time = mktime(&_newTime_struct);
+							_newTime_struct = *localtime(&_newTime_time);
+							if(_newTime_struct.tm_year == 0)
+							{
+									_newTime_struct = _currentTime_struct;
+							}
+							_currentTime_struct = _newTime_struct;
+						}
+						
+						void addYear (INT_32 years  =1){
+							_newTime_struct = _currentTime_struct;
+							_newTime_struct.tm_year = _currentTime_struct.tm_year + years;
+							updateStruct();
+						}
+						
+						void addMonth(S_BYTE months =1){
+							_newTime_struct = _currentTime_struct;
+							_newTime_struct.tm_mon = _currentTime_struct.tm_mon + months;
+							updateStruct();
+						}
+            void addDay	 (S_BYTE days   =1){
+							_newTime_struct = _currentTime_struct;
+							_newTime_struct.tm_mday = _currentTime_struct.tm_mday + days;
+							updateStruct();
+						}
+            void addHour (S_BYTE hours  =1){
+							_newTime_struct = _currentTime_struct;
+							_newTime_struct.tm_hour = _currentTime_struct.tm_hour + hours;
+							updateStruct();
+						}
+            void addMin  (S_BYTE minutes=1){
+							_newTime_struct = _currentTime_struct;
+							_newTime_struct.tm_min = _currentTime_struct.tm_min + minutes;
+							updateStruct();
+						}
+            void addSec  (S_BYTE seconds=1){
+							_newTime_struct = _currentTime_struct;
+							_newTime_struct.tm_sec = _currentTime_struct.tm_sec + seconds;
+							updateStruct();
+						}
+						
+            void setSystemTime(){set_time(mktime(&_currentTime_struct));}
+            char* getSystemTime(){time_t rawTime; time(&rawTime); _currentTime_struct = *localtime(&rawTime); return getTime();}
+            
+            char* getTime() {sprintf(dateTimeStr,"%02d/%02d/%4d %02d:%02d:%02d",getDay(),getMonth(),getYear(),getHour(),getMin(),getSec()); return dateTimeStr;}
+            //char* getTime() {updateTime(); sprintf(dateTimeStr, "Hello world %d:)",42);return dateTimeStr;};
+            
+            signed INT_32 getYear() {return _currentTime_struct.tm_year + 1900;}
+            BYTE getMonth()  {return _currentTime_struct.tm_mon + 1;    }
+            BYTE getDay()    {return _currentTime_struct.tm_mday;       }
+            BYTE getHour()   {return _currentTime_struct.tm_hour;       }
+            BYTE getMin()    {return _currentTime_struct.tm_min;        }
+            BYTE getSec()    {return _currentTime_struct.tm_sec;        }
+        private:
+            //time_t _currentTime_time;
+            struct tm _currentTime_struct;
+						struct tm _newTime_struct;
+            char dateTimeStr[20];
+            //01/09/
+    };
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/displayThread.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,178 @@
+#include "displayThread.h"
+//InterruptIn button1(b1);
+//InterruptIn button2(b2);
+
+InterruptIn button1(b1);
+InterruptIn button2(b2);
+
+U_BYTE buttonPressed;
+
+signed INT_32 increment[] = {10,1,10,1,1000,100,10,1,10,1,10,1,10,1};
+signed INT_32 cursorPosition[] = {0,1,3,4,6,7,8,9,11,12,14,15};
+
+dateTime d;
+Pages page(RS,E,d4,d5,d6,d7); //rs,e,d4,d5,d6,d7
+U_BYTE cursorPos=0;
+enum pageNumber {PAGEONE, PAGETWO, PAGETHREE};
+
+pageNumber currentPage;
+
+EventQueue buttonQueue;
+
+Timeout doublePress;
+
+void DisplayThread()
+{
+  page.INIT();
+	page.pageOne();
+	page.pageOne();
+	currentPage = PAGEONE;
+	buttonPressed = 0;
+	
+	button1.rise(buttonISR1);
+	button2.rise(buttonISR2);
+	
+	while(1)
+	{
+		buttonQueue.dispatch_forever();
+	}
+}
+
+void pageSelect(U_BYTE buttonValue)
+{
+	switch (currentPage)
+		{
+			case PAGEONE:
+				buttonActionOne(buttonValue);
+				break;
+			case PAGETWO:
+				buttonActionTwo(buttonValue);
+				break;
+			case PAGETHREE:
+				buttonActionThree(buttonValue);
+				break;
+		}
+}
+
+void buttonActionOne(U_BYTE buttonValue)
+{
+	switch(buttonValue)
+	{
+		case 0x01:
+			page.pageTwo();
+			currentPage = PAGETWO;
+			page.setDateTime(d.getTime());
+			cursorPos=0;
+      break;
+    //case 0x02:
+    //  page.pageOne();
+		//	currentPage = PAGEONE;
+    //  break;   
+    case 0x03:
+      page.pageThree();
+			currentPage = PAGETHREE;
+      break;
+   }
+}
+void buttonActionTwo(U_BYTE buttonValue)
+{
+	switch (buttonValue)
+	{
+		case 0x01:
+			setValue(cursorPos,increment[cursorPos]);
+			break;
+		case 0x02:
+			setValue(cursorPos,0-increment[cursorPos]);
+			break;
+		case 0x03:
+			cursorPos++;
+			break;
+	}
+	page.cursorPos(LINE1+cursorPosition[cursorPos]);
+	if(cursorPos == 12)
+	{
+		page.pageOne();
+		currentPage = PAGEONE;
+	}
+	
+}
+
+void buttonActionThree(U_BYTE buttonValue)
+{
+	switch(buttonValue)
+	{
+		case 0x01:
+			page.pageOne();
+			currentPage = PAGEONE;
+      break;
+	}
+}
+void setValue(BYTE cycle,signed INT_32 value)
+{
+    switch(cycle){
+        case 0:
+        case 1:
+            d.addDay(value);
+            page.setDateTime(d.getTime());
+            
+            break;
+        
+        case 2:
+        case 3:
+            d.addMonth(value);
+            page.setDateTime(d.getTime());
+            break;
+            
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+            d.addYear(value);
+            page.setDateTime(d.getTime());
+            break;
+            
+        case 8:
+        case 9:
+            d.addHour(value);
+            page.setDateTime(d.getTime());
+            break;
+        
+        case 10:
+        case 11:
+            d.addMin(value);
+            page.setDateTime(d.getTime());
+            break;
+        
+        /*case 12:
+        case 13:   
+            d.addSec(value);
+            page.setDateTime(d.getTime());
+            break;*/
+    }
+}
+
+void buttonISR1()
+{
+	buttonPressed |= 1;
+	
+	if(buttonPressed != 3){
+		doublePress.attach(&buttonTO, 0.2);
+	}
+}
+
+void buttonISR2()
+{
+	buttonPressed |= 2;
+	
+	if(buttonPressed != 3){
+		doublePress.attach(&buttonTO, 0.2);
+	}
+}
+
+void buttonTO()
+{
+	if(buttonPressed != 0){
+		buttonQueue.call(&pageSelect,buttonPressed);
+		buttonPressed = 0;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/displayThread.h	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,36 @@
+#ifndef _DISPLAYTHREAD_H
+#define _DISPLAYTHREAD_H
+    #include "Pages.hpp"
+    #include "mbed.h"
+    #include "dateTime.hpp"
+    
+    #define b1 PE_12
+    #define b2 PE_14
+    
+    #define RS  PD_15   //D9
+    #define E   PF_12   //D8
+    #define d4  PF_13   //D7
+    #define d5  PE_9    //D6
+    #define d6  PF_14   //D4
+    #define d7  PF_15   //D2
+    
+    
+    #define PRESSED 1
+
+    extern Thread Display;
+    
+void setValue(BYTE cycle,signed INT_32 value);
+void waitForInput();
+void DisplayThread();
+void pageSelect(U_BYTE buttonValue);
+void buttonActionOne(U_BYTE buttonValue);
+void buttonActionTwo(U_BYTE buttonValue);
+void buttonActionThree(U_BYTE buttonValue);
+
+void buttonISR1();
+void buttonISR2();
+
+void buttonTO();
+		
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,73 @@
+#include "mbed.h"
+#include "SDReader.hpp"
+#include "rtos.h"
+#include "General.hpp"
+#include "NetWorking.hpp"
+#include "Pages.hpp"
+#include "Terminal.hpp"
+#include "displayThread.h"
+#include "sample_buffer.hpp"
+#include "dateTime.hpp"
+
+// Threads
+Thread SDcard_THREAD;
+Thread Terminal_THREAD;
+Thread NetWorking_THREAD;
+Thread Display;
+
+
+int number = 22;
+
+char itemTestA[10];
+char itemTestB[] = "Hello";
+
+// Thread ID for the Main function (CMSIS API)
+osThreadId tidMain;
+
+//int main starts all threads then becomes TerminalThread
+int main(void)
+{   
+    //Main thread ID
+    //tidMain = Thread::gettid();  
+    
+    // Start each thread
+    //SDcard_THREAD.start(SDThread);
+    //Terminal_THREAD.start(TerminalThread);
+    //NetWorking_THREAD.start(NetWorkingThread);
+    //Display.start(DisplayThread);  
+    
+    //NetWorkingThread();
+
+
+    Display.start(DisplayThread);
+	
+		
+	
+	
+	
+//		struct tm test_tm;
+//		test_tm.tm_year = 0;
+//		test_tm.tm_mon = 0;
+//		test_tm.tm_mday = 1;
+//		test_tm.tm_hour = 0;
+//		test_tm.tm_min = 0;
+//		test_tm.tm_sec = 0;
+//	
+//	
+//	
+//	
+//	
+//		time_t test_time;
+//	
+//		test_tm.tm_year = 70;
+//		test_time = mktime(&test_tm);
+//		test_tm = *localtime(&test_time);
+//		
+//		printf("year = %d\n\r",test_tm.tm_year + 1900);
+//		printf("time = %d\n\r",test_time);
+		
+	
+	
+    while(1);    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#e62a1b9236b44e70ae3b0902dc538481c04d455b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sample_buffer.cpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,58 @@
+#include "mbed.h"
+#include "sample_buffer.hpp"
+
+//Thread sychronisation primatives
+Semaphore spaceAvailable(BUFFERSIZE);
+Semaphore samplesInBuffer(0);
+Mutex bufferLock;
+
+//Output buffer
+char buffer[BUFFERSIZE];
+unsigned int newestIndex = BUFFERSIZE-1;    //First time it is incremented, it will be 0
+unsigned int oldestIndex = BUFFERSIZE-1;   
+
+//Producer
+void addCharacterToQueue(const char c)
+{    
+    //Is there space?
+    int32_t Nspaces = spaceAvailable.wait();
+             
+    //Ok, there is space - take the lock
+    bufferLock.lock();
+        
+    //Update buffer
+    newestIndex = (newestIndex+1) % BUFFERSIZE;  
+    buffer[newestIndex] = c;
+    //printf("\tAdded ASCII Character: %2Xh (%c) to buffer, %d spaces available\n", c, c, Nspaces-1);
+    
+    //Release lock
+    bufferLock.unlock();
+    
+    //Signal that a sample has been added
+    samplesInBuffer.release();
+}
+
+//Consumer
+char takeCharacterFromQueue()
+{    
+    //Are thre any samples in the buffer
+    int32_t Nsamples = samplesInBuffer.wait();
+        
+    //Ok, there are samples - take the lock
+    bufferLock.lock();   
+    
+    //Update buffer - remove oldest
+    oldestIndex = (oldestIndex+1) % BUFFERSIZE;
+    char cc = buffer[oldestIndex];
+    //printf("\t\tTaking ASCII Character: %2Xh (%c) from buffer, %d bytes remaining\n", cc, cc, Nsamples-1);
+    
+    //Release lock
+    bufferLock.unlock();
+    
+    //Signal there is space in the buffer
+    spaceAvailable.release();
+    
+    //return a copy of the result
+    return cc;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sample_buffer.hpp	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,8 @@
+#include "mbed.h"
+
+//Size of the morse character buffer
+#define BUFFERSIZE 100
+
+extern void addCharacterToQueue(const char c);
+extern char takeCharacterFromQueue();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sd-driver.lib	Thu Dec 06 15:38:09 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/sd-driver/#ae7e7440054c9447f8255bdccbcc523b3f6dffe4