MAX20361 Demo Firmware

Dependencies:   SX1276GenericLib USBDevice

Fork of PICO_LoRa_Module_developing by Walter Luu

main.cpp

Committer:
walterluu
Date:
2020-10-14
Revision:
6:51f492ca61a2
Parent:
5:9e751733a6f3

File content as of revision 6:51f492ca61a2:


#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"

//#if defined(TARGET_MAX32630FTHR) // using the RFM95 board
//    #include "max32630fthr.h"
//    MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
//#endif

// 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);

///***************************************************************************
// * Virtual COM Instantiation
// **************************************************************************/
//#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;
}

int main() {

/***************************************************************************

 
 
    /* Setup begins here: */
    #if   MASTER == 1 // Master Device
//        pc.printf("MAX32625PICO: MASTER DEVICE\r\n");
//        wait(1);
    #elif SLAVE == 1 // Slave Device
//        pc.printf("MAX32625PICO: SLAVE DEVICE\r\n");
//        wait(1);
    #endif
    
    /* Introduction text: */
//    pc.printf("Welcome to the SX1276GenericLib\r\n");
//    wait(5);
//    pc.printf("Starting a simple LoRa PingPong\r\n");
//    wait(5);
    
     /***************************************************************************
     * 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
    
    /***************************************************************************
     * Dummy Data Buffers
     **************************************************************************/
    #if MASTER == 1  // Master Device
//        uint8_t curr_dum_to_slave[size_of_dum];
    #elif SLAVE == 1 // Slave Device
//        uint8_t curr_dum_from_master[size_of_dum];
//        uint8_t prev_dum_from_master[size_of_dum];
    #endif
    
    /***************************************************************************
     * MAX30208 Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
//        uint8_t curr_MAX77650_from_slave[size_of_MAX77650];
//        uint8_t curr_raw_temp_from_slave[size_of_MAX30208];
        char curr_raw_temp_from_slave[size_of_MAX30208];   // to match data type
//        uint8_t prev_MAX77650_from_slave[size_of_MAX77650];
        char prev_raw_temp_from_slave[size_of_MAX30208];  
    #elif SLAVE == 1 // Slave Device
//        uint8_t curr_MAX77650_to_master[size_of_MAX77650];
//        bool chrg_status = false; //True = ON False = OFF
        uint8_t curr_raw_temp_to_master[size_of_MAX30208];
    #endif
    
    
    /***************************************************************************
     * MAX44009 Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
//        uint8_t curr_raw_light_from_slave[size_of_MAX44009];
        char curr_raw_light_from_slave[size_of_MAX44009];    // to match data type
        char prev_raw_light_from_slave[size_of_MAX44009];
    //    static int16_t conv_frame_data_from_slave[64];
    #elif SLAVE == 1 // Slave Device
        uint8_t curr_raw_light_to_master[size_of_MAX44009];
    //    static char prev_raw_light_data_to_master[size_of_MAX44009];
    //    static int16_t conv_frame_data_to_master[64];
    #endif
    
    /***************************************************************************
     * MAX20361 Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
//        uint8_t curr_raw_AO32_from_slave[size_of_MAX20361];
        char curr_raw_AO32_from_slave[size_of_MAX20361];            // to match data type
        char prev_raw_AO32_from_slave[size_of_MAX20361];
    //    static int16_t conv_frame_data_from_slave[64];
    #elif SLAVE == 1 // Slave Device
        uint8_t curr_raw_AO32_to_master[size_of_MAX20361];
    //    static char prev_raw_AO32_data_to_master[size_of_MAX20361];
    //    static int16_t conv_frame_data_to_master[64];
    #endif
    
    /***************************************************************************
     * Other Data Buffers
     **************************************************************************/
    #if   MASTER == 1 // Master Device
//        uint8_t curr_raw_other_from_slave[size_of_other];
//        uint8_t prev_raw_other_from_slave[size_of_other];
    //    static int16_t conv_frame_data_from_slave[64];
    #elif SLAVE == 1 // Slave Device
//        uint8_t curr_raw_other_to_master[size_of_other];
    //    static char prev_raw_other_data_to_master[size_of_other];
    //    static int16_t conv_frame_data_to_master[64];
    #endif
    
    /***************************************************************************
     * Finish Setting up LoRa Radios: This passes in pointers to Buffers to send
     **************************************************************************/
    SX1276PingPongSetup(BufferTx, BufferRx, &pc);
    
//    Pointer Tutorials
//    https://www.tutorialspoint.com/cprogramming/c_pointers.htm
    
    /***************************************************************************
     * Create Dummy Data For Master and Slave
     **************************************************************************/
//    Array Tutorials    
//    http://www.cplusplus.com/doc/tutorial/arrays/
    #if MASTER == 1
//    curr_dum_to_slave[0] = {33, 34};
//    curr_dum_to_slave[0] = 33;
//    curr_dum_to_slave[1] = 34;
    #endif
    
    #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] = 100;
    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, 3);        //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);
    
