I'm working on making doctor a who k-9 project.
What I'm attempting to do is with the buttons on top have each one switch to that mode. (i.e. button 1 sets to "follow me {Cooler}" , button 2 sets to "autonomous {with ultrasonic}, button 3 sets to "remote" etc.)
Is difficult with the follow me mode because it combines GPS, Bluetooth (blynk) & a compass. So the code I'm trying to combine is-
a keypad code (to reduce wires and hopefully code)
-Arduino Playground - KeypadTutorial
And then the 5 follow me pages:
#define BLYNK_USE_DIRECT_CONNECT
// 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;
}
// Get and process GPS data
GeoLoc gpsdump(TinyGPS &gps) {
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
GeoLoc coolerLoc;
coolerLoc.lat = flat;
coolerLoc.lon = flon;
Serial.print(coolerLoc.lat, 7); Serial.print(", "); Serial.println(coolerLoc.lon, 7);
return coolerLoc;
}
// Feed data as it becomes available
bool feedgps() {
while (nss.available()) {
if (gps.encode(nss.read()))
return true;
}
return false;
}
// 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;
//Stop the wheels
stop();
}
// GPS Streaming Hook
BLYNK_WRITE(V2) {
GpsParam gps(param);
Serial.println("Received remote GPS: ");
// Print 7 decimal places for Lat
Serial.print(gps.getLat(), 7); Serial.print(", "); Serial.println(gps.getLon(), 7);
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;
... SHORTENED TO MEET CHARACTER REQIREMENTS
void setServo(int pos) {
lidServo.attach(SERVO_PIN);
lidServo.write(pos);
delay(2000);
lidServo.detach();
}
void setSpeedMotorA(int speed) {
digitalWrite(MOTOR_A_IN_1_PIN, LOW);
digitalWrite(MOTOR_A_IN_2_PIN, HIGH);
// set speed to 200 out of possible range 0~255
analogWrite(MOTOR_A_EN_PIN, speed + MOTOR_A_OFFSET);
}
void setSpeedMotorB(int speed) {
digitalWrite(MOTOR_B_IN_1_PIN, LOW);
digitalWrite(MOTOR_B_IN_2_PIN, HIGH);
// set speed to 200 out of possible range 0~255
analogWrite(MOTOR_B_EN_PIN, speed + MOTOR_B_OFFSET);
}
void setSpeed(int speed)
{
// this function will run the motors in both directions at a fixed speed
// turn on motor A
setSpeedMotorA(speed);
// 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);
}
void drive(int distance, float turn) {
int fullSpeed = 230;
int stopSpeed = 0;
// drive to location
int s = fullSpeed;
if ( distance < 8 ) {
int wouldBeSpeed = s - stopSpeed;
wouldBeSpeed *= distance / 8.0f;
s = stopSpeed + wouldBeSpeed;
}
int autoThrottle = constrain(s, stopSpeed, fullSpeed);
autoThrottle = 230;
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;
}
Serial.print("steerA: "); Serial.println(autoSteerA);
Serial.print("steerB: "); Serial.println(autoSteerB);
int speedA = (int) (((float) autoThrottle) * autoSteerA);
int speedB = (int) (((float) autoThrottle) * autoSteerB);
setSpeedMotorA(speedA);
setSpeedMotorB(speedB);
}
void driveTo(struct GeoLoc &loc, int timeout) {
nss.listen();
GeoLoc coolerLoc = checkGPS();
bluetoothSerial.listen();
if (coolerLoc.lat != 0 && coolerLoc.lon != 0 && enabled) {
float d = 0;
//Start move loop here
do {
nss.listen();
coolerLoc = checkGPS();
bluetoothSerial.listen();
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);
}
/* Display some basic information on this sensor */
displayCompassDetails();
}
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);
//Debugging via serial
Serial.begin(4800);
//GPS
nss.begin(9600);
//Bluetooth
bluetoothSerial.begin(9600);
Blynk.begin(bluetoothSerial, auth);
}
// Testing
void testDriveNorth() {
float heading = geoHeading();
int testDist = 10;
Serial.println(heading);
while(!(heading < 5 && heading > -5)) {
drive(testDist, heading);
heading = geoHeading();
Serial.println(heading);
delay(500);
}
stop();
}
void loop()
{
Blynk.run();
}
And the wall avoidance code
And then I would also like to add a joystick from blynk for the remote mode which I haven't made yet, and also a stop mode,
and then a button for stopping any actions.
If anyone can help with combining these code to be called and looped (until unpowered or another button is pressed) when a button is pressed. Its been hard to find any info online because using the word Goto is a command and it is apparently told to be usually avoided. any info helps Thanks
K-9 files.zip (549 KB)