broadcasts repeated notification upon change of analog input

Dependencies:   sx12xx_hal

Revision:
0:a25661fcf9b2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 22 17:55:34 2018 -0700
@@ -0,0 +1,209 @@
+#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 (;;)
+}