///////////// Header Files ////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <sysctl.h>
#include <eeprom.h>
#include <SPI.h>
#include "epd1in54.h"
#include "epdif.h"
#include "epdpaint.h"
#include "imagedata.h"
int COLORED = 0; // White in Black on epaper
int UNCOLORED = 1; // Black in White on epaper
unsigned char image[8120]; // buffer for epaper
// variable array to write and read eeprom
uint32_t romdata_written[2] ;
uint32_t romdata_read[2] ;
// ISR variable for frequency of flow sensor pulses
volatile unsigned long frequency = 0;
volatile unsigned long last_micro = 0;
// variable for number of breaths during exercise
uint32_t breath_counter = 0;
uint32_t net_breaths = 0;
/////////// Enum for epaper//////////////
////// width must be multiple of 8///////
Paint paint(image, 0, 0); // epaper enum
Epd epd; // epaper enum
char VAL[9]; // buffer for int to char conversion
/////////////////////////////////////////////////
////////////// I/O pin mapping //////////////////
//// I/O pins used interfacing paper display ////
// see inside epdif.c , epdif.h files and also //
// check for tiva tm4c123 energia SPI0 pinmap //
// #define RST_PIN 9 // PA6 (GPIO)
// #define DC_PIN 10 // PA7 (GPIO)
// #define BUSY_PIN 19 // PB2 (GPIO)
// #define MSI_SPI0 8 // PA5 (SPI0)
// #define MIS_SPI0 13 // PA4 (SPI0)
// #define CSL_SPI0 12 // PA3 (SPI0)
// #define CLK_SPI0 11 // PA2 (SPI0)
// note : MISO (PA4) has no actual physical wiring
// between tm4c123 and epaper, just SPI MISO pin
///////////////////////////////////////////////////
///////////////////////////////////////////////////
//// Input for sensing AIR flow ////
#define FLOW_METER 31 // PF4
//Tiva on board RGB LED for breath sequence//
#define LED_BLU 40 // PF2
#define LED_RED 30 // PF1
#define LED_GRN 39 // PF3
#define BUZZER 32 // PD7
///////////////////////////////////////////////
//ISR to measure pulses from air flow sensor //
///////////////////////////////////////////////
void PortFIntHandler()
{
// clear interrupt
uint32_t flag = 0;
flag = GPIOIntStatus(GPIO_PORTE_BASE, true);
GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
// measuring frequency // f=1000000/t (t in uSeconds)
frequency = 1000000.0 / (micros() - last_micro);
last_micro = micros();
// time_passed = last_micro- first_micro ;
}
////////////////////////////////////////////////
////////////////////////////////////////////////
void setup()
{
// initialize I/O pins //
pinMode(LED_RED, OUTPUT);
pinMode(LED_BLU, OUTPUT);
pinMode(LED_GRN, OUTPUT);
pinMode(BUZZER, OUTPUT);
// wrire I/O pins init states //
digitalWrite(LED_RED, LOW);
digitalWrite(LED_BLU, LOW);
digitalWrite(LED_GRN, LOW);
digitalWrite(BUZZER, LOW);
// set PF4 as input pullup //
pinMode(FLOW_METER, INPUT_PULLUP); // <---- PORT F pin 4, PF4
// configure for falling edge interrupt
GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE);
// associate with ISR function
GPIOIntRegister(GPIO_PORTF_BASE, PortFIntHandler);
// enable interrupt to sense AIR flow pulses
//GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
// Initialize EEPROM for storing breathing data
SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);
while (!SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0))
{}
EEPROMInit();
EEPROMRead(romdata_read, 0x80, sizeof(romdata_read));
net_breaths = romdata_read[0];
// clear and init e paper //
flush_epd();
init_epd();
// flush_epd();
// init_epd();
// show device intro logo //
// epd.SetFrameMemory(Meno_Logo);
epd.DisplayFrame();
delay(1200);
flush_epd();
init_epd();
// enable interrupt to sense AIR flow pulses //
GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
}
////////////////////////////////////////////////
////////////////////////////////////////////////
void loop()
{
// all *_epd() and paint.*() -> epaper functions
// show user instruction on display and LED //
erase_epd();
while (frequency == 0)
{
digitalWrite(LED_BLU, HIGH);
delay(100);
paint.DrawStringAt(8, 26, "TAKE A LONG" , &Font24, COLORED);
paint.DrawStringAt(8, 60, "DEEP BREATH" , &Font24, COLORED);
paint.DrawStringAt(5, 133, "Breath Counter:", &Font16, COLORED);
paint.DrawStringAt(5, 155, "Past Sessions", &Font16, COLORED);
paint.DrawStringAt(5, 170, "Breath Counts:", &Font16, COLORED);
paint.DrawStringAt(170, 133, itoa(breath_counter, VAL, 10), &Font16, COLORED);
paint.DrawStringAt(160, 170, itoa(net_breaths, VAL, 10), &Font16, COLORED);
epd.SetFrameMemory(paint.GetImage(), 0, 0, paint.GetWidth(), paint.GetHeight());
epd.DisplayFrame();
digitalWrite(LED_BLU, LOW);
delay(200);
}
// wait while breath in
while (micros() < last_micro + 200000)
{
digitalWrite(LED_BLU, HIGH);
}
// hold breath
digitalWrite(LED_BLU, LOW);
digitalWrite(LED_RED, HIGH);
erase_epd();
paint.DrawStringAt(8, 26, " HOLD YOUR " , &Font24, COLORED);
paint.DrawStringAt(8, 60, " BREATH ! " , &Font24, COLORED);
paint.DrawStringAt(5, 133, "Breath Counter:", &Font16, COLORED);
paint.DrawStringAt(5, 155, "Past Sessions", &Font16, COLORED);
paint.DrawStringAt(5, 170, "Breath Counts:", &Font16, COLORED);
paint.DrawStringAt(170, 133, itoa(breath_counter, VAL, 10), &Font16, COLORED);
paint.DrawStringAt(160, 170, itoa(net_breaths, VAL, 10), &Font16, COLORED);
epd.SetFrameMemory(paint.GetImage(), 0, 0, paint.GetWidth(), paint.GetHeight());
epd.DisplayFrame();
delay(4000);
digitalWrite(LED_RED, LOW);
frequency = 0;
erase_epd();
while (frequency == 0)
{
digitalWrite(LED_GRN, HIGH);
delay(100);
paint.DrawStringAt(8, 26, "BREATH OUT" , &Font24, COLORED);
paint.DrawStringAt(8, 60, "SLOWLY ..." , &Font24, COLORED);
paint.DrawStringAt(5, 133, "Breath Counter:", &Font16, COLORED);
paint.DrawStringAt(5, 155, "Past Sessions", &Font16, COLORED);
paint.DrawStringAt(5, 170, "Breath Counts:", &Font16, COLORED);
paint.DrawStringAt(170, 133, itoa(breath_counter, VAL, 10), &Font16, COLORED);
paint.DrawStringAt(160, 170, itoa(net_breaths, VAL, 10), &Font16, COLORED);
epd.SetFrameMemory(paint.GetImage(), 0, 0, paint.GetWidth(), paint.GetHeight());
epd.DisplayFrame();
digitalWrite(LED_GRN, LOW);
delay(200);
}
// wait while breath out
while (micros() < last_micro + 200000)
{
digitalWrite(LED_GRN, HIGH);
}
digitalWrite(LED_GRN, LOW);
frequency = 0;
breath_counter += 1;
digitalWrite(BUZZER, HIGH);
delay(150);
digitalWrite(BUZZER, LOW);
//******************************************//
// update eeprom with breath count info //
// *****************************************//
EEPROMRead(romdata_read, 0x80, sizeof(romdata_read));
// update data before writing to eeprom, (first 32 byte area)
romdata_written[0] = romdata_read[0] + 1;
// write/save data to eeprom to 0x80 address with max size 64 bytes (32+32)
EEPROMProgram(romdata_written, 0x80, sizeof(romdata_written));
// Read eeprom 0x80 location data for new value
EEPROMRead(romdata_read, 0x80, sizeof(romdata_read));
net_breaths = romdata_read[0];
if (breath_counter >= 5)
{
erase_epd();
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GRN, HIGH);
digitalWrite(LED_BLU, HIGH);
while (1)
{
paint.DrawStringAt(8, 15, "YOU JUST HAVE" , &Font20, COLORED);
paint.DrawStringAt(8, 35, " SUCCESSFULLY" , &Font20, COLORED);
paint.DrawStringAt(2, 55, " COMPLETED ", &Font20, COLORED);
paint.DrawStringAt(2, 78, " YOUR BREATHING ", &Font16, COLORED);
paint.DrawStringAt(2, 93, " EXERCISE SESSION ", &Font16, COLORED);
paint.DrawStringAt(5, 133, "Breath Counter:", &Font16, COLORED);
paint.DrawStringAt(5, 155, "Past Sessions", &Font16, COLORED);
paint.DrawStringAt(5, 170, "Breath Counts:", &Font16, COLORED);
paint.DrawStringAt(170, 133, itoa(breath_counter, VAL, 10), &Font16, COLORED);
paint.DrawStringAt(160, 170, itoa(net_breaths, VAL, 10), &Font16, COLORED);
epd.SetFrameMemory(paint.GetImage(), 0, 0, paint.GetWidth(), paint.GetHeight());
epd.DisplayFrame();
}
}
}
///////////////////////////////////////////////
////////////////main loop ends here ///////////
///////////////////////////////////////////////
///////////////////////////////////////////////
///////////// Function body ///////////////////
///////////////////////////////////////////////
// clean up dark spots on epaper display //
void flush_epd (void)
{
if (epd.Init(lut_full_update) != 0)
{
return;
}
epd.ClearFrameMemory(0xFF);
epd.DisplayFrame();
//epd.ClearFrameMemory(0xFF);
//epd.DisplayFrame();
}
// initialize full e paper display //
void init_epd(void)
{
///// Init Full Display Update ///////////
if (epd.Init(lut_full_update) != 0)
{
return;
}
///// Init Partial Display Update ////////
if (epd.Init(lut_partial_update) != 0)
{
return;
}
////////// Clears Up Full Disp ///////////
// bit set = white, bit reset = black
epd.ClearFrameMemory(0xFF);
epd.DisplayFrame();
// epd.ClearFrameMemory(0xFF);
// epd.DisplayFrame();
}
// clean up lines on epaper //
void erase_epd(void)
{
paint.SetWidth(200);
paint.SetHeight(200);
paint.SetRotate(ROTATE_180);
paint.Clear(UNCOLORED);
}
Comments