//    if (AO19_read) {
//        pc.printf("AO19 Initial Read fail!\r\n");
//    }
//    else {
//        pc.printf("AO19 Initial Read success!\r\n");
//    } 
    
    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");
//    } 
    
    
    #endif
    
    while (1) {
    
    #if SLAVE == 1
    if(get_data_flag) {
        
        //reset the flag
        get_data_flag = false;
//        pc.printf("Timer interval reached!\r\n");
        
        /***************************************************************************
        * 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); 
//        pc.printf("OT07 add[%02X] data[%02X] data[%02X]\r\n", OT07_FIFO_DATA, rawtempdata[0], rawtempdata[1]);  
            
        //calculate temperature from data     
//        int count = (int)(rawtempdata[0]*256 + rawtempdata[1]);
//        if (count >= 32768)count = count - 65536;     // 2s comp
//        double Temp = (double)count*0.005; 
//        pc.printf("OT07  temperature[%.3f]  status[%d]\r\n", Temp, temp_error);
        double tempFinal = calc_temperature(rawtempdata);
//        pc.printf("OT07  Final temperature[%.3f] \r\n", tempFinal);
//        pc.printf("\r\n");
        
        
        //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 lux_error1 = MAX44009_read_register(&i2cBus0, MAX44009_i2c_add, MAX44009_LUX_HI, &rawluxdata[0]);
//        int lux_error2 = MAX44009_read_register(&i2cBus0, MAX44009_i2c_add, MAX44009_LUX_LO, &rawluxdata[1]);
//        pc.printf("MAX44009 hi_add[%02X] hi_data[%02X] lo_add[%02X] lo_data[%02X]\r\n", MAX44009_LUX_HI, rawluxdata[0], MAX44009_LUX_LO, rawluxdata[1]);
        
        //calculate temperature from data  
//        int exponent = int(rawluxdata[0] >> 4);
//        int mantissa = (int)((rawluxdata[0] << 4) & 0xF0) + (int)(rawluxdata[1]);
//        double lux = 0.045 * mantissa * pow((double) 2, exponent);
//        pc.printf("MAX44009  exponent[%d]  mantissa[%d]\r\n", exponent, mantissa);
//        pc.printf("MAX44009  lux[%.2f]  status[%d] status[%d]\r\n", lux, lux_error1, lux_error2);
//        pc.printf("MAX44009  lux[%.2f]  status[%d]\r\n", lux, lux_error);
        int luxFinal = (int) (calc_lux(rawluxdata));
//        pc.printf("MAX44009  Final Lux[%.2f] \r\n", luxFinal);
//        pc.printf("\r\n");
        
        //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
        **************************************************************************/
        // obtain register hex values
//        char AO32ID[2];
//        int id_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_DEVICE_ID, AO32ID);  // testing
//        pc.printf("AO32 add[%02X] data[%02X]\r\n", AO32_DEVICE_ID, AO32ID[0]);              // should be 0x00: 0x11
        
        int ocv_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_VOC, rawOCVdata);
//        pc.printf("AO32 add[%02X] data[%02X]\r\n", AO32_VOC, rawOCVdata[0]);
        int cnt_error = AO32_read_register(&i2cBus0, AO32_i2c_add, AO32_HARV_H, rawCntdata, 2); // burst read 2 bytes
//        pc.printf("AO32 hi_add[%02X] hi_data[%02X] lo_add[%02X] lo_data[%02X]\r\n", AO32_HARV_H, rawCntdata[0], AO32_HARV_L, rawCntdata[1]);
        
        //calculate open circuit voltage from data
        double voltage = (double)(rawOCVdata[0]) / 100;
//        pc.printf("AO32  OCV[%.2f]  status[%d]\r\n", voltage, ocv_error);  
        double OCVFinal = calc_OCV(rawOCVdata);
//        pc.printf("AO32  Final OCV[%.2f]  \r\n", OCVFinal);
//        pc.printf("\r\n");
        
        //calculate harvesting counts from data
//        int countHi = int(rawCntdata[0]) * 256;
//        int countLo = int(rawCntdata[1]);
//        int harvest_counts = countHi + countLo;
//        pc.printf("AO32  HarvesterCnt[%d]  status[%d]\r\n", harvest_counts, cnt_error); 
        int countFinal = calc_Harvest(rawCntdata);
//        pc.printf("AO32 Final HarvesterCnt[%d]\r\n",  countFinal);
//        pc.printf("\r\n");
        
        
        //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);
//        memcpy(&BufferTx[tx_idx_other],  curr_raw_other_to_master,  size_of_other);
        
        /***************************************************************************
        * In case of OnRxTimeout
        **************************************************************************/
        // Slave Device, these are values when LoRa communication did not happen
       // ID_of_master[0] = 'N'; // 0x4E or 78
//        ID_of_master[1] = 'A'; // 0x41 or 65
//        ID_of_master[2] = 'C'; // 0x43 or 67
//        ID_of_master[3] = 'K'; // 0x4B or 75
//        ID_of_master[4] = 'M'; // 0x4D or 77
//        ID_of_master[5] = 'A'; // 0x41 or 65
//        ID_of_master[6] = 'S'; // 0x53 or 83
//        ID_of_master[7] = '!'; // 0x21 or 33
//        
//        curr_dum_from_master[0] = 39;
//        curr_dum_from_master[1] = 40;       
        
        /***************************************************************************
        * LoRa Communication: Send Sensor Data
        **************************************************************************/
//        SX1276SensorSend();
        SX1276PingPong(); 
//        int sendTime = TimeOnAirSend();
//        pc.printf("Tx Time on Air: %d \r\n", sendTime);
        
        /***************************************************************************
        * Fill Main Program Buffers With Data From Received Payload Buffer
        **************************************************************************/
        // Slave Device
//        memcpy(ID_of_master,              &BufferRx[rx_idx_signature], size_signature);
//        memcpy(curr_dum_from_master,      &BufferRx[rx_idx_dum],       size_of_dum);
        
         /***************************************************************************
        * Slave Device: Print out Master Data
        **************************************************************************/
        //        memcpy(ID_of_master,              &BufferRx[rx_idx_signature], size_signature);
//        pc.printf("Print ID_of_master\r\n");
//        for(int i = 0; i < sizeof(ID_of_master); i++){
//            pc.printf("%d \r\n", ID_of_master[i]);
//        }
            
        //        memcpy(curr_dum_from_master,      &BufferRx[rx_idx_dum],       size_of_dum);
//        pc.printf("Print Dum From Master\r\n");
//        for(int i = 0; i < sizeof(curr_dum_from_master); i++){
//            pc.printf("%d \r\n", curr_dum_from_master[i]);
//        }
            
        // print loop counter
//        pc.printf("Loop Counter Slave: %d \r\n", loopCnt);
        loopCnt = loopCnt + 1;
    } // end of transmission frequency for slave
    #endif    
    
    
    #if MASTER == 1
    /***************************************************************************
     * Fill Payload Buffer With Data From Main Program Buffers for next LoRa Transmition
     **************************************************************************/
    memcpy(&BufferTx[tx_idx_signature], PingMsg,           size_signature);
