Hi all, brand new to arduino and programming. I am working on a project that controls the trim tabs on a boat via linear actuators. The below code has been created by a fellow member of a boat forum I am part of and works very well, however I am trying to add an additional switch to control one of the functions. So 2 switches controlling the one function. The idea being the switch can be operated by the driver or spotter at the back of the boat.
The first function called "surf" and it extends or retracts 2 x linear actuators based on pushing one side or the other of an on-off-on switch, the code has these switches going to pins 2 & 3 on the board. What I want to do is add 2 more pins to the function to receive a signal from a second switch that perform the same function as pins 2,3 within the code.
As I said I am brand new and cant figure it out It would be greatly appreciated if someone could tell me how to write this in.
The "launch" function works fine and needs no further adjusting.
Here is the current code.
#include <NMEAGPS.h>
#include <GPSport.h>
#include <EEPROM.h>
//RoMeo-specific motor controls
int E1 = 5; //M1 Speed Control (left gate pin deploy)was 5
int E2 = 6; //M2 Speed Control (right gate pin deploy) was 4
int M1 = 4; //M1 Direction Control (left gate pin retract)was 6
int M2 = 7; //M1 Direction Control (right gate pin retract) was 7
//Surf Settings - deploy speeds
float minSpeed = 6; // speed to deploy the tab when using GPS
float maxSpeed = 17; // speed above which to retract tab when using GPS
// Launch Settings
int launchDeploy = 4500; // Time to Run tabs when launching (full extension)
int launchRetract = 4700; // time to retract tabs when done launching (full retract)
int planeSpeed = 20; // Speed at which your boat planes (tabs full retract in launch mode)
int launch = -1;
int launchbutton = 0;
// Actuator settings
// Default -- can be edited with Bluetooth app
int tabTime[ ] = {4500, 4500}; // The default amount of time in ms each tab to deploy
// Static values
const int retractTime[ ] = {5500, 5500}; // full time in ms to retract tabs fully from fully extended.
const int maxTime[ ] = {5400, 5400}; // the max amount of time an actuator should run
const int coolDown = 500; // Wait 500ms before taking a second action on same tab to prevent any issues
/// DO NOT EDIT BELOW HERE ////
// Pin Settings
// Switch pins -- wire with a ground and pin 2/3 as your surf left/right buttons on your switch.
const int buttonPins[ ] = {2, 3};
const int rotInterval = 100; // Time to increase or decrease tab deployment with each button push
// Relay control pins
const int directionGate[ ] = {4, 7}; // Specific to ROMEO Board JB
const int speedGate[ ] = {5, 6};
const int LEDPIN = 13;
const int LaunchPin = 12;
// GPS Hookup:
//TX- pin 8
//RX- Pin 9
//VCC- Pin 11
//Gnd- Pin 10
// ** No need to edit below here **
//GPS data
long lastUpdate = 0; //when the last update occurred
float lastSpeed = 0;
int satCount;
bool gpsOut;
// Timers
long deployTimers[ ] = { -1, -1}; // deploy timer - 0= left, 1= right for all arrays
long retractTimers[ ] = { -1, -1}; // retracting of actuators;
long coolDownTimers[ ] = { -1, -1};
int buttonStart[ ] = { -1, -1}; // start deploy time for buttons
long LEDTimer = 0;
long loopTimer; // a reusable loop timer.
int loopTime; // how long the full last loop took
// Misc
int i; // counter
bool speedlimit;
int start = 0;
int surf = -1; //off=-1, surf left=0, surf right=1
String tabMap[ ] = {"LEFT", "RIGHT"}; // just for printing out in serial
int deployed[ ] = {0, 0}; // how far tab is deployed
int batchMoveTime = 1000; // How many ms to wait after a move to take actoin -- this prevents repeated short bursts of time, with more accurate longer ones.
long lastRotUpdate;
boolean pendingMove = false;
NMEAGPS gps; // This parses the GPS characters
gps_fix fix; // This holds on to the latest values
char BLETest = 999;
void setup()
{
Serial.begin(115200); //*********JB Sets the data rate in bits per second (baud) for serial data transmission
// Set the button pins to INPUT_PULLUP
for (i = 0; i < 2; i = i + 1) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode (LaunchPin, INPUT_PULLUP);
// LED pin
pinMode(LEDPIN, OUTPUT);
// Set the gates control pins to OUTPUT
for (i = 0; i < 2; i = i + 1) {
pinMode(directionGate[i], OUTPUT);
pinMode(speedGate[i], OUTPUT);
}
// If we have any saved settings, restore them from EEPROM
restoreSettings();
// Enable GPS
gpsPort.begin(9600);
}
//--------------------------///
void(* resetFunc) (void) = 0; //declare reset function @ address 0
void GPSloop()
{
while (gps.available( gpsPort )) {
fix = gps.read();
lastUpdate = millis();
lastSpeed = fix.speed_mph();
satCount = fix.satellites;
}
}
void saveSettings() {
for (i = 0; i < 2; i = i + 1) { // loop thru to save
EEPROM.write(i, tabTime[i] / rotInterval);
}
}
void restoreSettings() {
for (i = 0; i < 2; i = i + 1) { // loop thru to save
int ee = EEPROM.read(i);
if (ee > 1 and ee * rotInterval < maxTime[i]) {
tabTime[i] = ee * rotInterval;
} else {
}
}
}
void gpsLagCheck() {
if ((millis() - lastUpdate) > 5000) {
gpsOut = true;
} else {
gpsOut = false;
}
}
void checkSpeed() {
if (lastSpeed > minSpeed and lastSpeed < maxSpeed) {
speedlimit = true;
} else {
speedlimit = false;
surf = -1;
}
}
void LaunchGo()
{ analogWrite(E1, 255);
analogWrite(E2, 255);
digitalWrite(M1, HIGH);
digitalWrite(M2, HIGH); //deploy tabs
Serial.print("F");
delay(launchDeploy); //deploy for set time in parameters
{ analogWrite(E1, 0);
analogWrite(E2, 0);
} BLETest = -1;
launch = 1;
}
void LaunchAbort()
{ analogWrite(E1, 255);
analogWrite(E2, 255);
digitalWrite(M1, LOW);
digitalWrite(M2, LOW); //retract tabs
delay(launchRetract); //retract for set time in parameters
{ analogWrite(E1, 0);
analogWrite(E2, 0);
}//stop deploy}
Serial.print("G");
launch = -1;
}
void deployTab(int tab, int start) {
for (i = 0; i < 2; i = i + 1) { // loop thru to see if we need to retract anything
if (i != tab and (deployed[i] > 0 or deployTimers[i] > 0)) {
retractTab(i, 0);
}
}
retractTimers[tab] = -1;
analogWrite(speedGate[tab], 255);
digitalWrite(directionGate[tab], HIGH);
deployTimers[tab] = millis() - start;
}
void retractTab(int tab, int start) {
deployTimers[tab] = -1;
analogWrite(speedGate[tab], 255);
digitalWrite(directionGate[tab], LOW);
if (start != 0) {
retractTimers[tab] = millis() - (tabTime[surf] + start);
} else {
retractTimers[tab] = millis();
}
}
void resetTabs() {
for (i = 0; i < 2; i = i + 1) { // loop thru both
deployTimers[i] = -1;
deployed[i] = 0;
coolDownTimers[i] = -1;
retractTab(i, 0);
}
}
void goSurf() {
if (surf > -1) { // Is surf enabled? surf 0=left surf1=right
if (speedlimit == 1) { // Are we in a deploy speed range
if (deployTimers[surf] == -1 and retractTimers[surf] == -1 and deployed[surf] < 1 and (millis() - coolDownTimers[surf]) > coolDown) {
deployTab(surf, 0);
}
}
// Check if we have anything to retract
if (speedlimit == 0) { // Are we outside of a deploy speed range
for (i = 0; i < 2; i = i + 1) { // loop thru both to see if we need to retract
if (retractTimers[i] == -1 and deployTimers[i] == -1 and deployed[i] > 1 and (millis() - coolDownTimers[surf]) > coolDown) {
retractTab(i, 0);
}
}
}
} else { // auto-retract when surf is off
for (i = 0; i < 2; i = i + 1) { // loop thru both to see if we need to retract
if (retractTimers[i] == -1 and deployTimers[i] == -1 and deployed[i] > 1 and (millis() - coolDownTimers[surf]) > coolDown) {
retractTab(i, 0);
}
}
}
}
void tabTimers() {
// Check timers for status
for (i = 0; i < 2; i = i + 1) {
if (deployTimers[i] > 0 and (millis() - deployTimers[i]) > tabTime[i] and retractTimers[i] == -1) {
deployed[i] = tabTime[i];
//Do your deploy complete logic here, IE: set pins
Serial.print("H");
analogWrite(speedGate[i], 0);
deployTimers[i] = -1;
coolDownTimers[i] = millis();
}
}
for (i = 0; i < 2; i = i + 1) {
if (i != surf) {
if (retractTimers[i] > 0 and (millis() - retractTimers[i]) > retractTime[i] and deployTimers[i] == -1) {
deployed[i] = 0;
//Do your retract complete logic here, IE: set pins
analogWrite(speedGate[i], 0);
Serial.print("I");
retractTimers[i] = -1;
coolDownTimers[i] = millis();
}
} else {
// Do adjust here instead of full retract
if (retractTimers[i] > 0 and millis() > retractTimers[i] and (millis() - retractTimers[i]) > tabTime[i] and deployTimers[i] == -1) {
deployed[i] = tabTime[i];
//Do your retract complete logic here, IE: set pins
analogWrite(speedGate[i], 0);
retractTimers[i] = -1;
coolDownTimers[i] = millis();
}
}
}
}
void Buttoncheck() {
for (i = 0; i < 2; i = i + 1) {
int buttonValue = digitalRead(buttonPins[i]);
if (buttonValue == HIGH and surf == i and surf != -1)
{
if (buttonStart[i] == -1) {
buttonStart[i] = millis();
}
if (millis() - buttonStart[i] > 1000) {
surf = -1;
buttonStart[i] = -1;
}
}
delay(1); //COMMENT BACK IN IF HAVING INTERFERENCE ISSUES
if (buttonValue == LOW and surf != i) {
if (buttonStart[i] == -1) {
buttonStart[i] = millis();
}
if (millis() - buttonStart[i] > 1000) {
surf = i;
buttonStart[i] = -1;
}
}
}
delay(1); //COMMENT BACK IN IF HAVING INTERFERENCE ISSUES
}
void Bluetooth() {
if (Serial.available() > 0) // Send data only when you receive data:
{
BLETest = Serial.read(); //Read the incoming data and store it into variable data
if (BLETest == '1') //Checks whether value of data is equal to 1
{
lastRotUpdate = millis(); //trick into thinking rotary haas been updated
pendingMove = true; //tell control a movement is coming
{ if (tabTime[surf] < maxTime[surf] ) {
tabTime[surf] = tabTime[surf] + 100;
Serial.print("A");
} //add 100ms to tab time
else {
Serial.println(F("MAX"));
} //Print max and don't allow further extension
}
}
else if (BLETest == '0') //Checks whether value of data is equal to 0
{
lastRotUpdate = millis();
pendingMove = true;
{ if (tabTime[surf] > 0 ) {
tabTime[surf] = tabTime[surf] - 100;
Serial.print("B");
} // subtract 100ms from tab time
else {
}//Print min and don't allow further retraction
}
}
else if (BLETest == '3')
{
Serial.print("C");
resetFunc();
}
else if (BLETest == '4')
{
Serial.print("D");
resetTabs();
}
else if (BLETest == '5')
{
Serial.print("E");
saveSettings();
}
else if
(BLETest == '6' and surf == -1 and lastSpeed < planeSpeed) //Checks whether value of data is equal to 6, surf is off, and speed is under plane speed set in parameters
{ LaunchGo();}
else if (BLETest == '7' and surf == -1) //Checks whether value of data is equal to 7, surf is off
{ LaunchAbort();}
else if (BLETest == '8')
{
Serial.print("J");
minSpeed = -1;
}
else if (BLETest == '9')
{
Serial.print("K");
minSpeed = 7;
}
}
//check to make sure we should be able to move the tab and bunch multiple clicks into one move
if (millis() > lastRotUpdate + batchMoveTime and tabTime[surf] != deployed[surf] and deployTimers[surf] == -1 and retractTimers[surf] == -1 and pendingMove) {
if (tabTime[surf] > deployed[surf]) {
deployTab(surf, deployed[surf]);
} else {
retractTab(surf, tabTime[surf] - deployed[surf]);
}
pendingMove = false;
}
}
void ButtonLaunch()
{launchbutton = digitalRead(LaunchPin);
if (launchbutton == LOW and surf == -1 and lastSpeed < planeSpeed and launch == -1) //Checks whether button has been pushed, surf is off,speed is under plane speed set in parameters, and not currently launching
LaunchGo();
else if (launchbutton == LOW and surf == -1 and lastSpeed < planeSpeed and launch == 1)
LaunchAbort();
}
void OnPlaneCheck()
{ if (lastSpeed > planeSpeed and launch == 1)
{ analogWrite(E1, 255);
analogWrite(E2, 255);
digitalWrite(M1, LOW);
digitalWrite(M2, LOW); //retract tabs
delay(launchRetract); //retract for set time in parameters
{ analogWrite(E1, 0);
analogWrite(E2, 0);
}//stop deploy}
Serial.print("G");
launch = -1;
}
}
void surfSideSerial()
{
if (surf == 0)
Serial.print("L");
else if (surf == 1)
Serial.print("R");
else if (surf == -1)
Serial.print("N");
}
void loop()
{
loopTime = millis() - loopTimer;
loopTimer = millis();
tabTimers();
Buttoncheck(); //Comment back in to use hard buttons
ButtonLaunch();
checkSpeed(); // Check if my speed is in the deploy range
OnPlaneCheck(); //retract tabs if on plane
Bluetooth ();
//minSpeed = -1;
GPSloop(); // Get GPS data
goSurf();
}