Hola,
Tengo varias tarjetas, de fabricación propia, cada una de ellas con un pic 16f876a y un módem xbee xbp09.
Desde un pc con un xbee conectado al puerto serie, envío una misma cadena a todas la tarjetas. En la cadena va un id para que cada pic sepa si el mensaje es para el o no. Si el mensaje es para el responde con su id mas la acción realizada.
El problema es que si pruebo comunicarme con cada tarjeta por separado (sin encender las otras) todo funciona muy bien, pero si enciendo 2 o mas sólo puedo comunicarme con una de ellas, la primera a la cual envíe un mensaje.
Hice la prueba de que sean las tarjetas las que me envíen un mensaje en todo momento y recibo en el pc el mensaje correctamente de todos los pic, pero apenas envío un mensaje a una tarjeta dejo de tener comunicación con todas las demás, no reciben ni envían datos.
Por esto y por el hecho de que esta configuración de red xbee funciona bien con otro sistema que tenemos (hecho en assembler, del cual no entiendo nada) es que creo que debe haber algún problema en el buffer rs232 o en el control de errores de este.
Aquí esta el código del pic en C (ccs compiler).
#include <16F876A.h>
#include <stdlib.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES HS
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, STREAM=COM_A, parity=N, bits=8, ERRORS)
char p, term[2], command[48] = "", action[10] = "", values[45] = "", picid[8] = "";
char picsaved[8] = "", pass[8] = "", permited[9] = "";
short newcommand = 0;
int k = 0;
int32 seconds[14], times[14], epoch;
int1 logged;
#bit OERR=0x0018.1
#bit CREN=0x0018.4
#INT_RDA
void usart_modem(void)
{
disable_interrupts(INT_RDA);
if(OERR)
{
CREN=0;
delay_cycles(2);
CREN=1;
}
newcommand = 0;
if (kbhit(COM_A))
{
p = fgetc(COM_A);
if(p == '#') {
command[k] = '\0';
newcommand = 1;
k = 0;
}else{
command[k] = p;
k++;
}
}
enable_interrupts(INT_RDA);
}
int is_equal(char *p1, char *p2)
{
int *p3;
p3 = strstr(p1,p2);
return (p3);
}
void open(void)
{
int i, j=0;
char numbers[3] = "", letter;
unsigned char number;
for(i = 0; i < strlen(values); i += 3){
numbers[0] = values[i];
numbers[1] = values[i+1];
numbers[2] = '\0';
letter = values[i+2];
number = atoi(numbers);
if(letter == 77) number *= 60;
seconds[j] = number;
times[j] = epoch;
j++;
}
if(seconds[0] > 0) output_bit(PIN_C0, 1);
if(seconds[1] > 0) output_bit(PIN_C1, 1);
if(seconds[2] > 0) output_bit(PIN_C2, 1);
if(seconds[3] > 0) output_bit(PIN_C3, 1);
if(seconds[4] > 0) output_bit(PIN_B7, 1);
if(seconds[5] > 0) output_bit(PIN_B6, 1);
if(seconds[6] > 0) output_bit(PIN_B5, 1);
if(seconds[7] > 0) output_bit(PIN_B4, 1);
if(seconds[8] > 0) output_bit(PIN_B3, 1);
if(seconds[9] > 0) output_bit(PIN_B2, 1);
if(seconds[10] > 0) output_bit(PIN_B1, 1);
if(seconds[11] > 0) output_bit(PIN_B0, 1);
if(seconds[12] > 0) output_bit(PIN_C5, 1);
if(seconds[13] > 0) output_bit(PIN_C4, 1);
}
void close(void)
{
if(values[0] > 0) output_bit(PIN_C0, 0);
if(values[1] > 0) output_bit(PIN_C1, 0);
if(values[2] > 0) output_bit(PIN_C2, 0);
if(values[3] > 0) output_bit(PIN_C3, 0);
if(values[4] > 0) output_bit(PIN_B7, 0);
if(values[5] > 0) output_bit(PIN_B6, 0);
if(values[6] > 0) output_bit(PIN_B5, 0);
if(values[7] > 0) output_bit(PIN_B4, 0);
if(values[8] > 0) output_bit(PIN_B3, 0);
if(values[9] > 0) output_bit(PIN_B2, 0);
if(values[10] > 0) output_bit(PIN_B1, 0);
if(values[11] > 0) output_bit(PIN_B0, 0);
if(values[12] > 0) output_bit(PIN_C5, 0);
if(values[13] > 0) output_bit(PIN_C4, 0);
}
void read_pass(void)
{
int i, address = 12;
for(i = 0; i < 6; i++){
pass[i] = read_eeprom(address + i);
}
pass[i] = '\0';
}
void set_pass(void)
{
int i, address = 12;
for(i = 0; i < 6; i++){
write_eeprom(address + i, values[i]);
}
}
void read_pic(void)
{
int i, address = 22, x;
for(i = 0; i < 7; i++){
x = read_eeprom(address + i);
picsaved[i] = x;
}
picsaved[i] = '\0';
}
void set_pic(void)
{
int i, address = 22;
for(i = 0; i < 7; i++){
write_eeprom(address + i, values[i]);
picsaved[i] = values[i];
}
picsaved[i] = '\0';
}
void auto_off(void)
{
//epoch = secondsSinceYear1(yr, mn, day, hrs, min, sec);
if(seconds[0] > 0 && (epoch - times[0]) > seconds[0]) output_bit(PIN_C0, 0);
if(seconds[1] > 0 && (epoch - times[1]) > seconds[1]) output_bit(PIN_C1, 0);
if(seconds[2] > 0 && (epoch - times[2]) > seconds[2]) output_bit(PIN_C2, 0);
if(seconds[3] > 0 && (epoch - times[3]) > seconds[3]) output_bit(PIN_C3, 0);
if(seconds[4] > 0 && (epoch - times[4]) > seconds[4]) output_bit(PIN_B7, 0);
if(seconds[5] > 0 && (epoch - times[5]) > seconds[5]) output_bit(PIN_B6, 0);
if(seconds[6] > 0 && (epoch - times[6]) > seconds[6]) output_bit(PIN_B5, 0);
if(seconds[7] > 0 && (epoch - times[7]) > seconds[7]) output_bit(PIN_B4, 0);
if(seconds[8] > 0 && (epoch - times[8]) > seconds[8]) output_bit(PIN_B3, 0);
if(seconds[9] > 0 && (epoch - times[9]) > seconds[9]) output_bit(PIN_B2, 0);
if(seconds[10] > 0 && (epoch - times[10]) > seconds[10]) output_bit(PIN_B1, 0);
if(seconds[11] > 0 && (epoch - times[11]) > seconds[11]) output_bit(PIN_B0, 0);
if(seconds[12] > 0 && (epoch - times[12]) > seconds[12]) output_bit(PIN_C5, 0);
if(seconds[13] > 0 && (epoch - times[13]) > seconds[13]) output_bit(PIN_C4, 0);
}
void clean_values(char v)
{
int x = 0;
for(x = 0; x < 45; x++){
values[x] = v;
}
values[x] = '\0';
}
void clean_command(char v)
{
int x = 0;
for(x = 0; x < 48; x++){
command[x] = v;
}
command[x] = '\0';
}
/* Programa principal */
void main(void)
{
// Activo todos los pines B como salidas
set_tris_b(0b00000000);
// Activo PIN_C4 y PIN_C7 como entradas
set_tris_c(0b10010000);
// Todos los pines B y C apagados, excepto los que son entradas
output_B(0b00000000);
output_bit(PIN_C0, 0);
output_bit(PIN_C1, 0);
output_bit(PIN_C2, 0);
output_bit(PIN_C5, 0);
// Activo interrupciones
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
epoch = 0;
/*
read_pass();
clean_values(-1);
if(is_equal(values, pass)){
// Password por defecto
strcpy(values, "BUS554");
set_pass();
read_pass();
}
read_pic();
clean_values(-1);
if(is_equal(values, picsaved)){
// Pic Id por defecto
strcpy(values, "ITG0001");
set_pic();
read_pic();
}
*/
//clean_values(0);
strcpy(picsaved, "ITG0002");
strcpy(pass, "BUS554");
while(TRUE)
{
delay_ms(1000);
epoch++;
auto_off();
if(newcommand){
newcommand = 0;
//printf("%s command\r\n", command);
strcpy(term, "|");
strcpy(picid, strtok(command, term));
strcpy(action, strtok(0, term));
strcpy(values, strtok(0, term));
/*
strcpy(permited, "SETPASS");
if(is_equal(permited, action) && logged){
set_pass();
printf("%s\r\n", pass);
}
strcpy(permited, "READPASS");
if(is_equal(permited, action) && logged){
read_pass();
printf("%s\r\n", pass);
}
strcpy(permited, "READPIC");
if(is_equal(permited, action) && logged){
read_pic();
printf("%s read\r\n", picsaved);
}
strcpy(permited, "SETPIC");
if(is_equal(permited, action) && logged){
set_pic();
printf("%s setid\r\n", picsaved);
}
*/
//printf("%s picid %s picsaved\r\n", picid, picsaved);
if(is_equal(picid, picsaved)){
strcpy(permited, "LOGIN");
if(is_equal(permited, action)){
//read_pass();
if(is_equal(values, pass)){
logged = 1;
printf("logged %s\r\n", picsaved);
//printf("logged %s picid %s saved\r\n", picid, picsaved);
}
}
strcpy(permited, "OPEN");
if(is_equal(permited, action)){
open();
printf("%s opened\r\n", picid);
}
strcpy(permited, "CLOSE");
if(is_equal(permited, action)){
close();
printf("%s closed\r\n", picid);
}
strcpy(permited, "EXIT");
if(is_equal(permited, action)){
logged = 0;
printf("%s exited\r\n", picid);
}
}
//clean_command(0);
//clean_values(0);
//enable_interrupts(INT_RDA);
}else{
//printf("%s - %s\r\n", picsaved, pass);
}
}
}
La variable picsaved (id del pic) está fija en este código, pero la cambio, recompilo y grabo con distinto valor para cada pic. Hice esto por que en algún momento pensé que el problema estaba al leer de la eeprom el id del pic.