PICO I2C FW

Dependencies:   USBDevice

main.cpp

Committer:
cyberjoey
Date:
2018-08-31
Revision:
17:401a5bb8d403
Parent:
16:2f373d3c8214
Child:
18:d913ec9dd9c2

File content as of revision 17:401a5bb8d403:

#include "mbed.h"
#include "SDFileSystem.h"
#include "max32630fthr.h"
#include "USBSerial.h"
#include <ctype.h>


#define I2C_ADDRESS 0x30    // DS2484 I2C address
#define DS2484_ADD  0x30    // DS2484 I2C write address


#define PERIOD      10       // Logging period in seconds

//DS2484 Status register bits
#define OWB 0x01            // status reg, One Wire Busy
#define PPD 0x02            // status reg, Presence Pulse Detected
#define SD  0x04            // status reg, Short Detected
#define LL  0x08            // status reg, Logic Level
#define RST 0x10            // status reg, Device Reset  (DS2484 Reset)
#define SBR 0x20            // status reg, Single Bit Result
#define TSB 0x40            // status reg, Triplet Second Bit
#define DIR 0x80            // status reg, Branch Direction Taken
//DS2484 Command bytes
#define RESET       0xF0    // DS2484 Reset
#define SRP         0xE1    // DS2484 Set Read Pointer
#define WDC         0xD2    // DS2484 Write Device Configuration                     
#define ACP         0xC3    // DS2484 Adjust one wire Control Port
#define OW_RESET    0xB4    // DS2484 One Wire Reset
#define OW_SB       0x87    // One Wire Single Bit (write or read)
#define OWWB        0xA5    // One Wire Write Byte
#define OWRB        0x96    // One Wire Read Byte
#define OWT         0x78    // One Wire Triplet  (read 2 bits, write 1 bit)
//One Wire Commands
#define OW_SEARCH   0xF0    // Search Rom
#define OW_READ     0x33    // Read Rom
#define OW_MATCH    0x55    // Match Rom
#define OW_SKIP     0xCC    // Skip Rom
#define OW_OD_MATCH 0x69    // Match Rom
#define OW_OD_SKIP  0x3C    // Skip Rom
#define OW_ALARM    0xEC    // Alarm Search
// OT07 OW commands
#define OT07_OW_CONVERT     0x44    //OT07 OW convert temperature command
#define OT07_OW_WRITE       0xCC    // OT07 OW Write Register command
#define OT07_OW_READ        0x33    // OT07 OW Read Register command
#define OT07_OW_RESET       0x82    // OT07 OW Soft Reset command

//OT07 Registers
#define OT07_STATUS         0x00    // OT07 status regiter
#define OT07_INT_EN         0x01    // OT07 Interrupt Enable
#define OT07_FIFO_W         0x04    // OT07 FIFO Write Pointer
#define OT07_FIFO_R         0x05    // OT07 FIFO Read Pointer
#define OT07_FIFO_OF        0x06    // OT07 FIFO Overflow Counter
#define OT07_FIFO_COUNT     0x07    // OT07 FIFO Data Count
#define OT07_FIFO_DATA      0x08    // OT07 FIFO Data
#define OT07_FIFO_CNFG1     0x09    // OT07 FIFO Configuration 1 (FIFO_A_FULL)
#define OT07_FIFO_CNFG2     0x0A    // OT07 FIFO Configuration 2
#define OT07_SYS            0x0C    // OT07 System Configuration
#define OT07_ALARM_HIGH_MSB 0x10    // OT07 Alarm High MSB
#define OT07_ALARM_HIGH_LSB 0x11    // OT07 Alarm High LSB
#define OT07_ALARM_LOW_MSB  0x12    // OT07 Alarm Low MSB
#define OT07_ALARM_LOW_LSB  0x13    // OT07 Alarm LOW LSB
#define OT07_ADC_SETUP      0x14    // OT07 Temp Seneor Setup (ADC_RES[7:6]) & Convert Temperature [0]
#define OT07_GPIO_SETUP     0x20    // OT07 GPIO Setup,  sets GPIO modes
#define OT07_GPIO_CTRL      0x21    // OT07 GPIO control
#define OT07_ROM_ID         0x30    // OT07 ROM_ID address of LSB?


#define MAX_DEVICES 64      // Maximum number of rom devices allowed
#define ID_LENGTH   8       // Rom ID length in bytes


#define BS          8       // ASCII Back Space
#define CR          13      // ASCII Carriage Return

struct OT07_struct {
    char rom_id[ID_LENGTH];     // device 8 byte ROM ID
    char I2C_address;           // I2C addess, based on GPIO0 and GPIO1 at power up
}; 

const char* settings_file = "/sd/settings.txt";
const char* log_file = "/sd/MAX30207Log.csv";

//global variable

//******************** init Feather Boared Hardware ***********************

MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);  

//microSD logging file system setup
SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd");  // mosi, miso, sclk, cs

//SD card insertion detection pin
DigitalIn SDDetect(P2_2, PullUp);
InterruptIn SDInsert(P2_2);


// Virtual serial port over USB
USBSerial pc(0x0B6A, 0x0042, 0x0001, false);

// I2C setup
I2C i2c(P3_4,P3_5);             // P3_4 -> I2C1_SDA,  P3_5-> I2C1_SCL

//Timer setup
Ticker timer_1;                 // timer for blinking led heartbeat

bool tick_flag;                 // used for counting seconds
bool log_flag = false;
bool led_toggle_flag = false;
bool button_flag = false;
bool sd_insert_flag = false;
bool error_flag;
int error_ticks;

//LED  blink setup
DigitalOut rLED(LED1);
DigitalOut gLED(LED2);
DigitalOut bLED(LED3);

InterruptIn button(SW1);


