Skip to content

Instantly share code, notes, and snippets.

@tylerjw
Created August 18, 2017 00:17
Show Gist options
  • Save tylerjw/2267672702ccf432e632822d3eef8258 to your computer and use it in GitHub Desktop.
Save tylerjw/2267672702ccf432e632822d3eef8258 to your computer and use it in GitHub Desktop.
Basic rally computer for use with Adafruit feathers.
#include <TinyGPS++.h>
// Enable one of these two #includes and comment out the other.
// Conditional #include doesn't work due to Arduino IDE shenanigans.
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
//#include <TinyWireM.h> // Enable this line if using Adafruit Trinket, Gemma, etc.
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_7segment red = Adafruit_7segment();
Adafruit_7segment white = Adafruit_7segment();
static const uint32_t GPSBaud = 9600;
static const int lightPin = 5;
static const int lowLight = 300;
static const int highLight = 1000;
static const int lowBrightness = 0;
static const int highBrightness = 15;
static const int blackButtonPin = 12;
static const int clockOdoState = 0;
static const int speedOdoState = 1;
static const int brightnessState = 2;
static const int batteryState = 3;
static const int numStates = 4;
int state = speedOdoState;
boolean odoResetDisplay = false;
static double tripDistance = 0.0; // miles
#define VBATPIN A9
// The TinyGPS++ object
TinyGPSPlus gps;
TinyGPSCustom fixQuality(gps, "GPGSA", 2); // fix
static const int timeout = 5000;
void setup()
{
Serial.begin(9600);
Serial1.begin(GPSBaud);
red.begin(0x70);
white.begin(0x71);
pinMode(blackButtonPin, INPUT_PULLUP); // button
}
void loop()
{
// This sketch displays information every time a new sentence is correctly encoded.
while (Serial1.available() > 0)
gps.encode(Serial1.read());
// read photoresister
int light = constrain(analogRead(lightPin), lowLight, highLight);
int brightness = map(light, lowLight, highLight, lowBrightness, highBrightness);
red.setBrightness(brightness);
white.setBrightness(brightness);
// handle the button
odoButton(blackButtonPin);
// check to see if the gps was disconnected somehow
if (gps.time.age() < timeout)
{
switch(state) {
case clockOdoState:
if(gps.time.isUpdated())
displayClock(white);
break;
case speedOdoState:
if(gps.speed.isUpdated())
displaySpeed(white);
break;
case brightnessState:
displayBrightness(white, brightness);
break;
case batteryState:
displayBatteryVoltage(white);
break;
}
if (gps.location.isUpdated()) {
if(odoResetDisplay == false) {
displayOdo(red);
} else {
red.printError();
}
}
} else {
red.printError();
white.printError();
}
red.writeDisplay();
white.writeDisplay();
}
void displayBrightness(Adafruit_7segment &disp, int brightness)
{
disp.print(brightness);
// display a B or 8 or whatever you want to call it
disp.writeDigitRaw(0, 0b11111111);
}
void displayBatteryVoltage(Adafruit_7segment &disp)
{
float measuredvbat = analogRead(VBATPIN);
measuredvbat *= 2; // we divided by 2, so multiply back
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredvbat /= 1024; // convert to voltage
disp.print(measuredvbat);
}
void displayClock(Adafruit_7segment &disp)
{
// assume clock is updated
int minutesecond = gps.time.minute() * 100 + gps.time.second();
disp.print(minutesecond, DEC);
disp.drawColon(true);
}
void displayOdo(Adafruit_7segment &disp)
{
// assume gps.location is updated
static TinyGPSLocation previousLocation;
if(previousLocation.isValid()) // not the first time
{
double distance = gps.distanceBetween(gps.location.lat(), gps.location.lng(),
previousLocation.lat(), previousLocation.lng()) * _GPS_MILES_PER_METER;
if(gps.speed.isValid() && gps.speed.mph() > 1.0)
{
// increment the trip distance
tripDistance += distance;
}
// display the distance
disp.print(tripDistance);
}
previousLocation = gps.location;
}
void displaySpeed(Adafruit_7segment &disp)
{
// assume gps.speed.updated()
static int speed = 0;
if(gps.speed.isValid() && gps.speed.mph() != speed)
{
speed = gps.speed.mph();
}
disp.print(speed);
// display fix quality
static char mask = 0b01000000;
if( fixQuality.isUpdated() )
{
int fix = atoi(fixQuality.value());
if( fix == 2 ) {
mask = 0b01001001;
} else if ( fix == 3 ) {
mask = 0b01001001;
} else {
mask = 0b01000000;
}
}
disp.writeDigitRaw(0, mask);
}
void odoButton(int pin)
{
static long button_timer = 0;
static const long longpress_time = 500;
static const long shortpress_time = 50;
static boolean button_active = false;
static boolean longpress_active = false;
if(digitalRead(pin) == LOW) {
// button pressed
if (button_active == false) {
button_active = true;
button_timer = millis();
}
if ((millis() - button_timer > longpress_time) && (longpress_active == false)) {
longpress_active = true;
odoResetDisplay = true;
// reset trip distance
tripDistance = 0.0;
}
} else {
// button not pressed
if(button_active == true) {
if(longpress_active == true) {
odoResetDisplay = false;
longpress_active = false;
} else if(millis() - button_timer > shortpress_time) {
// switch state
state = (state + 1) % numStates;
}
button_active = false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment