Envio de Dato cadena y Recepcion por serial MIKROC

Buenas tardes,

Estoy trabajando con mikroc para enviar y recibir datos cadena, ya logre leer el dato. en el Receptor con la funcion

UART1_Read_Text(output, OK, 10).

al leer el dato y presentarlo en LCD no lee el dato completo.

ej: dato enviado 22640
dato recibido y presentado LCD 22

alguna sugerencia de cual prodri ser la falla

Gracias
 
Gracias dosmetros,

Lo que hace el programa del emisor, es leer unas celdas de presion por HX711, y enviar los datos por LCD y UART, por medio de modulos RF. esto sin complicaciones. que se lee el peso en la LCD y en el terminar en la PC

pic 16f628a
osc interno 4mhz


El codigo emisor es:

PHP:
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RA2_bit;
sbit LCD_D6 at RA3_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISA2_bit;
sbit LCD_D6_Direction at TRISA3_bit;
sbit LCD_D7_Direction at TRISB3_bit;

sbit HX711SDAT at RA6_bit;
sbit HX711CLK  at RA7_bit;

sbit HX711SDAT_Direction at TRISA6_bit;
sbit HX711CLK_Direction  at TRISA7_bit;


char txt[24];
int times;

unsigned long  HX711_read ()
{

 unsigned long conteo;
 unsigned long i;
 
     TRISA.RA6=1;
     TRISA.RA7=0;
     
     HX711SDAT = 1;
     HX711CLK  = 0;
     
     conteo=0;
     
     while(HX711SDAT);
           for(i=0; i<24; i++){
                     HX711CLK=1;
                     delay_us(5);
                     conteo  =   conteo << 1;
                     HX711CLK=0;
                     delay_us(5);
                     if (HX711SDAT)  conteo ++;
                               }
                               
           HX711CLK=1;
           delay_us(5);
           HX711CLK=0;
           conteo= conteo ^ 0x800000;

           return(conteo);

}


unsigned long HX711_prom ( int times){

    int j;
    unsigned long sum;

   for (j=0; j<times; j++){
   
         sum = sum + HX711_read();

                          }
                          
         return (sum/times);


}




void main() {

CMCON=0x07;
NOT_RBPU_bit=1;
lcd_init();

UART1_init(1200);
delay_ms(100);

Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);


while(1){

    unsigned long Peso, Esca  ;
    unsigned int kg, gr;
    
    Peso = HX711_prom(20);
    Esca = (Peso - 8714200.75 ) / (23761/1000);
    LongToStr(Esca, txt);
    LCD_Out(1,1,"PESO");
    LCD_Out(2,1,txt);
    UART1_Write_Text(txt);
    UART1_Write(13);
    UART1_Write(10);

}

     //8714200.75    23.761

}


En el receptor realiza las siguientes tareas por tipo menú se prodria comentar.

Pantalla de inicio.
Pulsa botón toma de distancia por ultrasonido
Pulsa botón, toma de peso es la lectura del serial por radiofrecuencia,
Pulsa botón presentación de peso y distancia en LCD


Código del Receptor:

PHP:
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

sbit SR04_Echo at RA6_bit;
sbit SR04_Tigger at RA7_bit;

sbit SR04_Echo_Direction at TRISA6_bit;
sbit SR04_Tigger_Direction at TRISA7_bit;


unsigned char peso[12] ;
long txt[8];
int contador, variable;
int i = 0 ;
int distancia, talla1;
long dato,dato1;

int talla(){

      distancia = HCSR04_Get_Distance(_cm);
      IntToStr(distancia,txt);
      return txt;
}


void main() {

CMCON=0x07;
NOT_RBPU_bit=1;
TRISB.RB0=1;

lcd_init();

UART1_init(1200);
delay_ms(100);

HCSR04_Init();

Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
contador=0;
variable=0;


      do {
            if(Button(&PORTB,0, 1, 1))
                 {
                   variable=1;
                 }
                 
            if (variable && Button(&PORTB,0, 1,0))
                 {
                   variable=0;
                   contador++;
                   Lcd_Cmd(_LCD_CLEAR);
                   Lcd_Cmd(_LCD_CURSOR_OFF);
                 }
                 
           switch(contador){
           
                  case 0: DELAY_MS(20);
                          Lcd_Out(1,3,"Mensaje");
                          Lcd_Out(2,5,"Bienvenida");

                          break;
                 
                  case 1: DELAY_MS(20);
                          Lcd_Out(1,1,"DISTANCIA");
                          talla1 = talla();
                          Lcd_Out(2,4,talla1);
                          break;
                          
                  case 2: DELAY_MS(20);

                          Lcd_Out(1,3,"TOMA DE PESO");             // aqui  es donde no se lee el 
                          if (UART1_DATA_Ready()==0){            // dato enviado,  por RF  
                                                                                 // por teclado lo recibe bien y lo 
                              Uart1_Read_Text(peso, "0", 7);         // presenta.
                              Uart1_Write_Text(peso);

                             lcd_Out(2,1, peso);
                             

                                                   }

                          break;
                          
                  case 3: DELAY_MS(20);
                          Lcd_Out(1,1,"Dist:       CM");
                          Lcd_Out(1,7,talla1);
                          Lcd_Out(2,1,"PESO:        KGS");
                          Lcd_Out(2,6,peso);
                          
                          break;
                          
                  case 4: contador=0;
           
                          break;
           
           

                           }

        }
         
         while(1);

    }