void LED_blink_callback(){ // LED Heart beat
    
    led_toggle_flag = !led_toggle_flag;
    
    if(log_flag) //if logging
    {
        
        if(led_toggle_flag)
        {
        //toggle red led
        rLED = LED_ON;
        }
        else
        {
            rLED = LED_OFF;
            gLED = LED_OFF;
            bLED = LED_OFF;
        } 
    }
    else if(error_flag) //if error (no sd card)
    {
        if(led_toggle_flag)
        {
        //toggle red led
        rLED = LED_ON;
        gLED = LED_ON;
        }
        else
        {
            rLED = LED_OFF;
            gLED = LED_OFF;
            bLED = LED_OFF;
        }
        error_ticks--; 
        if(error_ticks <= 0)
            error_flag = false;
    }
    else
    {
        if(led_toggle_flag)
        {
        //toggle teal leds
        gLED = LED_ON;
        bLED = LED_ON;
        }
        else
        {
            rLED = LED_OFF;
            gLED = LED_OFF;
            bLED = LED_OFF;
        } 
    }
      
    tick_flag = true;
}

void btn_pressed() //button pressed isr
{
    button_flag = true;
}

void sd_insert() //sd_insert pressed isr
{
    sd_insert_flag = true;
}


// *****************************************************************************
//            Define CRC-8 Table
// *****************************************************************************

