Ciao. Stavo cercando un decoder Pelco D. per azionare due motori semplici in dc.
Ho una telecamera ip con uscita rs485 Pelco D e volevo intefacciarla con un pic16f870 0 18f25k20 (cito questi perchè li ho disponibili subito) in modo da decodificare i comandi inviati tramite seriale dalla telecamera e comandare i due motori per avere un mini ptz.
Per muovere i motori destra sinistra e alto basso ho pensato a dei TC4427 che mi permettono ,tramite i due input che hanno, di effettuare l'inversione di marcia del motore.
questo è un esempio di stringa in pelco D che invia la mia telecamera
FF 01 00 04 3F 00 XX Pan left
Byte 1 FF lo terrò sempre così
Byte 2 01 l'indirizzo della telecamera ed essendo un sistema per una sola tlc lo terrò a 01
Byte 3 00 resta fisso così
Byte 4 04 è il comando di Pan left quello che interessa a me
Byte 5 01-3F è la velocità di Pan
Byte 6 01-3F è la velocità di tilt
Byte 7 cheksum non mi interessa
Qualcuno può aiutarmi con il codice per il pic? oppure aiutarmi a modificare il codice presente nei post precedenti?
Ho molta manualità in ambito elettronico ma mi manca la parte della programmazione dei pic.
Grazie ciao
Ho modificato così il codice
codice:
#include <pic16f870.h> //libreria standard di riconoscimento hardware
#include <stdio.h>
#define _XTAL_FREQ 20000000
#include <xc.h>
// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = ALL // FLASH Program Memory Write Enable (Unprotected program memory may be written to by EECON control)
#define LED0 RB0
#define LED1 RB1
#define LED2 RB2
#define LED3 RB3
#define RESET 0
#define CHECKSUM 0
#define DEVICEADDRESS 1
extern void Par_ser(void); //predichiarazione funzione scansione contenuto stringhe
extern void Var_Init(void); //predichiarazione funzione inizializzazione variabili
unsigned char chk = 0, okaddress = 1, okchk = 0;
unsigned char C1,C2,C3,C4,C5,C6,RxPos,Flags; //dichiarazione variabili contenute in stringa e di riconoscimento stringa
unsigned char gAddress,gCommand;
void main(void) //inizia la funzione principale
{
TRISA = 0x00; // tutte uscite per evitare interferenze
TRISB = 0x00; // uscite comandi
TRISC = 0xf8; // bit 6-7 Seriale
PORTA = 0x00; // azzera le porte
PORTB = 0x00; // azzera il PORT B
PORTC = 0x00;
Var_Init(); //inizializza le variabili di trasmissione seriale
ADCON1= 0x87; // PORTA all digital mode
//Inizializzazione uart
TXSTA= 0x20; // TX abilitato
RCSTA= 0X90; // Registro RX USART
BRGH = 1; // USART alta velocità
SPBRG= 25; // Generatore di Baud Rate (25=9600 baud)
//Inizializzazione TIMER1
T1CON = 0; // TIMER 1 resettato
T1CKPS1 = 0,T1CKPS0=0; // TIMER1 prescaler = 1
T1OSCEN = 0; // TIMER1 external oscillator disable
TMR1CS = 0; // TIMER1 internal clock (fosc/4)
TMR1ON = 0; // TIMER1 in STOP
//Inizializzazione interrupt
INTCON = 0; // Interrupt disabilitato
PIE1 = 0; // Interrupt di periferica disabilitati
GIE = 1; // Global Interrupt Enable
PEIE = 1; // Periferal Interrupt Enable
RCIE = 1; // USART Receive Interrupt Enable
for (;; ) {
if (Flags==1) Par_ser();
__delay_ms(2); // Delay aggiuntivo
}
} // Fine del main
void __interrupt ()Ser_Char (void) // Protitopo ricezione
{
if (RCREG==0xFF) //se arriva FF considero SEMPRE come START FRAME
{
RxPos=0;
gAddress = 0;
gCommand = 0;
okaddress = 1;
chk = 0;
}
if(okaddress)
{
if(RxPos==1)
{
gAddress = RCREG;
okaddress = (gAddress==DEVICEADDRESS);
}
if(RxPos==2)
{
//NOOP
}
if(RxPos==3)
{
gCommand = RCREG;
}
if(RxPos==4)
{
//NOOP
}
if(RxPos==5)
{
//NOOP
}
if(RxPos==6)
{
okchk = (chk==RCREG);
#if CHECKSUM==1
Flags= (okchk && okaddress) ? 1 : 0;
#else
Flags= (okaddress!=0) ? 1 : 0;
#endif
}
if(RxPos>7)
{
//Reset
}
}
chk+=RCREG;
RxPos++;
}
void Var_Init(void)
{
RxPos=0;
Flags=0;
}
void Par_ser(void) //Analisi comandi
{
Flags=0;
switch (gCommand) {
case 0x04: // Comando Pan Left
LED0 = 0;
LED1 = 1;
break;
case 0x02: // Comando Pan Right
LED0 = 1;
LED1 = 0;
break;
case 0x08: // Comando Tilt Up
LED2 = 0;
LED3 = 1;
break;
case 0x10: // Comando Tilt Down
LED2 = 1;
LED3 = 0;
break;
case 0x00: //Comando di stop
LED0 = 0;
LED1 = 0;
LED2 = 0;
LED3 = 0;
break;
}
}
Ho provato con Real pic simulator e funziona ma non appena monto il circuito e gli invio i comandi tipo FF 01 00 02 00 00 00 00 il pic non fa niente.
Dove sbaglio?