Category Archives: Motors

18F14K22 Accelerometer Analog to Digital Converter C Electronics Microcontrollers Motors PIC Steppers

18F14K22 Self-Balancing Platform

Well, it’s not finished but this is what I’m working on:

Balancing platform on a breadboard
Balancing platform on a breadboard

Ta-da.. yet another balancing something-or-rather.. except this one isn’t so great at it’s balance. This was a big old fail. I went wrong with steppers… I should have just used DC motors and maybe the next version I will. I used Pololu A4988 stepper motor drivers (A4988-based)  to control my steppers while attempting to use variable speed step resolution control. This worked okay but really while trying to drop holding current while balanced was a nightmare. Also the current usage was above what I consider useful… either backing the current limiting off to save some power (and your driver) then loosing control or you’re just cooking your motor driver and the current isn’t useful other than for a cute demonstration or a non-battery powered application.

I’m not dropping code, you can request it directly if you want it but it’s nothing magical. It has my own hacked up version of a PID loop. I didn’t use derivative. I think far too many cycles are wasted on it when PI will probably work for you. I haven’t fine tuned it because I’m unhappy with my results.

I was a little bummed out on past-Chas’ selection of an MMA7361 accelerometer;  I had gotten it from Sparkfun who-knows-how-long-ago. The link leads to the retired product. It’s just plain voltage output per axis. I must have still been shying away from I2C at the point? The board shown below:

Accelerometer break-out board
Accelerometer break-out board

For a micro I used a PIC 18F14K22 on the TAUTIC dev board with some AtomSoft breadboard goodies for troubleshooting, power and the serial interface (Breadboard Buddy).  <– that link will probably die soon. Tindie updates a lot and products are replaced with newer versions.. if you sniff around you’ll find it.

I’ll move along to another project now, perhaps order some parts and revisit this one again. If you run along this and you’ve done this with steppers I’d be interested in knowing how it worked out for you.

Electronics Motors VFD

Electric Scooter & new VFD update

I finally got my brother over to do some welding for me. The electric scooter is only a couple of nuts and bolts away from a complete frame. I have the core electronics finished .. so maybe this weekend I’ll be able to take it for my first test drive… I can tell I’ll need to extend my handle bar.. but that can wait for another day.

 

