wayne roberts
/
alarm_analog_master
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 (;;) }