openstatic.org

openstatic.org

Danger Board 1.0

A portable, lightweight, rideable, thruster powered body board



Introduction

I was watching a ton of videos about jet powered surf boards, and i was inspired to try something a little less crazy since I don't have the space or skill to ride one. So, I decided a body board was a good place to start. The only major downside to a body board was limited space for components, so proper jets were out of the question.

Propulsion

I started by digging around on amazon and found a pair of cheap thrusters. I had some previous experience playing with R/C cars and the idea of powering the whole thing with a 2s LiPo battery seemed promising.

I was pretty dissapointed at first by the power output, but I quickly learned that the motors were capable of handling around 12V. This resulted in water being thrown from my testing tank, perfect!

ESCs where my next challenge, In the past i've only worked with brushless ESCs, luckily amazon recommended a suitable pair

Now it was time to figure out how to mount the thrusters to the board.

Fins

Most body boards are made of a bunch of compressed styrofoam which isnt great for mounting, so i started to look at surfboard fins i could modify and 3d print. (3D-Printing-a-Surf-Board-Replaement-Fin)

Now that i had a good model to work with, i started playing around with adding a thruster socket using 3d paint

pretty satisfied with the simple design i started printing 2 fins.

I wish i had the CAD skills to have hit the wires in the fin somehow, but i had a plan to address that later!


Project Box

One of my favorite challenges of this project was figuring out how to keep everything waterproof. Instead of using a traditional project box, i opted to use a watertight box for keeping cellphones/keys etc. I used a exacto-knife to cut out a cubby at the front of the board, and the box slid into place perfectly.

The absolute worst part of this project was creating a conduit for the wires from the fins to the project box, ultimately the best tool was a sharpened and unwound coat hanger covered in lubricant. I was able to fish it through the side of the board to the project box area. Once this was complete i used the same coathanger to pull wires through.

Wiring components

Now comes the fun part, wiring everything up. For my initial tests, i just connected a simple R/C receiver to the ESCs. However the thought of taking my RadioLink remote into the water with me was just a NO. Like most embedded projects I ran to my favorite chip manufacturer Espressif, and grabbed an ESP32.

It was at this point i started to think about features, and what this project needed to acomplish.

  • Safety
    • LiPo Battery Monitoring
    • ESC Temperature Monitoring
    • Remote monitoring
    • Moisture detection
  • Ease of use
    • Simple waterproof conroller for rider
    • Easy to recharge on the go
    • Waterproof On/Off switch
    • Display showing battery life / stats
  • Versatility
    • Maintain remote control features
    • WiFi connection (seriously why not when using an esp32)

For those of you that have never played with an ESC one of the best parts is that they function just like a Servo. Usually with most servos a 90 degree angle represents idle, more then that is foward thrust and less then that is reverse. During my testing with the motors i learned one very important thing, reverse is out of the question. The propeller seems to be held on by pressure alone and a quick jolt in reverse will rip it right off!

I started with the Servo library in Arduino, and started to think about how i would translate the steering into thrust vectors. Nothing too complicated, just wanted simple steering control. I thought about rowing, if you want to turn left you row more on the right, visa-versa. With that I figured angles less then 90 degrees should lower the left thruster, and higher then 90 should lower the right.

void translateThrust()
{  
  float leftAdjust = 1.0;
  float rightAdjust = 1.0;
  if (steeringOutputAngle < 90)
  {
    leftAdjust = mapfloat(steeringOutputAngle, 90, 0, 1, 0);
  } else if (steeringOutputAngle > 90) {
    rightAdjust = mapfloat(steeringOutputAngle, 90, 180, 1, 0);
  }
  leftThrustOutputAngle = 90 + ((throttleOutputAngle - 90) * leftAdjust);
  rightThrustOutputAngle = 90 + ((throttleOutputAngle - 90) * rightAdjust);
}

Mapping out the connections to the chip was pretty easy given the insane amount of GPIOs and ESP32 has. I left the I2C pins available for temperature sensors and a 20x4 LCD display to give the rider battery info.

For monitoring the temp of the ESCs and detecting moisture in the project box, i went with these little sensors. Right now i'm going to skip forward a bit to my first water test because it really changed the direction of the project.

Underwhelmed

  • Turning... CHECK
  • Appearence.. CHECK
  • Speed.. LAME
So at the very least i hoped it would go the same speed (without a rider) as an average non olympic swimmer, It did not. With a rider it seemed like there was no chance it would move. Time to reconsider things a bit. I was already driving the motors at their maximum voltage rating so the solution was obvious, more thrusters. My fins were already mounted and i didn't want to damage the board trying to remove them, so the solution i came up with was a third center fin with two additional motors.

With that, a serious update of the steering code was required. The method i came up with was averaging the two thrusters output for the center thruster.


void translateThrust()
{
  float leftAdjust = 1.0;
  float rightAdjust = 1.0;
  if (steeringOutputAngle < 90)
  {
    leftAdjust = mapfloat(steeringOutputAngle, 90, 0, 1, 0);
  } else if (steeringOutputAngle > 90) {
    rightAdjust = mapfloat(steeringOutputAngle, 90, 180, 1, 0);
  }
  
  leftThrustOutputAngle = throttleIdle + ((throttleOutputAngle - throttleIdle) * leftAdjust);
  rightThrustOutputAngle = throttleIdle + ((throttleOutputAngle - throttleIdle) * rightAdjust);
  centerThrustOutputAngle = ((leftThrustOutputAngle + rightThrustOutputAngle) / 2.0); // Average the two thrusts together
  
  if (leftThrustOutputAngle >= 90 && leftThrustOutputAngle >=90 && centerThrustOutputAngle >= 90)
  {
    float leftPercent = ((leftThrustOutputAngle - 90) / 90.0) * 100.0;
    float rightPercent = ((rightThrustOutputAngle - 90) / 90.0) * 100.0;
    float centerPercent = ((centerThrustOutputAngle - 90) / 90.0) * 100.0;
    
    //Highlight the turning direction on the display
    if (steeringOutputAngle == steeringCenter)
    {
      line3Text = "Left [Center]  Right";
    } else if (steeringOutputAngle < steeringCenter) {
      line3Text = "[Left] Center  Right";
    } else if (steeringOutputAngle > steeringCenter) {
      line3Text = "Left Center  [Right]";
    }
    char str[30];
    // Show the thrust percentages for each engine on the display.
    sprintf(str, "%3.0f%%    %3.0f%%    %3.0f%%", leftPercent, centerPercent, rightPercent);
    line4Text = String(str);
  }
  if (internalTemp < 50.0) // Only allow engine operation below 50.0 C (122 F)
  {
    left_thruster.write(leftThrustOutputAngle);
    right_thruster.write(rightThrustOutputAngle);
    center_thruster.write(centerThrustOutputAngle);
  } else {
    line4Text = " *ENGINE OVERHEAT*  ";
    left_thruster.write(throttleIdle);
    right_thruster.write(throttleIdle);
    center_thruster.write(throttleIdle);
  }
}


Take 2, or 4..

Ok it was time to try again now that there were 4 motors working in unison

Now we're moving, after about 40 minutes of testing i mangaged to trigger the thermal cutoff 50C (122F)

I think i might have been a little cautious on the cutoff temperature, I plan to increase it to 60C (140F) which should still be below the melting temperature for all of the components in the project box. Thermal runaway for the battery is around 80C (176F) so we should be Ok!


Sadly i have to wait a few months for the water to warm up for rider tests.



THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.