The transmitting code for JetX Engineering

Dependencies:   MLX90614 mbed nRF24L01P

main.cpp

Committer:
FraserLaw23
Date:
2017-03-23
Revision:
0:42fb8bed86d5

File content as of revision 0:42fb8bed86d5:

#include "mbed.h"
#include <math.h>
#include "mlx90614.h"
#include "nRF24L01P.h"

Serial pc (USBTX, USBRX);
InterruptIn rpm1 (p21); // initiate two rpm sensors 130/140 degrees was the best output for the rpm1 resistor
InterruptIn rpm2 (p22); 
InterruptIn vibr (p23); // initiate vibration sensor
AnalogIn press1 (p15); // initiate four pressure sensors
AnalogIn press2 (p16);
AnalogIn press5 (p17);
AnalogIn press3 (p19);
AnalogIn press4 (p18);
AnalogIn air (p20);

I2C i2c(p28,p27);   // sda,scl
MLX90614 temp1(&i2c, 0x5A<<1); // initiate using default address
MLX90614 temp2(&i2c, 0x04<<1); // initiate using changed address

Timer t_rpm1; // create two timers for rpm calculations
Timer t_rpm2;
Timer t_vibr; // create a timer for vibration calculations
Ticker ticker; // create ticker to send data

nRF24L01P wireless(p5, p6, p7, p8, p9, p10); // mosi, miso, sck, csn, ce, irq

// viarables
union rpm1_sensor{
    float rpm_value;
    char bytes[4];
    }r1;
    
union rpm2_sensor{
    float rpm_value;
    char bytes[4];
    }r2;
    
union vibr_sensor{
    float vibr_value;
    char bytes[4];
    }v;

union press1_sensor{
    float press_value;
    char bytes[4];
    }p1;
    
union press2_sensor{
    float press_value;
    char bytes[4];
    }p2;

union press3_sensor{
    float press_value;
    char bytes[4];
    }p3;

union press4_sensor{
    float press_value;
    char bytes[4];
    }p4;
    
union air_sensor{
    float air_value;
    char bytes[4];
    }a;
    
union temp1_sensor{
    float temp_value;
    char bytes[4];
    }t1;

union temp2_sensor{
    float temp_value;
    char bytes[4];
    }t2;

int rpm1_count = 0;
int rpm2_count = 0;
int rpm_sample_size = 6; //changed to 5 from 10

int vibr_count = 0;
int vibr_sample_size = 10;

int press_sample_size = 10;
float press_sample1 = 0.0;
float press_sample2 = 0.0;
float press_sample3 = 0.0;
float press_sample4 = 0.0;

int air_sample_size = 10;
float air_sample = 0.0;
// voltage from a voltage divider with 5v input
float air_volt_ref = 3.24;

const int DATA_SIZE = 20;
char data[DATA_SIZE];
char* data_pointers[DATA_SIZE] = {&r1.bytes[2], &r1.bytes[3], &r2.bytes[2], &r2.bytes[3], &v.bytes[2], &v.bytes[3], 
    &p1.bytes[0], &p1.bytes[1], &p2.bytes[0], &p2.bytes[1], &p3.bytes[0], &p3.bytes[1], 
    &p4.bytes[0], &p4.bytes[1], &a.bytes[2], &a.bytes[3], &t1.bytes[2], &t1.bytes[3], &t2.bytes[2], &t2.bytes[3]};


struct 
{
    float pressure0, pressure1, pressure2, pressure3;
    float temperature0, temperature1;
    float rpm0, rpm1;
    float vibration;
    float airflow;
}ddata;
// functions 
void setRpm1(){
    if (rpm1_count == rpm_sample_size){
        t_rpm1.stop();
        
        // calculate frequency
        float time = t_rpm1.read();
        float frequency = rpm1_count/time; // in Hz
        r1.rpm_value = frequency;
        rpm1_count = 0;
        
        t_rpm1.reset();
        t_rpm1.start();
        }
    else{
        rpm1_count++;
        }
    }
    
void resetRpm1(){
    if(t_rpm1.read()>rpm_sample_size/2){
        t_rpm1.reset();
        rpm1_count = 0;
        r1.rpm_value = 0;
        }
    }
    