static unsigned char crc_table[] = {
    0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
    157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
    35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
    190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
    70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
    219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
    101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
    248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
    140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
    17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
    175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
    50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
    202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
    87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
    233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
    116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
    
    
    
// -----------------------------------------------------------------------------
// Calculate the CRC8 of the byte value provided with the current total
// calc_crc8(unsigned char, unsigned char)  crc8 total, byte to add
// pass crc8 total = 0 to start new crc sum.

// Returns  new crc8 total
// -----------------------------------------------------------------------------

unsigned char calc_crc8(unsigned char crc8, unsigned char value){
        
    return crc_table[crc8 ^ value];
}

// *****************************************************************************
//   OW_reset()
//   returns  0 no device present,  1 device present
// *****************************************************************************

int OW_reset(){
    char data[2];                       // define as minimun array size so 'data' is a pointer
    data[0] = OW_RESET;                 // One Wire Reset 0xB4     
    i2c.write(DS2484_ADD,data,1,0);     // write reset command to DS2484
    wait_ms(1);                     
    do{                                 // poll OW-busy 
        i2c.read(DS2484_ADD,data,1);    // read back status byte from DS2484        
    }while(OWB & data[0]);    
    if(PPD & data[0])return 1;          // Presence Pulse Detected bit true?
    return 0;                           // else 
} // end OW_reset()

// *****************************************************************************
//   OW_write_byte(char)   takes char to send over one wire
//   returns  DS2484 status byte
// *****************************************************************************

char OW_write_byte(char byte){

    char data[2];
    data[0] = 0xA5;
    data[1] = byte;
    i2c.write(DS2484_ADD,data,2,1);
    i2c.read(DS2484_ADD,data,1);    // read status byte  
    
    // db.printf("[%02X]",byte);              
    wait_us(700);                   // assumes normal speed OW write
    return data[0];                 // return DS2484 Status byte
   
}// end OW_write_byte()


// *****************************************************************************
//   OW_read_byte(char *, int)    char* (save data pointer)
//                                int (number of bytes to read)
//   returns  0x00
//
//   assumes OW_reset, OW_match rom, and OW device register read address already sent.
//   
// *****************************************************************************

char OW_read_byte(char* a, int n){

    char data[2];
    int i; 
    
    //read n bytes of data 
    i=0;                       
    do{                         
        data[0] = OWRB;                     // send 0x96;   DS2484 command, OW read byte
        i2c.write(DS2484_ADD,data,1,0);
        wait_us(600);
        do{
            i2c.read(DS2484_ADD,data,1);    // read status byte and test OW-busy?                                
        }while(data[0]&0x01 == 1);          // status bit[0] set --> OW busy 
                             
        //get byte from DS2484
        data[0] = SRP;                      // send 0xE1, set read pointer
        data[1] = 0xE1;                     // set read pointer address 0xE1 read OW data
        i2c.write(DS2484_ADD,data,2,1);            
        i2c.read(DS2484_ADD,data,1);        // read bytes from OW register
                            
        a[i] = data[0];

        i++;
        //pc.printf("[%02X] ",data[0]);
    }while(i<n);
    //for(i=0;i<n;i++) db.printf("OW_read_byte - [%2d][%02X]\r\n",i,a[i]);
    return 0x00;
}// end OW_read_byte()



// *****************************************************************************
//   OW_match_rom(char *)      pointer to device_id byte array
//   returns 0x00
//   assumes OW_reset alread sent
// *****************************************************************************

char OW_match_rom(char *device_id){
    
    int i;
    //Match rom
    OW_write_byte(OW_MATCH);                    // send 0x55, match rom command                      
    //send rom code for device
    for(i=0;i<8;i++){
        OW_write_byte(device_id[i]);           //I2C write ow byte 
    } 
    return 0x00;
    
}// end OW_macth_rom


// *****************************************************************************
//   search_rom(char *)         pointer to start of 2D array rom_id_list
//   returns  number of devices found
// *****************************************************************************


int search_rom(char rom_id_list[MAX_DEVICES][ID_LENGTH]){   // searches for all device on OW bus, returns # found

    int bit_num;
    int byte_num;
    int last_zero;
    int last_discrep;
    int search_dir;
    int rom_count;
    char byte_mask;
    int last_device;
    int i; 
    
    char rom_id[8];     //used in rom search
    char data[8];
    char crc;
    
    //init for first search only
    last_device = 0;
    last_discrep = 0;
    rom_count = 0;
    
    for(i=0;i<8;i++)rom_id[i] = 0x00;  //clear rom_id    
    
    do{  // loop for each rom search (end when last_device = 1)
                        
        //init variable for each search
        bit_num = 1;
        byte_num = 0;
        byte_mask = 1;
        last_zero = 0;
        
                                                                        
        //OW reset
        if(OW_reset()){  //returns 1 if at least one device present                
            //test if last device found
            if(last_device!=1){         // more devices to find                                
                search_dir = 0;                    
                OW_write_byte(OW_SEARCH);       //send 0xF0 over one wire to init search rom              
                                
                do{
                    //determine search direction
                    if(bit_num < last_discrep){ //before last discrepancy
                        if((rom_id[byte_num] & byte_mask) > 0){// use last rom path
                            search_dir = 1;             // last path was 1
                        }else{
                            search_dir = 0;             // last path was 0
                        }
                    }else{                              // at or past last discrepancy
                        if(bit_num == last_discrep){    // at last discrepancy
                            search_dir = 1;             //been here before so use 1
                        }else{
                            search_dir = 0;             //past last discrepancy so use 0
                        }
                    }
                                    
                    //write direction bit and get reply                               
                    data[0] = 0x78;
                    data[1] = search_dir << 7;          //sets bit 7 of status reg to search_dir
                    i2c.write(DS2484_ADD,data,2,1);                                    
                                    
                    wait_us(250);
                                    
                    //read in rom_id bits
                    i2c.read(DS2484_ADD,data,1);        // read status byte   
                                    
                    //(todo) check for no device error here
                                    
                    //get search direction used by triplet command                                   
                                    
                    if(data[0]&0x80){                   //true --> DIR bit = 1
                        search_dir = 1;                                        
                    }else{
                        search_dir = 0;                                        
                    }
                    
                    //test for discrepancy (both 0 and 1 present at current bit number)(TSB = 0 (1's present) and SBR = 0 (0's present))
                    if(!(data[0] & 0x60)){             // true --> discrepancy exist, both TSB and SBR = 0                                               
                        if(search_dir == 0)last_zero = bit_num; 
                    }
                    if(search_dir == 1){               // write search dir to rom bit
                        rom_id[byte_num] |= byte_mask;
                    }else{
                        rom_id[byte_num] &= ~byte_mask;
                    }
                                    
                    //increment bit_num and byte_num if needed
                    bit_num++;
                    byte_mask <<= 1;        //rotate 1 bit left
                    if(byte_mask == 0){     //if bit shifts out of byte set byte to 1
                        byte_num++;             //also increnent byt num
                        byte_mask = 1;     
                    }
                                    
                                
                }while(bit_num<65);  //bit nun started at 1 so end after 64 
                last_discrep = last_zero;
                if(last_discrep == 0)last_device = 1;
                //copy rom_id into rom_id_list and calc crc of first 7 bytes
                crc = 0x00;                 // reset crc8 total to 0
                for(i=7;i>=0;i--){
                    rom_id_list[rom_count][i] = rom_id[i];
                }              
                
                //clac_crc of rom ID
                for (i=0;i<7;i++){
                    crc = calc_crc8(crc, rom_id[i]);
                }
                                                                                              
                rom_count++;  
            }//if(last_device..)
        }else{//if prescent -- if no device present rom count is 0
            return 0;
        }
    }while(last_device == 0); 
    return rom_count;
}// end search_rom()

// *****************************************************************************
//   OT07_write_register(char, char, char)  writes single byte to OT07
//                       char   I2C address
//                       char   OT07 register address
//                       char   data byte to be writen
//   returns                    0 on success ACK, 1 on NACK 
// *****************************************************************************

int OT07_write_register(char I2C_add, char reg_add, char byte){
    char data[2];
    int error;
    data[0] = reg_add;
    data[1] = byte;
    error = i2c.write(I2C_add,data,2);  
    //if(DEBUG)db.printf("wr[%02X %02X %d]\r\n", data[0], data[1], error);
    return error; 
    
}

/// ****************************************************************************
//   OT07_write_register(char, char, char *, int)  writes multiple bytes to OT07
//                       char   I2C address
//                       char   OT07 register address
//                       char * data vector of bytes to be written
//                       int    number of bytes to write
//   returns                    0 on success ACK, 1 on NACK 
// *****************************************************************************

int OT07_write_register(char I2C_add, char reg_add, char *bytes, int n){
    int i;   
    //set start address
    char data[16];
    int error;                          
    data[0] = reg_add; 
    for(i=1;i<=n;i++){                   
       data[i] = bytes[i-1];
    }
    error = i2c.write(I2C_add,data,n+1);  // send n bytes of data
  
    return error;      
}

// *****************************************************************************
//   OT07_read_register(char, char, char *, int)  writes single byte to OT07
//                       char   I2C address
//                       char   OT07 register address
//                       char * data vector for read bytes to be stored in 
//                       int    number of bytes to read
//   returns                    0 on success, 1 on fail 
// *****************************************************************************

int OT07_read_register(char I2C_add, char reg_add, char *bytes, int n){
    int error;
    error = i2c.write(I2C_add,&reg_add,1,1); 
    if(error)return error;   
    error = i2c.read(I2C_add,bytes,n);  
    //if(DEBUG)db.printf("rr e[%d]\r\n",error);
    return error; 
}

// *****************************************************************************
//   search_I2C_bus(OT07_struct *)  searches I2C address 0xA0, 0xA2, 0xA4 and 0xA6        
//                  OT07_struct *   structure array to holds I2C address and rom_ids
//   returns                        number of devices found
// *****************************************************************************

int search_I2C_bus(OT07_struct OT07[]){
    char data[16];
    char I2C_add;
    //char GPIO;
    int error;
    int device_count = 0;
    int i;
    int j;
    for(i = 0;i<4;i++){
        I2C_add = 0xA0 + i*2;
        error = OT07_read_register(I2C_add,0xff,data,1); 
        
        if(error == 0){
            if(data[0] == 0x30){ 
            
                OT07[device_count].I2C_address = I2C_add;
                
                OT07_read_register(I2C_add,OT07_ROM_ID,data,8);
                for(j=7;j>=0;j--){
                    OT07[device_count].rom_id[j] = data[j];
                     
                }
            device_count++;    
            }                       
        }

    }
    return device_count;
}

// *****************************************************************************
// convert_temperature(char)    sends convert command to OT07 device
//                     char     I2C address
// *****************************************************************************

void convert_temperature(char I2C_add){   // set convert bit to start conversion

    char data[2];  
    
    //read ADC_SETUP register 0x14
    OT07_read_register(I2C_add, OT07_ADC_SETUP,data,1);       

    //mask convert register value with 0x01 and write back register 0x14      
    OT07_write_register(I2C_add, OT07_ADC_SETUP, data[0]|0x01);
}

//******************************************************************************
// get_temperature(char)    read temperature from OT07 device FIFO register
//                 char     I2C address
// returns                  double temperature in oC
//******************************************************************************

double get_temperature(char I2C_add){
    char data[2];
    double T;
    int count;
 
    OT07_read_register(I2C_add,OT07_FIFO_DATA,data,2);     // Read temperature from FIFO, 2 bytes 
    //if(DEBUG)db.printf("get_temperature -- FIFO[%02X %02X]\r\n",data[0],data[1]);
    //calculate temperture from data     
    count = (int)(data[0]*256 + data[1]);
    if (count >= 32768)count = count - 65536;     // 2s comp
    T = (double)count*0.005; 

    return T;  
}

// *****************************************************************************
//   alarm_search(char *)         pointer to start of 2D array rom_id_list
//   returns  number of devices found with alarm triggered
// *****************************************************************************

int alarm_search(char rom_id_list[MAX_DEVICES][ID_LENGTH]){   // searches for all devices with alarm triggered on OW bus, returns # found

    int bit_num;
    int byte_num;
    int last_zero;
    int last_discrep;
    int search_dir;
    int rom_count;
    char byte_mask;
    int last_device;
    int i; 
    
    char rom_id[8];   //used in rom search
    char data[8];
    char crc;
    
    //init for first search only
    last_device = 0;
    last_discrep = 0;
    rom_count = 0;
    
    for(i=0;i<8;i++)rom_id[i] = 0x00;  //clear rom_id    
    
    do{  // loop for each rom search (end when last_device = 1)
                        
        //init variable for each search
        bit_num = 1;
        byte_num = 0;
        byte_mask = 1;
        last_zero = 0;
        
                                                                        
        //OW reset
        if(OW_reset()){  //returns 1 if at least one device present                
            //test if last device found
            if(last_device!=1){         // more devices to find                                
                search_dir = 0;                    
                OW_write_byte(OW_ALARM);       //send 0xEC over one wire to init alarm search              
                                
                do{
                    //determine search direction
                    if(bit_num < last_discrep){ //before last discrepancy
                        if((rom_id[byte_num] & byte_mask) > 0){// use last rom path
                            search_dir = 1;             // last path was 1
                        }else{
                            search_dir = 0;             // last path was 0
                        }
                    }else{                              // at or past last discrepancy
                        if(bit_num == last_discrep){    // at last discrepancy
                            search_dir = 1;             //been here before so use 1
                        }else{
                            search_dir = 0;             //past last discrepancy so use 0
                        }
                    }
                                    
                    //write direction bit and get reply                               
                    data[0] = 0x78;
                    data[1] = search_dir << 7;          //sets bit 7 of status reg to search_dir
                    i2c.write(DS2484_ADD,data,2,1);                                    
                                    
                    wait_us(250);
                                    
                    //read in rom_id bits
                    i2c.read(DS2484_ADD,data,1);        // read status byte   
                                    
                    //(todo) check for no device error here
                                    
                    //get search direction used by triplet command                                   
                                    
                    if(data[0]&0x80){                   //true --> DIR bit = 1
                        search_dir = 1;                                        
                    }else{
                        search_dir = 0;                                        
                    }
                    
                    //test for discrepancy (both 0 and 1 present at current bit number)(TSB = 0 (1's present) and SBR = 0 (0's present))
                    if(!(data[0] & 0x60)){             // true --> discrepancy exist, both TSB and SBR = 0                                               
                        if(search_dir == 0)last_zero = bit_num; 
                    }
                    if(search_dir == 1){               // write search dir to rom bit
                        rom_id[byte_num] |= byte_mask;
                    }else{
                        rom_id[byte_num] &= ~byte_mask;
                    }
                                    
                    //increment bit_num and byte_num if needed
                    bit_num++;
                    byte_mask <<= 1;        //rotate 1 bit left
                    if(byte_mask == 0){     //if bit shifts out of byte set byte to 1
                        byte_num++;             //also increnent byt num
                        byte_mask = 1;     
                    }
                                    
                                
                }while(bit_num<65);  //bit nun started at 1 so end after 64 
                last_discrep = last_zero;
                if(last_discrep == 0)last_device = 1;
                //copy rom_id into rom_id_list and calc crc of first 7 bytes
                crc = 0x00;                 // reset crc8 total to 0  
                for(i=7;i>=0;i--){
                    rom_id_list[rom_count][i] = rom_id[i];
                }                 
                
                //clac_crc of rom ID
                for (i=0;i<7;i++){
                    crc = calc_crc8(crc, rom_id[i]);
                }
                                                                                              
                rom_count++;  
            }//if(last_device..)
        }else{//if prescent -- if no device present rom count is 0
            return 0;
        }
    }while(last_device == 0);

    //check if rom_id from alarm search is all 1s (this means there was a presence pulse but no alarm is triggered)
    bool bad_rom_id = true;
    for(int i = 0; i < 7; i++)
    {
        if(rom_id_list[0][i] != 0xFF)
            bad_rom_id = false; //found a byte in the rom id that isn't all 1s
    }
    if(bad_rom_id)
        return 0;
    
    return rom_count;
}// end alarm_search()


// ********************  write_OW_register()  ********************************
// write_OW_register(char*, int, int, char*) 
//                          char*   pointer to rom_id 
//                          int     start address
//                          int     number of bytes to write
//                          char*   pointer to write data location
// returns  0 if CRC match data 
// returns -1 if CRC does not match data
// 
// *****************************************************************************



int write_OW_register(char *device_ID, int start_add, int n, char *data){
    int i;   
    //select device
    OW_reset();
    OW_match_rom(device_ID);
    //set start address
    OW_write_byte(OT07_OW_WRITE);       // send 0xCC, OW write register command for OT07
    OW_write_byte(start_add);           // send write register start address 
    OW_write_byte(n-1);                 // send length of bytes to write (00-> one byte)
    for(i=0;i<n;i++){                   // send n bytes of data
        OW_write_byte(data[i]);
    }
    OW_read_byte(data,2);               // read 2 byte CRC
    
    // --- todo ----
    // calculate CRC of
    // Command + length + n bytes sent
    // compare with 2 bytes read
   
    return 0;
    
}//end write_OW_register




// ********************  read_OW_register()  ********************************
// read_OW_register(char*, int, int, char*) 
//                          char*   pointer to rom_id 
//                          int     start address
//                          int     number of bytes to read, not including CRC bytes
//                          char*   pointer to save data location
// returns  0 if CRC match data 
// returns -1 if CRC does not match data
// 
// *****************************************************************************



int read_OW_register(char *device_ID, int start_add, int n, char *data){
       
    //int i;
    //select device
    OW_reset();
    OW_match_rom(device_ID);
    //set start address
    OW_write_byte(OT07_OW_READ);        // send 0x33, OW read register command for OT07
    OW_write_byte(start_add);           // send read register start address 
    OW_write_byte(n-1);                   // send length of bytes to read (0 -> 1 byte)
    OW_read_byte(data,n+2);             // read n bytes plus 2 byte CRC
    
    // --- todo ----
    // calculate CRC of
    // Command + length + n bytes
    // compare with last 2 bytes read   
    return 0;
    
}//end read_OW_register

int set_test_mode(char *device_id){
    char data[4];
    
    // enter test mode
    OW_reset();
    OW_match_rom(device_id);            // match ROM                                
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0xFF);                // device register address
    OW_write_byte(0x00);                // number of bytes to write -1
    OW_write_byte(0x54);                // first half of test mode pass code                                    
    OW_read_byte(data,2);               // read 2 byte CRC 
                                   
    OW_reset();
    OW_match_rom(device_id);
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0xFF);                // device register address
    OW_write_byte(0x00);                // number of bytes to write -1
    OW_write_byte(0x4D);                // second half of test mode pass code
    OW_read_byte(data,2);               // read 2 byte CRC 
    
    // set ADC_ENABLED                               
    OW_reset();
    OW_match_rom(device_id);
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0x81);                // device register address
    OW_write_byte(0x00);                // number of bytes to write -1
    OW_write_byte(0x04);                // ADC_ENABLED code    
    OW_read_byte(data,2);               // read 2 byte CRC
    
    OW_reset();
    OW_match_rom(device_id); 
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0x98);                // device register address
    OW_write_byte(0x05);                // number of bytes to write -1
    OW_write_byte(0x40);                // add 98 data 40
    OW_write_byte(0xD4);                // add 99 data D4 
    OW_write_byte(0xE0);                // add 9A data E0 
    OW_write_byte(0xB3);                // add 9B data B3 
    OW_write_byte(0x09);                // add 9C data 09 
    OW_write_byte(0xBA);                // add 9D data BA    
    OW_read_byte(data,2);               // read 2 byte CRC 
     
     
    //OTP copy
    OW_reset();
    OW_match_rom(device_id); 
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0x80);                // device register address
    OW_write_byte(0x00);                // number of bytes to write -1
    OW_write_byte(0x82);                //    
    OW_read_byte(data,2);               // read 2 byte CRC 
    
    OW_reset();
    OW_match_rom(device_id);
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0x80);                // device register address
    OW_write_byte(0x00);                // number of bytes to write -1
    OW_write_byte(0x02);                //    
    OW_read_byte(data,2);               // read 2 byte CRC 
       
    
    OW_reset();
    OW_match_rom(device_id);    
    OW_write_byte(OT07_OW_WRITE);       // device write register command
    OW_write_byte(0xFF);                // device register address
    OW_write_byte(0x00);                // number of bytes to write -1
    OW_write_byte(0x00);                // exit Test mode   
    OW_read_byte(data,2);               // read 2 byte CRC 
    return 0;
}// end set_test_mode()



