RS232 16F877A error Python

Hola a todos, mucho gusto y gracias por atender a este mensaje.

Primero les voy a contar lo que quiero hacer:

Quiero enviar y recibir datos a un PIC 16F877A el cual deberá decidir qué hacer cuando reciba un dato en específico, para comunicarme con el PIC estoy usando un conversor USB-TTL de los chinos, de los baratos que hasta el momento me ha funcionado.

Los datos para procesar en el computador los estoy implementando en PYTHON con algo muy sencillo pues el núcleo del procesamiento recae en las librerías.

Entonces el programa envía datos al PIC y el PIC ajusta un PWM según lo recibido, luego el PIC hace una lectura de un ACD y envía ese dato al computador.

Segundo, voy a exponer aquí los códigos que tengo para poder llevar a cabo lo mencionado anteriormente.

Este es el código de PYTHON

Python:
import serial
import time
import sys
puerto   = serial.Serial(port = "COM3",
                         baudrate = 9600,
                         bytesize = serial.EIGHTBITS,
                         parity   = serial.PARITY_NONE,
                         stopbits = serial.STOPBITS_ONE,
                         rtscts = 1)
print(puerto.name)
# implementar un bucle
tiempi = b'1000'
recibido = str(puerto.readline())
print(recibido)
puerto.write(tiempi)

El código del PIC:


C:
#include <16f877a.h>
#device adc=10
#fuses xt,NOWDT,NOPROTECT,NOLVP,NOWRT,NOBROWNOUT
#use delay(crystal=4MHz)
#use fast_io(C)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) // configuracion de los pines RS232

#include <stdlib.h>  //librerias para trabajar con el protocolo RS232
#include <input.c>
#include <string.h>

#byte port_a=5   
#byte port_b=6   
#byte port_d=8
#byte port_e=9

//Variables para los sensores
int16 r,t;
float s,u;
int pot1=0;
int pot2=0;
char RX_Buffer[5];
int16 numero;

sensor1()
   {
   //canal 0
   set_adc_channel(0);
   delay_us(20);
   r = read_adc();
   s = 4.98 * r / 1023.0;
   pot1=s*100;   
   delay_ms(20);
   return pot1;
   }

sensor2()
 {
   //canal 1
   set_adc_channel(1);
   delay_us(20);
   t = read_adc();
   u = 4.98 * t / 1023.0;
   pot2=u*100;   
   delay_ms(20);
   return pot2;
 }
 
#INT_RDA
void  RDA_isr(void)
{       
      //string.h es necesario para usar la función fgets().
      gets(RX_Buffer);
      // Aca convierto a entero
      numero = atol(RX_Buffer);
}

void main()
{   
   setup_adc_ports( RA0_RA1_RA3_ANALOG );
   setup_adc(ADC_CLOCK_INTERNAL);
   set_tris_d(0x00);
   set_tris_c(0b10000000);
  
   //    Configuracion de los temporizadores y contadores
   setup_timer_2(T2_DIV_BY_16,255,16);
  
   //    Habilitamos las interrupciones
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
  
   //    Habilitamos los PWM
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   set_pwm1_duty(0);
   set_pwm2_duty(0);
      
   //  valores iniciales randómicos
   output_low(pin_D0);
   output_high(pin_D1);
      
   while(TRUE)
   {                 
      sensor1();
      sensor2();     
      printf("%u$%u\n ",pot1,pot2);
      delay_ms(90);
      //----------------
          
      if(numero > 0 )
      {           
      if(numero >=2000 && numero < 2255)
         {
         // Termino de hacer lo   que necesite
         output_low(pin_D0);
         output_high(pin_D1);
         numero = numero-2000;
         set_pwm1_duty(numero);
         set_pwm2_duty(numero);
         }
      if(numero >=1000 && numero < 1255)
         {
         // Termino de hacer lo que necesite         
         output_high(pin_D0);         
         output_low(pin_D1);
         numero = numero-1000;
         set_pwm1_duty(numero);
         set_pwm2_duty(numero);
         }       
      if(numero == 1)
         {
         // Termino de hacer lo que necesite
         set_pwm1_duty(0);         
         set_pwm2_duty(0);
         }
      }   
   }
}

Al implementar lo anteriormente mencionado, si me limito a leer el puerto, no me genera ningún problema, puedo hacerlo eternamente y voy a obtener respuesta en tiempo real de los sensores, pero a intentar enviar desde el Python al PIC un dato cualquiera, el PIC se bloquea y debo aplicar un reinicio físico al PIC para que el PIC vuelva a enviar datos de manera "normal".

Por último quiero comentarles que implementé un formulario en VB.NET para probar si el problema es de PYTHON o del PIC, pero el PIC responde perfectamente enviando y recibiendo datos con visual y el código del PIC mencionado líneas arriba.


Espero puedan ayudarme y desde ya les agradezco el tiempo y la disposición que le inviertan a ayudarme para resolver este problema.

Gracias.
 

D@rkbytes

Moderador
Para que la instrucción gets() retorne, la cadena enviada debe tener un retorno de carro al final.
O sea, "\r" que viene siendo el carácter 13
Si esto no se cumple gets() quedará en bucle.
Esto se puede omitir agregando TIMEOUT = X dentro de la declaración #use RS232, donde X será el tiempo en milisegundos para que gets() retorne aunque no reciba el retorno de carro.
 
Para que la instrucción gets() retorne, la cadena enviada debe tener un retorno de carro al final.
O sea, "\r" que viene siendo el carácter 13
Si esto no se cumple gets() quedará en bucle.
Esto se puede omitir agregando TIMEOUT = X dentro de la declaración #use RS232, donde X será el tiempo en milisegundos para que gets() retorne aunque no reciba el retorno de carro.
Muy buenos días, muchas gracias, efectivamente modifiqué el código en Python añadiendo el final carrera y funciona perfectamente, muy agradecido con su pronta respuesa.
 
Arriba