mbed-os github

Dependencies:   ADS1015 Faulhaber HTU21D_mod MS5837_potless Sensor_Head_RevB_3 USBDevice_dfu Utilsdfu beep

Fork of ARNSRS_testDFU by POTLESS

main.cpp

Committer:
POTLESS_2
Date:
2017-05-01
Revision:
4:d84250f67dec
Parent:
3:bc6d4222db12
Child:
5:ff7aa975646c

File content as of revision 4:d84250f67dec:

/* procédure lecture capteur COZIR ou MINIR - CO2 seul
sur broches F401RE SERIAL PA_11 et PA_12
renvoie sur moniteur (IDE arduino par exemple) de la valeur lue

procédures possibles sont :
request (char commande) - renvoie la valeur lue si la commande ne représente qu'un seul caractère (entre '')
cozirSend (string commande) - permet d'envoyer des commandes multicaractères (entre "") - exemple A 32 - donne la réponse obtenue


la fonction cozirSend est davantage "sécurisée"
*/


#include "mbed.h"
#include <string>
#include "MS5803_14BA.h"
#include "Adafruit_ADS1015.h"

#ifdef TARGET_K64F
#define SPI_SCK     PTD1
#define SPI_MOSI    PTD2
#define SPI_MISO    PTD3
#define SPI_CS      PTD0
#define I2C_SDA     PTE25
#define I2C_SCL     PTE24
#elif defined(TARGET_KL25Z)
#define SPI_SCK     PTD1
#define SPI_MOSI    PTD2
#define SPI_MISO    PTD3
#define SPI_CS      PTD0
#define I2C_SDA     PTE0
#define I2C_SCL     PTE1
#endif

//COM Série
Serial serialCozir (PA_11,PA_12,9600);
Serial serialMonit (USBTX,USBRX,9600);

//Buffer pour Cozir
char reponse[20];
//Init ADS1015
I2C i2c(D14, D15);
Adafruit_ADS1015 ads(&i2c, 0x48);
//Variables pour PPO2
int16_t valeurO2_01 = 0;
int16_t valeurO2_02 = 0;
// pin d2 pour Adc_AlerRdy (fil bleu) : démarre et arrete l'ADC pour sauver l'energie
int Adc_AlerRdy = 2;
float calibO2 = 0;
float   gainAmpli = 128.0F;   // ADS1115 @ +0,256V gain (16-bit results) gain de l'ampli de l'ADS
//Init MS5803
MS5803_14BA  ps(D14, D15, MS5803_ADDRC_L, D1_OSR_4096, D2_OSR_4096); // SDA, SCL, I2C_address (0x76 or 0x77 look at MS5803.h)

///////////////////////////////////
// fonction de lecture capteur/////
///////////////////////////////////
int request(char commande)
{
    int index=0;
    char ch = ' ';;
    int valeurCommande;

// interrogation capteur
    do {
        if (serialCozir.writeable())  {
            serialCozir.putc(commande);
            serialCozir.putc('\r');
            serialCozir.putc('\n');
        }

        while (!serialCozir.readable()) {}
        ch = serialCozir.getc();
    }

    while ( ch != commande);

// attente réponse capteur
// le format de la reponse est :     Z xxxxx z yyyyy\r\n
// c'est uniquement xxxxx qui nous interesse

    do {
        if (serialCozir.readable()) {
            ch = serialCozir.getc();  // on a reçu Z, on continue de lire la valeur qui suit en stockant caractère par caractère dans une chaine
            if (index<20)     // index <n b de digits max attendus ? (test pour ne pas depasser la capacité du buffer)
                reponse[index++]=ch;  // on stocke le caractere reçu et on passe au suivant
        }
    } while (ch!='\n');    // on s'arrete de lire quand on a recu le retour à la ligne \n de la réponse

//reponse[index++]='\x0';  //  mettre un zero à la fin de la reponse
    sscanf (reponse,"%5d\r\n",&valeurCommande); // on extrait le int de la chaine et on le stocke à l'adresse où pointe valeurCO2
    return valeurCommande;
}


