broadcasts repeated notification upon change of analog input
main.cpp
- Committer:
- wroberts@semtech.com
- Date:
- 2018-10-23
- Revision:
- 1:b5b1352d36d1
- Parent:
- 0:a25661fcf9b2
File content as of revision 1:b5b1352d36d1:
#include "radio.h"
#define NUM_ANALOG_IN 4
#if defined(SX127x_H) || defined(SX126x_H)
#define BW_KHZ 500
#define SPREADING_FACTOR 11
#define CF_HZ 910800000
#if defined(SX126x_H)
#define TX_DBM (Radio::chipType == CHIP_TYPE_SX1262 ? 20 : 14)
#else
#define TX_DBM 17
#endif
#elif defined(SX128x_H)
#define BW_KHZ 200
#define SPREADING_FACTOR 11
#define CF_HZ 2487000000
#define TX_DBM 5
#endif
#define PWM_HZ 120
#if defined(TARGET_FF_MORPHO) && defined(TARGET_FAMILY_STM32)
PinName pin_names[NUM_ANALOG_IN] = {
PC_2, /* CN7-35 */
PC_3, /* CN7-37 */
PC_4, /* CN10-34 */
PC_5 /* CN10-6 */
};
#endif
#define CMD_PWM_A 0x02
#define CMD_PWM_B 0x03
#define CMD_PWM_C 0x04
#define CMD_PWM_D 0x05
const uint8_t rfCmds[NUM_ANALOG_IN] = {
CMD_PWM_A,
CMD_PWM_B,
CMD_PWM_C,
CMD_PWM_D
};
typedef struct {
AnalogIn* ain;
uint16_t prev;
int8_t movement;
bool sent;
} analog_t;
analog_t _a_[NUM_ANALOG_IN];
Timer t;
volatile bool tx_done;
static uint16_t crc_ccitt( uint8_t *buffer, uint16_t length )
{
// The CRC calculation follows CCITT
const uint16_t polynom = 0x1021;
// CRC initial value
uint16_t crc = 0x0000;
if( buffer == NULL )
{
return 0;
}
for( uint16_t i = 0; i < length; ++i )
{
crc ^= ( uint16_t ) buffer[i] << 8;
for( uint16_t j = 0; j < 8; ++j )
{
crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
}
}
return crc;
}
void transmit(unsigned target, uint8_t cmd, uint16_t ain)
{
unsigned t_diff;
uint16_t crc;
Radio::radio.tx_buf[0] = cmd;
Radio::radio.tx_buf[1] = PWM_HZ;
Radio::radio.tx_buf[2] = ain >> 8; // pwm duty
t_diff = target - t.read_us();
Radio::radio.tx_buf[3] = t_diff >> 24;
Radio::radio.tx_buf[4] = t_diff >> 16;
Radio::radio.tx_buf[5] = t_diff >> 8;
Radio::radio.tx_buf[6] = t_diff & 0xff;
crc = crc_ccitt(Radio::radio.tx_buf, 7);
Radio::radio.tx_buf[7] = crc >> 8;
Radio::radio.tx_buf[8] = crc & 0xff;
Radio::Send(9, 0, 0, 0);
for (tx_done = false; !tx_done; )
Radio::service();
printf("t_diff:%u crc:%04x\r\n", t_diff, crc);
}
#define TARGET_LATENCY 2000000
void send_alarm(uint8_t cmd, uint16_t ain)
{
int i;
unsigned target = t.read_us() + TARGET_LATENCY;
printf("send_alarm() %u\n", target);
for (i = 0; i < 5; i++) {
transmit(target, cmd, ain);
wait(0.1);
}
}
void txDoneCB()
{
tx_done = true;
}
void rxDoneCB(uint8_t size, float Rssi, float Snr)
{
}
#define AIN_REST_THRESHOLD 96 // 12bit left justified
void analog_mainloop(analog_t* ana, uint8_t rfCmd)
{
uint16_t ain = ana->ain->read_u16();
uint16_t diff = abs(ain-ana->prev);
if (diff > AIN_REST_THRESHOLD) {
ana->sent = false;
if (ana->movement < 1)
ana->movement = 1;
else {
if (++ana->movement > 16)
ana->movement = 16;
}
} else {
/* steady state */
if (ana->movement > 0)
ana->movement = 0;
else {
if (--ana->movement < -16) {
ana->movement = -16;
if (!ana->sent) {
printf("## %02x ##\r\n", ain >> 8);
send_alarm(rfCmd, ain);
ana->sent = true;
}
}
}
}
//printf("%05u diff:%04u move:%d\r\n", ain, diff, ain_movement);
ana->prev = ain;
}
void trigger_init()
{
unsigned n;
for (n = 0; n < NUM_ANALOG_IN; n++) {
_a_[n].ain = new AnalogIn(pin_names[n]);
_a_[n].prev = _a_[n].ain->read_u16();
_a_[n].movement = 0;
_a_[n].sent = false;
}
}
const RadioEvents_t rev = {
/* Dio0_top_half */ NULL,
/* TxDone_topHalf */ NULL,
/* TxDone_botHalf */ txDoneCB,
/* TxTimeout */ NULL,
/* RxDone */ rxDoneCB,
/* RxTimeout */ NULL,
/* RxError */ NULL,
/* FhssChangeChannel */NULL,
/* CadDone */ NULL
};
int main()
{
printf("\r\nreset-tx\r\n");
trigger_init();
t.start();
Radio::Init(&rev);
Radio::Standby();
Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
Radio::LoRaPacketConfig(8, false, true, false); // preambleLen, fixLen, crcOn, invIQ
Radio::SetChannel(CF_HZ);
Radio::set_tx_dbm(TX_DBM);
for (;;) {
unsigned n;
for (n = 0; n < NUM_ANALOG_IN; n++) {
analog_mainloop(&_a_[n], rfCmds[n]);
}
wait_us(5000);
} // ..for (;;)
}