• More Code

    Joe08/24/2016 at 21:12 0 comments

    I 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...
    Read more »

  • Code

    Joe04/28/2016 at 04:43 0 comments

    I 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:

    1. Failsafe mechanisms (Connectivity loss, rider falls off, user indicates an error, low voltage)
    2. Smooth acceleration/deceleration ability
    3. Error state to enter and stop the board in case of one of the failsafes triggering
    4. LED control

    Now for some pseudocode to accomplish these goals:


    Initialization of variables

    Variables 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... Read more »

  • Parts are here!

    Joe04/28/2016 at 04:22 0 comments

    All 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

    Joe04/25/2016 at 15:01 0 comments

    I 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.