Todo se realiza bien hasta la parte de la lectura del peso, aparentemente no sabe la función donde inicia la secuencia ya que en lecturas lee mitad de los datos y así los presenta.

Intente varias formas de leer ese dato y lo mejor fue hasta ahorita pero lee solo parte del dato enviado.

gracias por el apoyo de antemano
 
Buenas noches foristas. al parecer el problema que se esta presentando es que el Pic se vuelve lento al realizar la lectura de serial

de manera directa conectando pic a pic. el primer valor tarda en aparecer en la pantalla en 6 seg

y con el modulo de radiofrecuencia hasta 25 seg o mas.

este retardo tambien influye en la presentacion de LCD.

en la LCD el peso medido es de 7 931 gr y lo presenta la LCD de esta forma, despues de un tiempo lo presenta bien y despues de mas tiempo encima los valores 793179 por ejem.
 

Adjuntos

  • image1.JPG
    image1.JPG
    101.2 KB · Visitas: 5
Es mejor que envíes el resultado en bytes y no como una cadena de texto.
Si tu cifra es de 24 bits, (0xFFFFFF) tendrás que descomponerla y enviar 3 bytes.
En el receptor recuperas el valor con los 3 bytes recibidos y realizas las conversiones.
 
No uso mikroC y desconozco si tenga funciones como make8, make16 o make32.

En caso de que no, se podría implementar de esta forma:

byte1 = valor >> 16;
byte2 = valor >> 8;
byte3 = valor & 0xFF;

Con eso descompones la cifra en bytes de MSB a LSB y los envías.

Ya en el receptor recuperas nuevamente el valor con una función:
PHP:
unsigned long make24(char byte1, char byte2, char byte3) 
{       
    return (byte3 + 0x100 * byte2 + 0x10000 * byte1);
}
 
Es mas fácil usar una union ya que no hay que andar sacando cuentas y haciendo desplazamientos. Algo como esto:
Código:
/* por comodidad declaramos un tipo */
typedef union {
    int dato;     /* este debe ser un int16 */
    byte partes[2];
} EnteroABytes;
...
...
/* por alguna parte se declara la variable de tipo EnteroABytes */
EnteroABytes paraEnviar, paraRecibir;

paraEnviar.dato = talla1;      /* O lo que sea que quieren enviar de tipo int */

/*  y lo enviamos... */
enviarSerie( paraEnviar.partes[0] );
enviarSerie( paraEnviar.partes[1] );
...

/*  si hay que recibir */
recibirSerie( paraRecibir.partes[0] );
recibirSerie( paraRecibir.partes[1] );

/*  y para usarlo es directo */
algo = paraRecibir.dato + otra_cosa;
...

Si se quieren enviar 24 bits, hay que usar una union entre un long y un arreglo de 4 bytes, pero la historia es exactamente la misma.

Fácil, fácil y sin andar haciendo conversiones molestas. Hay que dejar que el compilador se encargue de su trabajo...
 
Gracias D@rkbytes y dr.zoidberg.

Si hay funciones en mikroc para obtener datos por bytes, las encontré leyendo el manual completo y con calma

Lo. 0 - 7 bits
Hi. 8 - 15
Higher 16 - 23
Highest 24 a 31

La duda es al recibir el receptor sabe el orden de los bytes enviados o llega a alterarse la lectura

Envió dato 1
Envió dato 2
Envió dato 3

Recibo si hay datos
Dato [0] = recibir dato 1. Aquí si es el primer dato por defaul se envía del emisor o requiere un dato de asignación o especial que indique la secuencia inicial de envió

Gracias
 
...
La duda es al recibir el receptor sabe el orden de los bytes enviados o llega a alterarse la lectura

Envió dato 1
Envió dato 2
Envió dato 3

Recibo si hay datos
Dato [0] = recibir dato 1. Aquí si es el primer dato por defaul se envía del emisor o requiere un dato de asignación o especial que indique la secuencia inicial de envió
No entiendo cual es la consulta :confused: :confused: :confused:
El orden la lectura depende la forma en la que envíes los bytes y de cantidad de bytes que envíes para formar la variable que te interesa usar.
Por ejemplo, si desde el "emisor" enviás 24 bits y en el receptor querés armar un int32 (un long), vas a tener que leer 3 bytes, y el byte con los bits 31..24 (el byte mas significativo) vas a tener que igualarlo a cero.
Ahora, si lo que lees primero es el byte mas significativo o el menos significativo, depende de como sea la secuencia de envío desde el emisor.
 
