#define sclk 13 // Don't change
#define mosi 11 // Don't change
#define cs 10
#define dc 9
#define YP A2
#define XM A3
#define XP 9
#define YM 8
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
#define MINPRESSURE 10
#define MAXPRESSURE 1000
unsigned long TotalWheelCount;
unsigned long TotalPedalCount;
unsigned long NewTime;
unsigned long Time;
unsigned long previoustime = 0;
byte sec;
byte minute;
byte hour;
volatile byte WheelRpmCount;
unsigned int WheelRpm;
volatile byte PedalRpmCount;
unsigned int PedalRpm;
int WheelDiameter = 15;
int RiderWeight;
int Calories;
int TotalCalories;
float Speed;
float Distance;
float Pace;
#include <Adafruit_GFX_AS.h> // Core graphics library
#include <Adafruit_ILI9341_AS.h> // Hardware-specific library
#include <SPI.h>
#include "TouchScreen.h"
Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(cs, dc); // Invoke custom library
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
void setup(void){
tft.init();
tft.setRotation(1);
/* **** uncomment this block and the two blocks of code below to test touch calibration in Serial Monitor
Serial.begin(9600);
Serial.println(F("Touch to mark point"));
*/
Serial.begin(9600);
Serial.println(testLines(ILI9341_CYAN)); // print opening graphic
delay(500);
Serial.println(Startup()); // print title screen
delay(1500);
attachInterrupt(0, WheelRpm_fun, RISING); // interrupt for wheel sensor
WheelRpmCount = 0;
WheelRpm = 0;
attachInterrupt(1, PedalRpm_fun, RISING); // interrupt for pedal sensor
PedalRpmCount = 0;
PedalRpm = 0;
Time = 0;
tft.fillScreen(ILI9341_BLACK);
}
void loop (){
tft.setTextColor(ILI9341_CYAN);
Serial.println(calcTime());
Serial.println(calcSpeed());
Serial.println(calcDistance());
Serial.println(calcCadence());
Serial.println(calcCalories());
Serial.println(calcPace());
TSPoint p = ts.getPoint(); //acquire touch data
/* Testing purpose only prints touch data to serial monitor
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
*/
if (p.z < MINPRESSURE || p.z > MAXPRESSURE) { // sets a touch pressure range
return;
}
p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width()); // maps the x touch location
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height()); // maps the y touch location
/* Testing purpose only prints touch data to serial monitor
Serial.print("("); Serial.print(p.x);
Serial.print(", "); Serial.print(p.y);
Serial.println(")");
*/
if ((p.x > 180) && (p.x < 250) && (p.y > 100) && (p.y < 200)) {
// sends user to setup screen
// PROBLEM once touched the touch functionality goes away so how do i receive data and return to loop
Serial.println (SetupScreen());
}
}
unsigned long Startup() {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Team D:",0,10,2);
tft.drawString("CYCLING TRACKER",50,110,4);
delay(2000);
}
unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(ILI9341_BLACK);
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing
}
unsigned long SetupScreen (){
}
unsigned long calcTime () { //prints time since program started
// PROBLEM seems to work but actual time is off
if (millis () >= (previoustime) ) {
previoustime = previoustime + 1000;
sec = sec +1;
if (sec == 60){
sec = 0;
minute = minute +1;
}
if (minute == 60){
minute = 0;
hour = hour +1;
}
if (hour == 13){
hour = 1;
}
}
tft.fillRect(200,10,120,25,ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Ride Time:",0,10,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawNumber(hour, 200,10,4);
tft.drawString(":", 230,10,4);
tft.drawNumber(minute, 240,10,4);
tft.drawString(":", 270,10,4);
tft.drawNumber(sec, 280,10,4);
// wait a second so as not to send massive amounts of data
delay (560);
}
unsigned long calcSpeed (){
// calculate speed using single hall effect sensor attachted to pin 2 using interrupt 0
// PROBLEM speed never seems to update correctly and i may be getting 0 for wheel RPM even though its counting
delay(1000);
detachInterrupt(0);
WheelRpm = (60*1000/65768)* WheelRpmCount;
TotalWheelCount = TotalWheelCount + WheelRpmCount;
WheelRpmCount = 0;
Speed = ((WheelDiameter * 3.14159 * WheelRpm) / 63360);
Speed = Speed * 60.00;
tft.fillRect(200,40,120,25,ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Speed:",0,40,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawNumber(Speed, 200,40,4);
tft.drawString("MPH", 260,40,4);
attachInterrupt(0, WheelRpm_fun, RISING);
}
unsigned long calcCadence () {
// calculate Cadance or pedal RPM using single hall effect sensor and interrupt 1
// PROBLEM cadence RPM does not update
delay(1000);
detachInterrupt(1);
PedalRpm = (60*1000/65768)* PedalRpmCount;
tft.fillRect(200,70,120,25,ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Cadence:",0,70,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawNumber(Speed, 200,70,4);
tft.drawString("RPM", 260,70,4);
attachInterrupt(1, PedalRpm_fun, RISING);
}
unsigned long calcDistance () {
// calculate total distance traveled using the hall effect on the tire to count revolutions
// PROBLEM distance does not update and does not display decimals .00
Distance = TotalWheelCount * (WheelDiameter * PI / 12);
Distance = Distance / 5280.00;
tft.fillRect(200,100,120,25,ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Distance:",0,100,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawNumber(Distance, 200,100,4);
tft.drawString("Mi", 280,100,4);
}
unsigned long calcCalories() {
// calculate calories burned based on speed and rider weight multiplied by time
// not tested need other code to function first
Time = millis()-Time;
if (Speed < 5.5 && Speed > 1){
Calories = 3.5 * RiderWeight * Time;
}
else if (Speed >5.5 && Speed < 9.4){
Calories = 5.8 * RiderWeight * Time;
}
else if (Speed > 9.4 && Speed < 11.9){
Calories = 6.8 * RiderWeight * Time;
}
else if (Speed > 11.9 && Speed < 13.9){
Calories = 8.0 * RiderWeight * Time;
}
else if (Speed >13.9 && Speed < 15.9){
Calories = 10.0 * RiderWeight * Time;
}
else if (Speed >15.9 && Speed < 20){
Calories = 12.0 * RiderWeight * Time;
}
else if (Speed >20){
Calories = 15.8 * RiderWeight * Time;
}
else {
Calories = 0;
}
Time = millis();
TotalCalories = TotalCalories + Calories;
tft.fillRect(200,130,120,25,ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Calories:",0,130,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawNumber(TotalCalories, 200,130,4);
tft.drawString("Cal", 260,130,4);
}
unsigned long calcPace () {
// calculates minutes per mile or the pace of the cyclist
// not tested need other code to function first
Pace = 3600/Speed;
Pace = Pace / 60;
tft.fillRect(200,160,120,25,ILI9341_BLACK);
tft.setTextColor(ILI9341_CYAN);
tft.drawString("Pace:",0,160,4);
tft.setTextColor(ILI9341_GREEN);
tft.drawNumber(Speed, 200,160,4);
tft.drawString("m/Mi", 260,160,4);
}
void WheelRpm_fun ()
{ // function to count the hall effect
WheelRpmCount++;
}
void PedalRpm_fun()
{ // function to count the hall effect
PedalRpmCount++;
}