Long Range E-Board Build 16Amp 6S Madness

BLDC-ADDICT

10 mW
Joined
Jan 29, 2014
Messages
24
Ok, first things first.
I think I have read most of the threads here on the Endless-sphere Forums and thought it was time to give something back.. :D

So My E-Board Build is as follows :)

Build constraints:

Single motor / ESC combo
Already purchased 34t and 12t pulleys.
Already purchased 80mm wheels
Discreet controller
Long range
And fast!

Motor Kv needs to be calculated for my already determined gear ratio.. I took a rough guess based everyone else's ratios.

Ok so it's math time..

I've calculated the motor "kV" I needed by using the following formula. ( I wanted a theoretical top speed without compensating for losses of around 30+ KM/H

Formula: (Ki *V*C*60/1000)/R

Ki = 1/kv (RPM per Volt)
V = Battery Voltage
C = Pi(3.14) * wheel diameter in mm (distance traveled per revolution.) then converted back Meters
R = Gear Ratio = 34/12 = 2.83

Meters/minute to km/h conversion is = x60/1000

Ki: 260
V: 3.7Vx6 = 22.2V
C: 3.14x80=251.2mm per revolution.(must be in meters .2512M
R: 34teeth/12teeth = 2.83 (to two decimal places)

(260x22.2x.2512x60/1000)/2.83

Max theoretical speed without any losses factored in is = 30.74 KM/H

This calculation works as I'm hoping for a "real" top speed of 15 to 20 KM/H
I know some guys want 30 a 40 KM/H but this is madness of a skateboard! Crap, 10 clicks is fast last time I checked
I want a cruiser anyway. Hopefully I can throw in my headphones for some nice indie listening too :)

Ok so I now have my motor Kv sorted.

Now it's Shopping time.

I ordered most of the following items from Hobby King and a Bit of Ebaying for the ESC, Wireless Nunchuck and the Drive-train Components.

[*]Turnigy SK3 Aerodrive 260kv Motor.
[*]Hobbywing EZRUN 150A Electronic Speed controller.
[*]2x Zippy 8A 6S Lipos made into a custom 16A 6S2P Pack!
[*]34t timing pulley,
[*]12t pulley.
[*]1x ardunio nano board
[*]Logic3 Wireless Nintendo Wii Nun-chuck


Time for Progress Photos. I have since received my HK goodies in the mail. Damm fast might I add. Hobbyking's shipping to Australia has got much faster these days. :p

Also you will notice that I have made a trip done to my local Engineer to Machine up my gears and to make a mounting spacer.

Stay Tuned more progress to come. I also Must pay respect to Mantas for his Code for the Wii Nunchuck speed controller. :p :p
 
Can't wait to see it unfold. Please do share more info on how you setup your wii remote. I am definitely interested in actually setting up a Wii controller for my board as well just haven't done my thorough research yet. You should also get some crazy distance with the 16ah.
 
I'd love to compare your range to the range of my 17.4 Ah MTB!

I haven't come to test the full range yet, but I will soon...
 
Heya Murfix, wow your board is a monster. What sort of rum times have you been getting? Defiantly would be intresting to compare max Times and speeds. Id imagine your board might be a bit more hungry than mine though.. :)
 
torqueboards said:
Can't wait to see it unfold. Please do share more info on how you setup your wii remote. I am definitely interested in actually setting up a Wii controller for my board as well just haven't done my thorough research yet. You should also get some crazy distance with the 16ah.


Will do, im looking for some aluminum plate to build the motor moumt next And will keep the photos and info coming. Re the Wii remote. Ill re post Mantas' Code tonight if you like. The trickiest problem I had getting it all to work was setting up thw wiichuck.h library in arduino. Also had problems with the Z button hold function not working, but I figured it out as the joystick needed calibration to a zero vaule center.
 
//Ardunio Code that I used:

#include <Servo.h>

#include <Wiichuck.h>

#include <Wire.h>

WiiChuck chuck = WiiChuck();
Servo myservo;
int speed_val; // Speed value
int speed_val_cur = 60; // Current speed value
int y = 0; // Jaystick value
int time = 200; // Delay timer
int speed_val_hold; // speed value which will be holded while Z button is pressed