Sip no se altera el orden de recepción de los datos.

emisor

envio dato1
envio dato2
envio dato3

receptor

recibir después de checa dato de entrada, si se reciben en orden

recibo dato1
recibo dato2
recibo dato3

o llega a leer en desorden

digamos inicia en

recibir dato2
recibir dato3
recibir dato1

que se reciban en otro orden inicial al de envio que es en dato1

espero haberle esplicado

gracias
 
recibir después de checa dato de entrada, si se reciben en orden

recibo dato1
recibo dato2
recibo dato3

o llega a leer en desorden

digamos inicia en

recibir dato2
recibir dato3
recibir dato1

que se reciban en otro orden inicial al de envio que es en dato1
Sigo sin entender la consulta... :confused: :confused:
La unica forma en que podrías recibir fuera de orden es que lo envíes fuera de orden. Si vos envias 1,2,3 por que recibirías 2,3,1 ????
Estás transmitiendo punto-a-punto con un enlace serie, así que no hay forma de que la secuencia se altere en el camino de los datos...
 
Hola! Estoy renegando por la misma razón. Uso MikroC y la función Uart_Read para almacenar datos recibidos en un array de char. El problema es que sólo recibe el dato último.
 
Sin saber mucho sobre esa librería:

UART Library

Al parecer Uart_Read, solo lee el último byte.

Alternativa que te da la librería:

UART_Read_Text: lee hasta que recibe la secuencia designada o un límite de caracteres, ej "OK".

El inconveniente con este tipo de funciones es que son bloqueantes, es decir, hasta no recibir la secuencia o el límite máximo de caracteres, la función se queda esperando.

Lo mejor, es usar interrupciones, pero dependerá de tus necesidades, tal vez que sea bloqueante no es un inconveniente para tu proyecto.
 
Sin saber mucho sobre esa librería:

UART Library

Al parecer Uart_Read, solo lee el último byte.

Alternativa que te da la librería:

UART_Read_Text: lee hasta que recibe la secuencia designada o un límite de caracteres, ej "OK".

El inconveniente con este tipo de funciones es que son bloqueantes, es decir, hasta no recibir la secuencia o el límite máximo de caracteres, la función se queda esperando.

Lo mejor, es usar interrupciones, pero dependerá de tus necesidades, tal vez que sea bloqueante no es un inconveniente para tu proyecto.
Oh, sí. Muy cierto. Otra cosa es cierta: Si en el loop pones el "Uart_Write" fuera de un "if", se te queda enviando siempre lo mismo. Tiene sentido. Es un loop... pero más allá de eso, debería mandar todo el string y sin embargo sólo envía el primer caracter.

Programo:


C:
char array[5], head;
int rec,i;
...
...

void main(){
    CMCON = 0x07; //deshabilito comparadores...
    Uart1_Init(9600);
    Delay_ms(100);
    while(1){
        if(Uart1_Data_Ready()){
            head = Uart1_Read();
        }
        if(head == 'A'){
            rec = 1;
            i = 0;
            array[0] = head;
            i++;
        }
        if(rec == 1){
            if(Uart1_Data_Ready()){
                Uart1_Read_Text(head,"\r",5);
                array[i] = head;
                i++;
            }
        }
    }
}

y en la salida recibo todas
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Rarísimo, dado que tendría que recibir toda la cadena, no sólo el header.
 
Yo haría esto:

C:
char array[5], head[2]="OK";
int rec,i;
...
...

void main(){
    CMCON = 0x07; //deshabilito comparadores...
    Uart1_Init(9600);
    Delay_ms(100);
    while(1){
        if(Uart1_Data_Ready()){
            UART_Read_Text(output, head, 5);    // Lee hasta que se encuentra[I] 'OK'[/I]   
            UART_Write_Text(output);                  // Devuelve el texto recibido por UART
        }       
    }
}
 
Yo haría esto:

C:
char array[5], head[2]="OK";
int rec,i;
...
...

void main(){
    CMCON = 0x07; //deshabilito comparadores...
    Uart1_Init(9600);
    Delay_ms(100);
    while(1){
        if(Uart1_Data_Ready()){
            UART_Read_Text(output, head, 5);    // Lee hasta que se encuentra[I] 'OK'[/I]  
            UART_Write_Text(output);                  // Devuelve el texto recibido por UART
        }      
    }
}
Eso lo hice y en efecto funciona, pero la idea no era simplemente devolverlo, sino almacenar los datos para trabajarlos.
 
Si, bueno, solamente devuelve para comprobar que llegó bien, en realidad después de recibir deberías hacer algo con esos datos.

Por cierto, en el código que puse, usé "output" como buffer para recibir los datos, está mal, debería ser "array", se me pasó al copiar:


Código:
UART_Read_Text(array, head, 5);    // Lee hasta que se encuentra[I] 'OK'[/I]  
UART_Write_Text(array);                  // Devuelve el texto recibido por UART
 
Atrás
Arriba