Servocontrol serie mediante PIC

Estoy tratando de hacer un servocontrolador en serie usando el microcontrolador pic18f4550.

siguiendo si el código completo que he probado ...

tenga en cuenta que actualmente estoy enviando hexadecimal de 8 bits para controlar solo un servo. estoy enviando estos datos de una foto a otra ..

#define FREQ 20000000
#define baud 9600
#define spbrg_value (((FREQ/64)/baud)-1)


unsigned char rx_data(void);
void tx_data(unsigned char);


void main()
{
int i;
double state;
int ip1=0;
SPBRG=spbrg_value;      // Fill the SPBRG register to set the Baud Rate
RCSTA.SPEN=1;           // To activate Serial port (TX and RX pins)
TXSTA.TXEN=1;           // To enable transmission
RCSTA.CREN=1;           // To enable continuous reception

TRISB.RB0=0;

while(1)
{
    ip1=rx_data();    // Receive data from PC

    //this part doesn't gets executed!!
    state=max((ip1/4)+1,12);
    LATB.LATB0=1;

    for (i=0;i<state;i++)
       delay_us(10);

    LATB.LATB0=0;

    for (i=0;i<200-state;i++)
       delay_us(1);
}
}


void tx_data(unsigned char data1)
{
TXREG=data1;                                     // Store data in Transmit register
while(PIR1.TXIF==0);                             // Wait until TXIF gets low
}


unsigned char rx_data(void)
{
while(PIR1.RCIF==0);                           // Wait until RCIF gets low
return RCREG;                                 // Retrieve data from reception register
}

Me aseguré de que la imagen maestra envíe los datos correctos conectándolo al puerto serie de la PC y observe la salida.

como se indica en el código, la parte posterior ip1=rx_data();no se ejecuta.

También confirmé comentando la ip1=rx_data();parte y luego reemplazando la variable ip1 con un valor int ... luego el servo se mueve a la posición adecuada de acuerdo con el valor en lugar de ip1 (que varía de 0 a 255).

¿alguna ayuda?

ACTUALIZAR:

con las sugerencias dadas en las respuestas, he verificado lo siguiente.

1.Both PICs running on 20mhz so frequency is correct.

2.serial data format is correct. i am receiving the proper data to the PC.

3.Wiring checked.

4.decoupling( plz explain how to do proper decoupling).

5.power supply. ( both running of a 5v 1 amp wall chargers).

por lo que el problema más probable (aparte del software) puede ser el desacoplamiento inadecuado. ¿Puede alguien explicarme esto?

Tu pregunta no tiene nada que ver con el servocontrol. Sugiero cambiarle el nombre y eliminar la etiqueta.
Desacoplamiento: un condensador (típicamente 0.1uF) conectado directamente a través de los pines de alimentación de MCU.

Respuestas (2)

En primer lugar, su código está bloqueando. Esa no es la forma de esperar los datos en serie. Tendrá que monitorear el indicador de interrupción RX desde el bucle principal y, si está configurado, haga lo mismo ip1=rx_data();para obtener los datos. En su caso, si el cableado de los pines UART es incorrecto o no hay datos de la MCU maestra, la línea while(PIR1.RCIF==0);es un bucle infinito. Eso explica por qué el resto de su código no funciona.

Lo segundo que noté es que le estás dando al servo solo un pulso por señal de control. La mayoría de los servomotores RC para aficionados esperan al menos 3 pulsos de este tipo para posicionar la bocina de manera confiable.

No solo 3. Los servos RC se aflojarán si deja de recibir pulsos. Por lo tanto, debe enviar pulsos continuamente a una velocidad de 20 por segundo para mantener la posición de la bocina.
Eso es cierto si hay carga en la bocina del servo tratando de moverla. Si no hay carga o hay poca carga, 3 pulsos son suficientes para ponerlo en la poción correcta.
3 pulsos pueden no ser suficientes. Un Hitec HS-325HB que probé necesitaba 13~14 pulsos consecutivos para pasar de la posición de 1ms a 2ms.

Su código parece estar funcionando bien, por lo que si se queda pegado rx_data(), entonces el PIC se está ejecutando en la frecuencia incorrecta, el formato de datos en serie es incorrecto o tiene un problema de hardware (error de cableado, desacoplamiento inadecuado, mala fuente de alimentación, etc.) .

Para obtener suficiente precisión de reloj, debe usar un resonador de cristal o cerámica, y los bits de configuración deben establecerse en el oscilador HS. También verifique que el PIC maestro esté enviando datos en serie con el mismo formato y velocidad de transmisión (con una precisión superior al 2%). ¡El hecho de que su PC pueda leerlo no prueba que sea correcto!

Otro posible problema es que su código solo produce un pulso de servo por cada byte en serie recibido. Si tiene la intención de enviar un byte cada 20 ms, está bien, pero tenga en cuenta que es posible que el servo no funcione correctamente si la frecuencia de repetición del pulso es demasiado baja o demasiado alta.