Guys, a while ago Darrel and Steve (and a few others) helped me out with the development of a PWM pic based train controller. However although the prototype worked fine on the breadboard, when I re-designed the board to include the powersupplies (5v and 12v) I got some strange behaviour from the resulting PCB. Sometimes the PWM would stop and the PIC needed resetting, but I put this down to the noise these models cause (RF etc) and I also noted that whilst the slow speed was exceptional, the range of control was very fine, so I went back to the breadboard.
I've breadboarded the schematic attached, but with the 20 Mhz xtal. The code in the PIC is as follows
Code:
'****************************************************************
'* Name : Twin Track Controller.BAS *
'* Author : M. Crabbe *
'* Notice : Copyright (c) 2007 M. Crabbe *
'* : All Rights Reserved *
'* Date : 17/02/2007 *
'* Version : 1.0 *
'* Notes : 16F767 using 20 Mhz xtal *
'* : *
'****************************************************************
@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF
DEFINE OSC 20
ANSEL = %00010111 ' Set which ports are digital and which are analogue
CMCON=7 ' Turm Comparitors off
TRISA=%11111111 ' set PORTA as all input
TRISC=%00000001 ' set PORTC as all output apart from RC0
DEFINE ADC_BITS 8 ' ADCIN resolution (Bits)
DEFINE ADC_CLOCK 2 ' ADC clock source (Fosc/32)
DEFINE ADC_SAMPLEUS 11 ' ADC sampling time (uSec)
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "SPWM_INT.bas" ' Software PWM module
DEFINE SPWM_FREQ 150 ' SPWM Frequency (Hz)
DEFINE SPWM_RES 254 ' SPWM Resolution (0 - 255)
DutyVar VAR byte[4] ' Array used to store ADC [channels]
ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTC, 2, _DutyVar ; and the associated DutyCycle variables
SPWM_PIN PORTC, 3, _DutyVar+1 ; (Additional channels DutyVar+2, +3 etc)
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
Main:
ADCIN 0, DUTYVAR[0] ; if having more channels add ADCIN 2, DUTYVAR[2] etc
ADCIN 1, DUTYVAR[1]
GOTO Main ; program simply loops round reading ADC and sending corresponding PWM out
The result of this code can be seen in the avi (4MB DIVX) http://www.micro-heli.co.uk/scope2.avi which you will see and hear is a good variable square wave. This drives the 2N3904 and darlington pair well and the resulting in fantastic slow speed crawl as can be seen in the avi http://www.micro-heli.co.uk/controller.avi
However, the amount of rotation of the pot is quite small before the loco is up to a medium speed. I've tried changing the pot for 100K, 22K and even 2k, and I've played about with different values for R1, R2 and R3 and it still makes no difference.
So my question... Is there a way to "scale" or range the ADC so that the PWM performs is less proportional, and more log like in action. Ie instead of the pulse being 50% when the pot is 50% travel (and presumably the value is 127 on the ADC) its say 25%, but when the pot is at 75% travel the value is 75% if you follow my drift ? This way it will provide better slow motion control and still give excellenf high speed performance as well.
Also, what would be the best way to protect the PIC from interfearence, placing 0.1uf caps between inputs and gnd or simply take all unsused pins to gnd ?
Bookmarks