void setRpm2(){
    if (rpm2_count == rpm_sample_size){
        t_rpm2.stop();
        
        // calculate frequency
        float time = t_rpm2.read();
        float frequency = rpm2_count/time; // in Hz
        r2.rpm_value = frequency;     
        rpm2_count = 0;
        
        t_rpm2.reset();
        t_rpm2.start();
        }
    else{
        rpm2_count++;
        }
    }
    
void resetRpm2(){    
    if(t_rpm2.read()>rpm_sample_size/2){
        t_rpm2.reset();
        rpm1_count = 0;
        r2.rpm_value = 0;
        }
    }

void setPressure(){
    float press_sample1 = 0;
    float press_sample2 = 0;
    float press_sample3 = 0;
    float press_sample4 = 0;
    
    for (int i = 0; i < press_sample_size; i++){
        press_sample1 += press1.read();
        press_sample2 += press2.read();
        press_sample3 += press3.read();
        press_sample4 += press4.read();
        wait(0.02);
    }
    
    float avgPr1 = press_sample1/press_sample_size;
    // Transfer Function from data sheet:
    //Vout = VS*(0.0018*P+0.04) ± Error
    // Where :
    // VS = 5.0 Vdc
    // Temperature = 0 to 85°C
    //pc.printf("avg press 1 = %0.2f\n", avgPr1);
    //float avg = avgPr1;
    avgPr1 *= 100;
    //avgPr1 = (((avgPr1+0.2) / 5.13) - 0.04) / 0.0018; 
    //avgPr1 = ((avgPr1 / 5) - 0.04) / 0.0018;
    //pc.printf("avg press 1 = %0.2f\n", avgPr1);
    p1.press_value = avgPr1; // converts to integer
    
    float avgPr2 = press_sample2/press_sample_size; 
    avgPr2 *= 100;
    //avgPr2 = (((avgPr2+1.0) / 4.6) - 0.04) / 0.0018;  
    p2.press_value = avgPr2;
    
    float avgPr3 = press_sample3/press_sample_size;
    avgPr3 *= 100; // (((avgPr3+1.1) / 4.6) - 0.04) / 0.0018; 
    p3.press_value = avgPr3;
    
    float avgPr4 = press_sample4/press_sample_size;
    avgPr4 *= 100; //(((avgPr4+1.0) / 4.6) - 0.04) / 0.0018; 
    p4.press_value = avgPr4;
    }
    
void setAirspeed(){
    float air_sample = 0;
    for (int i = 0; i < air_sample_size; i++){
        air_sample += air.read();
        wait(0.02);
    }
    //pc.printf("analog read %f\n", air.read() );
    float avgAir = air_sample/air_sample_size;
    // transfer function from datasheet
    
    //NOTE added comments
    //avgAir = (avgAir/air_volt_ref - 0.5) * 5;
    //pc.printf("pressure is %f\n", pressure);
    // END NOTE
    // Vout = Vs * (0.2 * P(kPa) + 0.5) +- 6.25%
    avgAir = avgAir / 3.3 *  5;
    float pressure = ((avgAir * air_volt_ref / 5) - 0.5f) * 1/0.2f;
    pressure *= 1000;
    //pc.printf("pressure is %f\r", pressure);
    
    
    // air speed (m/s) formula: speed_of_sound(in m/s)in room temp (20 degrees) * sqrt(  (   (measured_pressure/pressure_at_sea_level + 1)^(2/7)  -1)  *5)
    float calc_power = pow((((avgAir) / 10132.5) + 1), 0.285714286);
    float calc_sqrt = 5 * (calc_power - 1);
    calc_sqrt = sqrt(calc_sqrt);
    float calc_airSpeed = 343.21 * calc_sqrt;
    //pc.printf("calc airspeed %f\n", calc_airSpeed);
    a.air_value = calc_airSpeed;
    }

void setVibration(){
    if (vibr_count == vibr_sample_size){
        vibr.disable_irq();
        t_vibr.stop();
        
        // calculate frequency
        float time = t_vibr.read();
        float frequency = vibr_count/time; // in Hz
        v.vibr_value = frequency;
        vibr_count = 0;
        
        t_vibr.reset();
        t_vibr.start();
        wait(0.025);
        vibr.enable_irq();
        }
    else{
        vibr_count++;
        vibr.disable_irq();
        wait(0.025);
        vibr.enable_irq();
        }
    }

