fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

Transmitir datos en...
 
Avisos
Vaciar todo

Transmitir datos entre 2 pics

20 Respuestas
4 Usuarios
0 Reactions
15.1 K Visitas
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

PIC que envia

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05
#BYTE TRISC = 0X87
#BYTE PORTC = 0X07

void main() {

int16 pre,temp,hum ;
int presiol,presioh;
int temperatural,temperaturah;
int humedadl,humedadh;
int dato[6];
int i=0;

setup_adc_ports(all_analog);
setup_adc (ADC_CLOCK_INTERNAL);

lcd_init();

while(TRUE){

//TEMPERATURA POSITIVA
set_adc_channel(0);
delay_us(20);
temp=read_adc();
temperatural=make8(temp,0); // parte temperatura baja
temperaturah=make8(temp,1); // parte temperatura alta

//TEMPERATURA NEGATIVA

//PRESIÓN
set_adc_channel(2);
delay_us(20);
pre=read_adc();
presiol=make8(pre,0); // parte presión baja
presioh=make8(pre,1); // parte presión alta

//HUMEDAD
set_adc_channel(3);
delay_us(20);
hum=read_adc();
humedadl=make8(hum,0); // parte humedad baja
humedadh=make8(hum,1); // parte humedad alta

dato[0]=temperatural;
dato[1]=temperaturah;
dato[2]=presiol;
dato[3]=presioh;
dato[4]=humedadl;
dato[5]=humedadh;

for(i=0;i<=5;i++){
putc(dato); //Envia los 6 datos

if(i==5)
i==0; //Reseteo de la variable i

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3.2ld ", temp);
printf (lcd_putc, "P=%3.2ld ", pre);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3.2ld ", hum);
delay_ms(250);

}

}
}

PIC que recibe

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05

int temperatural, temperaturah;
int presiol, presioh;
int humedadl, humedadh;
int16 presio, temperatura, humedad;
int dato[6];
int i;

#int_RDA

RDA_isr(){

for(i=0;i<=5;i++){
dato=GETC(); //recibe los datos

}
}

void main() {
lcd_init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

temperatural=dato[0];
temperaturah=dato[1];
presiol=dato[2];
presioh=dato[3];
humedadl=dato[4];
humedadh=dato[5];

temperatura=((int16)temperaturah<<8)|((int16)temperatural); //Deshago el cambio
presio=((int16)presioh<<8)|((int16)presiol); //Deshago el cambio
humedad=((int16)humedadh<<8)|((int16)humedadl); //Deshago el cambio

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%4.2ld ",temperatura);
printf (lcd_putc, "P=%4.2ld ", presio);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%4.2ld ", humedad);
}

Se trata de una estación meteorológica inalámbrica que mide la temperatura, presión atmosférica y humedad, lo que hago es medir los valores con los sensores, después hago una conversión de un int16 a int8, envió todos los int8 que en mi caso son 6, y luego el otro pic deshace el cambio y saca por pantalla los datos.

Muchas gracias.

Responder
19 respuestas
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

Hola gracias por contestar, si utilizo el CCS.

El problema es que tengo que enviar las 6 variables al otro pic, y como vosotros decís, lo hago mal por culpa de las interrupciones y del bucle for.
El bucle lo pongo para que no pare de enviar los 6 valores.

Sería mucho pedir que me escribierais el código de las interrupciones, porque no tengo ni idea de las interrupciones, todo lo que se, que es nada, lo sé gracias a internet y a un libro que me compre. No sé como desactivar las interrupciones y además ¿un contador no se hace con un for? Respecto el flag me imagino que será la bandera, pero no sé cómo se hace.
Perdonad por tantas preguntas.
Muchísimas gracias.

Responder
boops
Respuestas: 1813
(@boops)
Ardero
Registrado: hace 19 años

Sobre el bucle for basta con que quites la parte del reseteo de i y lo cierres. de forma que mandes los 6 datos a la vez y después hagas la impresión en pantalla. Después para asegurarte el buen funcionamiento in-interrupidamente colocaria aun while(1) justo antes de la lectura de los sensores que acabase en el final del código.

Responder
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

PIC 1

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05
#BYTE TRISC = 0X87
#BYTE PORTC = 0X07

void main() {

int16 pre,temp,hum ;
int presiol,presioh;
int temperatural,temperaturah;
int humedadl,humedadh;

setup_adc_ports(all_analog);
setup_adc (ADC_CLOCK_INTERNAL);

lcd_init();

while(1){

//TEMPERATURA POSITIVA
set_adc_channel(0);
delay_us(20);
temp=read_adc();
temperatural=make8(temp,0); // parte temperatura baja
temperaturah=make8(temp,1); // parte temperatura alta

//TEMPERATURA NEGATIVA

//PRESIÓN
set_adc_channel(2);
delay_us(20);
pre=read_adc();
presiol=make8(pre,0); // parte presión baja
presioh=make8(pre,1); // parte presión alta

//HUMEDAD
set_adc_channel(3);
delay_us(20);
hum=read_adc();
humedadl=make8(hum,0); // parte humedad baja
humedadh=make8(hum,1); // parte humedad alta

putc(0xF); //Envio 15
delay_ms(250);
putc(temperatural); //Envio 1º dato
delay_ms(250);
putc(temperaturah); //Envio 2º dato
delay_ms(250);
putc(presiol); //Envio 3º dato
delay_ms(250);
putc(presioh); //Envio 4º dato
delay_ms(250);
putc(humedadl); //Envio 5º dato
delay_ms(250);
putc(humedadh); //Envio 6º dato
delay_ms(250);
putc(0x37); //Envio 55

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3.1ld ", temp);
printf (lcd_putc, "P=%3.2ld ", pre);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3.2ld ", hum);
delay_ms(250);

}
}