// ********************  convert_temperature()  ********************************
// convert_temperature()
// returns 0
// dose not block for 0.75 seconds.
// *****************************************************************************

int convert_temperature(){   // convert sent to all OW devices

    char data[8];   
    OW_reset();
                        
    OW_write_byte(OW_SKIP);     // send 0xCC, skip rom command
    
    // activate strong pullup                       
    data[0] = WDC;              // send 0xD2 Write Device Configuration     
    data[1] = 0xA5;             // 1010 0101 b  strong and active pullup on
    i2c.write(DS2484_ADD,data,2,0);
                        
    //convert command
    OW_write_byte(OT07_OW_CONVERT);       // send 0x44, Convert Temperature
    OW_read_byte(data,2);                 // read 2 byte CRC
    return 0;
}


// ********************  convert_temperature()  ********************************
// convert_temperature(char *)  takes 8 byte rom_id as input
// returns 0
// dose not block for 0.75 seconds.
// *****************************************************************************

int convert_temperature(char *device_id){ 

    char data[8];   
    OW_reset();
    OW_match_rom(device_id);    // send device id 
    
    // activate strong pullup                       
    data[0] = WDC;              // send 0xD2 Write Device Configuration     
    data[1] = 0xA5;             // 1010 0101 b  strong and active pullup on
    i2c.write(DS2484_ADD,data,2,0);
                        
    //convert command
    OW_write_byte(OT07_OW_CONVERT);       // send 0x44, Convert Temperature
    OW_read_byte(data,2);                 // read 2 byte CRC
    return 0;
}

//************************  get_temperature()  *********************************
// get_temperature(char *)  takes 8 byte rom_id as input
// returns                  double temperature in oC
//******************************************************************************

double get_temperature(char *device_id){
 
    char t[4];
    double T;
    int count;
 //   char data[2];  
    
    read_OW_register(device_id,OT07_FIFO_DATA,0x02,t);     // Read temperature from FIFO, 2 bytes 
    //calculate temperture from data     
    count = (int)(t[0]*256 + t[1]);
    if (count >= 32768)count = count - 65536;     // 2s comp
    T = (double)count*0.005; 
    
    return T;    
}// end get_temperature()


void write_settings_file(int interval, bool device_logged[MAX_DEVICES])
{
    FILE *fp = fopen(settings_file, "w");
    if (fp != NULL) 
    {
        fprintf(fp, "i %d\r\n", interval);

        fprintf(fp, "d");

        for(int i = 0; i < MAX_DEVICES; i++)
        {
            if(device_logged[i] == true)
            {
                fprintf(fp," %d", i);
            }
        }
        fprintf(fp,"\r\n");

        fclose(fp);  
    }
    return;
}

bool print_settings_file()
{
    FILE *fp = fopen(settings_file, "r");
    if (fp != NULL) 
    {
        pc.printf("*\r\n");
        
        // Read contents from file
        char c = fgetc(fp);
        
        while (!feof(fp))
        {
            pc.printf("%c", c);
            c = fgetc(fp);
        }
        
        pc.printf("*\r\n");
        
        fclose(fp);  
    }
    else
    {
        return false;
    }
    return true;
}