Work continues on the electric scooter... I got my brother to weld for me because he is better at it (but don't tell him that).
Work continues on the electric scooter… I got my brother to weld for me because he is better at it (but don’t tell him that).

The frame I build out of over priced metal stock from Home Depot.. (most of it is under the vehicle in the above photo) .. the front end is from a kid’s bike.. The motor and drive have already checked out.. don’t know what kind of speed I’ll get out of it, I doubt over 15mph or so.

 

I also scored another VFD today. It’s another Rockwell Automation VTAC9 but this one is much smaller and very bench-friendly. I have about 280VDC on the bus and I got it power up into precharge (kicks on at about 250VDC). I have another 90VDC in batteries and I thought another case (so 180V.).. I hope that’s enough to get me out of precharge or I’ll have to build a high voltage DC power supply. meh. I couldn’t finish my testing because my brother has shown up for the welding.

I scored another VFD. This one has a crap AC input but driving the DC bus direct works just fine as it has on all Rockwell Automation drives I've tried.
I scored another VFD. This one has a crap AC input but driving the DC bus direct works just fine as it has on all Rockwell Automation drives I’ve tried.

It’s front end (AC input) is dead but it looks like I can chop some jumpers to disconnect it. Though I had it hooked up when I ran up the DC input. I was running about 50 mA with the fans and UI running.  If you have one with no wires attached .. mine starts up with Terminal 1, 3, 4, 5, 6 and 7 jumpered and Terminal 8 and 9 jumpered. This base doesn’t have a “DC -” terminal like the large drive has.. so you can either tie it to the big DC bus jumpers off the capacitor board or there is a DC+ terminal and the DC- is a little single test point pin to the right of the terminals. If I have enough VDC in this house maybe I’ll be spinning a motor by the end of the week. I reprogrammed the drive already… it’s pretty self-explanatory.

 

Update: 402 VDC… still in pre-charge. I have a 150VDC power supply I’ll did out. I’m hoping 550V will do the trick.. 600VDC is nominal.

Electronics MOSFETs Motors

Project: MOSFET Driver v1 (Product?)

Today I received the first of a couple batches of PCBs from OSH Park. This set is a simple MOSFET w/ driver. The MOSFET can be logic level driven and all my testing was done at 5VDC however the driver had a wide voltage range so running this at 9V or 12V should present no issues (16V max! VGS). I do have a few minor adjustments I want to add (silk screen additions and adjustments). I built this board as an electric scooter motor drive and I tested it with the motor I was interested in using and thankfully all testing worked out well including loading my power supply at max load for over an hour straight 🙂 This board can be used for an assortment of load control applications.

MOSFET Driver v1

The build was easy enough, next board I think I’ll just skip the chipquik and stick to straight soldering iron… and I think I also “figured out” the trick to solder the heat sink without making too much of a mess.

MOSFET Driver v1

I tested the load for 60 minutes at 66% duty cycle and 1.5KHz PWM with total load at 140watts (45Volts 3.1 Amps)..  the heat sink temperature on the MOSFET raised from ambient (78 deg F) to 90.7 deg F (32.3 deg C) steady for an hour.  The MOSFET is rated for 55V (max) at 30 amps but the board isn’t designed to handle that load. I used 50mil power traces which is roughly 3 amp handling according to the google machine; 5A if you don’t mind a 40 deg C rise (though there is a fan) so I’ll call this a 140W MOSFET board (47×3). I personally feel I could squeeze more current out of this in short bursts but I would need to do more testing.. and I can’t promise anything along those lines. The PWM signal was generated and directly fed from a PIC 18F16K22 microcontroller running @ 5V. You’re NOT going to be able to drive this at 3.3V.

 

Fresh off the soldering iron!
Fresh off the soldering iron!
Driving an electric scooter motor. Note the diode for flyback near the bottom of the photo just hanging out. The flyback is a must in this application.
Driving an electric scooter motor. Note the diode for flyback near the bottom of the photo just hanging out. The flyback diode is a must in this application.
MOSFET PWM signal vs VDSS
MOSFET PWM signal vs VDSS

 

I will likely stick a 75VDSS MOSFET in the next revision…

.. I’m considering selling these on Tindie. If you’re interested in getting on of these “BETA” boards at cost let me know before they’re gone.

C Electronics Microcontrollers MOSFETs Motors PIC Programming

PIC 18F26K22 PWM+A/D with MOSFET, the start of an eScooter?

I’m considering building an electric scooter; considering it probably putting it lightly.. I have almost everything I need for it.  Interested? Why type so much when you can just watch my proof of concept!

If you’re following along and want to use the same hardware (warning totally untested… ):
Controller found on the TAUTC Tindie Store
Search on eBay for “24VDC scooter motor” ..
..and pick up a MOSFET that’ll pull off a couple 20 amps and saturates at or below 5VDC.
…what am I talking about? Try google or read this.

To the important stuff, the code:


/* 
 * File:   main.c
 * Author: Charles M Douvier
 * Contact at: http://iradan.com
 *
 * Created on March 27, 2014, 4:12 PM
 *
 * Target Device:
 * 18F26K22 on TAUTIC Dev Board
 *
 * Project:
 * Electric Scooter
 *.. a real hack job, comment, delete garbage, etc.
 *
 * Version:
 * 0.1
 *
 */
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 4000000 //4Mhz FRC internal osc
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#endif

#include 
#include 
#include 
#include 

//config bits
#pragma config FOSC=INTIO67, WDTEN=OFF, PWRTEN=OFF, CP0=OFF, CP1=OFF, BOREN=ON
#pragma config STVREN=ON, LVP=OFF, HFOFST=OFF, IESO=OFF, FCMEN=OFF

//WRT=OFF, FOSC=INTOSC, MCLRE=ON

#define _XTAL_FREQ 4000000 //defined for delay

//clean up on isle 2.. 

    int     an9_value;          //value for a/d
    char    buf[10];            //buff for iota
    long int    fvar;           //long for format math
    long int    tens;           //left of decm
    long int    decm;           //decimal places
    int     tempi;              //to add leadign zeros..
    int     vtxdata;             //volts int for TX
    int     itxdata;

    volatile unsigned int uart_data;    // use 'volatile' qualifer as this is changed in ISR
/*
 * 
 */
void interrupt ISR() {

    if (PIR1bits.RCIF)          // see if interrupt caused by incoming data
    {
        uart_data = RCREG;     // read the incoming data
        PIR1bits.RCIF = 0;      // clear interrupt flag
    }

}

void init_io(void) {
    TRISAbits.TRISA0 = 0; // output
    TRISAbits.TRISA1 = 0; // output
    TRISAbits.TRISA2 = 0; // output
    TRISAbits.TRISA3 = 0; // output
    TRISAbits.TRISA4 = 0; // output
    TRISAbits.TRISA5 = 0; // output
    TRISAbits.TRISA6 = 0; // output
    TRISAbits.TRISA7 = 0; // output

    ANSELA = 0x00; // all port A pins are digital I/O

    TRISBbits.TRISB3 = 1; // AN9
    TRISBbits.TRISB4 = 0; // RB4 = nc
    TRISBbits.TRISB5 = 1; // RB5 = nc
    TRISBbits.TRISB6 = 0; // RB6 = nc
    TRISBbits.TRISB7 = 0; // RB7 = nc

    ANSELB = 0b00001000;     //RB3, AN9

    TRISCbits.TRISC0 = 0; // output
    TRISCbits.TRISC1 = 0; // output
    TRISCbits.TRISC2 = 0; // output
    TRISCbits.TRISC3 = 0; // output
    TRISCbits.TRISC4 = 0; // output
    TRISCbits.TRISC5 = 0; // output
    TRISCbits.TRISC6 = 1; // input
    TRISCbits.TRISC7 = 1; // input
    ANSELC = 0x00; // all port C pins are digital I/O
}

void pwm_init(){

//         PSTR1CONbits.STR1A
//hackhackhackhack... TODO

//    CCPR1L = 0x120;
    CCPR1Lbits.CCPR1L = 0xFE;
    PR2 = 0xFE;
    CCPTMRS0bits.C1TSEL = 0;     //CCP TMR2 Selection
    CCP1CONbits.P1M = 0x00;
    CCP1CONbits.DC1B = 0x00;
    PWM1CONbits.P1RSEN = 0;
    T2CONbits.T2CKPS = 1;  //1:2 Prescale
    T2CONbits.TMR2ON = 1;  //timer 2 go

    CCP1CON = 0x0C;       //PWM (CCP)1 ON

}

void uart_xmit(unsigned int mydata_byte) {

    while(!TXSTA1bits.TRMT);    // make sure buffer full bit is high before transmitting
    TXREG = mydata_byte;       // transmit data
}

void serial_init(void)
{
    //9600 8N1
    // calculate values of SPBRGL and SPBRGH based on the desired baud rate
    //
    // For 8 bit Async mode with BRGH=0: Desired Baud rate = Fosc/64([SPBRGH:SPBRGL]+1)
    // For 8 bit Async mode with BRGH=1: Desired Baud rate = Fosc/16([SPBRGH:SPBRGL]+1)

    TXSTA1bits.BRGH=1;       // select low speed Baud Rate (see baud rate calcs below)
    TXSTA1bits.TX9=0;        // select 8 data bits
    TXSTA1bits.TXEN = 1;     // enable transmit

    RCSTA1bits.SPEN=1;       // serial port is enabled
    RCSTA1bits.RX9=0;        // select 8 data bits
    RCSTA1bits.CREN=1;       // receive enabled

    SPBRG1=25;  // here is calculated value of SPBRGH and SPBRGL
    SPBRGH1=0;

    PIR1bits.RCIF=0;        // make sure receive interrupt flag is clear
    PIE1bits.RCIE=1;        // enable UART Receive interrupt
    INTCONbits.PEIE = 1;    // Enable peripheral interrupt
    INTCONbits.GIE = 1;     // enable global interrupt

         __delay_ms(50);        // give time for voltage levels on board to settle

    uart_xmit('R');         // transmit some data "restart" notification
}

int main(void) {

    init_io();
    serial_init();
    LATCbits.LATC2 = 0;
    pwm_init();

    // set up oscillator control register, using internal OSC at 4MHz.
    OSCCONbits.IRCF = 0x05; //set OSCCON IRCF bits to select OSC frequency 4MHz
    OSCCONbits.SCS = 0x02; //set the SCS bits to select internal oscillator block

    ADCON0 = 0b00100101;                            //select AN9 and enable
    ADCON1 = 0b00000000;                  //speed Vref=AVdd, VssRef=AVss
    ADCON2 = 0b00111011;                //ledft justified, 20RAD, FRC
    __delay_us(5);

//loop

    while (1) {

        PORTAbits.RA0 = 1; //blinky i'm alive.
        __delay_ms(140);
        PORTAbits.RA0 = 0;
        __delay_ms(140);

            GO = 1;
    while (GO) continue;              //wait for conversion
    an9_value = ADRESH;               //AN9 value

        fvar = an9_value; //this is hacked off another project but works
        fvar = fvar * 10749;        //calibration
        fvar = fvar / 256;
        tens = fvar / 100;
        //tens = tens % 10;
        decm = fvar % 100;
        vtxdata = fvar / 43; //because I'm lazy... I'll change this later.
        uart_xmit(vtxdata);
        CCPR1Lbits.CCPR1L = vtxdata;

    }
    return (EXIT_SUCCESS);
}