MAX20361 Demo with LoRa Module on LP0 mode

Dependencies:   SX1276GenericLib USBDevice

Fork of NonPingPong_PICO_LoRa_LP0 by Walter Luu

main.cpp

Committer:
walterluu
Date:
2020-10-16
Revision:
7:c0872971aef4
Parent:
6:51f492ca61a2

File content as of revision 7:c0872971aef4:


#include "mbed.h"

// Board pins related
#include "PinMap.h"

// LORA related
#include "global_buffers.h"
#include "GenericPingPong2.h"
#define FEATURE_LORA
#include "sx1276-mbed-hal.h"

#include "main.h"

// OT07 related
#include "OT07_lib.h"      
#define CONVERT_T_DELAY 30 

// MAX44009 related
#include "MAX44009_lib.h"    

// AO32 related
#include "AO32_lib.h" 

// AO19 related
#include "AO19_lib.h"

// Low Power Mode
#include "lp.h"
#include "mxc_config.h"
#include "lp.h"
#include "rtc.h"
//#include "board.h"      // Cannot find source?
#define LP1_WakeTime    3 //seconds
#define LP0_WakeTime    3 //seconds

// Virtual COM related
#include "USBSerial.h"      // for virtual COM
#define BS          8       // ASCII Back Space
#define CR          13      // ASCII Carriage Return

// Virtual serial port over USB TODO NEW VID PID NEEDED!!
USBSerial pc(0x0B6A, 0x0042, 0x0001, false);

/***************************************************************************
 * LEDs Instantiation
 **************************************************************************/
DigitalOut myled(LED2);          // LED = LED2 green
DigitalOut rLED(LED1);          // red LED
DigitalOut bLED(LED3);          // blue LED
//DigitalOut *led3;

/***************************************************************************
 * I2C Bus Instantiation
 **************************************************************************/
I2C i2cBus0(P1_6, P1_7);            // I2C of MAX32625PICO


bool get_data_flag = false;         // used for data tramission frequency on the SENSOR side
bool print_data_flag = false;       // used for data display on the GATEWAY side

//Timer setup
Ticker timer_1;                     // timer for data tramission frequency on the SENSOR side
Ticker timer_M;                     // timer for data print out on the GATEWAY side

void onTimerInterrupt(){
    get_data_flag = true;
}

void onGatewayInterrupt(){
    print_data_flag = true;
}

// *****************************************************************************
void RTC_Setup()
{
    rtc_cfg_t RTCconfig;

    RTCconfig.compareCount[0] = LP0_WakeTime;//3 second timer          
//    RTCconfig.compareCount[1] = LP1_WakeTime;      //3 second timer
    RTCconfig.prescaler = RTC_PRESCALE_DIV_2_12; //1Hz clock
    RTCconfig.prescalerMask = RTC_PRESCALE_DIV_2_12;//used for prescaler compare
    RTCconfig.snoozeCount = 0;
    RTCconfig.snoozeMode = RTC_SNOOZE_DISABLE;

    RTC_Init(&RTCconfig);

    RTC_Start();
}