void setup() {

Serial.begin(115200);
chuck.begin();
chuck.update();
myservo.attach(9); // ESC attached to 9 pin of Arduino

}

void loop() {

// If you hold down Z button of Nunchuck you accelerate faster
if ((chuck.buttonZ)||(chuck.buttonC)) {
if (chuck.buttonZ) {
Serial.print(" Z ");
//time = 100;
speed_val_hold = speed_val_cur; // Sets speed value to hold
}
// If you hold down C button of Nunchuck you accelerate slower
if (chuck.buttonC) {
Serial.print(" C ");
time = 100;
}
} else {
time = map (speed_val_cur,60,80,100,250);
speed_val_hold = 60;
}

delay(time);

chuck.update();
y = chuck.readJoyY();

// Maps the joystick value to the speed value (max speed 130) max posible 179
Serial.println();
speed_val = map(y, 0, 119, 62, 130);


// This is what hapens in case we loose a Blue tooth conecction
if (y > 122) {
speed_val = 60; // 60 means - no speed , motor stoped
speed_val_cur = 60; // 60 means - no speed , motor stoped
speed_val_hold = 60;
}
// This is whats hapens then we again have BT signal, it just restarts everything
if (y == 124) setup();

if (y <= 0) {
speed_val_cur = 60;
speed_val = 60;

}


if (speed_val_cur < speed_val) {

speed_val_cur = speed_val_cur + 1;



}
else speed_val_cur = speed_val;

if ((speed_val_hold > 60) && (y > 0) ) speed_val_hold++; // If hold button is pressed and joistic moved up - increase speed
if ((speed_val_hold > 60) && (y < 0) ) speed_val_hold--; // If hold button is pressed and joistic moved down - decrease speed

if (speed_val_hold > 60) speed_val_cur = speed_val_hold;



myservo.write(speed_val_cur); // Here we control ESC


//----- Printing to screen to see results ---------
Serial.print("Joy = ");
Serial.print(y);
Serial.print(" ");
Serial.print("Speed = ");
Serial.print(speed_val_cur);


}
 
//Wii.h library


/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.

This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2 requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").

Contact information
-------------------

Kristian Lauszus, TKJ Electronics
Web : http://www.tkjelectronics.com
e-mail : kristianl@tkjelectronics.com

IR camera support added by Allan Glover (adglover9.81@gmail.com) and Kristian Lauszus
*/

#ifndef _wii_h_
#define _wii_h_

#include "BTD.h"
#include "controllerEnums.h"

/* Wii event flags */
#define WII_FLAG_MOTION_PLUS_CONNECTED 0x01
#define WII_FLAG_NUNCHUCK_CONNECTED 0x02

#define wii_check_flag(flag) (wii_event_flag & (flag))
#define wii_set_flag(flag) (wii_event_flag |= (flag))
#define wii_clear_flag(flag) (wii_event_flag &= ~(flag))

/** Enum used to read the joystick on the Nunchuck. */
enum HatEnum {
/** Read the x-axis on the Nunchuck joystick. */
HatX = 0,
/** Read the y-axis on the Nunchuck joystick. */
HatY = 1,
};

