Hey guys! First time poster here. I am getting back into the coding game that I haven't been in since the Commodore 128 days.
A recent project I embarked on is building a trolling "cruise control" for my boat. The idea is to be able to take GPS speed and move a servo motor that will control the throttle of my trolling motor (even wide open it only pushes the boat 3-4mph). I came up with the code and assembled a rig including:
Arduino Uno
Adafruit Ultimate GPS
Buck converter to step down the 12v boat battery to 6v for the servo
Adafruit micro high torque servo
It took a lot of trial and error but I finally had the rig working good. Tonight I tried to connect the servo and it doesn't operate correctly. Regardless of the mode I use, it always "hunts" back and forth about 45*. The input (pot or otherwise) does seem to move the servo, but it always is moving around.
Initially I suspected a power supply problem, but when using the Servo Library example code for both sweep and knob, the servo works perfectly fine! This is probably me showing my "green-ness", as I am sure there is something with my code. Let me know what you guys think.
//libraries and definitions
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <Wire.h>
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
//objects
LiquidCrystal_I2C lcd_1(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
Servo servo; // create servo object to control a servo
TinyGPSPlus gps; // sets up gps
SoftwareSerial ss(8, 7); //sets up software serial for GPS
//variables
int potpin = 0; // analog pin used to connect the potentiometer
int pot = 0; // variable to read the value from the analog pin
int tper = 0; //variable for throttle percentage
int srbuttonstate = 0; //stop run switch state
int mabuttonstate = 0; // manual auto switch state
float gpsspeed = 0.0; //speed over ground from GPS
float setspeed = 0.0; //set speed for auto mode
int servopos = 0; //servo position
void setup() {
//servo
servopos = constrain(servopos, 0, 90); //sets limit on servo
servo.write(servopos); //sets servo to idle position
servo.attach(9); // attaches the servo on pin 9 to the servo object
//pins
pinMode(3, INPUT); //set stop/run input pin
pinMode(4, INPUT); //set man/auto input pin
pinMode(9, OUTPUT); //sets servo output
//lcd
lcd_1.init(); // initialize the lcd
lcd_1.backlight();
//GPS
//uncomment for testing Serial.begin(115200);
ss.begin(9600);
}
void loop() {
//gps
if (gps.speed.isUpdated()) {
gpsspeed = (gps.speed.mph());
//uncomment for testing Serial.println(F("Speed:"));
//uncomment for testing Serial.println(gps.speed.mph());
}
while (ss.available() > 0) {
gps.encode(ss.read());
}
//buttons
srbuttonstate = digitalRead(3); //read stop/run switch
mabuttonstate = digitalRead(4); //read man/auto switch
if (srbuttonstate == LOW) //standby loop
{
servopos = 0; //set servo to idle
servo.write(servopos); // move servo to idle
lcd_1.setCursor(0, 0); //go to start of screen
lcd_1.print(" System Standby "); //print status
lcd_1.setCursor(0, 1); //go to second line
lcd_1.print(" "); //clear second line
}
else if (mabuttonstate == LOW) //manual mode loop
{
lcd_1.setCursor(0, 0); //go to start of screen
lcd_1.print(" Manual "); //print status
lcd_1.setCursor(0, 1); //go to second line
lcd_1.print(" Throttle %: "); //print throttle
lcd_1.setCursor(12, 1); //go to end of writing
lcd_1.print(tper); // print throttle position
pot = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
tper = map(pot, 1023, 0, 0, 100); //scale for throttle percentage
servopos = map(pot, 0, 1023, 0, 90); // scale it to use it with the servo (value between 0 and 90)
servo.write(servopos); // sets the servo position according to the scaled value
}
else { //auto mode loop
pot = analogRead(potpin); //reads potentiometer position
pot = (pot - 1023); //converts pot singal to negative- backwards pot
setspeed = (pot * -.003); //converts pot signal to speed
tper = map(servopos, 0, 90, 0, 100); //converts servo position to throttle position
lcd_1.setCursor(0, 0); //goto beginning of screen
lcd_1.print("SS: AS:"); //prints top line headings
lcd_1.setCursor(12, 0); // goto gpsspeed part of screen
lcd_1.print(gpsspeed); //prints gps speed
lcd_1.setCursor(3, 0); //goto setspeed part of screen
lcd_1.print(setspeed); //prints setspeed
lcd_1.setCursor(0, 1); //go to second line
lcd_1.print(" Throttle %: "); //print throttle
lcd_1.setCursor(12, 1); //go to end of writing
lcd_1.print(tper); // print throttle position
if (setspeed > gpsspeed) { //speed too slow loop
servopos = (servopos + 2); //increases throttle position
servo.write(servopos); //moves servo to increased throttle position
delay(1000); //wait one second
}
else if (setspeed < gpsspeed) { //speed too fast loop
servopos = (servopos - 2); //decreases throttle position
servo.write(servopos); //moves servo to decreased throttle position
delay(1000); //wait one second
}
else { //speed accurate loop
servo.write(servopos); //keeps servo in same position
delay(1000); //wait one second
}
}
}