//void Wakeup_LP1() {
//    
//        /***************************************************************************
//        * Temperature Sensor Data Measurement
//        **************************************************************************/
//        // obtain register hex values
//        convert_temperature(&i2cBus0, OT07_i2c_add);  //send OW convert selected device
//        wait_ms(CONVERT_T_DELAY);  //wait 20 ms for convert temperature to complete
//        int temp_error = OT07_read_register(&i2cBus0, OT07_i2c_add, OT07_FIFO_DATA, rawtempdata, 2); 
//        double tempFinal = calc_temperature(rawtempdata);
//        
//        //fill raw temp data into the array
//        curr_raw_temp_to_master[0] = rawtempdata[0];
//        curr_raw_temp_to_master[1] = rawtempdata[1];      
//        
//        /***************************************************************************
//        * Light Intensity Sensor Data Measurement
//        **************************************************************************/
//        // obtain register hex values
//        int lux_error = MAX44009_read_lux_register(&i2cBus0, MAX44009_i2c_add, MAX44009_LUX_HI, rawluxdata);
//        int luxFinal = (int) (calc_lux(rawluxdata));
//        
//        //fill raw lux data into the array
//        curr_raw_light_to_master[0] = rawluxdata[0];
//        curr_raw_light_to_master[1] = rawluxdata[1];
//        
//        /***************************************************************************
//        * Solar Harvester Data Measurement
//        **************************************************************************/
//        
//        int ocv_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_VOC, rawOCVdata);
//        int cnt_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_HARV_H, rawCntdata, 2); // burst read 2 bytes
//        
//        //calculate open circuit voltage from data
//        double OCVFinal = calc_OCV(rawOCVdata);
//        
//        //calculate harvesting counts from data
//        int countFinal = calc_Harvest(rawCntdata);
//        
//        //fill raw AO32 data into the array
//        curr_raw_AO32_to_master[0] = rawOCVdata[0];         // Fill OCV hex first
//        curr_raw_AO32_to_master[1] = rawCntdata[0];         // Fill Harvesting count high byte
//        curr_raw_AO32_to_master[2] = rawCntdata[1];         // Fill Harvesting count low byte
//        
//        // print out sensor data
//         pc.printf("SENSOR: [%.3f] [%d] [%.2f] [%d] [0]\r\n", tempFinal, luxFinal, OCVFinal, countFinal);
//        
//        /***************************************************************************
//        * Fill Payload Buffer With Data From Main Program Buffers for next LoRa Transmition
//        **************************************************************************/
//        memcpy(&BufferTx[tx_idx_signature], PongMsg,                  size_signature);
//        memcpy(&BufferTx[tx_idx_MAX30208],  curr_raw_temp_to_master, size_of_MAX30208);
//        memcpy(&BufferTx[tx_idx_MAX44009],  curr_raw_light_to_master, size_of_MAX44009);
//        memcpy(&BufferTx[tx_idx_MAX20361],  curr_raw_AO32_to_master,  size_of_MAX20361);
//
//        /***************************************************************************
//        * LoRa Communication: Send Sensor Data
//        **************************************************************************/
//        SX1276SlaveSendData();    
//}

