Code
Code
// Imports
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#include <BlynkSimpleSerialBLE.h>
#include "./TinyGPS.h" // Use local version of this library
#include "./CoolerDefinitions.h"
// GPS
TinyGPS gps;
// Lid
Servo lidServo;
CoolerLid lidState = CLOSED;
// Master Enable
bool enabled = false;
//WidgetTerminal terminal(V3);
// Serial components
SoftwareSerial bluetoothSerial(BLUETOOTH_TX_PIN, BLUETOOTH_RX_PIN);
SoftwareSerial nss(GPS_TX_PIN, 255); // TXD to digital pin 6
/* Compass */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
GeoLoc checkGPS() {
Serial.println("Reading onboard GPS: ");
bool newdata = false;
unsigned long start = millis();
while (millis() - start < GPS_UPDATE_INTERVAL) {
if (feedgps())
newdata = true;
}
if (newdata) {
return gpsdump(gps);
}
GeoLoc coolerLoc;
coolerLoc.lat = 0.0;
coolerLoc.lon = 0.0;
return coolerLoc;
}
GeoLoc coolerLoc;
coolerLoc.lat = flat;
coolerLoc.lon = flon;
return coolerLoc;
}
// Lid Hook
BLYNK_WRITE(V0) {
switch (lidState) {
case OPENED:
setServo(SERVO_LID_CLOSE);
lidState = CLOSED;
break;
case CLOSED:
setServo(SERVO_LID_OPEN);
lidState = OPENED;
break;
}
}
// Killswitch Hook
BLYNK_WRITE(V1) {
enabled = !enabled;
GeoLoc phoneLoc;
phoneLoc.lat = gps.getLat();
phoneLoc.lon = gps.getLon();
driveTo(phoneLoc, GPS_STREAM_TIMEOUT);
}
// Terminal Hook
BLYNK_WRITE(V3) {
Serial.print("Received Text: ");
Serial.println(param.asStr());
String rawInput(param.asStr());
int colonIndex;
int commaIndex;
do {
commaIndex = rawInput.indexOf(',');
colonIndex = rawInput.indexOf(':');
if (commaIndex != -1) {
String latStr = rawInput.substring(0, commaIndex);
String lonStr = rawInput.substring(commaIndex+1);
if (colonIndex != -1) {
lonStr = rawInput.substring(commaIndex+1, colonIndex);
}
void displayCompassDetails(void)
{
sensor_t sensor;
mag.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value);
Serial.println(" uT");
Serial.print ("Min Value: "); Serial.print(sensor.min_value);
Serial.println(" uT");
Serial.print ("Resolution: "); Serial.print(sensor.resolution);
Serial.println(" uT");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
#ifndef DEGTORAD
#define DEGTORAD 0.0174532925199432957f
#define RADTODEG 57.295779513082320876f
#endif
float geoBearing(struct GeoLoc &a, struct GeoLoc &b) {
float y = sin(b.lon-a.lon) * cos(b.lat);
float x = cos(a.lat)*sin(b.lat) - sin(a.lat)*cos(b.lat)*cos(b.lon-a.lon);
return atan2(y, x) * RADTODEG;
}
return R * y;
}
float geoHeading() {
/* Get a new sensor event */
sensors_event_t event;
mag.getEvent(&event);
// Hold the module so that Z is pointing 'up' and you can measure the heading
with x&y
// Calculate heading when the magnetometer is level, then correct for signs of
axis.
float heading = atan2(event.magnetic.y, event.magnetic.x);
// Offset
heading -= DECLINATION_ANGLE;
heading -= COMPASS_OFFSET;
return headingDegrees;
}
// turn on motor B
setSpeedMotorB(speed);
}
void stop() {
// now turn off motors
digitalWrite(MOTOR_A_IN_1_PIN, LOW);
digitalWrite(MOTOR_A_IN_2_PIN, LOW);
digitalWrite(MOTOR_B_IN_1_PIN, LOW);
digitalWrite(MOTOR_B_IN_2_PIN, LOW);
}
// drive to location
int s = fullSpeed;
if ( distance < 8 ) {
int wouldBeSpeed = s - stopSpeed;
wouldBeSpeed *= distance / 8.0f;
s = stopSpeed + wouldBeSpeed;
}
float t = turn;
while (t < -180) t += 360;
while (t > 180) t -= 360;
Serial.print("turn: ");
Serial.println(t);
Serial.print("original: ");
Serial.println(turn);
float t_modifier = (180.0 - abs(t)) / 180.0;
float autoSteerA = 1;
float autoSteerB = 1;
if (t < 0) {
autoSteerB = t_modifier;
} else if (t > 0){
autoSteerA = t_modifier;
}
setSpeedMotorA(speedA);
setSpeedMotorB(speedB);
}
d = geoDistance(coolerLoc, loc);
float t = geoBearing(coolerLoc, loc) - geoHeading();
Serial.print("Distance: ");
Serial.println(geoDistance(coolerLoc, loc));
Serial.print("Bearing: ");
Serial.println(geoBearing(coolerLoc, loc));
Serial.print("heading: ");
Serial.println(geoHeading());
drive(d, t);
timeout -= 1;
} while (d > 3.0 && enabled && timeout>0);
stop();
}
}
void setupCompass() {
/* Initialise the compass */
if(!mag.begin())
{
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while(1);
}
void setup()
{
// Compass
setupCompass();
// Motor pins
pinMode(MOTOR_A_EN_PIN, OUTPUT);
pinMode(MOTOR_B_EN_PIN, OUTPUT);
pinMode(MOTOR_A_IN_1_PIN, OUTPUT);
pinMode(MOTOR_A_IN_2_PIN, OUTPUT);
pinMode(MOTOR_B_IN_1_PIN, OUTPUT);
pinMode(MOTOR_B_IN_2_PIN, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
//GPS
nss.begin(9600);
//Bluetooth
bluetoothSerial.begin(9600);
Blynk.begin(bluetoothSerial, auth);
}
// Testing
void testDriveNorth() {
float heading = geoHeading();
int testDist = 10;
Serial.println(heading);
stop();
}
void loop()
{
Blynk.run();
}