PIC 2

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05

int temperatural, temperaturah;
int presiol, presioh;
int humedadl, humedadh;
int16 presio, temperatura, humedad;
int dato[6];
int i=0;
int lectura;

#int_RDA

RDA_isr()
{

lectura=GETC(); //Lee el primer valor

if (lectura==0xF){ // El primer valor tiene que ser un 15

for(i=0;i<=5;i++){ //Hace el bucle
dato=GETC();

}
}
}

void main() {
lcd_init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

temperatural=dato[0];
temperaturah=dato[1];
presiol=dato[2];
presioh=dato[3];
humedadl=dato[4];
humedadh=dato[5];

temperatura=((int16)temperaturah<<8)|((int16)temperatural); //Deshago el cambio
presio=((int16)presioh<<8)|((int16)presiol); //Deshago el cambio
humedad=((int16)humedadh<<8)|((int16)humedadl); //Deshago el cambio

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3ld ",temperatura);
printf (lcd_putc, "P=%3ld ", presio);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3ld ", humedad);
}

Hola chicos y gracias por vuestra ayuda, he estado intentando mejorar el código y por fin lo he conseguido ya consigo transmitir. Ahora por favor que algún experto en C me diga algunas cosas que no tenga bien.
Porque seguro que habrá alguna cosa que no esté bien y yo no sepa, por ejemplo BoOpS me dijo que enviara primero un carácter al principio que en mi caso es una 0xF y después al final envió un 0x37, ¿que hago con el 0x37?, ¿para qué sirve?
Después de esto intentare utilizar los módulos xBee.
Muchas gracias chicos buen foro.

Responder
fj_sanchez
Respuestas: 1083
(@fj_sanchez)
Ardero
Registrado: hace 19 años

Buenas, lo que yo haría sería calcular un checksum (ahora te explico) y ponerlo como carácter final, así te aseguras que la transmisión ha sido correcta. Un checksum no es más que un número que sirve para asegurar que todos los datos llegaron bien, quizás lo más simple sería hacer una XOR de todos los bytes que vas a enviar, quedaría así:
#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05
#BYTE TRISC = 0X87
#BYTE PORTC = 0X07

void main() {

int16 pre,temp,hum ;
int presiol,presioh;
int temperatural,temperaturah;
int humedadl,humedadh;
char checksum = 0x00;

setup_adc_ports(all_analog);
setup_adc (ADC_CLOCK_INTERNAL);

lcd_init();

while(1){

//TEMPERATURA POSITIVA
set_adc_channel(0);
delay_us(20);
temp=read_adc();
temperatural=make8(temp,0); // parte temperatura baja
temperaturah=make8(temp,1); // parte temperatura alta

//TEMPERATURA NEGATIVA

//PRESIÓN
set_adc_channel(2);
delay_us(20);
pre=read_adc();
presiol=make8(pre,0); // parte presión baja
presioh=make8(pre,1); // parte presión alta

//HUMEDAD
set_adc_channel(3);
delay_us(20);
hum=read_adc();
humedadl=make8(hum,0); // parte humedad baja
humedadh=make8(hum,1); // parte humedad alta

// Calculamos el checksum como una XOR
checksum ^= temperatural ^ temperaturah ^ presionl ^ presionh ^ humedadl ^ humedadh;

putc(0xF); //Envio 15
delay_ms(250);
putc(temperatural); //Envio 1º dato
delay_ms(250);
putc(temperaturah); //Envio 2º dato
delay_ms(250);
putc(presiol); //Envio 3º dato
delay_ms(250);
putc(presioh); //Envio 4º dato
delay_ms(250);
putc(humedadl); //Envio 5º dato
delay_ms(250);
putc(humedadh); //Envio 6º dato
delay_ms(250);
putc(cheksum); //Enviamos el checksum

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3.1ld ", temp);
printf (lcd_putc, "P=%3.2ld ", pre);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3.2ld ", hum);
delay_ms(250);

}
}

Creo que es fácil ver el cambio, ahora en el receptor tendrías que hacer lo mismo con los 6 datos, y comprobar que el resultado es lo mismo que lo recibido en el último byte (el byte de checksum), si no coinciden es que la transmisión ha sido incorrecta. Otra cosa que yo haría sería cambiar el preámbulo (el primer byte que envías) por otro valor, como por ejemplo 0xAA, además lo enviaría 2 veces. El usar este valor es por varias cosas, primero porque crea más alternancia en la banda base (en este caso 0V y 5V) por lo que evitamos que sea un ruido temporal, ya que los fallos por ruido se suelen producir en ráfagas de bits. Otro motivo es que ayuda al sincronismo de la señal, ya que al tener tantos cambios de voltaje, ayuda a detectar mejor el tiempo de bit.

Espero que te sea de ayuda.
Un saludo.

Responder
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

Muchísimas gracias, me pongo manos a la obra y cuando tenga terminado los dos códigos los pongo y me los corriges, jejeje.
Me has ayudado mucho, gracias de nuevo.

Responder
Página 2 / 4
Compartir: