Vamos lá, por partes:
Vamos chamar de kit um conjunto arduino+xbee+sensores.
No Kit1, Kit2 e Kit3 tenho monitoramento de corrente e temperatura. No Kit 4 monitoramento de temperatura e acionamento de 4 relés (via placa externa, com transistores).
O meu coordenador está espetado diretamente o PC através de um UartSbee pela porta USB (FTDI serial) e recebo os dados para teste através do X-CTU (Terminal). Com isso funcionando, monto depois meu supervisório. Não há nada de programação nesse ponto. É o xbee "cru" somente recebendo de todos.
A atualização de leitura dos sensores está em 50ms (abaixo o código). Estou usando modo API em todos eles, pois quando estava usando modo AT no meu supervisório demorava demais atualizar as tags.
Desculpe a ignorância, mas não sei o que são os "threads".
Quanto ao hardware do meu projeto propriamente dito, tenho somente o arduino UNO, com uma placa externa com resistores (para os sensores) e o xbee pendurado no Arduino.
Como seria, por exemplo, a realização de um "request" do coordenador para que cada um responda no seu tempo correto, sem que haja aquele embaraço de informações. Ou ainda, existe uma forma mais fácil de resolver?
Abaixo o código:
#include <math.h>
#define TEMPERATURA_ADC 1
#define CORRENTE_ADC 0
#define BAT_ADC 7
#define blinkLed 8
#define BAUDRATE 9600
void sendXbeeTxAPI(byte address64bits[], byte divisor, int valor, int latency_ms, boolean typeTransmission);
float pad = 9805; //valor resistencia do divisor de tensão
float thermr = 10000; float Temp;
long previousMillis = 0;
long previousMillis2 = 0;
long interval = 100;
//For analog read
double value;
//Constants to convert ADC divisions into mains current values.
double ADCvoltsperdiv = 0.0032;
double VDoffset = 2.4476; //Initial value (corrected as program runs)
//Equation of the line calibration values
double factorA = 15.2; //factorA = CT reduction factor / rsens
double Ioffset = -0.08;
//Constants set voltage waveform amplitude.
double SetV = 127;
//Counter
int i=0;
int samplenumber = 1000;
//Used for calculating real, apparent power, Irms and Vrms.
double sumI=0.0;
int sum1i=0;
double sumVadc=0.0;
double Vadc,Vsens,Isens,Imains,sqI,Irms;
double apparentPower;
void setup()
{
pinMode(blinkLed, OUTPUT);
Serial.begin(BAUDRATE);
}
void loop()
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
byte address64bits[] = {0x00, 0x13, 0xA2, 0x00, 0x40, 0x6C, 0xBC, 0xC5};
int latency_ms = 50;
//trata dado temperatura e envia pacote API para coordenador
byte divisor = 'T';
int valor = Temp;
sendXbeeTxAPI(address64bits, divisor, valor, latency_ms, true);
//trata dado corrente e envia pacote API para coordenador
divisor = 'I';
valor = Irms;
sendXbeeTxAPI(address64bits, divisor, valor, latency_ms, true);
//trata dado tensão bateria e envia pacote API para coordenador
divisor = 'B';
analogReference(INTERNAL);//referencia de tensão interna 1.1v no Atmega328
delay(20);
valor = analogRead(7);
analogReference(DEFAULT);
delay(20);
sendXbeeTxAPI(address64bits, divisor, valor, latency_ms, true);
}
corrente();
temperatura();
}
void temperatura(){
value = analogRead(TEMPERATURA_ADC);
long Resistance;
Resistance=((1024 * pad / value) - pad);
Temp = log(Resistance);
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15;
}
void corrente(){
value = analogRead(CORRENTE_ADC);
//Summing counter
i++;
//Voltage at ADC
Vadc = value * ADCvoltsperdiv;
//Remove voltage divider offset
Vsens = Vadc-VDoffset;
//Current transformer scale to find Imains
Imains = Vsens;
//Calculates Voltage divider offset.
sum1i++; sumVadc = sumVadc + Vadc;
if (sum1i>=1000) {VDoffset = sumVadc/sum1i; sum1i = 0; sumVadc=0.0;}
//Root-mean-square method current
//1) square current values
sqI = ImainsImains;
//2) sum
sumI=sumI+sqI;
if (i>=samplenumber)
{
i=0;
//Corrente em mA
Irms = 100factorA*sqrt(sumI/samplenumber)+Ioffset;
apparentPower = Irms * SetV;
sumI=0.0;
}
}
void sendXbeeTxAPI(byte address64bits[], byte divisor, int value, int latency_ms, boolean typeTransmission)
{
if(value > 9999)
return;
if (typeTransmission)
{
byte unidade = value%10+0x30;
value /= 10;
byte dezena = value%10+0x30;
value /= 10;
byte centena = value%10+0x30;
value /= 10;
byte milhar = value%10+0x30;
//Inicializa pacote API
//0x7E inicia pacote
Serial.print(0x7E ,BYTE);
//Tamanho pacote MSB
Serial.print(0x00 ,BYTE);
//Tamanho pacote LSB
Serial.print(0x16 ,BYTE);
//Frame ID (0x10: transmissão mensagem)
Serial.print(0x10 ,BYTE);
//Sem retorno de resposta
Serial.print(0x00 ,BYTE);
//64 bits address
Serial.print(address64bits[0] ,BYTE);
Serial.print(address64bits[1] ,BYTE);
Serial.print(address64bits[2] ,BYTE);
Serial.print(address64bits[3] ,BYTE);
Serial.print(address64bits[4] ,BYTE);
Serial.print(address64bits[5] ,BYTE);
Serial.print(address64bits[6] ,BYTE);
Serial.print(address64bits[7] ,BYTE);
//16 bit MY
//Se desconhecido, MY: 0xFFFE
Serial.print(0xFF ,BYTE);
Serial.print(0xFE ,BYTE);
//Opcções de envio
Serial.print(0x00 ,BYTE);
Serial.print(0x00 ,BYTE);
//Pacote de mensagem
Serial.print('[' ,BYTE);
Serial.print(divisor ,BYTE);
Serial.print(':' ,BYTE);
Serial.print(milhar ,BYTE);
Serial.print(centena ,BYTE);
Serial.print(dezena ,BYTE);
Serial.print(unidade ,BYTE);
Serial.print(']' ,BYTE);
//Soma do checksum
long sum = 0x10 +
address64bits[0] +
address64bits[1] +
address64bits[2] +
address64bits[3] +
address64bits[4] +
address64bits[5] +
address64bits[6] +
address64bits[7] +
0xFF + 0xFE +
'[' + divisor + ':' +
milhar + centena + dezena + unidade + ']';
Serial.print(0xFF - (sum & 0xFF) ,BYTE);
}
if (!typeTransmission)
{
byte valueHighBit = value >> 8 & 0xFF;
byte valueLowBit = value & 0xFF;
//Inicializa pacote API
//0x7E inicia pacote
Serial.print(0x7E ,BYTE);
//Tamanho pacote MSB
Serial.print(0x00 ,BYTE);
//Tamanho pacote LSB
Serial.print(0x14 ,BYTE);
//Frame ID (0x10: transmissão informação)
Serial.print(0x10 ,BYTE);
//Sem retorno de resposta
Serial.print(0x00 ,BYTE);
//64 bits address
Serial.print(address64bits[0] ,BYTE);
Serial.print(address64bits[1] ,BYTE);
Serial.print(address64bits[2] ,BYTE);
Serial.print(address64bits[3] ,BYTE);
Serial.print(address64bits[4] ,BYTE);
Serial.print(address64bits[5] ,BYTE);
Serial.print(address64bits[6] ,BYTE);
Serial.print(address64bits[7] ,BYTE);
//16 bit MY
//Se desconhecido, MY: 0xFFFE
Serial.print(0xFF ,BYTE);
Serial.print(0xFE ,BYTE);
//Opcções de envio
Serial.print(0x00 ,BYTE);
Serial.print(0x00 ,BYTE);
//Pacote de mensagem
Serial.print('[' ,BYTE);
Serial.print(divisor ,BYTE);
Serial.print(':' ,BYTE);
Serial.print(valueHighBit ,BYTE);
Serial.print(valueLowBit ,BYTE);
Serial.print(']' ,BYTE);
//Soma do checksum
long sum = 0x10 +
address64bits[0] +
address64bits[1] +
address64bits[2] +
address64bits[3] +
address64bits[4] +
address64bits[5] +
address64bits[6] +
address64bits[7] +
0xFF + 0xFE +
'[' + divisor + ':' +
valueHighBit + valueLowBit + ']';
Serial.print(0xFF - (sum & 0xFF) ,BYTE);
}
//digitalWrite(8, HIGH);
//delay(latency_ms);
//digitalWrite(8, LOW);