Denwis La / Mbed OS mDot_Send_Data

Dependencies:   libmDot-dev-mbed5-deprecated ISL29011

Fork of mdot-examples by 3mdeb

Revision:
4:b0ce6385d008
Child:
5:c9ab5062cfc3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/peer_to_peer_example.cpp	Fri Dec 01 01:07:57 2017 +0000
@@ -0,0 +1,782 @@
+#include "dot_util.h"
+#include "RadioEvent.h"
+#include <string.h>
+#include <mbed.h>
+ 
+
+/////////////////////////////////////////////////////////////////////////////
+// -------------------- DOT LIBRARY REQUIRED ------------------------------//
+// * Because these example programs can be used for both mDot and xDot     //
+//     devices, the LoRa stack is not included. The libmDot library should //
+//     be imported if building for mDot devices. The libxDot library       //
+//     should be imported if building for xDot devices.                    //
+// * https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/    //
+// * https://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/        //
+// * https://developer.mbed.org/teams/MultiTech/code/libxDot-dev-mbed5/    //
+// * https://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/        //
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////
+// * these options must match between the two devices in   //
+//   order for communication to be successful
+//-------------------MDOT variables------------------------//
+/////////////////////////////////////////////////////////////
+static uint8_t network_address[] = { 0x00, 0x11, 0x22, 0x33 };
+static uint8_t network_session_key[] = { 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33 };
+static uint8_t data_session_key[] = { 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00 };
+
+mDot* dot = NULL;
+lora::ChannelPlan* plan = NULL;
+//--------------End of MDOT variables-------------------//
+
+Serial pc(USBTX, USBRX);
+
+// ADXL372 Slave SPI
+DigitalOut MOSI(D11);
+DigitalIn MISO(D12);
+DigitalOut SPI_CLK(D13);
+DigitalOut SPI_CS(D10);
+//InterruptIn INT1();
+//InterruptIn INT2();
+DigitalOut CS(D10); // Used for CS chip select
+
+// ADXL372 Slave I2C
+I2C ADXL372(I2C_SDA, I2C_SCL);  // (D14,D15) (MISO, CS)
+
+// ADT7410 Temperature
+I2C ADT7410(I2C_SDA, I2C_SCL);      // Attempt at making I2C connection to slaves (D14,D15)
+InterruptIn ADT7410_Int(D2);    // Allow this pin for ADT7410 Interrupt critical temperature notice
+
+// DS7505s Temperature
+I2C DS7505(I2C_SDA, I2C_SCL);      // Attempt at making I2C connection to slaves (D14,D15)
+
+// Create reocurring interrupt function that could be used to periodically take temperatures
+// Not working right now due to some mutex initialize error
+// Suspect that it is due to it having be a RTOS task thing
+// Should probably go back to using an in processor timer interrupt instead of mbed
+Ticker interruptEverything;
+
+const int ADT7410_Address_7BIT = 0x49;  // A0 set HIGH and A1 set LOW
+const int ADT7410_Address_8BIT = ADT7410_Address_7BIT << 1; // Shift 1 bit to left for R/~W bit, and basic I2C format
+
+const int ADXL372_Address_7bit = 0x1D;      // Address for the I2C if MISO pulled low, 0x53 if pulled high
+const int ADXL372_Address_8bit = ADXL372_Address_7bit << 1; // Same
+
+const int DS7505s_Address_7bit = 0x48;  // A0 set LOR, A1 set LOW, A2 set LOW
+const int DS7505s_Address_8bit = DS7505s_Address_7bit << 1; // Same
+
+
+//-------------------All prototype functions-----------------------//
+void ADXL372Initialize(void);
+
+int accelerometerI2CWrite(int hexAddress, int hexData);
+char * accelerometerI2CRead(int hexAddress);
+void ADXL372Reset(void);
+void BitBangSPIWrite(const unsigned char regAddr, const unsigned char regData);
+unsigned char BitBangSPIRead (const unsigned char regAddr);
+
+int ADT7410Write(unsigned char registerAddress, unsigned char data);
+char * ADT7410Read(int hex);
+
+int DS7505sWrite(unsigned char registerAddress, unsigned char data);
+char * DS7505sRead(int hex);
+
+unsigned char * twosComplementConversion(unsigned char *value);
+//---------------------End of prototype functions-----------------------------//
+
+void printMenu(){
+    pc.printf("Please eneter a debug option: \n\r"
+                "1: Read converted values from Accelerometer ADXL372\n\r"
+                "2: Read converted values from Temperature ADT7410\n\r"
+                "3: Read raw values from Accelerometer ADXL372\n\r"
+                "4: Read raw values from Temperature ADT7410\n\r"
+                "5: Initialize Accelerometer\n\r"
+                "6: Reset Accelerometer\n\r"
+                "7: Send Temperature data\n\r");
+}
+
+
+/*******************************************************************************
+ *  Function to be called by the ticker interrupt
+ *  Read temperatures and send it 
+ *
+ *
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+void interruptReadTemperature(void){
+    std::vector<uint8_t> tx_data;
+    uint16_t temperatures;
+    char data[2] = {0, 0};
+    char cmd[1];
+    cmd[0] = 0x00;
+    //pc.printf("Register Addres is: %x \n\r", cmd[0]); 
+    if(ADT7410.write(ADT7410_Address_8BIT, cmd,1) == 0){
+        if(ADT7410.read(ADT7410_Address_8BIT, data, 2) == 0){
+            temperatures = ((data[0] << 8) | data[1]) >> 3;
+            tx_data.push_back((temperatures >> 8) & 0xFF);
+            tx_data.push_back(temperatures & 0xFF);
+            logInfo("light: %lu [0x%04X]", temperatures, temperatures);
+            send_data(tx_data);
+            //return (data[0] >> 8 | data[1])>>3;     // Explained here: https://stackoverflow.com/a/141576 SOOO GOOOOODDD
+            
+        }
+    }
+}
+////////////////////////////////////////////////////////////////////////////////
+
+int main() {
+    // Custom event handler for automatically displaying RX data
+    interruptEverything.attach(&interruptReadTemperature, 7.0);
+    RadioEvent events;
+    uint32_t tx_frequency;
+    uint8_t tx_datarate;
+    uint8_t tx_power;
+    uint8_t frequency_band;
+    
+    // Points to the returned char pointer from called functions
+    char * rawTempValues;           // Could change to uint8_t, same for other char pointers
+    
+    // Save converted values here
+    uint16_t convertedTempValue;    // Data values must be uint16_t for conversion and send prep
+    char *accelValues;
+    uint16_t XData;
+    uint16_t YData;
+    uint16_t ZData;
+    int regAddress;
+
+    // Change baud rate in serial terminal to this value
+    pc.baud(115200);
+    
+    
+    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
+    
+    // Sometimes when calling this, it creates error: type specifier expected
+    // Even with identical include files I would get this in another workspace.
+    plan = new lora::ChannelPlan_US915();
+
+    logInfo("Now asserting");
+    assert(plan);
+
+    // Careful when using this. The production ready libmdot-mbed5 has a void constructor
+    // Therefore, can only use the libmDot-dev-mbed5 version, for now.
+    dot = mDot::getInstance(plan);
+    assert(dot);
+
+    logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
+
+    // start from a well-known state
+    logInfo("defaulting Dot configuration");
+    dot->resetConfig();
+
+    // make sure library logging is turned on
+    dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
+
+    // attach the custom events handler
+    dot->setEvents(&events);
+
+    // update configuration if necessary
+    if (dot->getJoinMode() != mDot::PEER_TO_PEER) {
+        logInfo("changing network join mode to PEER_TO_PEER");
+        if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) {
+            logError("failed to set network join mode to PEER_TO_PEER");
+        }
+    }
+    
+/*
+ *  Get the Frequency and then choose transfer frequency, datarate, and power accordingly
+ *
+ */
+////////////////////////////////////////////////////////////////////////////////
+    frequency_band = dot->getFrequencyBand();
+    switch (frequency_band) {
+        case lora::ChannelPlan::EU868_OLD:
+        case lora::ChannelPlan::EU868:
+            // 250kHz channels achieve higher throughput
+            // DR_6 : SF7 @ 250kHz
+            // DR_0 - DR_5 (125kHz channels) available but much slower
+            tx_frequency = 869850000;
+            tx_datarate = lora::DR_6;
+            // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7
+            tx_power = 4;
+            break;
+
+        case lora::ChannelPlan::US915_OLD:
+        case lora::ChannelPlan::US915:
+        case lora::ChannelPlan::AU915_OLD:
+        case lora::ChannelPlan::AU915:
+            // 500kHz channels achieve highest throughput
+            // DR_8 : SF12 @ 500kHz
+            // DR_9 : SF11 @ 500kHz
+            // DR_10 : SF10 @ 500kHz
+            // DR_11 : SF9 @ 500kHz
+            // DR_12 : SF8 @ 500kHz
+            // DR_13 : SF7 @ 500kHz
+            // DR_0 - DR_3 (125kHz channels) available but much slower
+            tx_frequency = 915500000;
+            tx_datarate = lora::DR_13;
+            // 915 bands have no duty cycle restrictions, set tx power to max
+            tx_power = 20;
+            break;
+
+        case lora::ChannelPlan::AS923:
+        case lora::ChannelPlan::AS923_JAPAN:
+            // 250kHz channels achieve higher throughput
+            // DR_6 : SF7 @ 250kHz
+            // DR_0 - DR_5 (125kHz channels) available but much slower
+            tx_frequency = 924800000;
+            tx_datarate = lora::DR_6;
+            tx_power = 16;
+            break;
+
+        case lora::ChannelPlan::KR920:
+            // DR_5 : SF7 @ 125kHz
+            tx_frequency = 922700000;
+            tx_datarate = lora::DR_5;
+            tx_power = 14;
+            break;
+
+        default:
+            while (true) {
+                logFatal("no known channel plan in use - extra configuration is needed!");
+                wait(5);
+            }
+            break;
+    }
+    
+////////////////////////////////////////////////////////////////////////////////
+
+    // in PEER_TO_PEER mode there is no join request/response transaction
+    // as long as both Dots are configured correctly, they should be able to communicate
+    update_peer_to_peer_config(network_address, network_session_key, data_session_key, tx_frequency, tx_datarate, tx_power);
+    
+    // save changes to configuration
+    logInfo("saving configuration");
+    if (!dot->saveConfig()) {
+        logError("failed to save configuration");
+    }
+
+    // Display configuration
+    // It's gonna output a lot of information onto the Serial Terminal
+    display_config();
+    
+/*
+ *
+ *  From here on is my own code
+ *  Can add more options to choose from
+ *
+ */
+////////////////////////////////////////////////////////////////////////////////
+    printMenu();
+    pc.printf("\n\rChoose what you want to do: \n\r");
+    
+    char userInput = pc.getc();
+    while(1){
+        // Create a vector of uint8_t elements to be sent later
+        std::vector<uint8_t> tx_data;
+        
+        // Checks if a character has been pressed;
+        // Works right now for 1 digit numbers :(
+        // Change to work with larger inputs
+        if(pc.readable())   
+        {
+            userInput = pc.getc();
+            switch(userInput){
+            case 49:    // 1
+                pc.printf("Reading converted values from accelerometer\n\r");
+                for(int i = 0; i < 15; ++i){
+                    regAddress = 0x08;  // This is the register address for XData
+                    accelValues = accelerometerI2CRead(regAddress);
+                    XData = ((*(accelValues + 0) << 8) | *(accelValues + 1)) >> 4;  // Combine two bytes into short in, remove last 4 flag bits
+                    YData = ((*(accelValues + 2) << 8) | *(accelValues + 3)) >> 4;
+                    ZData = ((*(accelValues + 4) << 8) | *(accelValues + 5)) >> 4;
+                    pc.printf("\n %d: X: 0x%x | Y: 0x%x | Z: 0x%x \n\r", i+1, XData, YData, ZData);
+                    wait(0.2);
+                }
+                break;
+            case 50:    // 2
+                pc.printf("Reading converted values from temperature\n\r");
+                for(int i = 0; i < 10; ++i){
+                    regAddress = 0x00;
+                    rawTempValues = ADT7410Read(regAddress);
+                    convertedTempValue = ((*(rawTempValues + 0) << 8) | *(rawTempValues + 1)) >> 3; // Combine the two bytes into 
+                                                                                                    // a short int variable, remove last 3 
+                                                                                                    
+                    pc.printf("\n %d: Temperature is: 0x%x \n\r", i+1, convertedTempValue);
+                }
+                
+                break;
+            case 51:    // 3
+                pc.printf("Reading raw values from accelerometer\n\r");
+                for(int i = 0; i < 15; ++i){
+                    regAddress = 0x08;
+                    accelValues = accelerometerI2CRead(regAddress);
+                    XData = ((*(accelValues + 0) << 8) | *(accelValues + 1)) >> 4;  // Combine two bytes into short in, remove last 4 flag bits
+                    YData = ((*(accelValues + 2) << 8) | *(accelValues + 3)) >> 4;
+                    ZData = ((*(accelValues + 4) << 8) | *(accelValues + 5)) >> 4;
+                    pc.printf("\n %d: X:: H: %x | L: %x | Y:: H: %x | L: %x | Z: H: %x | L: %x \n\r", i+1, *(accelValues + 0), *(accelValues + 1), *(accelValues + 2), *(accelValues + 3), *(accelValues + 4), *(accelValues + 5));
+                    wait(0.2);
+                }
+                break;
+            case 52:    // 4
+                pc.printf("Reading raw values from temperature\n\r");
+                for(int i = 0; i < 10; ++i){
+                    regAddress = 0x00;
+                    rawTempValues = ADT7410Read(regAddress);
+                    pc.printf("\n %d: Temperature is: HIGH BYTE: %x | LOW BYTE: %x \n\r", i+1, *(rawTempValues + 0), *(rawTempValues + 1));
+                }
+                break;
+            case 53:    // 5
+                ADXL372Initialize();
+                break;
+            case 54:    // 6
+                ADXL372Reset();
+                break;
+                
+            case 55:    // 7
+                regAddress = 0x00;
+                rawTempValues = ADT7410Read(regAddress);
+                convertedTempValue = ((*(rawTempValues + 0) << 8) | *(rawTempValues + 1)) >> 3; // Combine the two bytes
+
+                tx_data.push_back((convertedTempValue >> 8) & 0xFF);
+                tx_data.push_back(convertedTempValue & 0xFF);
+                logInfo("light: %lu [0x%04X]", convertedTempValue, convertedTempValue);
+                send_data(tx_data);
+                
+            default:
+                printMenu();
+                break;
+            }
+        }
+        
+    }
+    
+    return 0;    
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+/*******************************************************************************
+ *                                                                             
+ *  I2C function for the the ADXL372 accelerometer for a write sequence
+ *  Param:
+ *      hexAddress: Pass the hexadecimal value for what register you want
+ *      hexData: Pass the hexadecimal value for what data you want to send
+ *               i.e. hexadecimal represenatation of certain bits
+ *  Returns:             
+ *      1: Write was a complete success
+ *      2: Writing data to register failed
+ *      3: Writing to register Address failed     
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+int accelerometerI2CWrite(int hexAddress, int hexData){
+ //--------- One full writing cycle for ADXL372 for X enable ------------------//
+/*    '0' - NAK was received
+ *    '1' - ACK was received, <---- This good
+ *    '2' - timeout
+ */
+    int flag;
+    int registerAddress = hexAddress;
+    int data = hexData;
+    
+    ADXL372.start();
+    flag = ADXL372.write(ADXL372_Address_8bit);
+    if(flag == 1)
+    {
+        pc.printf("Write to I2C address success\n\r");
+        wait(0.1);
+        flag = ADXL372.write(registerAddress);
+        if(flag == 1)
+        {
+            pc.printf("Write to register 0x%x address success\n\r", registerAddress);
+            flag = ADXL372.write(data);
+            if(flag == 1)
+            {
+                pc.printf("Writing data 0x%x to register address success\n\r", data);
+                ADXL372.stop();
+                return 1;
+            }else {ADXL372.stop(); return 2;} 
+        }else {ADXL372.stop(); return 3;}
+    }else ADXL372.stop();
+       
+    return 0;
+// ---------------- End of writing cycle --------------------------//   
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+/*******************************************************************************
+ *  I2C read sequence for the accelerometer
+ *  Param:
+ *      hexAddress: pass the hexadecimal representation of desired Register address
+ *  Return:
+ *      Char pointer to the array of read data. 
+ *
+ *  Right now it works only for the XData, YData, ZData because I wrote it to read
+ *  6 bytes(6 registers).
+ *  Should change it to be 1 byte at a time
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+char * accelerometerI2CRead(int hexAddress){
+    char accelData[6];
+    char registerAddress[1];
+    registerAddress[0] = hexAddress;
+    
+    // Perform mbed's way sending a start bit, then device address[r/~w], and then the register address
+    // Also if it succeeds, continue to the next operation
+    if(ADXL372.write(ADXL372_Address_8bit, registerAddress, 1) == 0){
+        
+        // If previous sequence works, get 6 bytes into char array accelData
+        // Char array because it uses 1 byte(8bits)
+        // Should probably change it to uint8_t type
+        if(ADXL372.read(ADXL372_Address_8bit, accelData, 6) == 0){
+            return accelData;
+        }else pc.printf("Failed to read\n\r");
+    }else pc.printf("Failed to write\n\r");
+    return 0; // Only if it fails   
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+/*******************************************************************************
+ *  Initializes whatever settings you want for the accelerometer
+ *  Can change it to use the previous I2C write function instead of all this mess
+ *
+ ******************************************************************************/  
+////////////////////////////////////////////////////////////////////////////////
+void ADXL372Initialize(void){
+    int flag;
+    
+//--------- Change mode to full Bandwidth Measurement Mode ------------------//
+/*    '0' - NAK was received
+ *    '1' - ACK was received, <---- This good
+ *    '2' - timeout
+ */
+    pc.printf("Initializing Single Byte write\n\r");
+    ADXL372.start();                                                // Send start
+    flag = ADXL372.write(ADXL372_Address_8bit | 0);                 // Send Device Address
+    if(flag == 1)
+    {
+        pc.printf("Write to I2C address for write success\n\r");
+        wait(0.1);
+        flag = ADXL372.write(0x3F);                                 // Send Register Address
+        if(flag == 1)
+        {   
+            
+            pc.printf("Write to 0x3F register address success\n\r");
+            flag = ADXL372.write(0x03);         // Send Data that represents Full BandWidth mode
+            if(flag == 1)
+            {
+                pc.printf("Write data to register address success\n\r");
+                ADXL372.stop();
+            }
+        }
+    }
+    else ADXL372.stop();
+// ---------------- End of writing cycle --------------------------//
+
+//--------- One full writing cycle for ADXL372 for X enable ------------------//
+/*    '0' - NAK was received
+ *    '1' - ACK was received, <---- This good
+ *    '2' - timeout
+ */
+    ADXL372.start();
+    flag = ADXL372.write(ADXL372_Address_8bit);
+    if(flag == 1)
+    {
+        pc.printf("Write to I2C address success\n\r");
+        wait(0.1);
+        flag = ADXL372.write(0x24);
+        if(flag == 1)
+        {
+            pc.printf("Write to register 0x24 address success\n\r");
+            flag = ADXL372.write(0x01);
+            if(flag == 1)
+            {
+                pc.printf("Write data to register address success\n\r");
+                pc.printf("X Enable should be set now\n\r");
+                ADXL372.stop();
+            }
+        }
+    }
+    else ADXL372.stop();
+// ---------------- End of writing cycle --------------------------//
+
+//--------- One full writing cycle for ADXL372 for Y Enable ------------------//
+/*    '0' - NAK was received
+ *    '1' - ACK was received, <---- This good
+ *    '2' - timeout
+ */
+    ADXL372.start();
+    flag = ADXL372.write(ADXL372_Address_8bit);
+    if(flag == 1)
+    {
+        pc.printf("Write to I2C address success\n\r");
+        wait(0.1);
+        flag = ADXL372.write(0x25);
+        if(flag == 1)
+        {
+            pc.printf("Write to 0x25 register address success\n\r");
+            flag = ADXL372.write(0x01);
+            if(flag == 1)
+            {
+                pc.printf("Write data to register address success\n\r");
+                pc.printf("Y Enable should be set now\n\r");
+
+                ADXL372.stop();
+            }
+        }
+    }
+    else ADXL372.stop();
+// ---------------- End of writing cycle --------------------------//
+
+//--------- One full writing cycle for ADXL372 for Z Enable ------------------//
+/*    '0' - NAK was received
+ *    '1' - ACK was received, <---- This good
+ *    '2' - timeout
+ */
+    ADXL372.start();
+    flag = ADXL372.write(ADXL372_Address_8bit);
+    if(flag == 1)
+    {
+        pc.printf("Write to I2C address success\n\r");
+        wait(0.1);
+        flag = ADXL372.write(0x26);
+        if(flag == 1)
+        {
+            pc.printf("Write to 0x26 register address success\n\r");
+            flag = ADXL372.write(0x01);                             // Set bit 0
+            if(flag == 1)
+            {
+                pc.printf("Write data to register address success\n\r");
+                pc.printf("Z Enable should be set now\n\r");
+
+                ADXL372.stop();
+            }
+        }
+    }
+    else ADXL372.stop();
+// ---------------- End of writing cycle --------------------------//
+
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+/*******************************************************************************
+ * BitBangSPIWrite for ADXL372 if you wire it up as SPI
+ *
+ * Sends the 6-0bits of desired register with LSB of transmission bit R/!W
+ * 
+ ******************************************************************************/
+ ///////////////////////////////////////////////////////////////////////////////
+ void BitBangSPIWrite(const unsigned char regAddr, const unsigned char regData)
+{
+    unsigned char SPICount;                                          // Counter used to clock out the data
+
+    unsigned char SPIData;                                          // Define a data structure for the SPI data   
+    SPI_CS = 0;                                                     // Make sure we start with active-low CS high
+    SPI_CLK = 0;                                                      // and CK low
+    
+    SPIData = regAddr;                                            // Preload the data to be sent with Address
+    SPI_CS = 1;                                                   // Set active-low CS low to start the SPI cycle 
+    
+    for (SPICount = 0; SPICount < 8; SPICount++)                  // Prepare to clock out the Address byte
+    {
+    if (SPIData & 0x80)                                         // Check for a 1 at MSB
+        MOSI = 1;                                               // and set the MOSI line appropriately
+    else
+        MOSI = 0;
+    SPI_CLK = 1;                                                 // Toggle the clock line
+    SPI_CLK = 0;
+    SPIData <<= 1;                                                  // Rotate to get the next bit
+    }                                                             // and loop back to send the next bit
+      
+    // Repeat for the Data byte
+    SPIData = regData;                                            // Preload the data to be sent with Data
+    for (SPICount = 0; SPICount < 8; SPICount++)
+    {
+    if (SPIData & 0x80)
+        MOSI = 1;
+    else
+        MOSI = 0;
+    SPI_CLK = 1;
+    SPI_CLK = 0;
+    SPIData <<= 1;                                              // After each bit, move next bit one to left
+    }          
+    SPI_CS = 0;
+    MOSI = 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+/*******************************************************************************
+ *  BitBangSPIRead for ADXL372 if you wire it up as SPI
+ *  
+ *  
+ *
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+unsigned char BitBangSPIRead (const unsigned char regAddr)
+{
+
+  unsigned char SPICount;   // Counter used to clock out the data
+  
+  unsigned char SPIData;                  
+  
+  SPI_CS = 0;   // Make sure we start with active-low CS high
+  SPI_CLK = 0;  // and CK low
+  SPIData = regAddr;    // Preload the data to be sent with Address and Data
+
+  SPI_CS = 1;   // Set active-low CS low to start the SPI cycle
+  for (SPICount = 0; SPICount < 8; SPICount++)  // Prepare to clock out the Address and Data
+  {
+    if (SPIData & 0x80)
+      MOSI = 1;
+    else
+      MOSI = 0;
+    SPI_CLK = 1;
+    SPI_CLK = 0;
+    SPIData <<= 1;
+  }// and loop back to send the next bit
+  
+  MOSI = 0; // Reset the MOSI data line
+  
+  SPIData = 0;
+  for (SPICount = 0; SPICount < 8; SPICount++)  // Prepare to clock in the data to be read
+  {
+    SPIData <<=1;   // Rotate the data, keep previous bit value
+    SPI_CLK = 1;    // Raise the clock to clock the data out of the MAX7456
+    SPIData += SPI_MISO;    // Read the data one bit at a time, starting from MISO MSB
+    SPI_CLK = 0;    // Drop the clock ready for the next bit
+  }// and loop back for next bit
+  SPI_CS = 0;   // Raise CS
+                      
+  return ((unsigned char)SPIData);  // Finally return the read data
+}
+
+/*******************************************************************************
+ *  Not really used at the moment
+ *  Not really needed. But keep just in case because I don't want to rewrite it
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+unsigned char twosComplementConversion(unsigned char value)
+{
+    /*
+     * Go from bit 0 to bit 7 and invert them
+     * Then finally add 1
+     */
+    char mask = value & 0x80;
+    if(mask == 0x80){   // Check for sign
+        value = ~value + 1;
+        return value;
+    } 
+    return value;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+/*******************************************************************************
+ *  Performs one byte write I2C protocol
+ *  PARAM:
+ *      registerAddress: register you want access to in device, one byte char hex format
+ *      data: one byte data that you want to write to device register
+ *  Return:
+ *      0: failure at writing i2c address
+ *      1: successful write
+ *      2: failure at writing data
+ *      3: failure at writing register address
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+int ADT7410Write(unsigned char registerAddress, unsigned char data){
+    int flag;
+    ADT7410.start();
+    flag = ADT7410.write(ADT7410_Address_8BIT);
+    if(flag == 1)
+    {
+        pc.printf("Write to I2C address success\n\r");
+        wait(0.1);
+        flag = ADT7410.write(registerAddress);
+        if(flag == 1)
+        {
+            pc.printf("Write to register 0x%x address success\n\r", registerAddress);
+            flag = ADT7410.write(data);
+            if(flag == 1)
+            {
+                pc.printf("Writing data 0x%x to register address success\n\r", data);
+                ADT7410.stop();
+                return 1;
+            }else {ADT7410.stop(); return 2;} 
+        }else {ADT7410.stop(); return 3;} 
+    }else ADT7410.stop();
+       
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+/*******************************************************************************
+ *  I2C Read function for ADT7410 Temperature sensor
+ *  Param:
+ *      hex: hexadecimal representation for desired register
+ *  Return:
+ *      Char pointer to the array of data values.
+ *  Could also change from a char pointer to a uint8_t pointer.
+ *
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+char * ADT7410Read(int hex){
+    //short int convertedVal;
+    char data[2] = {0, 0};
+    char cmd[1];
+    cmd[0] = hex;
+    //pc.printf("Register Addres is: %x \n\r", cmd[0]); 
+    if(ADT7410.write(ADT7410_Address_8BIT, cmd,1) == 0){
+        if(ADT7410.read(ADT7410_Address_8BIT, data, 2) == 0){
+            
+            return data;
+            //return (data[0] << 8 | data[1])>>3;     // Explained here: https://stackoverflow.com/a/141576 SOOO GREAT
+            
+        }else {pc.printf("Failed to read \n\r"); return data;}
+    }else {pc.printf("Failed to write \n\r"); return data;}
+    
+}
+////////////////////////////////////////////////////////////////////////////////
+
+
+/*******************************************************************************
+ *  ADXL372 reset function
+ *  Resets all registers and settings back to default
+ *  Basically the same as the previous ADXL372 I2C write function
+ *
+ ******************************************************************************/
+////////////////////////////////////////////////////////////////////////////////
+void ADXL372Reset(void){
+    int flag;
+//--------- One full writing cycle for ADXL372 for Z Enable ------------------//
+/*    '0' - NAK was received
+ *    '1' - ACK was received, <---- This good
+ *    '2' - timeout
+ */
+    ADXL372.start();
+    flag = ADXL372.write(ADXL372_Address_8bit | 0);
+    if(flag == 1)
+    {
+        //pc.printf("Write to I2C address success\n\r");
+        
+        flag = ADXL372.write(0x41);
+        if(flag == 1)
+        {
+            //pc.printf("Write to 0x41 register address success\n\r");
+            flag = ADXL372.write(0x52);                             // Set bit 0
+            if(flag == 1)
+            {
+                pc.printf("Everything has been reset\n\r");
+                ADXL372.stop();
+            }
+        }
+    }
+    else ADXL372.stop();
+// ---------------- End of writing cycle --------------------------//
+}
+////////////////////////////////////////////////////////////////////////////////