posilani dat

Dependencies:   FatFileSystemCpp mbed PowerControl USBHostLite

main.cpp

Committer:
jkaderka
Date:
2015-03-13
Revision:
2:f623d1815dc4
Parent:
1:3ec5f7df2410
Child:
4:030c7726c7dc

File content as of revision 2:f623d1815dc4:

#include "mbed.h"
#include "L3GD20_init.h"
#include "math.h"
#include "stdint.h"
#include "DirHandle.h"
#include "SDCard.h"
#include "L3GD20.h"
#include "adc.h"
#include "utils.h"
#include "RF.h"
#include <stdio.h>

#define SAMPLE_RATE         750000                          // S mple rate for ADC conversion
#define PERIOD              0.01                            // Setting the period of measuring, 0.01 menas 100 times per second
#define SIZE                1000                            // Setting number of instance in array - for saving to SD card


#define SAVING_START 'S'
#define SAVING_STOP 'E'
#define TRANSFER_START 'T'
#define CHECK_READY 'R'                         //will be received when checking if device is alive

#define leds_off() { led_measuring = led_sending = led_working = led_saving = 0; }
#define leds_error() { led_measuring = led_sending = led_working = led_saving = 1; }


class Watchdog {
public:
    void kick(float s) {
        LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
        uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4 
        LPC_WDT->WDTC = s * (float)clk;         
        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset        
        kick();
    }
    
    void kick() {
        LPC_WDT->WDFEED = 0xAA;
        LPC_WDT->WDFEED = 0x55;
    }
};

Watchdog w;

SDCard Logger(p5, p6, p7, p8, "SDCard");                // Initialise the SD Card to SPI interface
ADC adc(SAMPLE_RATE, 1);                                // Initialise ADC to maximum SAMPLE_RATE and cclk divide set to 1   originally MMA7361L
RF nRF(p11, p12, p13, p14, p15);                        // Connecting of wireless module nRF24L01P to SPI
Ticker Saving_Ticker;                                   // Tickers for interrupts on measuring
I2C i2c(p28, p27);                                      // NEW function GYRO connection                                     originally L3G4200D
     
DigitalOut led_measuring(LED1); 
DigitalOut led_sending(LED2); 
DigitalOut led_working(LED3); 
DigitalOut led_saving(LED4); 

static volatile uint64_t absolute = 0;                         // Variable for numbering saved data
volatile int relative = 0;
volatile short swimmer_id = 0;

char fname[40];                                         // Variable for name of Text file saved on SDCard

int acc_x[SIZE];
int acc_y[SIZE];
int acc_z[SIZE];

float gyro_x[SIZE];
float gyro_y[SIZE];
float gyro_z[SIZE];

char readByte(char address, char reg)
{
    char result;    
    i2c.start();
    i2c.write(address);         // Slave address with direction=write
    i2c.write(reg);             // Subaddress (register)
    i2c.start();                // Break transmission to change bus direction
    i2c.write(address + 1);     // Slave address with direction=read [bit0=1]
    result = i2c.read(0);
    i2c.stop();
    return (result);
}
    
void writeByte(char address, char reg,char value)       // Sends 1 byte to an I2C address
{    
    i2c.start();
    i2c.write(address);         // Slave address
    i2c.write(reg);             // Subaddress (register)
    i2c.write(value);
    i2c.stop();    
}
    
void initSensors (void)
{
    //pc.printf("\n L3GD20 init \n");
    //pc.printf("Ping L3GD20 (should reply 0xD4): %x \n",readByte(L3GD20_ADDR,gWHO_AM_I));
    writeByte(L3GD20_ADDR,gCTRL_REG1,0x0F); // Set ODR to 95Hz, BW to 12.5Hz, enable axes and turn on device
    writeByte(L3GD20_ADDR,gCTRL_REG4,0x10); // Full scale selected at 500dps (degrees per second)
    //pc.printf("L3GD20 gyro Temp: %x degrees C \n",readByte(L3GD20_ADDR,gOUT_TEMP));
    
    wait(1); // Wait for settings to stabilize
}    


/*
 * Periodically called, make measurements
 * save data into array and then into file
 */
