Showing posts with label microchip. Show all posts
Showing posts with label microchip. Show all posts

Thursday, June 02, 2011

RS Servo Tester

Progetto per movimentare un servo RC da aeromodelli con un Pic 12F628A (8Pin)

Il progetto è alquanto semplice usare un timer del pic per generare un PWM idoneo a controllare la posizione del servomotore. Il servo alla accensione si posiziona al centro della corsa e con due tasti Destro e Sinistro raggiunge la posizione -120° e +120°.
Alla pressione di ambedue i tasti ritorna alla posizione centrale.
Qualcuno mi ha domandato perchè non usare il PWM del Chip? La spiegazione è semplice i servi RC hanno una temporizzazione alquanto delicata e il PWM Hardware del pic non ha una risoluzione adeguata alla richiesta di posizionamento di precisione dei Servi RC digitali.
Quindi vista la velocità di esecuzione del microcodice dei pic e optando per un generatore di clock interno a 4mhz disponibile nel CHIP ( nessun quarzo esterno ) ho scritto il codice e mi sono messo a provarlo. Confesso che sono partito da una versione in basic scritta per PIC che funzionava alquanto male, della quale nel source OPEN ho mantenuto l'intestazione originale del writer.
Tradotto in "C" e corretto il codice, usando il timer il comparatore gli interrupt e un po di calcoli svolge splendidamente il suo lavoro. Ha una risoluzione di posizionamento dei contatori di 1microsecondo pari a circa 0,07° gradi, con i controllo tasti a 0,3° per step.
Il codice è scritto in MickroC che è free per impieghi con tutti i PIC 12/16/18/24/32 e la loro bella libreria compilando codice fino a 2Kbyte in ROM (download). Consiglio per chi volesse un approccio soft al PIC di adottarlo usando la probe PICKIT2 o 3 della Microchip che trovate presso qualsiasi distributore elettronico a €37,00(circa)
Con questo investimento potete sperimentare una serie di progetti che sono veramente interessanti con il PIC e che pubblico qui sul mio Blog.

Per reneder ancora più intrigante il codice stò elaborandone una versione per controllarlo da I2Bus ( non supportato da PIC12F628) in versione slave 10bit per comandare la posizione di strumenti analogici virtuali in Xplane.

Il codice:

/***************************************************************************
***** *****
***** 50Hz SINGLE SERVO TESTER USING 2 BUTTONS *****
***** 16F628A @ 4MHz INTOSC_NoClkout *****
***** Written By Warren Schroeder on 12.31.08 Mikrobasic 7.2 *****
***** Rewrite By mcmax on 10-05-2011 MikroC *****
***** software tested and run with *****
***** 1 microsecond position accuracy *****
***** Range of 1us to 19,999us *****
***** User can setup Min, Max, & Center Sweep Range as needed *****
***** *****
***** Features 2 Button Control For 3 Main Functions: *****
***** *****
***** Button1 = move to min position by user declared Step Value *****
***** Button2 = move to max position by user declared Step Value *****
***** Button1+Button2 = move to center position *****
***** *****
***** HOLDING a BUTTON WILL AUTO INCREMENT/DECREMENT Till MAX/MIN *****
***** *****
****************************************************************************/

// macro

typedef unsigned char uchar;
typedef unsigned int uint;

#define delay30() Delay_ms(30)
#define SetTMR1(t) { CCPR1L = (uchar)(t & 0x00FF); \
CCPR1H = (uchar)((t & 0xFF00) >> 8 ); }
#define GetTMR1() (int)CCPR1L + ((int)CCPR1H << 8 )
#define ClearTimer1() TMR1L=0; TMR1H=0;

// definition

#define _STEPVAL 5 // in microseconds Step ogni 30ms
#define _MAXPWM 20000 // 20ms (valori in millisecondi)
#define _MINPOS 600 // 0,6ms -90 -+
#define _CENTER 1500 // 1,5ms 0 -+----position servo centrale
#define _MAXPOS 2400 // 2,4ms +90 -+

// global var

unsigned int ServoPos;

//***** I N T E R R U P T ************************************************

void Interrupt( void )
{
if ( CCP1IF_bit == 1) {
if ( GP4_bit == 1 ){ // bit ccp1 bit 5 pin 3
GP4_bit = 0; // turn servo off
SetTMR1( _MAXPWM - ServoPos ); // off time to finish 20ms
}
else {
GP4_bit = 1; // turn servo on
SetTMR1( ServoPos); // on time in microseconds
}
ClearTimer1(); // rimette a 0 il timer1
PIR1.CCP1IF = 0; // clear int flag
}
}

//-------------------------------------------------------------------------

