Skip to content

Instantly share code, notes, and snippets.

Created September 25, 2013 16:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/6702370 to your computer and use it in GitHub Desktop.
Save anonymous/6702370 to your computer and use it in GitHub Desktop.
//GPS--------------------------------------
//-----------------------------------------
//Data Sheeet
// http://www.adafruit.com/datasheets/PMTK_A08.pdf
//libraries
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
//declarations
SoftwareSerial mySerial(7, 6); //pins to use for GPS
Adafruit_GPS GPS(&mySerial); //?
//constants
#define GPSECHO true
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2C" //String required for 10Hz //This is the one I am using at the moment
#define PMTK_SET_NMEA_UPDATE_5HZ "$PMTK220,200*2C" //String required for 5Hz //
boolean usingInterrupt = false;
void useInterrupt(boolean);
float velocity;
//-----------------------------------------
//Encoder----------------------------------
//-----------------------------------------
//libraries
//declarations
//constants
enum PinAssignments {
encoderPinA = 2,
encoderPinB = 3,
};
volatile unsigned int encoderPos = 60; // a counter for the dial
unsigned int lastReportedPos = 1; // change management
static boolean rotating=false; // debounce management
// interrupt service routine vars
boolean A_set = false;
boolean B_set = false;
//-----------------------------------------
//LED Display------------------------------
//-----------------------------------------
//libraries
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
//declarations
Adafruit_7segment matrix = Adafruit_7segment();
//constants
//-----------------------------------------
//Servo------------------------------------
//-----------------------------------------
//libraries
#include <Servo.h>
//declarations
Servo servo;
//constants
int servo_angle_max = 38;
int servo_angle_min = 93;
int servo_angle = 64;
//-----------------------------------------
void setup(){
//GPS--------------------------------------
//-----------------------------------------
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ); // 1 Hz update rate
//? comment out------??????
// Request updates on antenna status, comment out to keep quiet
GPS.sendCommand(PGCMD_ANTENNA);
//---------???
useInterrupt(true);
delay(1000);
//-----------------------------------------
//Encoder----------------------------------
//-----------------------------------------
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
// turn on pullup resistors
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
//-----------------------------------------
//LED Display------------------------------
//-----------------------------------------
matrix.begin(0x70);
//-----------------------------------------
//Servo------------------------------------
//-----------------------------------------
servo.attach(10);
//servo.write(servo_angle);
//-----------------------------------------
Serial.begin(9600);
}
//Stuff for GPS------------------------------
//-------------------------------------------
// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
char c = GPS.read();
// if you want to debug, this is a good time to do it!
#ifdef UDR0
if (GPSECHO)
if (c) UDR0 = c;
// writing direct to UDR0 is much much faster than Serial.print
// but only one character can be written at a time.
#endif
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
usingInterrupt = true;
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
usingInterrupt = false;
}
}
//-------------------------------------------
void loop(){
//Encoder----------------------------------
//-----------------------------------------
rotating = true; // reset the debouncer
//will if want to display on LED display
if (lastReportedPos != encoderPos) {
// //Comment out depending on if need to see GPS speed or desired speed
//
//// matrix.writeDigitNum(1, (encoderPos/100), false);
//// matrix.writeDigitNum(3, (encoderPos/10) % 10, true);
//// matrix.writeDigitNum(4, encoderPos % 10, false);
//// matrix.writeDisplay();
//
// //-------------------------------------------------------------------
lastReportedPos = encoderPos;
}
//-----------------------------------------
//GPS--------------------------------------
//-----------------------------------------
// in case you are not using the interrupt above, you'll
// need to 'hand query' the GPS, not suggested :(
if (! usingInterrupt) {
// read data from the GPS in the 'main loop'
char c = GPS.read();
// if you want to debug, this is a good time to do it!
if (GPSECHO)
if (c) Serial.print(c);
}
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trytng to print out data
//Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
}
if (GPS.fix){
velocity = GPS.speed*1.15077945; //[mph] convert from knot to mph
matrix.print(velocity);
matrix.writeDisplay();
s
if ((int)(velocity*10)<(encoderPos-60)){
servo.write(servo_angle_min);
}
else if((int)(velocity*10)>(encoderPos+60)){
servo.write(servo_angle_max);
}
else{
servo_angle = map( (int)(velocity*10), encoderPos-60, encoderPos+60, servo_angle_max, servo_angle_min); //min and max are swapped because the max is actually the smaller angle and vice versa
servo.write(servo_angle);
}
}
//-----------------------------------------
//Servo------------------------------------
//-----------------------------------------
//-----------------------------------------
Serial.println(servo_angle);
}
//Interupts for Encoder----------------------
//-------------------------------------------
// Interrupt on A changing state
void doEncoderA(){
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done
// Test transition, did things really change?
if( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set;
// adjust counter + if A leads B
if ( (A_set && !B_set) && encoderPos < 120.0 )
encoderPos += 1;
rotating = false; // no more debouncing until loop() hits again
}
}
// Interrupt on B changing state, same as A above
void doEncoderB(){
if ( rotating ) delay (1);
if( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter - 1 if B leads A
if( (B_set && !A_set) && encoderPos > 0 )
encoderPos -= 1;
rotating = false;
}
}
//--------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment