• Welcome to Jetboaters.net!

    We are delighted you have found your way to the best Jet Boaters Forum on the internet! Please consider Signing Up so that you can enjoy all the features and offers on the forum. We have members with boats from all the major manufacturers including Yamaha, Seadoo, Scarab and Chaparral. We don't email you SPAM, and the site is totally non-commercial. So what's to lose? IT IS FREE!

    Membership allows you to ask questions (no matter how mundane), meet up with other jet boaters, see full images (not just thumbnails), browse the member map and qualifies you for members only discounts offered by vendors who run specials for our members only! (It also gets rid of this banner!)

    free hit counter

DIY GPS Speed Control Project

And in case anyone is interested, here is my arduino sketch:


#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <PID_v1.h>

static const int RXPin = 10, TXPin = 11, CruiseUp1 = 5, CruiseUp2 = 6, CruiseDown1 = 3, CruiseDown2 = 4, ButtonPin = 7;
static const uint32_t GPSBaud = 9600;
double TargetSpeed;
double CurrentSpeed;
double DeadZone = 1.1; //amount of space where no adjustment made

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
Serial.begin(57600);
ss.begin(GPSBaud);
Serial.println("Firing it up");
pinMode(CruiseUp1, OUTPUT); //two cruise ups and down because of the chip i'm using to trip the switch
pinMode(CruiseUp2, OUTPUT);
pinMode(CruiseDown1, OUTPUT);
pinMode(CruiseDown2, OUTPUT);
pinMode(ButtonPin, INPUT);
//CurrentSpeed = 20;
}

void loop()
{

if (digitalRead(ButtonPin) == HIGH) {
TargetSpeed = CurrentSpeed;
Serial.println("Got Button Press");
Serial.print("Target speed is now: ");
Serial.println(TargetSpeed);
}
while (ss.available() > 0)
if (gps.encode(ss.read()) && gps.speed.mph() > 0){
//CurrentSpeed = gps.speed.mph();
}
//else Serial.println("GPS Not Ready");

if (millis() > 7000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while(true);
}

if (TargetSpeed > 0) DoCruiseCheck();
if (CurrentSpeed < 10) {
TargetSpeed = 0;
Serial.println("Current Speed less than 10 MPH, setting Target Speed to 0.");
}

ReadInputString(); //check if there is a serial monitor input string
DisplayInfo();
}

void DoCruiseCheck(){
if ( abs((TargetSpeed * 100) - (CurrentSpeed * 100)) > DeadZone * 100){ //if delta is greater than deadzone, take action
if (CurrentSpeed > TargetSpeed) CruiseButtonDown();
else CruiseButtonUp();
}
}

void CruiseButtonUp(){
digitalWrite(CruiseUp1, HIGH);
Serial.println("Simulating Cruise Up - One Second Delay.....");
delay(1000);
digitalWrite(CruiseUp1, LOW);
}

void CruiseButtonDown(){
digitalWrite(CruiseDown1, HIGH);
Serial.println("Simulating Cruise Down - One Second Delay.....");
delay(1000);
digitalWrite(CruiseDown1, LOW);
}

void ReadInputString(){
String readString;
while (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
delay(2); //slow looping to allow buffer to fill with next character
}

if (readString.length() >0) {
CurrentSpeed = readString.toDouble(); //convert readString into a number
}
}

void DisplayInfo(){
Serial.println("GPS INFO:-------");
Serial.print("GPS Coordinates:");
Serial.print(gps.location.lat(), 6); // Latitude in degrees (double)
Serial.print(", ");
Serial.println(gps.location.lng(), 6); // Longitude in degrees (double)

//Serial.println("---------------------------------------");
Serial.println();
Serial.print("Current MPH: ");
Serial.println(CurrentSpeed);

Serial.print("Target MPH: ");
Serial.println(TargetSpeed);



}
 
The priniple is the same as what I did but the execution does have fundamental differences. The biggest one is that @seabass2020 has gone with a hardcoded absolute value do loop along with simple error handling and defined ranges to handle the the ouput logic. Also since n2k is not needed with the standard cruise toggle switch going with an ic on top of receive and transmit pins is simpler than all of the n2k I had to deal with.

I think this will work better than what I did. It will certainly work better than a human driver trying to keep the target speed too. The part that may be the more annoying than a human driver is hearing the frequent 200 rpm jumps up and down for those in the boat because the controller will correct more than a human. That may be something that is more noticed by me than others though.

One thing I have noticed is that the connext display speed updates are slow so make sure you have a steady speed before relying on that to know when to press the button for set speed. I have also noticed that Connext rounds the speed to get to a whole number vs having the speed in tenths so from pull to pull the set speed may be up to 1 mph different. By itself it is not a lot but add in the 1.1 mph allowed variance (deadzone) in the controller program along with the delay and there could be times when the rider may notice it. This can be partly solved with a display for the Arduino to constantly ouput the speed or a method of inputing the target speed on the Arduino then using the set button as a cruise on button to go to that input speed.

Testing with just the driver in the boat in a low traffic area making turns and such to simulate load I think goes without saying but throwing it out there just the same.

One last thing. If all else fails pull the lanyard.
 
Depending on how well this works, I had thought about adding a bluetooth module and connecting an iphone app to be able to have better control of it.

It could show the exact speed, like you're talking about. And other information, like num of satellites, tuning parameters, etc.

Of course, if this is a flop, I may just bail on the whole thing :)
 
I don't see how it is going to be a flop. I think the IC will handle the load and you are telling it to do the right things. Aside from the other factors of comparing it to how well the current retail solutions well it won't be as good but is it good enough for you? I gave up for a multitude of reasons. Some of those were my doing in over complicating my execution making debugging and iterating a time consuming process after what was a very time consuming process with the propriety n2k. Add to that my season was ending with three kids headed back to school and in sports I could not justify the more time after I was not happy with initial results when there are retail solutions that would always work better because of the control interface with the machine. My "free" time at that point was just worth too much and I knew I would be time poor this year with relocating and needed something that would just work. The only way it would have been worth it for me would be to bring a product to retail at a far lesser price point than the current products since mine would have been somewhat inferior. Given back of the napkin total cost/benefit/risk/support analysis on that endevor I decided not to pursue it at that time.

Posting the detailed code and parts is a bold and selfless move. I wish you great success tomorrow. I hope everyone realizes the contribution you have already made is very significant. Anyone with a cruise rocker switch wanting a dirt cheap gps speed control solution should be glued to this thread.
 
I'm interesting in seeing how this works as well. Thanks for putting in all the work seabass!

I think if the fundamentals work, it's a great first step and then you should be able to iterate on it to make it work much better.

In my implementation I had a button which activated the cruise. It would read the current speed and attempt to hold it. I kept track of of the the current cruise setting and limited the button presses. If I remember correctly the cruise works to plus or minus 7. The greater the speed difference from the target the more I would allow the cruise setting to vary from zero. I had most of the system coded but never ended pursuing it any further and trying it in the boat.
 
I don't see how it is going to be a flop. I think the IC will handle the load and you are telling it to do the right things. Aside from the other factors of comparing it to how well the current retail solutions well it won't be as good but is it good enough for you? I gave up for a multitude of reasons. Some of those were my doing in over complicating my execution making debugging and iterating a time consuming process after what was a very time consuming process with the propriety n2k. Add to that my season was ending with three kids headed back to school and in sports I could not justify the more time after I was not happy with initial results when there are retail solutions that would always work better because of the control interface with the machine. My "free" time at that point was just worth too much and I knew I would be time poor this year with relocating and needed something that would just work. The only way it would have been worth it for me would be to bring a product to retail at a far lesser price point than the current products since mine would have been somewhat inferior. Given back of the napkin total cost/benefit/risk/support analysis on that endevor I decided not to pursue it at that time.

Posting the detailed code and parts is a bold and selfless move. I wish you great success tomorrow. I hope everyone realizes the contribution you have already made is very significant. Anyone with a cruise rocker switch wanting a dirt cheap gps speed control solution should be glued to this thread.

Thanks for the kind words. It would be great to sell it if it works, but ultimately, the target audience is so small that, like you, I don't know if it would be worth the work going into it. You've published a lot of your ideas too, so I just tried to help push it along a bit.
 
I'm interesting in seeing how this works as well. Thanks for putting in all the work seabass!

I think if the fundamentals work, it's a great first step and then you should be able to iterate on it to make it work much better.

In my implementation I had a button which activated the cruise. It would read the current speed and attempt to hold it. I kept track of of the the current cruise setting and limited the button presses. If I remember correctly the cruise works to plus or minus 7. The greater the speed difference from the target the more I would allow the cruise setting to vary from zero. I had most of the system coded but never ended pursuing it any further and trying it in the boat.

That sounds exactly like my first iteration. I also kept track of the current setting (like you said, plus or minus 7). But then I worried that for some reason the current setting could get off, maybe from manually bumping it up or down, or the cruise getting cancelled because the throttles were pulled back. Then, i thought what's the point of keeping track of the current setting. If the boat's going to slow, then bump it up - regardless of where the current setting is ( i realize you could possibly max out). And that kind of led me to removing PID from my code (which let me bump up or down multiple times per calculation). I'm happy to post my PID code with the "current setting" if you'd like to see it.
 
Small Update:

Spent a little bit of time with it at the lake Saturday. Overall, it was a fail, but I think the concept may work. I had a problem with the GPS not updating once the code tried to change the speed (i think i just need to adjust the code for this). The problem is it will take another week before I get back to the lake to test again.

However, I believe the concept will work. It was able to adjust up and down at higher speeds - until now I've only been able to test no wake mode in the driveway.

I am also wondering if removing the PID was the right thing. I still think maybe it was because I only have up and down adjustment. However, my code doesn't currently account for the fact that the speed may be heading in the right direction. For example, if my set point is 20 and I'm at 25, but my speed is falling at a decent rate. I should probably quit bumping down the cruise assist because "soon enough" it will land where it should. Normally a PID would account for this, but this situation feels differnent because of how slow the boat responds to change in throttle. 1 second intervals on the water seem very very quick. I'm almost thinking maybe bump it up to 3 seconds. Though, I need to fix the GPS issue before i can do more testing. I should be able to clear that up just by testing in a car though.
 
I think you could get it to work without the PID with a bit more logic in your code. The boat slows much more easier than it speeds up, so I don't think there'd be a problem with overshooting the speed, it's just undershooting in a situation like you've mentioned. I'm not sure how tricky it would be to tune the parameters for a PID controller considering this. It might also help if you remove the spin delays after the button presses, and instead just kept track of when the last button pressed happened. This would allow you to sample and process the info from gps more frequently and also allow you to change the speed of the button presses independently of your logic loop.
 
I think you could get it to work without the PID with a bit more logic in your code. The boat slows much more easier than it speeds up, so I don't think there'd be a problem with overshooting the speed, it's just undershooting in a situation like you've mentioned. I'm not sure how tricky it would be to tune the parameters for a PID controller considering this. It might also help if you remove the spin delays after the button presses, and instead just kept track of when the last button pressed happened. This would allow you to sample and process the info from gps more frequently and also allow you to change the speed of the button presses independently of your logic loop.

Great point about slowing much quicker than speeding up - I think I may just need to factor in the rate of decrease / increase to help the loop know if it should make a change.

I think the GPS problem is the GPS doesn't output information every single time through the loop, so the current speed was staying the same. And the boat thought it was supposed to slow down. So, the speed down event was happening every single loop, but the gps wasn't giving information every loop.

So, i just need to wait to perform any other operation until i get a GPS update (still happens multiple times per second). Thanks for your suggestions. I think I'm getting close.
 