void measuring(void)
{
    char buffer[BUFFER_SIZE];
    int pos = 0;
    
    // At the beginning, global variable i is set to 1
    // Accelerometr
    // i is total order variable
    // j is relative order variable in one measuring step
        
    adc.start();                                        // Starting ADC conversion
    adc.select(p18);                                    // Measure pin 20
    while(!adc.done(p18))
        ;                              // Wait for it to complete
    acc_x[relative] = adc.read(p18); 
       
    adc.start();                                        // Again .....
    adc.select(p19);                                    // Measure pin 20     
    while(!adc.done(p19))
        ;                              // Wait for it to complete
    acc_y[relative] = adc.read(p19);
    
    adc.start(); 
    adc.select(p20);                                    // Measure pin 20
    while(!adc.done(p20))
        ;                              // Wait for it to complete
    acc_z[relative] = adc.read(p20);  

    // Gyro
    char        xL, xH, yL, yH, zL, zH;
    int16_t     gX, gY, gZ;
    
    xL=readByte(L3GD20_ADDR,gOUT_X_L);
    xH=readByte(L3GD20_ADDR,gOUT_X_H);
    yL=readByte(L3GD20_ADDR,gOUT_Y_L);
    yH=readByte(L3GD20_ADDR,gOUT_Y_H);
    zL=readByte(L3GD20_ADDR,gOUT_Z_L);
    zH=readByte(L3GD20_ADDR,gOUT_Z_H);
    
    gX = (xH<<8) | (xL);                      // 16-bit 2's complement data
    gY = (yH<<8) | (yL);
    gZ = (zH<<8) | (zL);
    
    gyro_x[relative] = (float) gX * (17.5/1000.0);        // At 500dps sensitivity, L3GD20 returns 17.5/1000 dps per digit
    gyro_y[relative] = (float) gY * (17.5/1000.0);
    gyro_z[relative] = (float) gZ * (17.5/1000.0);        //FIXME because of printing values  
    
    absolute++;
    relative++;  
    if ( absolute % (SIZE/20) == 0)
        led_working = !led_working;

    if ( absolute % SIZE == 0 ) {
        led_saving = !led_saving;
        FILE *fp = fopen(fname, "ab");
        if (fp == NULL) {
            printf("\nUnable to append data to file %s\r\n", fname);
            return;
        }

        for (int k = 0; k < SIZE; k++) {
            pos = absolute-SIZE+k;
            toBytes(buffer, &pos, sizeof(int));
            toBytes(buffer+sizeof(int), &acc_x[k], sizeof(int));
            toBytes(buffer+sizeof(int)*2, &acc_y[k], sizeof(int));
            toBytes(buffer+sizeof(int)*3, &acc_z[k], sizeof(int));
            toBytes(buffer+sizeof(int)*4, &gyro_x[k], sizeof(float));
            toBytes(buffer+sizeof(int)*4+sizeof(float), &gyro_y[k], sizeof(float));
            toBytes(buffer+sizeof(int)*4+sizeof(float)*2, &gyro_z[k], sizeof(float));
            
            fwrite(buffer, 1, BUFFER_SIZE, fp); 
        }
        fclose(fp);  
        relative = 0;                     
    }
}    

/*
 * Read data from sdcard and send them to pc
 */
void get_data(void)
{
    int i;
    char name[20];

    for (i = 0; i < swimmer_id; i++) {
        sprintf(name, "/SDCard/swimmer%d.txt", i);
        if (nRF.sendFile(name, i)) {
            leds_error();
            printf("\nUnable to send data\n\r");
        }  
    }
}

int main()
{
    FILE *fp;
    
    printf("Boot...\r\n");
    initSensors();                                      // INIT GYRO
    Logger.SelectCRCMode(1);                            // I dont know / it was in example code
    
    adc.setup(p18,1);                                   // Set up ADC on pin 18
    adc.setup(p19,1);                                   // Set up ADC on pin 19
    adc.setup(p20,1);                                   // Set up ADC on pin 20    

    sprintf(fname, "/SDCard/swimmer%d.txt", swimmer_id);
    remove(fname);  //remove file to avoid reading old data
    
    leds_off();
    printf("Ready...\n\r");
    
    while (1) {
        char cmd = nRF.getCmd();
        
        switch (cmd) {
        /* start measuring data periodically and save them info file */
        case SAVING_START:
            leds_off();
            
            fp = fopen(fname, "wb");
            if(fp == NULL) {
                leds_error();
                printf("Unable to open file %s for writing\r\n", fname);
                break;
            }
                       
            absolute = 0;
            relative = 0;     
            //run saving function            
            Saving_Ticker.attach(&measuring, PERIOD);
            
            printf("Saving...\n\r");
            led_measuring = 1;
        break;
        
        /* stop saving data */
        case SAVING_STOP:
            leds_off();
            //stop saving
            Saving_Ticker.detach();

            //append End of file text
            fp = fopen(fname, "a");
            if(fp == NULL) {
                leds_error();
                printf("Unable to open file %s before sending data\n\r", fname);
                break;
            }
            //append data left in buffers
            int base = ((absolute - (absolute%SIZE)) < 0) ? 0 : absolute - (absolute%SIZE);
            for (int k = 0; k < relative; k++) {
                char buffer[BUFFER_SIZE];
                int pos = base+k;
                toBytes(buffer, &pos, sizeof(int));
                toBytes(buffer+sizeof(int), &acc_x[k], sizeof(int));
                toBytes(buffer+sizeof(int)*2, &acc_y[k], sizeof(int));
                toBytes(buffer+sizeof(int)*3, &acc_z[k], sizeof(int));
                toBytes(buffer+sizeof(int)*4, &gyro_x[k], sizeof(float));
                toBytes(buffer+sizeof(int)*4+sizeof(float), &gyro_y[k], sizeof(float));
                toBytes(buffer+sizeof(int)*4+sizeof(float)*2, &gyro_z[k], sizeof(float));
            
                fwrite(buffer, 1, BUFFER_SIZE, fp); 
            }
            fclose(fp);
            
            //and finally, move to the next swimmer id
            swimmer_id++;
            sprintf(fname, "/SDCard/swimmer%d.txt", swimmer_id);
            remove(fname);  //remove file to avoid reading old data
            printf("Stopped...\n\r");
        break;
 
        /* send all data */
        case TRANSFER_START:
            leds_off();
            led_sending = 1;
            printf("Sending data...\n\r");
            get_data();

            leds_off();
        break;
        
        case CHECK_READY:
        break;

        default : 
            leds_error();
            printf("\nCommand %c is unknown!\n\r", cmd);
        break;
        }
    //end of while(1)
    }
}