/**
* This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension.
*
* It also support the Wii U Pro Controller.
*/
class WII : public BluetoothService {
public:
/**
* Constructor for the WII class.
* @param p Pointer to BTD class instance.
* @param pair Set this to true in order to pair with the Wiimote. If the argument is omitted then it won't pair with it.
* One can use ::pAIR to set it to true.
*/
WII(BTD *p, bool pair = false);

/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run part of the state machine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/

/** @name Wii Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
* @param b ::ButtonEnum to read.
* @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
*/
bool getButtonPress(ButtonEnum b);
bool getButtonClick(ButtonEnum b);
/**@}*/

/** @name Wii Controller functions */

/** Call this to start the paring sequence with a controller */
void pair(void) {
if(pBtd)
pBtd->pairWithWiimote();
};
/**
* Used to read the joystick of the Nunchuck.
* @param a Either ::HatX or ::HatY.
* @return Return the analog value in the range from approximately 25-230.
*/
uint8_t getAnalogHat(HatEnum a);
/**
* Used to read the joystick of the Wii U Pro Controller.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Return the analog value in the range from approximately 800-3200.
*/
uint16_t getAnalogHat(AnalogHatEnum a);

/**
* Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Pitch in the range from 0-360.
*/
double getPitch() {
if(motionPlusConnected)
return compPitch;
return getWiimotePitch();
};

/**
* Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Roll in the range from 0-360.
*/
double getRoll() {
if(motionPlusConnected)
return compRoll;
return getWiimoteRoll();
};

/**
* This is the yaw calculated by the gyro.
*
* <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected.
* @return The angle calculated using the gyro.
*/
double getYaw() {
return gyroYaw;
};

/** Used to set all LEDs and rumble off. */
void setAllOff();
/** Turn off rumble. */
void setRumbleOff();
/** Turn on rumble. */
void setRumbleOn();
/** Toggle rumble. */
void setRumbleToggle();

/**
* Set LED value without using the ::LEDEnum.
* @param value See: ::LEDEnum.
*/
void setLedRaw(uint8_t value);

/** Turn all LEDs off. */
void setLedOff() {
setLedRaw(0);
};
/**
* Turn the specific ::LEDEnum off.
* @param a The ::LEDEnum to turn off.
*/
void setLedOff(LEDEnum a);
/**
* Turn the specific ::LEDEnum on.
* @param a The ::LEDEnum to turn on.
*/
void setLedOn(LEDEnum a);
/**
* Toggle the specific ::LEDEnum.
* @param a The ::LEDEnum to toggle.
*/
void setLedToggle(LEDEnum a);
/**
* This will set the LEDs, so the user can see which connections are active.
*
* The first ::LEDEnum indicate that the Wiimote is connected,
* the second ::LEDEnum indicate indicate that a Motion Plus is also connected
* the third ::LEDEnum will indicate that a Nunchuck controller is also connected.
*/
void setLedStatus();

/**
* Return the battery level of the Wiimote.
* @return The battery level in the range 0-255.
*/
uint8_t getBatteryLevel();

/**
* Return the Wiimote state.
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
*/
uint8_t getWiiState() {
return wiiState;
};

/**
* Used to call your own function when the controller is successfully initialized.
* @param funcOnInit Function to call.
*/
void attachOnInit(void (*funcOnInit)(void)) {
pFuncOnInit = funcOnInit;
};
/**@}*/

/**@{*/
/** Variable used to indicate if a Wiimote is connected. */
bool wiimoteConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool nunchuckConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool motionPlusConnected;
/** Variable used to indicate if a Wii U Pro controller is connected. */
bool wiiUProControllerConnected;
/**@}*/

/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */

/**@{*/

/** Pitch and roll calculated from the accelerometer inside the Wiimote. */
double getWiimotePitch() {
return (atan2(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG;
};

double getWiimoteRoll() {
return (atan2(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG;
};
/**@}*/

/**@{*/

/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
double getNunchuckPitch() {
return (atan2(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
};

double getNunchuckRoll() {
return (atan2(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
};
/**@}*/

/**@{*/
/** Accelerometer values used to calculate pitch and roll. */
int16_t accXwiimote, accYwiimote, accZwiimote;
int16_t accXnunchuck, accYnunchuck, accZnunchuck;
/**@}*/

/* Variables for the gyro inside the Motion Plus */
/** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
double gyroPitch;
/** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
double gyroRoll;
/** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
double gyroYaw;

/**@{*/
/** The speed in deg/s from the gyro. */
double pitchGyroSpeed;
double rollGyroSpeed;
double yawGyroSpeed;
/**@}*/

/**@{*/
/** You might need to fine-tune these values. */
uint16_t pitchGyroScale;
uint16_t rollGyroScale;
uint16_t yawGyroScale;
/**@}*/

/**@{*/
/** Raw value read directly from the Motion Plus. */
int16_t gyroYawRaw;
int16_t gyroRollRaw;
int16_t gyroPitchRaw;
/**@}*/

/**@{*/
/** These values are set when the controller is first initialized. */
int16_t gyroYawZero;
int16_t gyroRollZero;
int16_t gyroPitchZero;
/**@}*/

#ifdef WIICAMERA
/** @name Wiimote IR camera functions
* You will have to set ::ENABLE_WII_IR_CAMERA in settings.h to 1 in order use the IR camera.
*/
/** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
void IRinitialize();

/**
* IR object 1 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx1() {
return IR_object_x1;
};

/**
* IR object 1 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy1() {
return IR_object_y1;
};

/**
* IR object 1 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs1() {
return IR_object_s1;
};

/**
* IR object 2 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx2() {
return IR_object_x2;
};

/**
* IR object 2 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy2() {
return IR_object_y2;
};

/**
* IR object 2 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs2() {
return IR_object_s2;
};

/**
* IR object 3 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx3() {
return IR_object_x3;
};

/**
* IR object 3 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy3() {
return IR_object_y3;
};

/**
* IR object 3 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs3() {
return IR_object_s3;
};

/**
* IR object 4 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx4() {
return IR_object_x4;
};

/**
* IR object 4 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy4() {
return IR_object_y4;
};

/**
* IR object 4 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs4() {
return IR_object_s4;
};

/**
* Use this to check if the camera is enabled or not.
* If not call WII#IRinitialize to initialize the IR camera.
* @return True if it's enabled, false if not.
*/
bool isIRCameraEnabled() {
return (wiiState & 0x08);
};
/**@}*/
#endif

private:
BTD *pBtd; // Pointer to BTD instance

/**
* Called when the controller is successfully initialized.
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
* This is useful for instance if you want to set the LEDs in a specific way.
*/
void onInit();
void (*pFuncOnInit)(void); // Pointer to function called in onInit()

void L2CAP_task(); // L2CAP state machine

/* Variables filled from HCI event management */
uint16_t hci_handle;
bool activeConnection; // Used to indicate if it's already has established a connection

/* Variables used by high level L2CAP task */
uint8_t l2cap_state;
uint32_t l2cap_event_flag; // L2CAP flags of received Bluetooth events
uint8_t wii_event_flag; // Used for Wii flags

uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
uint16_t hatValues[4];

uint8_t HIDBuffer[3]; // Used to store HID commands

uint16_t stateCounter;
bool unknownExtensionConnected;
bool extensionConnected;
bool checkExtension; // Set to false when getBatteryLevel() is called otherwise if should be true
bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it

/* L2CAP Channels */
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
uint8_t control_dcid[2]; // 0x0060
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
uint8_t interrupt_dcid[2]; // 0x0061
uint8_t identifier; // Identifier for connection

/* HID Commands */
void HID_Command(uint8_t* data, uint8_t nbytes);
void setReportMode(bool continuous, uint8_t mode);

void writeData(uint32_t offset, uint8_t size, uint8_t* data);
void initExtension1();
void initExtension2();

void statusRequest(); // Used to update the Wiimote state and battery level

void readData(uint32_t offset, uint16_t size, bool EEPROM);
void readExtensionType();
void readCalData();

void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
void initMotionPlus();
void activateMotionPlus();

double compPitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double compRoll; // Fusioned angle using a complimentary filter if the Motion Plus is connected

bool activateNunchuck;
bool motionValuesReset; // This bool is true when the gyro values has been reset
unsigned long timer;

uint8_t wiiState; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
uint8_t batteryLevel;

#ifdef WIICAMERA
/* Private function and variables for the readings from the IR Camera */
void enableIRCamera1(); // Sets bit 2 of output report 13
void enableIRCamera2(); // Sets bit 2 of output report 1A
void writeSensitivityBlock1();
void writeSensitivityBlock2();
void write0x08Value();
void setWiiModeNumber(uint8_t mode_number);

uint16_t IR_object_x1; // IR x position 10 bits
uint16_t IR_object_y1; // IR y position 10 bits
uint8_t IR_object_s1; // IR size value
uint16_t IR_object_x2;
uint16_t IR_object_y2;
uint8_t IR_object_s2;
uint16_t IR_object_x3; // IR x position 10 bits
uint16_t IR_object_y3; // IR y position 10 bits
uint8_t IR_object_s3; // IR size value
uint16_t IR_object_x4;
uint16_t IR_object_y4;
uint8_t IR_object_s4;
#endif
};
#endif
 
torqueboards said:
What pieces modules do you need as well for it? Do you have any links that helped you?

http://www.instructables.com/id/Wii-Nunchuck-as-general-purpose-controller-via-Ard/step4/Connections-between-Nunchuck-and-Arduino/

With the Bluetooth Version you wire up the receiver as if it was the cable end of a Wired controller.

Hope this helps :)
 
BLDC-ADDICT said:
Heya Murfix, wow your board is a monster. What sort of rum times have you been getting? Defiantly would be intresting to compare max Times and speeds. Id imagine your board might be a bit more hungry than mine though.. :)
I haven't tested the full range/run time yet. Longest trip I did was about 1 hour and I did about 8km. That was on a 7s lipo system (so not the full 17.4Ah), through forests and while starting/stopping all the time so that's not really comparable information. Anyways, I still had 3.75V on the cells afterwards.

Max speed: same thing, I got to 36km/h on a 7s system with cells charged at 3.7V and power limit in the alien ESC @75%. I don't know if I'll ever know the max speed, since my max was at 39km/h downhill and I don't think I'll dare go much faster.

I'll generate some more useful information in the coming weeks ;)
 
torqueboards said:
Awesome. What arduino board did you use?

I tested on my uno with a esc motor and nunchuck, But im going to finish it on a nano V3 just waiting on some header sockets. I don't want to solder the arduino straight to the circuit board. I've made that mistake before..
 
voodoojar said:
So you've tested that sketch and it works? Where is the wiiChuck library and why doesnt your sketch include the wii library? Did you just rename it it looks like the same library I'm using.



Heya voodoojar.

It most certainly works for me I've tested it with a motor and esc off my quadcopter.

The library is up in my earlier post called wii.h just copy it to a text file and rename the extention to .h and put in your ardunio library and it should all work :) good luck.
 
it might work for you but you're missing libraries in your post that you probably have in your library folder. You need more than the wii.h to make this work so the post is a bit misleading. I did a how to and posted all the files zipped as well as how to wire it up -- http://endless-sphere.com/forums/viewtopic.php?f=35&t=57316
 
voodoojar said:
it might work for you but you're missing libraries in your post that you probably have in your library folder. You need more than the wii.h to make this work so the post is a bit misleading. I did a how to and posted all the files zipped as well as how to wire it up -- http://endless-sphere.com/forums/viewtopic.php?f=35&t=57316


I had a Look over you code / libraries and there is more in your example. I've tested my code and all works exactly the same. For what I can tell the extra libraries must be for the gyroscope / Accelerometerfunctions which arent used. I would suggest that other people use your code as it is complete.
 
Progress :)

I got busy this weekend with my jigsaw, some files and my Soldering iron...

Just need to find someone to Tig weld the mount now.

Mount.jpgBoard.jpgBelt.jpgBack.jpgNano.jpg
 
I finally Got My Mount Welded Up.


Completed Mount.jpg

This thing is amazing! I strapped everything to the board for a quick test run.

Haven't pushed it to it's limits yet. the motor didn't get hot after a 20min run.

Hoping to Mount everything up properly tomorrow.

Stay tuned I'll do some range and speed tests once Iv'e completed the build.
 
Nearly Complete.

Iv'e mounted the battery and esc with some alumimum strapping and self tapping screws.
Just need to make a cover for the electronics.

13935747310160.jpg

13935747469671.jpg

13935747548812.jpg
 
I took it out for a spin and rode for and 1:30 and did 14.90kms. So much fun!! I hit a top speeds of 32kmph when doing sprints and the area I was riding wasn't completely flat. I'm surprised that I was dead on with my calculations. I was unsure how much more battery capacity was remaining so I put it on charge. and it only charged up with 79800mA. I had only used half of the 16000mAH pack so based on these numbers should be able to ride for 3 hours straight with a possible distance around 30 Kilometers. That's madness! The gearing works well. The motor does lose sync from a standing start but only briefly. I always kick off anyway as it feels more natural when accelerating. No heat issues with the motor or ESC. Just need to wire up my wireless nunchuck and install a watt meter, and a cover housing all the electronics :) .

more range testing to follow.

 
Back
Top