//    memcpy(&BufferTx[tx_idx_dum],       curr_dum_to_slave, size_of_dum);
    
     /***************************************************************************
     * LoRa Communication: Gateway Receive Sensor Data
     **************************************************************************/
//    SX1276GateWayReceive(333);
    SX1276PingPong();
//    int sendTime = TimeOnAirSend();
//    pc.printf("Tx Time on Air: %d \r\n", sendTime);
    
    /***************************************************************************
     * 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);
//    memcpy(curr_raw_other_from_slave,  &BufferRx[rx_idx_other],  size_of_other);

    /***************************************************************************
    * Master Device: Print out Slave Data
    **************************************************************************/
    
    //        memcpy(ID_of_slave,               &BufferRx[rx_idx_signature], size_signature);
    //pc.printf("Print ID_of_slave\r\n");
//    for(int i = 0; i < sizeof(ID_of_slave); i++){
//        pc.printf("%d \r\n", ID_of_slave[i]); 
//    }
    
    //        memcpy(curr_raw_temp_from_slave, &BufferRx[rx_idx_MAX30208],  size_of_MAX30208);
//    pc.printf("Print MAX30208 data\r\n");
//    for(int i = 0; i < sizeof(curr_raw_temp_from_slave); i++){
//        pc.printf("[%02X]\r\n", curr_raw_temp_from_slave[i]); 
//    } 
    
