4180


Jose Mendoza, Stephanie Lashley, Olivia Robles, Edward Vear

Electric Longboard

Jose Mendoza, Stephanie Lashley, Olivia Robles, Edward Vear

/media/uploads/OliviaR/bttf.gif

Description

This mbed project utilizes bluetooth to control an electric skateboard with an ESC and motor. A uLCD mounted on top of the board displays battery level and velocity in miles per hour using a hall effect sensor. A sonar on the front of the board prevents collisions. A pushbutton on top of the board is pressed by a rider's foot and the board stops if the rider falls off or steps off of the kill switch.

Parts List

  • 1 FVT 120A ESC
  • 1 Turnigy Aerodrive SK3 Brushless Motor
  • 1 11.1V LiPo Battery
  • 4 AAA Batteries
  • 1 Adafruit Bluetooth Module
  • 1 mbed LPC1768
  • 1 uLCD
  • 1 Push Button
  • 1 Hall Effect Sensor
  • 1 magnet with four pole pairs
  • 1 Sonar Module

Schematic

/media/uploads/edwardvear/4180_schematic.png

Code

Import programElectric-Longboard

Code for Longboard

Bluetooth Motor Control Code

#include "mbed.h"
#include "Servo.h"
#include "rtos.h"
#include "ultrasonic.h"

/// Objects
DigitalIn pb(p22);
Serial blue(p28,p27); // Bluetooh
Servo myservo(p21); // Motor
ultrasonic mu(p6, p7, .1, 1, &dist); //Sonar
Thread t1;
Thread t2;

Mutex off;
bool close=false;

void bluetooth()
{
    char bnum = 0;
    myservo=0.5;
    Thread::wait(2000);
    while(1) {

        Thread::wait(50);
        if (blue.getc() == '!') {
            if (blue.getc()=='B') {
                bnum = blue.getc();
                // Up Arrow

                if ((bnum == '5') && (myservo <= 1.0)) {
                    myservo = myservo + 0.05;
                }

                // Down Arrow
                else if ((bnum == '6') && (myservo >= 0.54)) {
                    myservo = myservo - 0.05;
                }

                // Left Arrow

                else if (bnum == '7') {

                    while (myservo > 0.0) {
                         if (myservo < 0.05)
                             myservo = 0.0;
                         else
                             myservo = myservo - 0.005; // Brake  
                     }  

                }

                // Right Arrow

                else if (bnum == '8') {
                    myservo = 0.5; // Neutral

                }
            }
        }
    }

}// ends bluetooh

void dist(int distance)
{
    //put code here to execute when the distance has changed
    if(distance<400) {
        close=true;

    }
}

void stop()
{

 while (myservo > 0.0) {
                         if (myservo < 0.05)
                             myservo = 0.0;
                         else
                             myservo = myservo - 0.008; // Brake
                     }  

}//ends stop

int main()
{
    pb.mode(PullUp);
    myservo = 0.0;
    wait(0.5); //detects signal
//Required ESC Calibration/Arming sequence
//sends longest and shortest PWM pulse to learn and arm at power on
    myservo = 1.0; //send longest PWM
    wait(8);
    myservo = 0.0; //send shortest PWM
    wait(8);
//ESC now operational using standard servo PWM signals

    t1.start(bluetooth);
    mu.startUpdates();

    while (true) {

        if(close) {
            t2.start(stop);
            Thread::wait(1000);
            close=false;
        }

        mu.checkDistance();
    }//ends While

}// ends Main

Display Code

#include "mbed.h"
#include "uLCD_4DGL.h"
#include "rtos.h"
 
Ticker t;
InterruptIn risingEdge(p8); //halleffect sensor
uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
AnalogIn batt(p19);
 
volatile int count = 0.0;
volatile float vel = 0.0;
float pbatt = 0.0;
 
void pulses() //hall effect triggers
{
    count++;
}
void halleffect() //calculates velocity
{
    float temp = count;   // Copy count
    count = 0;                 // Reset the count for next second
    temp = temp/4;         // four magnets in trigger - gives rps
    vel = temp * 3.14159 * 0.035 * 2 *60 * 60 * 0.000621371 ; // radius of .035m  
}

void display(void const *argument) //update battery voltage display and velocity
{
    while(1)
    {
        float battAdj = float(batt * 3.3 * 3.968);
         uLCD.color(WHITE);
         uLCD.locate(2,2);
         uLCD.printf("%3.1f", vel*0.67);
         uLCD.locate(2,3);
         uLCD.printf("MPH");
         if (battAdj >= 11) {
             uLCD.filled_rectangle(6,99,29,16,GREEN);
             pbatt = battAdj;
         }
         else if ((battAdj >= 9)&&(battAdj < 11)) {
             uLCD.filled_rectangle(6,99,29,16,WHITE);
             uLCD.filled_rectangle(6,99,29,45,(GREEN+RED));
             pbatt = battAdj;
         }
         else if (battAdj < 9) {
             uLCD.filled_rectangle(6,99,29,16,WHITE);
             uLCD.filled_rectangle(6,99,29,70,RED);
             pbatt = battAdj;
         }    
         Thread::wait(1000);   // Refresh after one second
    }

}
 
int main() 
{
    uLCD.cls();
    uLCD.baudrate(3000000); //jack up baud rate to max
    uLCD.background_color(BLACK);
    uLCD.cls();
    uLCD.text_width(3.5); 
    uLCD.text_height(3.5);
    uLCD.filled_rectangle(5,100,30,15,WHITE);
    uLCD.filled_rectangle(12,15,22,10,WHITE);
    risingEdge.rise(&pulses); //interrupt routine
    t.attach(&halleffect, 1.0); //calculate velocity every second
    Thread displaythread(display); //update display
}

Photos

Top View of the Board /media/uploads/edwardvear/top.jpg Underside of the Board /media/uploads/edwardvear/bottom.jpg

Demo Videos

Overall Demo

Sonar Demo


All wikipages