bool print_log_file()
{
    FILE *fp = fopen(log_file, "r");
    if (fp != NULL) 
    {
        pc.printf("*\r\n");

        // Read contents from file
        char c = fgetc(fp);
        while (!feof(fp))
        {
            pc.printf("%c", c);
            c = fgetc(fp);
        }

        pc.printf("*\r\n");

        fclose(fp);  
    }
    else
    {
        return false;
    }
    return true;
}

int getline(char **lineptr, int *n, FILE *stream) {
    char *bufptr = NULL;
    char *p = bufptr;
    size_t size;
    int c;

    if (lineptr == NULL) {
        return -1;
    }
    if (stream == NULL) {
        return -1;
    }
    if (n == NULL) {
        return -1;
    }
    bufptr = *lineptr;
    size = *n;

    c = fgetc(stream);
    if (c == EOF) {
        return -1;
    }
    if (bufptr == NULL) {
        bufptr = (char *)malloc(128);
        if (bufptr == NULL) {
            return -1;
        }
        size = 128;
    }
    p = bufptr;
    while(c != EOF) {
        if ((p - bufptr) > (size - 1)) {
            size = size + 128;
            bufptr = (char *)realloc(bufptr, size);
            if (bufptr == NULL) {
                return -1;
            }
        }
        *p++ = c;
        if (c == '\n') {
            break;
        }
        c = fgetc(stream);
    }

    *p++ = '\0';
    *lineptr = bufptr;
    *n = size;

    return p - bufptr - 1;
}

bool print_settings_file_2()
{
    char * line = NULL;
    int len = 0;
    
    FILE *fp = fopen(settings_file, "r");
    if (fp != NULL) 
    {
        pc.printf("*\r\n");
        
        // Read contents from file
        while ((getline(&line, &len, fp)) != -1) 
        {
            pc.printf("%s", line);
        }
        pc.printf("*\r\n");
        
        fclose(fp);  
    }
    else
    {
        return false;
    }
    return true;
}

//returns true if settings file exists and is in the proper format
bool apply_settings_file(bool (&logged_devices)[MAX_DEVICES], int& interval)
{
    
    char * line = NULL;
    int len = 0;
    int line_number = 0;
    

    FILE *fp = fopen("/sd/settings.txt", "r");
    if (fp != NULL) 
    {

        //initialize devices to all false;
        for(int i = 0; i < MAX_DEVICES; i++)
        {
            logged_devices[i] = false;
        }

        // Read contents from file
        while ((getline(&line, &len, fp)) != -1) 
        {
            line_number++;

            char i = 0;
            char c = line[i];
            while(c != '\0')
            {
                int number;
                int n;
                sscanf((line+i), "%d%n", &number, &n);
                if(isdigit(c))
                {
                    if(line_number == 1)
                    {
                        interval = number;
                    }
                    else if(line_number == 2)
                    {
                        logged_devices[number] = true;
                    }
                    if(n > 1)
                        i = i + (n - 1);
                }
                i++;
                c = line[i];
            }
        }

        fclose(fp);  
    }
    else
    {
        return false;
    }

    return true;
    
}

//******************************************************************************
//        main()
//******************************************************************************


