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);
}

@tymkrs MorePi Me v1 Pi shift register board

[EDIT] This product is now available on Tindie.

Normal if I’m doing a scratch ‘n sniff on a product I bought it myself because it was something I was interested in adding to a project. Truth be told I got this one for free; I won this board off a contest on twitter. So I don’t have any projects this thing is running on or slated for but I can tell if I need something with a bunch of IO, like perhaps a display this will be the board I use. I have a project list and nothing really fits, but that future project list is always growing and shrinking. If you’re curious I have 38 projects on the list in progress or to-be-started ๐Ÿ˜€ I have a spreadsheet to manage them all on google drive or I’m sure I’d forget half of them. Sorry, I know blah blah… back to what you’re here for…

 

The MorePi Me
The MorePi Me

I unpacked the board and soldered it all together. Not a lot to say about it because it’s just a board, four DIP sockets/74HC595’s a couple connectors and 3 resistors. I like that they included sockets; I would have added them myself but sockets is a must on hobbyist boards!

whixr also send me some test code … happy day.

So I hooked this up and dropped code into it last week.. I left it to burn in all week.. and checked it out today; no problems. I put the Pi on bench and hooked up my logic analyzer … works as advertised. Look at the screenshot of the output for how whixr code works. I’ll also include a copy.

I don’t know when they plan on releasing this product but I’m sure it’ll be on their Tindie store page sooner than later. I also know that tymkrs wouldn’t mind donations for their educational work

I could only find one insignificant thing I didn’t like; there is a little ringing on the output of the 74HC595’s.. I did my due-diligence to ensure this wasn’t a false measurement. No biggie, a little load killed the ringing…

I say kudos to the tymkrs for this great product!

 

The output of whixr's sample code on the MorePi Me v1
The output of whixr’s sample code on the MorePi Me v1

the code!



# MorePi Me v1 Demo by @tymkrs

def update():
for index in range(0, 32):
if state[32 - index]:
GPIO.output(DataPin, GPIO.HIGH)
else:
GPIO.output(DataPin, GPIO.LOW)
GPIO.output(ClockPin, GPIO.HIGH)
GPIO.output(ClockPin, GPIO.LOW)
GPIO.output(LatchPin, GPIO.HIGH)
GPIO.output(LatchPin, GPIO.LOW)

def clear():
for index in range(0, 32):
state[index] = False

state = [False for index in range(33)]

LatchPin = 11
ClockPin = 13
DataPin = 15

import time
import RPi.GPIO as GPIO

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BOARD)

GPIO.setup(LatchPin, GPIO.OUT) #latch
GPIO.setup(ClockPin, GPIO.OUT) #clock
GPIO.setup(DataPin, GPIO.OUT) #data

while True:
for n in range(0, 8):
clear()
state[n + 1] = True
update()
time.sleep(.03)
for n in range(0, 8):
clear()
state[8 - n] = True
update()
time.sleep(.03)

@tymkrs MorePi Me+Chip Quik TEC and More..

This weekend was a big old waste. I was at the Seattle Mini Maker Faire on Saturday morning.. ran into some of my cousins. It was a fun time.. then Saturday night I had to work from 7:30P to 10A Sunday morning.. that messed up my whole schedule… why? Because I had to change out some old critical controls… this DSC8500 had to be retired… and yes, we are going to Office-Space-it (see note on my demo tape).

weekend DSC project

So what did I get done? I received my @tymkrs MorePi Me! I don’t think they sell this yet but when they do I’ll drop a link. It’s a Pi expansion board… I set it up and dropped code into the Pi.. it’s been running for a few days burn in time on the Pi.. I’ll check it out later this week and give you the review it deserves. (assuming it doesn’t catch on fire between now and then ๐Ÿ˜‰ thanks whixr & Atidy!

the @tymkrs MorePi Me v1
the @tymkrs MorePi Me v1

What else? well amazingly enough I also started working on my Chip Quik bench frig!ย My wife complains about my Chip Quik in the frig so I want something that can sit in the workshop to keep the Chip Quik in the 40-50 deg F area.. It’s a little box that I insulated with some foil bubble wrap insulation and thin foam. I got the box at a hobby store when my wife was shopping for some yarn. The heatsink is just bench stock and I used a 3A TEC… it doesn’t work well. I get about 15 deg cooler than ambient. It’s not enough so back to the drawing board. I ordered a bigger TEC… bigger heat sinks and well maybe a different box if I have to.

… more coming on this when I get the parts… but here are some photos of my fail.

Chip Quik Thermo-electric cooler

Chip Quik Thermo-electric cooler
Chip Quik Thermo-electric cooler

Chip Quik Thermo-electric cooler 2

 

A review of a handful of PIC development boards

I don’t know what possessed me to make this video but I decided to go through some of the PIC microcontroller boards I have. I was inspired by my recent purchase of half a dozen of the new TAUTIC 18F26K22 development boards. This was money well spent. I think between this and the 20 pin board I’ll be pretty heartbroken if he stops making the boards.

You can buy many of the boards I reviewed on tindie or microcontrollershop. I didn’t mention that the 20 pin dev board TAUTIC has comes with a 16F1509, I have been dropping 18F14K22 into the board, and I also probably should have mentioned I used to use the ICD2 with the big old dev boards.. I don’t want anyone thinking their PICkit 3 will just plug-in read to go.. you’ll be making or buying a harness of some sort.

I feel like I’ve leaned on video a little too much lately. I’m looking for feedback on this: Love, hate, indifferent?

As a reminder: none of this product came to me for free or even at a reduced price that any one else couldn’t have gotten besides the PIC Clicker which I won randomly online two months ago.

The Hackers Bench Tone Sequencer

@JohnS_AZ shared his beautiful schematic of a tone sequencer [PDF] he designed with me a few weeks ago. I think he designed it for the @tymkrs ? I watched the video and it looked like a fun project, I wasn’t wrong!

John’s webpage is at : http://hackersbench.com/

I was shooting for sticking this project into an Altoids tin .. I had low expectations which is good because I’m about 1 cm t0 tall on the trimmers. If I found some lower profile parts and removed my DIP sockets I could pull this off. I’m not that motivated to take care of it but if you want to try you know what to do ๐Ÿ˜‰ I used the Adafruit Altoids tin PCB… I purchased a couple of these a while back; they’re good stuff. The oscillator is up on the top board and then ‘LS90, 4051, VCO and the audio amp are below. I am particularly impressed with John’s use of the Pin 5 input on the LM555 to use it as a VCO; Iย haven’t seen this done much, usually you’re sticking a cap to ground on this input or letting it float (gasp!). I just have to add some stand-offs and a couple connectors and this project is wrapped up.
My version of his circuit:

Yep, just a little to "thick" to fit in the can... oh well. Stand off's will work :)
Yep, just a little to “thick” to fit in the can… oh well. Stand off’s will work ๐Ÿ™‚

 

John made two great videos of this project:

 

Free Stickers!

They just came in, while supplies last..get a free sticker!

sticker_pnw

1. You have to have a twitter, Facebook, or blog/vlog that appears you have some interest in electronics, being a “maker”, or computer programming and your shipping address is in North America.

2. #tymkrs (irc) skip to the head of the line as long as they don’t wait more than a few days

3. E-mail or tweet @chasxmd your @ twitter_name or blog link.. and your shipping address to my e-mail address chas at this domain.. alternately see the full e-mail address on the right hand of this page under “Contact/Social”

Enjoy!