Tengo un PanStamp (compatible con arduino) y todo funcionaba bien hasta que cambio la cantidad de datos que estoy enviando a través de la serie.
send_altitude
se llama cada segundo mediante la interrupción del temporizador (biblioteca de TimerOne).
Esta es la función original que envía datos (y no se bloquea):
void send_altitude()
{
cli();
float_byte altitude;
byte buffer[6];
// Do one trash read to avoid fluctuations
analogRead(ALT_SENSOR);
delay(5);
altitude.asFloat = getAltitude(ALT_SENSOR);
buffer[0] = 0x05; /* Size */
buffer[1] = HUB_DATA;
buffer[2] = altitude.asByte[0];
buffer[3] = altitude.asByte[1];
buffer[4] = altitude.asByte[2];
buffer[5] = altitude.asByte[3];
send_through_serial(6, buffer);
sei();
}
Pero cuando lo cambié a este (básicamente estoy enviando un recuento de paquetes): Siguiendo la sugerencia de PeterJ, moví el búfer y la variable fuera de la función y también eliminé el sei () / cli (), pero no funcionó ... Una cosa que noté es que parece tardar más en colgar sin sei / cli.
float_byte altitude;
unsigned char buffer[10];
void send_altitude()
{
// Increments the counter;
packet_count.asULong = packet_count.asULong + 1;
// Do one trash read to avoid fluctuations
analogRead(ALT_SENSOR);
delay(5);
altitude.asFloat = getAltitude(ALT_SENSOR);
buffer[0] = 0x09; /* Size */
buffer[1] = HUB_DATA;
buffer[2] = altitude.asByte[0];
buffer[3] = altitude.asByte[1];
buffer[4] = altitude.asByte[2];
buffer[5] = altitude.asByte[3];
buffer[6] = packet_count.asByte[0];
buffer[7] = packet_count.asByte[1];
buffer[8] = packet_count.asByte[2];
buffer[9] = packet_count.asByte[3];
send_through_serial(10, buffer);
}
El PanStamp comenzó a colgar sin razón ...
packet_count
es un ulong_byte
.
Las otras funciones y estructuras de datos:
void send_through_serial(int lenght, unsigned char *data)
{
unsigned int i;
/* Send srync word */
Serial.write(0xBA);
Serial.write(0xBA);
/* Send data */
for(i = 0; i < lenght; i++)
{
Serial.write(data[i]);
}
}
/**
* @brief getAltitude
*
* Return the altitude (Voltage) of a
* analogue pressure sensor.
*
* Maybe later on it will return the
* altitude
*
* @param ain Analogue pin
* @return Altitude (Voltage)
*/
inline float getAltitude(int ain)
{
int aRead = analogRead(ain);
return aRead*(3.3/1023.0);
}
typedef union _float_byte
{
byte asByte[4];
float asFloat;
} float_byte;
typedef union _ulong_byte
{
unsigned long asULong;
byte asByte[4];
} ulong_byte;
Código de inicialización del temporizador:
Timer1.initialize(1000000);
Timer1.attachInterrupt(send_altitude);
La única "solución" que encontré es usar el WDT para restablecer después de un bloqueo, pero no es bueno porque tengo algunos contadores que no se pueden descansar.
¡Gracias a @JRobert está funcionando ahora! También hice algunos cambios más:
- La interrupción del temporizador solo establece una bandera booleana;
- Buffers dentro de la función;
- Usando sei / cli;
- getAltitude () ya no es
inline
.