Does the GPS info include a time stamp? You could use that information to know speed/heading/position change per second. It may help to have several samples to average the data somewhat. I think my gps module was providing updates at 5x per second, if I remember correctly.
 
Does the GPS info include a time stamp? You could use that information to know speed/heading/position change per second. It may help to have several samples to average the data somewhat. I think my gps module was providing updates at 5x per second, if I remember correctly.

Yes it does. That might be a great way to get the rate of increase / decrease
 
Baud rate of the gps module determines the number of updates per second that the hardware is capable of. Tiny gps library helps the software processing side by only collecting what you need in a easy format. I do recoomend using the native gps hardware baud rate which the code already does.
 
Small update:
Tried it out again this weekend with the modified GPS code. I think the concept works, but it overshoots on the high end and the low end. Basically keeps bouncing back and forth like +/- 8 mph.

I think the reason is because of how long it takes the boat the respond to a button press. As recommended by some of you guys, I am going to try to take the rate of change into consideration. If the rate of speed change is acceptable, do nothing. This may prevent overshoot.

The other thing I am finding, is my desire to work on the project while at the lake is very low. I'm there with my wife and 3 kids and generally having way too much fun to break out the laptop and arduino to jack with the speed control. Also I just landed my first wake to wake jump yesterday.

Anyway, here's a video anyway, you can see the room for improvement.
 
If you watch a system like ridesteady you can see it updating the rpms multiple times per second in as little as 10 rpm increments and much more when needed. The only way to hold steady speed with 200 rpm increments is to update more frequently so the full 200 rpm impact never takes place when you don't need it to. That said you may run into why I abandoned my project as the very frequent 200 rpm jumps are not only annoying they are also terrible for fuel economy. In other words it is very hard to overcome the 200 rpm delta. Yeah I know broken record but don't get down on yourself because that really is a difficult thing.

Congrats on the wake to wake jump. It takes willpower to stand tall and not to absorb the wake with your knees when you are cutting that hard at the speed needed to do that.
 
Well I still may play with it more, but just kind of hard when I can only test things once a week, at most.

And, if I'm honest, landing my first wake to wake felt so much more gratifying than controlling the cruise with an arduino :)
 
Guys, I've read through your ideas and none seem applicable to my dilemma since y'all have electronic controlled throttle but maybe you could offer some direction/advice. I have a 2005 SR230/twin MR1's with mechanical throttle. I've been looking hard at an automotive cruise control module/actuator that receives pulse input (adjustable) 2k-40k ppm, sine or square wave, controlled by a GPS speed sensor with adjustable output of the same range, and has sensitivity and PID adjustments. The cruise control module can be set and adjusted via a dash-mount control switch (on-set-up/down). The cost of these components is around $400. I'd use a single module tied to twin cables. The module has a 35lb pull with a magnetic safety release so if you pull back on the throttle, the module deenergizes. This seems like a win on a mechanical throttle system but now your thread has me in doubt.
 
Guys, I've read through your ideas and none seem applicable to my dilemma since y'all have electronic controlled throttle but maybe you could offer some direction/advice. I have a 2005 SR230/twin MR1's with mechanical throttle. I've been looking hard at an automotive cruise control module/actuator that receives pulse input (adjustable) 2k-40k ppm, sine or square wave, controlled by a GPS speed sensor with adjustable output of the same range, and has sensitivity and PID adjustments. The cruise control module can be set and adjusted via a dash-mount control switch (on-set-up/down). The cost of these components is around $400. I'd use a single module tied to twin cables. The module has a 35lb pull with a magnetic safety release so if you pull back on the throttle, the module deenergizes. This seems like a win on a mechanical throttle system but now your thread has me in doubt.
Did you consider PerfectPass - there is specific model for twin yamis. It is more expensive but can be occasionally found for way under 1k, and it’s proven to work very well in Yamahas with mechanical throttles.

 
Back
Top