//    int count = curr_raw_temp_from_slave[0] * 256 +  curr_raw_temp_from_slave[1];
//    if (count >= 32768)count = count - 65536;     // 2s comp
//    double tempResult = count * 0.005; 
    
    double tempResult = calc_temperature(curr_raw_temp_from_slave);
//    pc.printf("MSG: [%.3f] [] [] [] []\r\n", tempResult);
    
            
    //        memcpy(curr_raw_light_from_slave, &BufferRx[rx_idx_MAX44009], size_of_MAX44009);
//     pc.printf("Print MAX44009 data\r\n");
//    for(int i = 0; i < sizeof(curr_raw_light_from_slave); i++){
//        pc.printf("[%02X] \r\n", curr_raw_light_from_slave[i]);
//    }
    
    int luxResult = (int) calc_lux(curr_raw_light_from_slave);
//    pc.printf("MSG: [%.3f] [%.2f] [] [] []\r\n", tempResult, luxResult);
            
    //        memcpy(curr_raw_AO32_from_slave,  &BufferRx[rx_idx_MAX20361],  size_of_MAX20361);
//    pc.printf("Print MAX20361 data\r\n");
//    for(int i = 0; i < sizeof(curr_raw_AO32_from_slave); i++){
//        pc.printf("[%02X] \r\n", curr_raw_AO32_from_slave[i]);
//    }
    
    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);
    
    
    // only print out new results
//    int tempNew = memcmp(prev_raw_temp_from_slave, curr_raw_temp_from_slave, sizeof(size_of_MAX30208)); 
//    int luxNew = memcmp(prev_raw_light_from_slave, curr_raw_light_from_slave, sizeof(size_of_MAX44009)); 
//    int AO32New = memcmp(prev_raw_AO32_from_slave, curr_raw_AO32_from_slave, sizeof(size_of_MAX20361)); 
    
//    if (tempNew != 0 || luxNew != 0 || AO32New != 0) {
    
//        pc.printf("MSG: [%.3f] [%d] [%.2f] [%d] [0]\r\n", tempResult, luxResult, OCVResult, CntResult);
    
//    }
    
    if(print_data_flag) {
        
        //reset the flag
        print_data_flag = false;
        pc.printf("MSG: [%.3f] [%d] [%.2f] [%d] [0]\r\n", tempResult, luxResult, OCVResult, CntResult);
    
    }
    
    // copy the current recceived data into previous data
//    memcpy(prev_raw_temp_from_slave, curr_raw_temp_from_slave, sizeof(size_of_MAX30208));
//    memcpy(prev_raw_light_from_slave, c/urr_raw_light_from_slave, sizeof(size_of_MAX44009));         
//    memcpy(prev_raw_AO32_from_slave, curr_raw_AO32_from_slave, sizeof(size_of_MAX20361)); 
    
    // print loop counter
//    pc.printf("Loop Counter Master: %d \r\n", loopCnt);
    loopCnt = loopCnt + 1;
    
    #endif
        
    } // end of while(1) loop
        
}  // end of main()