int main()
{
    OT07_struct OT07[4];            // structure that holds I2C address and ROM_ID  
    char data[130];
    int device_count = 0;       // number of OW devices found by search_rom() 
    int i;
    int j;
    int k;
    
    
    char device_id[ID_LENGTH];                   //8 byte rom id of current slected device 
    char rom_id_list[MAX_DEVICES][ID_LENGTH];    //List of rom id for each device on OW bus 
    
    double T[MAX_DEVICES];  
    
    bool device_logged[MAX_DEVICES];
    //initialize device_logged to all false;
    for(int i = 0; i < MAX_DEVICES; i++)
    {
        device_logged[i] = false;
    }
    
    // i/o variables
    char rx_buff[128];              // comport input buffer
    int rx_index;                   // rx_buffer pointer
    char c;                         // command type character
    int n;                          // argument count
    int arg1;                       // argumnet 1
    int arg2;                       // argument 2
    int device;                     // device argument
    int num_bytes;
    
    int time_count;
    int log_interval = PERIOD;
    int time_to_sample; 
    
    apply_settings_file(device_logged, log_interval);
    
    //************* init ticker timer callbacks  ****************
    timer_1.attach(&LED_blink_callback,0.5);        //start ticker, once per  sec.      
    
    
    i2c.frequency(400000);      //set I2C clock to 400kHz     
    
    rLED = LED_OFF;
    gLED = LED_ON;
    bLED = LED_ON;


    // reset DS2484
    //data[0] = 0xE1;
    //data[1] = 0xF0;
    //i2c.write(DS2484_ADD,data,1,1);
    //i2c.read(DS2484_ADD,data,1);   
    
    // ******************  search for all OW devices on bus  *****************
    
    //device_count = search_rom(rom_id_list);
    device_count = search_I2C_bus(OT07);
    
    /*for(j=0;j<device_count;j++){                                   
        for(k=0;k<8;k++){                   
            device_id[k] = rom_id_list[j][k];   // get device_id from rom_id_list
        }
        set_test_mode(device_id);
    }*/ 
    
    
    rx_index = 0;               //character buffer index for input from PC
    
    button.fall(&btn_pressed);
    SDInsert.fall(&sd_insert);
    
    sd.disk_initialize(); //initialize sd card
     
    while(1) {  // start main loop,  take data if logging, check for input, repeat   
    
    if(sd_insert_flag == true)
    {
        sd.disk_initialize();
        sd_insert_flag = false;
    }
    
    if(button_flag == true)
    {
        if(log_flag == false){  //start logging        
        
            if(SDDetect)//if SD card not detected
            {
                error_flag = true;
                error_ticks = 6;
                log_flag = false;
            }
            else
            {
                apply_settings_file(device_logged, log_interval);
                
                FILE *fp = fopen(log_file, "a");
                if (fp != NULL) 
                {
                    fprintf(fp,"Device List\r\n");
                    fprintf(fp,"Device Number, ROM Code\r\n");
                    for(j=0;j<device_count;j++)
                    {
                        if(device_logged[j])
                        {
                            fprintf(fp,"%d,0x",j);
                            for(i=7;i>=0;i--)
                            {            
                                fprintf(fp,"%02X",rom_id_list[j][i]); 
                            }    
                            fprintf(fp,"\r\n");
                        }
                    } 
                    
                    fprintf(fp, "Time(s)");
                
                    for(j=0;j<device_count;j++)
                    {
                        if(device_logged[j])
                            fprintf(fp,",Device %d Temperature (C)",j);
                    }
                    fprintf(fp,"\r\n");
                
                    fclose(fp);  
                }
                
                time_count = 0;
                
                time_to_sample = 0;                     // force sample at time = 0;
                tick_flag = true;                       // force sample at time = 0;
                log_flag = true;
            }
        }else{
            log_flag = false;
        }  
        button_flag = false;  
    }

      while(tick_flag == false){ //check for input while waiting for next tick      
      
 // ----------------------------------------------------------------------------
 //             test for charater input for USB com port
 // ----------------------------------------------------------------------------
        
 //test if PC sent some charaters
        while(pc.readable()){  //characters in buffer,  get them                               
            rx_buff[rx_index] = pc.getc();
            
            if(rx_buff[rx_index] == CR){
                rx_buff[++rx_index] = 0;
                rx_index = -1;  // because i++ at end of while give i=0 on next loop 
                device = 0; 
                arg1 = 0;
                arg2 = 0;
                
                n = sscanf(rx_buff, " %c %d %x %x", &c, & device, &arg1, &arg2);
               //process input
                if(n > 0){//got input so process it
                    switch(c){
                        case 'a':   
                        case 'A':   // alarm search
                                    // ******************  search for all OW devices with alarm triggered on bus  *****************
                                    /*
                                    device_count = alarm_search(rom_id_list);
    
                                    pc.printf("%d devices:\r\n", device_count);
                                    for(j=0;j<device_count;j++){
                                        pc.printf("device[%02X]  rom id[",j);
                                        for(i=7;i>=0;i--){            
                                            pc.printf("%02X",rom_id_list[j][i]); 
                                        }    
                                        pc.printf("]\r\n");
                                    } */
                            break;
                        case 'c':
                        case 'C':
                                    if(!SDDetect)
                                        pc.printf("y\r\n");
                                    else
                                        pc.printf("n\r\n");
                                    break;
                        case 'd':
                        case 'D':
                                    if(n==1) // if no device number is given
                                    {
                                        //clear device_logged array
                                        for(int i = 0; i < MAX_DEVICES; i++)
                                        {
                                            device_logged[i] = false;
                                        }
                                        
                                        write_settings_file(log_interval, device_logged);
                                    }
                                    if(n == 2)
                                    {
                                        device_logged[device] = true;
                                        write_settings_file(log_interval, device_logged);
                                    }
                            break;
                        case 'f':   
                        case 'F':   //f is for "flash" for microSD
                                     if(!SDDetect)
                                        pc.printf("y\r\n");
                                    else
                                        pc.printf("n\r\n");
                            break;
                        case 'g':   
                        case 'G':   
                                    //0 means get config, 1 means get log
                                    if(n == 2)
                                    {
                                        bool fileExists = false;
                                        if(device == 0)//get config
                                        {
                                            fileExists = print_settings_file();
                                            //fileExists = print_settings_file_2();
                                        }
                                        if(device == 1)//get log
                                        {
                                            fileExists = print_log_file();
                                        }
                                        if(!fileExists)
                                        {
                                            pc.printf("no_file\r\n");
                                        }
                                    }
                            break;
                        case 'i':
                        case 'I':   //Set Logging sample intreval in seconds
                        
                                    log_interval = device;
                                    if(log_interval < 1)log_interval = 1; 
                                    if(log_interval > 60)log_interval = 60;  
                                    write_settings_file(log_interval, device_logged);                               
                                break;
                        case 'l':   
                        case 'L':   
                                    
                        /*
                                    // Toggle logging
                        
                                    if(log_flag == false){  //start logging   
                                        if(SDDetect)//if SD card not detected
                                        {
                                            error_flag = true;
                                            error_ticks = 6;
                                            log_flag = false;
                                        }
                                        else
                                        {
                                            FILE *fp = fopen(log_file, "a");
                                            if (fp != NULL) 
                                            {
                                                fprintf(fp, "Time(s)");
                                            
                                                for(j=0;j<device_count;j++)
                                                {
                                                    fprintf(fp,",Device %d Temperature (C)",j);
                                                }
                                                fprintf(fp,"\r\n");
                                            
                                                fclose(fp);  
                                            }
                                            
                                            time_count = 0;
                                            
                                            time_to_sample = 0;                     // force sample at time = 0;
                                            tick_flag = true;                       // force sample at time = 0;
                                            log_flag = true;
                                        }
                                    }else{
                                        //pc.printf("<stop logging>\r\n");
                                        log_flag = false;
                                    }*/
                            break;
                        case 'P':   
                        case 'p':   // power down One Wire buss
                                    /*if(n == 2){
                                        if (device == 0){        // power down mode ON.
                                            data[0] = WDC;      // 0xD2 Write Device Config
                                            data[1] = 0xD2;     // 1101 0010  set 1WS = 0, SPU = 0, PDN = 1, APU = 0
                                            i2c.write(DS2484_ADD,data,2,0);
                                            pc.printf("<Power down DQ>\r\n");
                                        }else{                  // power down mode OFF  
                                            data[0] = WDC;      // 0xD2 Write Device Config
                                            data[1] = 0xE1;     // 1110 0001  set 1WS = 0, SPU = 0, PDN = 0, APU = 1
                                            i2c.write(DS2484_ADD,data,2,0); 
                                            pc.printf("<Power up DQ>\r\n");
                                        }
                                    }*/
                            break;   
                        case 'r':
                        case 'R':   
                                    //read register "r device radd.start radd.end"                                      
                                    if(n==3){   //read single register from selected device
                                        OT07_read_register(OT07[device].I2C_address,arg1,data,1); 
                                        pc.printf("device[%02X] add[%02X] data[%02X] crc[FF FF]\r\n",device,arg1,data[0]);
                                    }
                                    if(n==4){   //read a range of regesters from selected device 
                                        num_bytes = arg2-arg1 + 1;                  // calculate number of bytes to read
                                        if (num_bytes < 1) num_bytes = 1;           // if arg2 <= arg 1 just read arg1 address.                                      
                                            OT07_read_register(OT07[device].I2C_address,arg1,data,num_bytes); 
                                        for(i=0;i<num_bytes;i++){
                                            pc.printf("\r\ndevice[%02X] add[%02X] data[%02X]",device,arg1+i,data[i]);
                                        }                                  
                                    } 
                                break;
                       
                        case 's':   
                        case 'S':   // search rom
                                    // ******************  search for I2C devices on bus  *****************
                                    //NOTE: MUST ADD I2C ADDRESS TODO
                                    device_count = search_I2C_bus(OT07);
                                    pc.printf("%d devices:\r\n", device_count);
                                    for(j=0;j<device_count;j++){
                                        pc.printf("device[%02X]  rom id[",j);
                                        for(i=7;i>=0;i--){            
                                            pc.printf("%02X",OT07[j].rom_id[i]); 
                                        }    
                                        pc.printf("]\r\n");
                                    }
                                    
                            break;
                        
                        case 'T':
                        case 't':            
                                if(n == 2){//get temperatures from selected device                                                              
                                    for(k=0;k<8;k++){                   
                                        device_id[k] = rom_id_list[device][k];   // get device_id from rom_id_list
                                    }      
                                    convert_temperature(device_id);          //send OW convert selected device
                                    wait(0.02);  //wait 20 ms for convert temperature to complete                         
                                    T[0] = get_temperature(device_id);
                                    pc.printf("device[%02X]  temperature[%.3f]\r\n",device,T[0]);
                                }
                                if(n == 3){ // "t 1 5"  get temperature for devices 1 thru 5
                                        
                                    convert_temperature();          //send OW convert to all devices
                                    wait(0.02);  //wait 750 ms for convert temperature to complete 
                                    for(j=device;j<=arg1;j++){
                                        for(k=0;k<8;k++){                   
                                            device_id[k] = rom_id_list[j][k];   // get device_id from rom_id_list
                                        } 
                                        pc.printf("device[%02X]  temperature[%.3f]\r\n",j,get_temperature(device_id));
                                    }                       
                                }
                                
                                
                                if(n == 2){//get temperatures from selected device                                                            
                                        
                                    convert_temperature(OT07[device].I2C_address);  //send OW convert selected device
                                    wait(0.02);  //wait 20 ms for convert temperature to complete                         
                                    T[device] = get_temperature(OT07[device].I2C_address);
                                    pc.printf("device[%02X]  temperature[%.3f]\r\n",device,T[device]);
                                }
                                
                                if(n == 3){ // "t 1 3"  get temperature for devices 1 thru 3
                                    //sprintf(str,"%x",arg1);     //convert arg1 input as hex to decimal  i.e. 0x10 becomes 10 dec
                                    //sscanf(str,"%d",&arg1);
                                   //IS THIS NEEDED? ^^^
                                   
                                    for(j=device;j<=arg1;j++){                                        
                                        convert_temperature(OT07[j].I2C_address);  //send convert to all devices
                                        wait(0.02);  //wait 20ms for convert temperature to complete
                                        T[j] = get_temperature(OT07[j].I2C_address);
                                    }
                                    
                                    for(j=device;j<=arg1;j++){                    
                                        pc.printf("device[%02X]  temperature[%.3f]\r\n",j,T[j]);
                                    }  
                                }
                                
                            break;
                            
                        case 'w':
                        case 'W':   //write register "w device w.addr data"
                                    
                                    OT07_write_register(OT07[device].I2C_address,arg1, arg2); 
                                    pc.printf("write -- device[%02X] add[%02X] data[%02X] crc[FF FF]\r\n",device,arg1,arg2);
                                break;
                        
                        case 'x':   
                        case 'X':   // experimental modes
                                    // ******************  set up ADC enabled in test mode*****************
                                    pc.printf("<set ADC_ENABLED in test mode>\r\n");
                                    
                                    for(j=0;j<device_count;j++){                                   
                                        for(k=0;k<8;k++){                   
                                            device_id[k] = rom_id_list[j][k];   // get device_id from rom_id_list
                                        }
                                        set_test_mode(device_id);
                                    } 
                            break;
                            
                                               
                    }//end switch(c)
                }//if(n>0)             
            }//end if(CR)           
            if(rx_buff[rx_index] == BS){//backspace received, back up buffer pointer                                
                 if(rx_index>0)rx_index--;//remove last char from buffer if not at start.                 
            }else rx_index++;                                      
        }//end while(pc.redable()) 
        wait(0.1);     // slow down polling  

      }// end (while tick == false)
      tick_flag = false;                // set to false for next time
             
      // only reached when tick_flag = true otherwise stuck in pc.readable() loop
      if(log_flag == true){                       
            if(time_count >= time_to_sample){ //take next sample
                time_to_sample += log_interval;   // calculate time for next sample
                   
                // start conversion    
                convert_temperature();
                wait(0.02);               //wait 20ms for convert to complete
                for(j=0;j<device_count;j++){ 
                    for(k=0;k<8;k++){                   
                        device_id[k] = rom_id_list[j][k];   // get device_id from rom_id_list
                    }
                    T[j] = get_temperature(device_id);            
                }

                //open file for microSD logging
                FILE *fp = fopen(log_file, "a");
                if (fp != NULL) 
                {
                    //fprintf(fp, "\n");
                    fprintf(fp, "%d",time_count);
                    for(j=0;j<device_count;j++)
                    {
                        if(device_logged[j])
                        {
                            fprintf(fp,",%.3f",T[j]);
                        }
                        
                    }
                    fprintf(fp,"\r\n");
                
                    fclose(fp);  
                }
            }// end if(time_count >= time_to_sample)        
            time_count ++;                    // 
            
      }// end if(log_flag)
      
    }//end while(1)
}