int main() {

/***************************************************************************
 
    /* Setup begins here: */
    #if   MASTER == 1 // Master Device
        rLED = LED_ON;      // red LED on
        myled = LED_OFF;
        bLED = LED_OFF;
    #elif SLAVE == 1 // Slave Device
        rLED = LED_OFF;
        myled = LED_OFF;
        bLED = LED_ON;      // blue LED on
        
        //configure RTC and start for slave
        RTC_Setup();
        
//        sleep();            // put slave in sleep mode LP2
        
    #endif
    
     /***************************************************************************
     * Combined Payload Buffers for LoRa Communications
     **************************************************************************/
    uint8_t BufferTx[BufferSizeTx];             // more info in global_buffers.h
    uint8_t BufferRx[BufferSizeRx];             // more info in global_buffers.h
    
    /***************************************************************************
     * Identification Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
        uint8_t ID_of_slave[size_signature]; 
    #elif SLAVE == 1 // Slave Device
        uint8_t ID_of_master[size_signature];
    #endif
    
    /***************************************************************************
     * MAX30208 Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
        char curr_raw_temp_from_slave[size_of_MAX30208];   // to match data type
        char prev_raw_temp_from_slave[size_of_MAX30208];  
    #elif SLAVE == 1 // Slave Device
        uint8_t curr_raw_temp_to_master[size_of_MAX30208];
    #endif
    
    
    /***************************************************************************
     * MAX44009 Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
        char curr_raw_light_from_slave[size_of_MAX44009];    // to match data type
        char prev_raw_light_from_slave[size_of_MAX44009];
    #elif SLAVE == 1 // Slave Device
        uint8_t curr_raw_light_to_master[size_of_MAX44009];
    #endif
    
    /***************************************************************************
     * MAX20361 Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
        char curr_raw_AO32_from_slave[size_of_MAX20361];            // to match data type
        char prev_raw_AO32_from_slave[size_of_MAX20361];
    #elif SLAVE == 1 // Slave Device
        uint8_t curr_raw_AO32_to_master[size_of_MAX20361];
    #endif
    
    /***************************************************************************
     * Finish Setting up LoRa Radios: This passes in pointers to Buffers to send
     **************************************************************************/
    SX1276PingPongSetup(BufferTx, BufferRx, &pc);
    
//    Pointer Tutorial
//    https://www.tutorialspoint.com/cprogramming/c_pointers.htm
    
    /***************************************************************************
     * Create Dummy Data For Master and Slave
     **************************************************************************/
    
    #if SLAVE == 1
//    curr_raw_temp_to_master[0] = 99;
//    curr_raw_temp_to_master[1] = 99;
//
//    curr_raw_light_to_master[0] = 25;
//    curr_raw_light_to_master[1] = 26;
//
//    curr_raw_AO32_to_master[0] = 99;
//    curr_raw_AO32_to_master[1] = 0;
//    curr_raw_AO32_to_master[2] = 101;
//    curr_raw_AO32_to_master[3] = 102;    
     #endif
    
    /***************************************************************************
     * Loop Counter
     **************************************************************************/
    int loopCnt = 0;
    
    #if MASTER == 1
     //************* init ticker timer callbacks  ****************
    timer_M.attach(&onGatewayInterrupt, 3);        //Gateway data print out frequency
    #endif
    
    #if SLAVE == 1
    //************* init ticker timer callbacks  ****************
    timer_1.attach(&onTimerInterrupt, 10);        //Sensor data transmission frequency
    
    //************* OT07 Variables  **************** 
    char rawtempdata[2];          
    char OT07_i2c_add = 0xA0;
    
    //************* MAX44009 Variables  ****************
    char rawluxdata[2];          
    char MAX44009_i2c_add = 0x94;      // 0b1001 010x
    
    //************* AO32 Variables  ****************
    char rawOCVdata[2];                 // only needs 1
    char rawCntdata[2];
    char AO32_i2c_add = 0x2A;      // 0b0010 101x
    
     //************* AO19 Settings  ****************
    // Enable AO19
    char AO19_i2c_add = 0xD0;      // 
    char AO19_BB_CFG[2];              // store result of AO19's register 0x01 BBstCfg0
    int AO19_read = AO19_read_register(&i2cBus0, AO19_i2c_add, AO19_BB_CFG0, AO19_BB_CFG);
    
    int AO19_en = AO19_write_register(&i2cBus0, AO19_i2c_add, AO19_BB_CFG0, AO19_BB_CFG[0]|0x80);
    
   // if (AO19_en) {
//        pc.printf("AO19 Enabled fail!\r\n");
//    }
//    else {
//        pc.printf("AO19 Enabledsuccess!\r\n");
//    } 
    
    
    
    // LP0 Wake Up call
    if(LP_IsLP0WakeUp()){
        
     /***************************************************************************
        * Temperature Sensor Data Measurement
        **************************************************************************/
        // obtain register hex values
        convert_temperature(&i2cBus0, OT07_i2c_add);  //send OW convert selected device
        wait_ms(CONVERT_T_DELAY);  //wait 20 ms for convert temperature to complete
        int temp_error = OT07_read_register(&i2cBus0, OT07_i2c_add, OT07_FIFO_DATA, rawtempdata, 2); 
        double tempFinal = calc_temperature(rawtempdata);
        
        //fill raw temp data into the array
        curr_raw_temp_to_master[0] = rawtempdata[0];
        curr_raw_temp_to_master[1] = rawtempdata[1];      
        
        /***************************************************************************
        * Light Intensity Sensor Data Measurement
        **************************************************************************/
        // obtain register hex values
        int lux_error = MAX44009_read_lux_register(&i2cBus0, MAX44009_i2c_add, MAX44009_LUX_HI, rawluxdata);
        int luxFinal = (int) (calc_lux(rawluxdata));
        
        //fill raw lux data into the array
        curr_raw_light_to_master[0] = rawluxdata[0];
        curr_raw_light_to_master[1] = rawluxdata[1];
        
        /***************************************************************************
        * Solar Harvester Data Measurement
        **************************************************************************/
        
        int ocv_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_VOC, rawOCVdata);
        int cnt_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_HARV_H, rawCntdata, 2); // burst read 2 bytes
        
        //calculate open circuit voltage from data