//////////////////////////////////////
// fonction communication capteur/////
// on peut envoyer des ordres avec ///
// plusieurs digits comme A 32     ///
//////////////////////////////////////
int cozirSend(string commande)
{


    int index=0;
    char ch = ' ';;
    int reponseCommande;
    int nbDigits = commande.size();

    commande[nbDigits]='\x0'; // on matérialise la fin de la chaine avc '\x0'

// interrogation capteur
    do {
        if (serialCozir.writeable())  {
            for (int j=0; j<nbDigits; j++) {
                serialCozir.putc(commande[j]);
                //serialMonit.printf(" commande digit %i sur %i => %c\r\n",j,nbDigits-1,commande[j]);   // pour le debug
            }
            serialCozir.putc('\r');
            serialCozir.putc('\n');
        }

        while (!serialCozir.readable()) {};
        ch = serialCozir.getc();
    }

    while ( ch != commande[0]);   // le format de la réponse reprend la première lettre de l'ordre

// attente réponse capteur
// exemple pour co2 : le format de la reponse est  Z xxxxx z yyyyy\r\n
// c'est uniquement xxxxx qui nous interesse

    do {
        if (serialCozir.readable()) {
            ch = serialCozir.getc();  // on a reçu Z, on continue de lire la valeur qui suit en stockant caractère par caractère dans une chaine
            if (index<8)     // index <n b de digits max attendus (les autres ne nous interessent pas)
                reponse[index++]=ch;  // on stocke le caractere reçu et on passe au suivant
        }
    } while (ch!='\n');    // on s'arrete de lire quand on a recu le retour à la ligne \n de la réponse

//reponse[index++]='\x0';  //  mettre un zero à la fin de la reponse
    sscanf (reponse,"%5d\r\n",&reponseCommande); // on extrait le int de la chaine et on le stocke à l'adresse où pointe valeurCommande
//serialMonit.printf(" reponse recue => %5d\r\n",reponseCommande); // pour le debug

    return reponseCommande;
}

////////////////////////
//  Lecture PPO2   /////
////////////////////////
int requestPpO2()
{

    int result3;
    //lecture des deux cellules O2 et P de la carte AQL

    //digitalWrite (Adc_AlerRdy, HIGH); // si le fil a été connecté à la carte (permet d'économiser l'énergie) - sur la carte 2014, il est à la masse donc pas utilisé
    wait_ms(100);                     // mettre la pin AlertRdy à 1 pour lancer conversion ADC
    valeurO2_01 = ads.readADC_Differential_0_1(); // lecture tension entre bornes cell O2 nmr1
    wait_ms(50);
    valeurO2_02 = ads.readADC_Differential_2_3(); // lecture tension entre bornes cell O2 nmr2
    wait_ms(50);
    //digitalWrite (Adc_AlerRdy, LOW); // remettre la pin AlertRdy à 0 pour économiser energie
    // pour le DEBUG
    //serialMonit.printf("Diff brute entre cell O2: "); serialMonit.printf((valeurO2_01-valeurO2_02)); serialMonit.printf("("); serialMonit.printf((valeurO2_01-valeurO2_02) / gainAmpli); serialMonit.printf("mV)"); // ramené en mV
    //serialMonit.printf("O2.1: "); serialMonit.printf(valeurO2_01); serialMonit.printf(" ("); serialMonit.printf((valeurO2_01) / gainAmpli); serialMonit.printf("mV) - ");serialMonit.printf((valeurO2_01) / gainAmpli/6354*calibO2*100000,0); serialMonit.printf("mbar de ppO2)"); // coef usine cellule + ramené en mV
    //serialMonit.printf("O2.2: "); serialMonit.printf(valeurO2_02); serialMonit.printf(" ("); serialMonit.printf((valeurO2_02) / gainAmpli); serialMonit.printf("mV) - ");serialMonit.printf((valeurO2_02) / gainAmpli/6528*calibO2*100000,0); serialMonit.printf("mbar de ppO2)"); // ramené en mV

    result3 = 0.5 * (valeurO2_01 + valeurO2_02) / gainAmpli * calibO2; // valeur en mbar
    return result3;
}

