-
More Code
08/24/2016 at 21:12 • 0 commentsI have taken the pseudocode and created version 1.0 of the code. Since last time, I have decided to take a slightly different path and further complicate the electronics and software side of things. Since I want the connection for commands from my phone to be constantly polled, I was struggling with combining all parts of the code into one file to run on one board. As such, I have moved to a two-board idea where a 5V 16Mhz Adafruit Trinket controls the motor, reads sensor data, and has most of the features the pseudocode mentioned, and the 3.3V Adafruit Feather Bluefruit M0 handles polling for commands and converting these into meaningful signals for the Trinket to read.
In the future, it may be possible to combine all parts of the code into the Feather, but for now this is the approach I am taking. The Trinket will have 3 analog inputs, 2 for the force sensors and 1 for the speed command from the Feather. It will have one digital input from the Feather as a killswitch pin to cause the Trinket to initiate the deceleration loop if it goes high. It will have one digital output as the PWM output to the ESC.
The Feather will have an analog output to the Trinket for speed control, and an analog input from the ESC for the current speed (just realized this may be a 5V signal while the Feather is 3.3V logic). It will be commanded by the Bluefruit companion app with 3 commands; 1) increase speed 2) decrease speed and 3) stop the longboard.
My current concerns involve the difference in logic voltage levels between the two boards, the increasingly complex nature of the whole electronics side of things, and controlling the ESC with just a simple PWM.
/********************************************* * Note the numbering of analog pins: Pin 2 is Analog 1, Pin 3 is Analog 3, Pin 4 is Analog 2. * For the Uno, the terms A1, A2, and A3 are mapped for you. For ATtiny85's, they are not. * So for the pinMode calls, use the Pin number (stenciled on Trinket), for analogRead, use the analog number. * */ #include <Servo.h> int desiredSpeedFrmCtrl; //analog input connected to analog pin #2 int force1; //first force sensor (analog) connected to analog input pin #4 int force2; //second force sensor (analog) connected to analog input pin #3 int forceThres; //threshold for force sensors to cutoff and read an error int forceVal1; int forceVal2; int stopPin = 0; int stopSpeed; //speed variable for the deceleration loop to use Servo ESC; //ESC object to be able to write PWM to void setup() { // put your setup code here, to run once ESC.attach(0); pinMode(2, INPUT); //analog input pinMode(3, INPUT); //analog input pinMode(4, INPUT); //analog input from auxillary board for BLE commands pinMode(0, INPUT); forceThres = 400; //arbitrary threshold until the sensors are calibrated Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly startupLoop(); runLoop(); } void runLoop() { //code for the main running loop of the board forceVal1 = analogRead(2); forceVal2 = analogRead(3); while((forceVal1 > forceThres) || (forceVal2 > forceThres)){ desiredSpeedFrmCtrl = analogRead(1); ESC.write(desiredSpeedFrmCtrl); Serial.print("Speed sent to ESC: "); //for debugging purposes (speed read from feather and sent to ESC) Serial.print(desiredSpeedFrmCtrl); Serial.println(); forceVal1 = analogRead(2); forceVal2 = analogRead(3); if(digitalRead(0) == HIGH){ //if there was a command from the controller to stop the decel loop is called decelerationLoop(); return; //the runLoop breaks becak into the main loop } } } void startupLoop() { //code to determine if the board can startup while (1 > 0){ forceVal1 = analogRead(2); //read the analog value from the first force sensor forceVal2 = analogRead(3); //read the analog value from the second force sensor if((forceVal1 > forceThres) && (forceVal2 > forceThres)){ ESC.write(0); //set speed to 0 return; //exit to main loop } delay(200); } } void decelerationLoop (){ //code to slow the board down if there is an error stopSpeed = desiredSpeedFrmCtrl; while(stopSpeed > 0){ ESC.write(stopSpeed - 200); //arbitrary step size until the ESC is calibrated delay(200); //wait so the deceleration is smooth } }
-
Code
04/28/2016 at 04:43 • 0 commentsI got around to start writing a basic feature list and some pseudocode for the longabord, which will all be written in Arduino running on the Adafruit feather M0 with Bluefruit. I have uploaded the document to the files section but also want to go over the code here.
First off a basic feature list:
- Failsafe mechanisms (Connectivity loss, rider falls off, user indicates an error, low voltage)
- Smooth acceleration/deceleration ability
- Error state to enter and stop the board in case of one of the failsafes triggering
- LED control
Now for some pseudocode to accomplish these goals:
Initialization of variablesVariables for speed/throttle Variables for LED color Declare ESC Servo object Variables for sensors
There will be variables for the speed and throttle, at least two. These two will be the current speed, obtained from the RPM sense wire coming from the ESC, and the desired speed or throttle, coming from commands from the bluetooth connection to the phone app. LEDs will be declared, and the ESC will exist as a Servo object as it needs to be sent PWM for throttle control. There will also be other sensors such as 2 piezoresistive force sensors, and potentially voltage sensors, which would be analog inputs.void setup ()
Attach ESC to correct pin Attach LEDs to correct pins Start Serial for debugging
The ESC Servo object will be attached to a pin as well as the LEDs to their respective pins. The Serial interface will also be started to send information to either the computer or phone if debugging is needed.void loop () (main loop)
Call startup function if all conditions are met Set speed to 0 Call run loop run loop loops within itself, only exits if base/error conditions are met
Here are the first instances of "startup function" and "run loop," which are just names at this point but will be described later. The main loop of the code will basically exist to call other loops, but it is important because if the run loop throws an error, calls the "deceleration loop," and breaks, we want it to run the startup function again to start everything over.run loop
Run forever Read all sensor data Read all throttle/speed data Read throttle command from app, reassign to desired speed variable every loop Calculate difference between current speed and desired speed Write first step above/below current speed (fixed step size) Delay fixed time period (probably 50-200ms) If any bases cases are met (sensors, connection, user command) Call deceleration error loop break (Will break to main loop, which will loop around to startup function)
The run loop is where most of the time will be spent while riding. It is called after the startup function, and loops while everything is "OK," only changing throttle when prompted by the user. It will first read the sensor data from the force sensors, then get the current speed from the RPM sense wire, and also read the current speed command from the app. This "desired speed" should be reassigned to the same variable every time the loop runs to ensure the user can change speed before the board actually gets to that speed. It should then calculate the difference between the current speed and the desired speed, and then move in the correct direction by telling the ESC to run at a speed a fixed step size higher or lower than the current speed. This happens only once per loop so the board can accelerate or decelerate at a comfortable pace, but also continuously check to see if anything has gone wrong. The delay is built in so the loop only runs ideally 5-20 times per second, instead of 1000s of times per second so the board doesn't jump to the desired speed and leave the rider in the dust (The motor can go 0-full speed (albeit, unloaded) in 300us, according to the spec sheet). The run loop then checks the numerous "failsafe" cases, if both force sensors read below a threshold (rider has fallen off), if connection is lost, and if the user wants to board to slow down immediately. If any of these conditions are true, the loop will call the "deceleration loop" and then break out to the main loop.deceleration loop
Called by run loop with 1 arg passed by value, last sent speed While speed > 0 Read last sent speed Calculate difference between current speed and 0 Write first step below current speed (use fixed step size) Store this last sent speed, used by loop for next write to ESC Delay fixed time period (probably 50-200ms) Break to run loop (which will then break to main loop) after speed goes to 0
This is the "error state" loop so to say, as whenever an erroneous or bad condition is met, this function is called and decelerates the board, then breaks out to the main loop, which as you recall, will run the startup function before letting the run loop go again.startup function
While 1 > 0 Check to make sure all base cases are ok and board is ready to go Connection User wants to go ahead (no kill switch flipped basically) Sensors read ok If yes, set speed to 0, cool LED sequence proceeds to run loop If no, continue looping Delay 500ms
Will run forever until conditions to enter the run loop are met. Plan is to run this twice a second but it could probably be a lot quicker.That's it so far, and hopefully I will get to actual code tomorrow.
-
Parts are here!
04/28/2016 at 04:22 • 0 commentsAll the parts I ordered from Adafruit, HobbyKing, and SDP/SI have arrived.
From Adafruit I got:
- 2 voltage sensors with LCD panels
- 5V to 3.3V regulator
- Adafruit Feather M0 Bluefruit
From HobbyKing I got:
- HobbyWing 100A Platinum ESC
- Turnigy AeroDrive SK3 375kV brushless motor
- 2 4000mAh 3S LiPo batteries
- Fireproof LiPo Bag
- LCD ESC programming module
- 1-6S LiPo Charger
And from SDP/SI I got:
- 2 Plastic 24T timing pulleys
- 1 Aluminum 10T timing pulley
- 2 265mm length timing belt
All the parts that end up in the final design will be put in the components section and more detail will be provided about each of them.
I didn't know it but the ESC also gives and RPM sensor lead, which is super useful as I needed a way to check speed in the code. See the next log and the feature list and pseudocode document in the files section.
-
First setback
04/25/2016 at 15:01 • 0 commentsI have encountered the first setback of the project.
I was riding the board I was planning on converting, fell off, it went into the road, and a car ran over it. Trucks and wheels are fine, but a new deck is necessary.