Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp
- Committer:
- legstar85
- Date:
- 2022-01-14
- Revision:
- 7:d77e95505e43
- Parent:
- 6:ebf4784ce92b
- Child:
- 8:07323fcab6d1
File content as of revision 7:d77e95505e43:
/*
* @ File main.cpp
* @ Author - David Leaming - 25574043
* @ Date - December 2021
*
* Acknowledgements
* Craig A. Evans, University of Leeds, TMP102 Library ,Feb 2016
* Dr Edmond Nurellari, University of Lincoln, Joystick & N5110 Libraries
*
*/
#include "mbed.h" // include the library header, ensure the library has been imported into the project
#include "TMP102.h"
#include "N5110.h"
#include "Joystick.h"
#include "Bitmap.h"
TMP102 tmp102(I2C_SDA,I2C_SCL); // Create TMP102 object
// VCC,SCE,RST,D/C,MOSI,SCLK,LED
N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11); // Create Screen Object - K64F - pwr from 3V3, GND Pin also needs connecting
// y x button
Joystick joystick(PTB10,PTB11,PTC16); // Define Joystick Object
Serial pc(USBTX,USBRX); // UART connection for PC
Ticker ticker_menu; // Create Menu ticker object
DigitalOut r_led(LED_RED); // K64F on-board LEDs
DigitalOut g_led(LED_GREEN); // K64F on-board LEDs
DigitalOut b_led(LED_BLUE); // K64F on-board LEDs
DigitalOut LED01 (PTA1); // PCB Surface Mounted LED's - LED1
DigitalOut LED02 (PTA2); // PCB Surface Mounted LED's - LED2
DigitalOut LED03 (PTC2); // PCB Surface Mounted LED's - LED3
DigitalOut LED04 (PTC3); // PCB Surface Mounted LED's - LED4
DigitalOut LED05 (PTC4); // PCB Surface Mounted LED's - LED5
DigitalOut LED06 (PTD3); // PCB Surface Mounted LED's - LED6
InterruptIn sw2(SW2); // K64F on-board switches
InterruptIn sw3(SW3); // K64F on-board switches
InterruptIn ButtonA (PTB9); // PCB Button - A
InterruptIn ButtonB (PTD0); // PCB Button - B
InterruptIn ButtonBack (PTB10); // PCB Button - Back
volatile int g_ButtonA_flag = 0; // flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
volatile int g_ButtonB_flag = 0; // flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
volatile int g_ButtonBack_flag = 0; // flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
volatile int g_sw2_flag = 0; // flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
volatile int g_menu_timer_flag = 0; // flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
volatile int option = 0; // Menu option selection based on joystick direction
void error(); // error function hangs flashing an LED
void init_serial(); // setup serial port
void init_K64F(); // set-up the on-board LEDs and switches
void init_PCB(); // set-up the PCB LEDs and buttons
void ButtonA_isr(); //
void ButtonB_isr(); //
void ButtonBack_isr(); //
void sw2_isr(); //
void menu_timer_isr(); //
void OnStartup(); //
void Run(); //
void ConstantMonitoring(); //
int main()
{
init_K64F(); // initialise the board
init_serial(); // initialise the serial port
init_PCB(); // initialise the PCB
tmp102.init(); // call the sensor init method using dot syntax
lcd.init(); // initialise display
joystick.init(); // initialise joystick
ticker_menu.attach(&menu_timer_isr,0.2); // Attach ticker for the Joystick
sw2.fall(&sw2_isr); // SW2 has a pull-up resistor, so the pin will be at 3.3 V by default and fall to 0 V when pressed. We therefore need to look for a falling edge on the pin to fire the interrupt
ButtonA.rise(&ButtonA_isr); // External push button, pin set to 0V by pull down command, means a rising edge is looked for
ButtonB.rise(&ButtonB_isr); // External push button, pin set to 0V by pull down command, means a rising edge is looked for
lcd.setContrast(0.5); // change set contrast in range 0.0 to 1.0
OnStartup(); //
Run(); //
}
void init_serial() {
pc.baud(115200); // set to highest baud - ensure terminal software matches
}
void init_K64F()
{
r_led = 1; // on-board LEDs are active-low, so set pin high to turn them off.
g_led = 1; // on-board LEDs are active-low, so set pin high to turn them off.
b_led = 1; // on-board LEDs are active-low, so set pin high to turn them off.
sw2.mode(PullNone); // since the on-board switches have external pull-ups, we should disable the internal pull-down
sw3.mode(PullNone); // resistors that are enabled by default using InterruptIn
}
void init_PCB ()
{
LED01 = 1; // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
LED02 = 1;
LED03 = 1;
LED04 = 1;
LED05 = 1;
LED06 = 1;
ButtonA.mode(PullDown); // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
ButtonB.mode(PullDown); // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
}
void ButtonA_isr() // ButtonA event-triggered interrupt
{
g_ButtonA_flag = 1; // set flag in ISR
}
void ButtonB_isr() // ButtonB event-triggered interrupt
{
g_ButtonB_flag = 1; // set flag in ISR
}
void ButtonBack_isr() // ButtonB event-triggered interrupt
{
g_ButtonBack_flag = 1; // set flag in ISR
}
void sw2_isr() // SW2 event-triggered interrupt
{
g_sw2_flag = 1; // set flag in ISR
}
void menu_timer_isr()
{
g_menu_timer_flag = 1; // set flag in ISR
}
void OnStartup() //Run some start up display
{
lcd.clear(); // clear buffer at start of every loop
lcd.printString("--------------",0,0); // can directly print strings at specified co-ordinates (must be less than 84 pixels to fit on display)
lcd.printString(" Smart Cold",0,1); // Just a welcome message before auto moving to main menu
lcd.printString(" Storage",0,2); //
lcd.printString(" Monitoring",0,3); //
lcd.printString("V07 - Jan 2022",0,4); //
lcd.printString("--------------",0,5); //
lcd.refresh(); // need to refresh display after setting pixels or writing strings
wait(5.0); // leave welcome screen on for designated amount of time
lcd.clear(); // clear buffer at start of every loop
lcd.refresh(); // need to refresh display after setting pixels or writing strings
lcd.printString(" Use Joystick",0,0); // Instruction for use of menu
lcd.printString(" To Navigate",0,1); //
lcd.printString("",0,2); // Blank Line
lcd.printString(" A = Select",0,3); //
lcd.refresh(); // need to refresh display after setting pixels or writing strings
wait(5.0); //
}
enum EMenuState //An enum controlling the current state of the display.
{
MENUSTATE_Main,
MENUSTATE_Monitor,
MENUSTATE_OneOff,
MENUSTATE_About,
MENUSTATE_Author,
MENUSTATTE_Num, // This is a special enum value that just gives is a way to get the number of elements in the enum.
};
void Run()
{
int MenuState;
int SelectedItem = 0;
int NumMenuItems = 1;
char buffer[14]; // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
while(1){
if (g_menu_timer_flag){
g_menu_timer_flag = 0;
bool bAButtonWasPressed = g_ButtonA_flag; // Get the value of the input flags and reset them
bool bBButtonWasPressed = g_ButtonB_flag;
g_ButtonA_flag = 0;
g_ButtonB_flag = 0;
lcd.clear(); // clear buffer at start of every loop
int NewMenuState = MENUSTATTE_Num; // The new menu we want to transition to, if any.
switch(MenuState) // Update and Draw whichever menu we're on.
{
case MENUSTATE_Main:
{
NumMenuItems = 4; // Dont for get to set this when changing number of items in the menu. We need this to wrap the selection around properly etc.
if(SelectedItem >= NumMenuItems)
{
SelectedItem = 0; // Something has gone wrong, reset selected item.
}
lcd.printString("---- MENU ----",0,0);
lcd.printString("M1 - Monitor",0,1);
lcd.printString("M2 - One-off",0,2);
lcd.printString("About",0,3);
lcd.printString("Author",0,4);
if(bAButtonWasPressed) // If A was pressed then we transition to the selected screen.
{
if(SelectedItem == 0)
{
NewMenuState = MENUSTATE_Monitor;
}
else if(SelectedItem == 1)
{
NewMenuState = MENUSTATE_OneOff;
}
else if(SelectedItem == 2)
{
NewMenuState = MENUSTATE_About;
}
else if(SelectedItem == 3)
{
NewMenuState = MENUSTATE_Author;
}
}
}
break;
case MENUSTATE_Monitor:
{
NumMenuItems = 1; // Dont for get to set this when changing number of items in the menu. We need this to wrap the selection around properly etc.
if(SelectedItem >= NumMenuItems)
{
NewMenuState = MENUSTATE_Main; // Something has gone wrong, drop back to the main menu.
}
float T = tmp102.get_temperature(); // read temperature and print to lcd
int length = sprintf(buffer," T = %.2f C",T); // print formatted data to buffer - it is important the format specifier ensures the length will fit in the buffer
if (length <= 14) // if string will fit on display (assuming printing at x=0)
lcd.printString("-- Constant --",0,0);
lcd.printString("- Monitoring -",0,1);
lcd.printString(buffer,0,3); // display on screen
lcd.printString(" 'A' to Menu",0,5);
lcd.refresh(); // need to refresh display after setting pixels or writing strings
wait(0.5);
if(bAButtonWasPressed)
{
if(SelectedItem == 0)
{
NewMenuState = MENUSTATE_Main;
}
}
}
break;
case MENUSTATE_OneOff:
{
NumMenuItems = 1; // Dont for get to set this when changing number of items in the menu. We need this to wrap the selection around properly etc.
if(SelectedItem >= NumMenuItems)
{
NewMenuState = MENUSTATE_Main; // Something has gone wrong, drop back to the main menu.
}
lcd.printString("-- One-off --",0,0);
lcd.printString("Back",0,1);
//TODO: Whatever the One-off screen should display...
if(bAButtonWasPressed)
{
if(SelectedItem == 0)
{
NewMenuState = MENUSTATE_Main;
}
}
}
break;
case MENUSTATE_About:
{
NumMenuItems = 1; // Dont for get to set this when changing number of items in the menu. We need this to wrap the selection around properly etc.
if(SelectedItem >= NumMenuItems)
{
NewMenuState = MENUSTATE_Main; // Something has gone wrong, drop back to the main menu.
}
lcd.printString("--- About ---",0,0);
lcd.printString("ELE3006M - IoT",0,1);
lcd.printString(" Project",0,2);
lcd.printString("Uni of Lincoln",0,3);
lcd.printString(" 'A' to Menu",0,5);
//TODO: Whatever the about screen should display...
if(bAButtonWasPressed)
{
if(SelectedItem == 0)
{
NewMenuState = MENUSTATE_Main;
}
}
}
break;
case MENUSTATE_Author:
{
NumMenuItems = 1; // Dont for get to set this when changing number of items in the menu. We need this to wrap the selection around properly etc.
if(SelectedItem >= NumMenuItems)
{
NewMenuState = MENUSTATE_Main; // Something has gone wrong, drop back to the main menu.
}
lcd.printString("--- Author ---",0,0);
lcd.printString(" ",0,1);
lcd.printString(" ",0,2);
lcd.printString("",0,3);
lcd.printString(" 'A' to Menu",0,5);
//TODO: Whatever the about screen should display...
if(bAButtonWasPressed)
{
if(SelectedItem == 0)
{
NewMenuState = MENUSTATE_Main;
}
}
}
break;
default:
{
NewMenuState = MENUSTATE_Main; // Something has gone wrong, drop back to the main menu.
}
};
if(NewMenuState != MENUSTATTE_Num) // If we have requested a new menu state.
{
printf("Transitioning to MenuState: %i\n", NewMenuState); //
MenuState = NewMenuState; // We want to transition the menu to a new state.
// Do any bookkeeping needed when moving to new state.
SelectedItem = 0; // Reset the selected item.
lcd.clear(); // Clear the display for one frame on state transition.
} // Could do something else like invert colour etc here.
else
{
// If we have not selected to move to a new menu.
unsigned int SelectionMarkerRadius = 4 ; // Draw a marker circle at end of line to show which is the currently selected item.
unsigned int SelectionMarkerX = WIDTH - (2 * SelectionMarkerRadius);
unsigned int SelectionMarkerY = (HEIGHT / 5) * (SelectedItem + 1); //+1 because of the menu title.
lcd.drawCircle(SelectionMarkerX, SelectionMarkerY, SelectionMarkerRadius, FILL_BLACK);
// Handle Joystick Input
switch (joystick.get_direction()) { // Call to check direction joystick is pointing
printf("Direction = %i\n"); //
case N: //
SelectedItem--; //
break; //
case S: //
SelectedItem++; //
break; //
}
if(SelectedItem < 0) //Wrap the selection around to the start/end of the menu if it goes below 0 or above NumMenuItems.
{
SelectedItem = NumMenuItems - 1;
}
else if(SelectedItem >= NumMenuItems)
{
SelectedItem = 0;
}
}
lcd.refresh(); //Finally update the display.
}
}
}
void ConstantMonitoring()
{
char buffer[14]; // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
while (1) {
lcd.normalMode(); // normal colour mode
lcd.setBrightness(0.5); // put LED backlight on 50%
lcd.clear(); // clear buffer at start of every loop
lcd.refresh(); // need to refresh display after setting pixels or writing strings
float T = tmp102.get_temperature(); // read temperature and print to lcd
int length = sprintf(buffer," T = %.2f C",T); // print formatted data to buffer - it is important the format specifier ensures the length will fit in the buffer
if (length <= 14) // if string will fit on display (assuming printing at x=0)
lcd.printString("-- Constant --",0,0);
lcd.printString("- Monitoring -",0,1);
lcd.printString(buffer,0,3); // display on screen
lcd.printString(" 'B' to Menu",0,5);
lcd.refresh(); // need to refresh display after setting pixels or writing strings
wait(5.0);
if (g_ButtonA_flag) { // check if flag i.e. interrupt has occured
g_ButtonA_flag = 0; // if it has, clear the flag
printf("Button A Press \n"); // send message over serial port - can observe in CoolTerm etc.
LED01=0;
wait(5.0);
LED01=1;
}
if (g_ButtonB_flag) { // check if flag i.e. interrupt has occured
g_ButtonB_flag = 0; // if it has, clear the flag
printf("Button B Press \n"); // send message over serial port - can observe in CoolTerm etc.
Run();
}
if (g_ButtonBack_flag) { // check if flag i.e. interrupt has occured
g_ButtonBack_flag = 0; // if it has, clear the flag
printf("Button Back Press \n"); // send message over serial port - can observe in CoolTerm etc.
LED02=0;
wait(5.0);
LED02=1;
}
}
}