///////////////////////////////////
// fonction initialisation    /////
///////////////////////////////////
void setup()
{
//Préparation PPO2 avec ADS1015
    ads.setGain(GAIN_SIXTEEN); // set range to +/-0.256V
    // calibration cellules O2
    // partie i2c : lecture des deux cellules O2 et P de la carte AQL
    //digitalWrite (Adc_AlerRdy, HIGH); // si le fil a été connecté à la carte (permet d'économiser l'énergie) - sur la carte 2014, il est à la masse donc pas utilisé
    wait_ms(100);

    for (int i = 0; i < 5; i++) {
        // proposition : mettre la pin AlertRdy à 1 pour lancer conversion ADC
        valeurO2_01 = valeurO2_01 + ads.readADC_Differential_0_1(); // lecture tension entre bornes cell O2 nmr1
        wait_ms(50);
        valeurO2_02 = valeurO2_02 + ads.readADC_Differential_2_3(); // lecture tension entre bornes cell O2 nmr2
        wait_ms(50);
    }

    valeurO2_01 = valeurO2_01 / 5;
    valeurO2_02 = valeurO2_02 / 5;
    calibO2 = 208 / (0.5 * (valeurO2_01 + valeurO2_02) / gainAmpli); //(air frais : 208 mbar supposés au moment de la calib)

//Préparation mode fonctionnement CO2 COZIR
    serialMonit.printf("reponse demande pooling  => K %5i\r\n",    cozirSend("K 2"));
    serialMonit.printf("reponse demande filtrage => A %5i\r\n",    cozirSend("A 32"));
    serialMonit.printf("reponse calibration      => G %5d\r\n",    cozirSend("G"));

}

/////////////////////////////////////
/// procédure principale    /////////
/////////////////////////////////////

int main()
{
    setup(); //initialisation capteurs

    while (1) {
        //CO2 / H / T sur Cozir
        serialMonit.printf("  co2 COZIR par methode cozirSend = %5d\r\n"  ,cozirSend("Z")*10);    // on multiplie par 10 pour etre en ppm
        serialMonit.printf("  co2 COZIR par methode request   = %5d\r\n"  ,request('Z')*10);      // on multiplie par 10 pour etre en ppm  (méthode précédente)
        serialMonit.printf("  H COZIR par methode cozirSend = %5d\r\n"  ,cozirSend ("H"));      // à laisser comme ça pour transmettre en BLE mais à diviser par 10 à réception dans l'app android pour être en xx,x%
        serialMonit.printf("  H COZIR par methode request   = %5d\r\n"  ,request('H'));         // à laisser comme ça pour transmettre en BLE mais à diviser par 10 à réception dans l'app android pour être en xx,x%
        serialMonit.printf("  T COZIR par methode cozirSend = %5d\r\n"  ,cozirSend ("T")-1000); // à laisser comme ça pour envoi BLE et à diviser par 10 à réception dans l'app android pour etre en yy,y°C
        serialMonit.printf("  T COZIR par methode request   = %5d\r\n"  ,request('T')-1000);    // à laisser comme ça pour envoi BLE et à diviser par 10 à réception dans l'app android pour etre en yy,y°C
        //P / T sur MS5803
        ps.convert();
        serialMonit.printf("  Pression    MS5803 = %f\r\n", ps.pressure);
        serialMonit.printf("  Temperature MS5803 = %f\r\n", ps.temperature);
        //PPO2 sur ADS1015
        //reading = ads.readADC_Differential_2_3();
        serialMonit.printf("  PPO2 sur ADS1015 : %d\r\n", requestPpO2()); // print diff
        wait_ms(2000);
    }
}