//        double voltage = (double)(rawOCVdata[0]) / 100;
        double OCVFinal = calc_OCV(rawOCVdata);
        
        //calculate harvesting counts from data
        int countFinal = calc_Harvest(rawCntdata);
        
        //fill raw AO32 data into the array
        curr_raw_AO32_to_master[0] = rawOCVdata[0];         // Fill OCV hex first
        curr_raw_AO32_to_master[1] = rawCntdata[0];         // Fill Harvesting count high byte
        curr_raw_AO32_to_master[2] = rawCntdata[1];         // Fill Harvesting count low byte
        
        // print out sensor data
         pc.printf("SENSOR: [%.3f] [%d] [%.2f] [%d] [0]\r\n", tempFinal, luxFinal, OCVFinal, countFinal);
        
        /***************************************************************************
        * Fill Payload Buffer With Data From Main Program Buffers for next LoRa Transmition
        **************************************************************************/
        memcpy(&BufferTx[tx_idx_signature], PongMsg,                  size_signature);
        memcpy(&BufferTx[tx_idx_MAX30208],  curr_raw_temp_to_master, size_of_MAX30208);
        memcpy(&BufferTx[tx_idx_MAX44009],  curr_raw_light_to_master, size_of_MAX44009);
        memcpy(&BufferTx[tx_idx_MAX20361],  curr_raw_AO32_to_master,  size_of_MAX20361);

        /***************************************************************************
        * LoRa Communication: Send Sensor Data
        **************************************************************************/
        SX1276SlaveSendData();   
        
    }
    
    
    
    #endif
    
    while (1) {
    
    #if SLAVE == 1
    
    
        /***************************************************************************
        * LP0 Experiment
        **************************************************************************/
        //Clear existing wake-up config
        LP_ClearWakeUpConfig();

        //Clear any event flags
        LP_ClearWakeUpFlags();

        //configure wake-up on RTC compare 0
        LP_ConfigRTCWakeUp(1, 0, 0, 0);


        //set RTC compare 0 value
        uint32_t cmp = RTC_GetCount() + LP0_WakeTime;
        RTC_SetCompare(0,cmp);
        RTC_ClearFlags(MXC_F_RTC_FLAGS_COMP0);

        //interrupts are disabled in LP_EnterLP0
        LP_EnterLP0();

        //firmware will reset on wake-up
    
    #endif                  // end define for Slave    
    
    
    #if MASTER == 1         // only Receive Sensor Data
    /***************************************************************************
     * Fill Payload Buffer With Data From Main Program Buffers for next LoRa Transmition
     **************************************************************************/
    memcpy(&BufferTx[tx_idx_signature], PingMsg,           size_signature);         // no need
    
     /***************************************************************************
     * LoRa Communication: Gateway Receive Sensor Data
     **************************************************************************/
//    SX1276PingPong();
    if(SX1276MasterCheckForNewData())
    {
    
    /***************************************************************************
     * Fill Main Program Buffers With Data From Received Payload Buffer
     **************************************************************************/
    memcpy(ID_of_slave,               &BufferRx[rx_idx_signature], size_signature);
    memcpy(curr_raw_temp_from_slave, &BufferRx[rx_idx_MAX30208],  size_of_MAX30208);
    memcpy(curr_raw_light_from_slave, &BufferRx[rx_idx_MAX44009], size_of_MAX44009);
    memcpy(curr_raw_AO32_from_slave,  &BufferRx[rx_idx_MAX20361],  size_of_MAX20361);

    /***************************************************************************
    * Master Device: Print out Slave Data
    **************************************************************************/
    
    double tempResult = calc_temperature(curr_raw_temp_from_slave);
    int luxResult = (int) calc_lux(curr_raw_light_from_slave);
    
    char OCVrawHex[2];
    OCVrawHex[0] = curr_raw_AO32_from_slave[0];
    OCVrawHex[1] = curr_raw_AO32_from_slave[1];
    char CntrawHex[2];
    CntrawHex[0] = curr_raw_AO32_from_slave[2];
    CntrawHex[1] = curr_raw_AO32_from_slave[3];
    
    double OCVResult = calc_OCV(OCVrawHex);
    int CntResult = calc_Harvest(CntrawHex);
        
    //reset the flag
    print_data_flag = false;        // no need
    pc.printf("MSG: [%.3f] [%d] [%.2f] [%d] [0]\r\n", tempResult, luxResult, OCVResult, CntResult);
    
    }   // end of SX1276MasterCheckForNewData

    loopCnt = loopCnt + 1;
    
    #endif            // end define for Master
        
//    sleep();        // going back to sleep mode    
        
    } // end of while(1) loop
        
}  // end of main()