void CCP_Setup( void )
{
T1CON = 0; // no prescale; off; 1us ticks
ClearTimer1(); // clear timer1

ServoPos = _MINPOS; // posizione iniziale

CCP1CON = 0b00001010; // compare-match no ADC start or
// reset timer1 when match
SetTMR1( ServoPos ); // set intitial position

PIR1.CCP1IF = 0; // clear int flag
PIE1.CCP1IE = 1; // enable int
T1CON.TMR1ON = 1; // timer1 run

PEIE_bit = 1; // start periferical int
GIE_bit = 1; // GIE, PEIE enabled
}

/*********************************************************
***** *****
***** Buttons Inputs are Pulled Low on RA0 and RA1 *****
***** *****
*********************************************************/


void KeyCtrl(void)
{
char Temp;

if ((GPIO & 3) != 0x03 ) { // check for active buttons

Delay_Ms(30); // debounce delay
Temp = GPIO & 0x03; // save button value

while ( Temp != 0) { // while a button is active do

if ( Temp == 3) { // both buttons active
ServoPos = _CENTER; // goto center position
}
else {
if ( Temp == 1) { // dec position by stepval
ServoPos = ServoPos - _STEPVAL;
if ( ServoPos < _MINPOS )
ServoPos = _MINPOS;
}
else { // inc position by stepval
ServoPos = ServoPos + _STEPVAL;
if ( ServoPos > _MAXPOS)
ServoPos = _MAXPOS;
}
}
Delay_Ms(30); // button release delay
Temp = GPIO & 3 ; // check again for release
}
} // if not released will inc or dec more
}

/****** M A I N ***********/

void main(void)
{
INTCON = 0; // disable alla interrupt

OSCCON = 0b01100000; // work at 4Mhz of internal
// clock without ext clk
ANSEL = 0x00; // disable analog ad digital I/O
CMCON0 = 0x07; // disable comparator

GPIO = 0x00; // init port setup
TRISIO = 0x03; // bit 0 = 7 Key UP
// bit 1 = 6 Key DW
// pwm su pin 3 al servo motor

CCP_Setup(); // setup value application and timing

while(1) // main loop
KeyCtrl(); // key controll

}

// end source

Lo schema del prototipo

Il PCB

Le foto del prototipo

Buon divertimento.

Monday, December 14, 2009

Piklab e pk2cmd integrare gli strumenti

Nella prededente post "pk2cmd PicKit2 microchip con Linux ubuntu" abbiamo preso in considerazione il PICkit 2 di microchip per programmare una vasta serie di CHIP di MicroChip della serie PIC.

Il tools di piklab integrato con sdcc e con pk2cmd diventa un ottimo strumento per lo sviluppo rapido di applicazioni in linguaggio C e ASM per Pic. Il problema maggiormente sentito è che il rapido sviluppo di prodotti propietari mal si concila con lo sviluppo opensource affidato da un volontariato di sempre meno mani esperte che modificano e seguono il codice sorgente opensource di prodotti specifici. Pare che le case di produzioni abbiano anche poco interesse a pagare chi potrebbe dare piattaforme alternative a sviluppatori di microchip o silicon slide programmabili. Tra queste possiamo fare un lungo elenco di produttori di Chip programmabilie che vendono o sponsorizzano semi free tools di programazione ma solo per piattaforma Windows, senza tener conto che ampliando l'offerta di software anche con licenza proprietaria ma ben supportata e disponibile per il free of download farebbe crescere il mercato di vendita del loro prodotto (silicio) programmabile e dei tools di programmazione e/o debug.

Bando alle polemiche e passiamo al problema della integrazione del comando descritto nel precedente post con l'interfaccia grafica di piklab.

Nel sito di piklab non ho trovato indicazioni su come "custom comand" prendendo variabili dal programma (es: tipo processore, nome file, eccc....) pertanto vi faccio vedere come ho usato delle stringhe per la customizzazione del programma a mio vantaggio per il PICKit 2.

Come vedete dalla seguente schermata le impostazioni interne al piklab per Pickit2 non vedono neppure il probe installato sulla USB ( problemi con ID e revision del SW del probe).




Selezionate la voce "programmatore->configuratore" e selezionate il pannello come segue:





Ora chiudete questo pannello e da comandi posizionate il file dati in modo che sia ricercabile dal pk2cmd. Piklab ignora il vostro path di percorso in .bashrc e qundi con questo comando risolviamo il problema.

ln -s /usr/share/pk2/PK2DeviceFile.dat /usr/local/bin/PK2DeviceFile.dat

questo link fa credere a pk2cmd che il file sia corretamente posizionato quando richiamato da pikLab.

ora provate a programmare il vostro Pic come qui sotto ottendo il success del comando.



Spero di essere stato utile alla sistemazione dell'itegrazione tra piklab e pk2cmd di microchip. La ricerca continua e spero di rendere autonomo il sistema di stringhe per allinearlo automaticamente al nome del file *.hex e al tipo di processore in conformita con il file di progetto aperto e i vari setup impostati.