void resetVibration(){    
    if(t_vibr.read()>vibr_sample_size/2){
        t_vibr.reset();
        vibr_count = 0;
        v.vibr_value = 0;
        }
    }
    
void synchronizeData(){
    for (int i = 0; i<DATA_SIZE; i++){
        data[i] = *data_pointers[i];
        }
    }
    
void pcHeader(){
    // Display the (default) setup of the nRF24L01+ chip
    pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  wireless.getRfFrequency() );
    pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  wireless.getRfOutputPower() );
    pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", wireless.getAirDataRate() );
    pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", wireless.getTxAddress() );
    pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n\n", wireless.getRxAddress() );
    }

void pcDataOut(){
    pc.printf("Temperature sensor 1 reading: %3.1f degrees celcius\n", t1.temp_value);
    pc.printf("Temperature sensor 2 reading: %3.1f degrees celcius\n", t2.temp_value);
    pc.printf("RPM sensor 1 reading: %.1f Hz, %d rpm\n", r1.rpm_value, (int) (r1.rpm_value*60 + 0.5));
    pc.printf("RPM sensor 2 reading: %.1f Hz, %d rpm\n", r2.rpm_value, (int) (r2.rpm_value*60 + 0.5));
    pc.printf("Vibration sensor reading: %.1f Hz, %d rpm\n", v.vibr_value, (int) (v.vibr_value*60 + 0.5));
    pc.printf("Pressure Sensor 1 reading: %.2f kPa\n", p1.press_value);
    pc.printf("Pressure Sensor 2 reading: %.2f kPa\n", p2.press_value);
    pc.printf("Pressure Sensor 3 reading: %.2f kPa\n", p3.press_value);
    pc.printf("Pressure Sensor 4 reading: %.2f kPa\n\n", p4.press_value);
    pc.printf("Air Speed Sensor reading: %.2f m/s\n\n", a.air_value);
    // individual bytes to be sent in hex
    //pc.printf("%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x\n", 
            //data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], 
            //data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19]);

    }
    
int main() {
    //static_assert(sizeof(data) == 40, "unexpected strucure size");
    wireless.powerUp();
    t_rpm1.start();
    t_rpm2.start();
    t_vibr.start();
    
    //pcHeader(); // print info on screen
    
    // wireless setup
    wireless.setTransferSize(DATA_SIZE);
    wireless.setReceiveMode();
    wireless.enable();
    
    // rpm1 sampling on rising edge
    rpm1.rise(&setRpm1);
    
    // rpm2 sampling on rising edge
    rpm2.rise(&setRpm2);
    
    // vibration ampling on rising edge
    vibr.rise(&setVibration);
    
    // sample pressure and airspeed every set interval
    ticker.attach(&setPressure, 0.7);
    ticker.attach(&setAirspeed, 0.7);
    
    while(1) {
        // reset to 0 if idle
        resetRpm1();
        resetRpm2();
        resetVibration();
        temp1.getTemp(&t1.temp_value);
        temp2.getTemp(&t2.temp_value);
        
        setPressure();
        
        synchronizeData();
        wireless.write(NRF24L01P_PIPE_P0, data, sizeof data);
        
        // fill in the data and send
        //ddata = {0};+
        //#define GUI
        #ifdef GUI
        memset(&ddata, 0, sizeof(ddata));
        ddata.temperature0 = t1.temp_value;
        ddata.temperature1 = t2.temp_value;
        ddata.rpm0 = r1.rpm_value;
        ddata.rpm1 = r2.rpm_value;
        ddata.vibration = v.vibr_value;
        ddata.pressure0 = p1.press_value;
        ddata.pressure1 = p2.press_value;
        ddata.pressure2 = p3.press_value;
        ddata.pressure3 = p4.press_value;
        ddata.airflow = a.air_value;
        char *ptr = (char*)&ddata;
        size_t s = sizeof(ddata);
        pc.putc('s');
        
        for (unsigned j = 0; j < s; ++j) {
            pc.putc(ptr[j]);
        }
        
        #else
        pcDataOut();
        #endif
        
        wait(0.2);
    }
}