top of page

ballon_sonde.c

 

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <string.h>
#include <time.h>
#include "../headers/config.h"
#include <math.h>
#include "../headers/spi.h"
#include "../headers/sram_MCP.h"
#include "../headers/serial.h"
#include "../headers/ballon_sonde.h"

 

//Initialisation globale du microcontrôleur

void initPIC(void){
  ANSELC = 0; //Les broches A,B et C sont configurées comme des entrées analogiques.
  ANSELA = 0;
  ANSELB = 0;
  OSCCONbits.IRCF = 0b1111; // Fosc = 16 MHz
  OPTION_REGbits.INTEDG = 1; //Interrupt on rising edge of INT pin
  return;
}

 

//Initialisation de la conversion analogique-numérique

void init_CAN(void)
{
  ADCON1bits.ADCS = 0b000; //ADC Conversion Clock = Fosc/2 soit 8MHz
  ADCON1bits.ADFM = 0; /*ADC Result Format = Right justified. Six Most Significant bits of ADRESH are set to ‘0’ when the conversion result isloaded.*/
  ADCON1bits.ADPREF = 0b00; /* ADC Positive Voltage Reference; V RPOS is connected to VDD */
  ADCON0bits.ADON = 1;  //ADC is enabled
  return;
}

 

void initPWM (void){
  TRISCbits.TRISC5=1; // configuration du port en entree
  T2CONbits.TMR2ON=1; // Timer2 is on
  T2CONbits.T2CKPS=0b01; // Prescaler is 4
  PIR1bits.TMR2IF=0; // Timer2 to PR2 Interrupt Flag bit, interrupt is not pending
  PWM1CONbits.PWM1OE=1; // enable output bits (bit 6)
  PWM1CONbits.PWM1EN=1; // enable output bits (bit 7)
  PWM1CONbits.PWM1POL=0; // sortie active à l'état haut
  PR2bits.PR2=0b1111100; // timer2 Period Register
  TRISCbits.TRISC5=0; // configuration du port en sortie
  return;
}

 

void init_accelerometre_x(void)
{//On configure RA2 comme étant l'entree analogique
  PORTAbits.RA2=1;
  TRISAbits.TRISA2 = 1; 
  ADCON0bits.CHS = 0b00010;
  return;
}

 

void init_accelerometre_y(void)
{//On configure RC0 comme étant l'entree analogique
  PORTCbits.RC0=1;
  TRISCbits.TRISC0 = 1; 
  ADCON0bits.CHS = 0b01011;
  return;
}

 

void init_accelerometre_z(void)
{//On configure RC1 comme étant l'entree analogique
  PORTCbits.RC1=1;
  TRISCbits.TRISC1 = 1; // entree analogique 
  ADCON0bits.CHS = 0b00101;
  return;
}

 

void init_hygrometre(void)
{ //On configure RC2 comme étant l'entree analogique
  PORTCbits.RC2=1;
  TRISCbits.TRISC2 = 1;
  ADCON0bits.CHS = 0b00110;
  return;
}

 

void init_thermistance(void){
  TRISAbits.TRISA4 = 1;
  ANSELAbits.ANSA4 = 1;
  ADCON0bits.CHS = 0b00011; // AN3
  return;
}

 

void init_particules(void){
  TRISCbits.TRISC6 = 1;
  //ANSELCbits.ANSC6 = 1;
  PORTCbits.RC6 = 1;   
  ADCON0bits.CHS = 0b01000; // AN8
  return; 
}

 

void init_pression(void){
  TRISBbits.TRISB5 = 1;
  ANSELBbits.ANSB5 = 1;//configuration de l'entrée analogique
  ADCON0bits.CHS = 0b01011; //AN11
  return;
}

 

void accelerometre_x_CAN(char * ligne){
  char res_acc_x;
  ADCON0bits.GO_nDONE = 1;
  while(ADCON0bits.GO_nDONE == 1);// On ne fait rien, on attend simplement que la conversion se termine
  res_acc_x= ADRESH;
  sprintf(ligne,"aX= %d.%d g\n",(res_acc_x-66)/12,abs(10*(res_acc_x-66)/12-(res_acc_x-66)/12*10));//conversion selon calibration

  return;
}

void accelerometre_y_CAN(char * ligne){
  char res_acc_y;
  ADCON0bits.GO_nDONE = 1;
  while(ADCON0bits.GO_nDONE == 1);// On ne fait rien, on attend simplement que la conversion se termine
  res_acc_y= ADRESH;
  sprintf(ligne,"aY= %d.%d g\n",(res_acc_y-66)/12,abs(10*(res_acc_y-66)/12-(res_acc_y-66)/12*10));//conversion selon calibration
  return;
}

 

void accelerometre_z_CAN(char * ligne){
  char res_acc_z;
  ADCON0bits.GO_nDONE = 1;
  while(ADCON0bits.GO_nDONE == 1);// On ne fait rien, on attend simplement que la conversion se termine
  res_acc_z= ADRESH;
  sprintf(ligne,"aZ= %d.%d g\n",(res_acc_z-70)/13,abs(10*(res_acc_z-70)/13-(res_acc_z-70)/13*10));

//Ce calcul résulte des différentes calibrations effectuées pour l'accéléromètre
  return;
}

​

float hygrometre_CAN(char *ligne, float T){
  char res_hygrometre;
  float A1 = -0.0945; //A1, A2, B1, B2 sont des constantes calculées à partir des courbes d'étalonnage de la datasheet (http://www.farnell.com/datasheets/1355476.pdf)
  float A2 = -0.112;
  float B1 = -17.4;
  float B2 = 94.4;
  float hum;
  ADCON0bits.GO_nDONE = 1; // On démarre la conversion
  while(ADCON0bits.GO_nDONE == 1);// On attend que la conversion se termine
  res_hygrometre= ADRESH;
  hum=log(res_hygrometre)*(A1*(T-273.15)+B1)+A2*(T-273.15)+B2; //equation calculee a partir des courbes    //d'etalonnage de la datasheet
  sprintf(ligne,"hum=%d\n",(int)hum); /*On stocke le résultat dans ligne, sous la forme "hum=x" avec x le pourcentage d'humidité*/
  return hum;
}

 

float thermistance_CAN(char * ligne){
  char res_thermistance;
  float A = 0.003354016;   // Ce sont des constantes données dans la datasheet de la thermistance CTN10
  float B = 0.0002569850;
  float C = 0.000002620131;
  float D = 0.00000006383091;
  int R = 9780; // Valeur de la résistance choisie pour le pont diviseur de tension (on la prend égale à la résistance interne de la                                // thermistance)
  float RT, U, T1;
  int T,T2;
  ADCON0bits.GO_nDONE = 1;
  while(ADCON0bits.GO_nDONE);
  res_thermistance=ADRESH;   // mesure analogique
  U = (double)res_thermistance*5/255;    // conversion
  RT=(double)U*R/(5-U); // calcul de RT à partir de la mesure
  T1=1/(A+B*log(RT/R)+C*log(RT/R)*log(RT/R)+D*log(RT/R)*log(RT/R)*log(RT/R));  //équation donnant la valeur de la température  //(tirée de la datasheet)
  T=(int)(T1);
  T2=(int)((T1-T)*10);
  sprintf(ligne,"T=%d,%dK\n",T,T2); //affichage grâce à l'Arduino
  return T1;
}

 

void particules_CAN(char * ligne){
  char res_particules;
  float seuil = 0.25;
  float  U1, U2; 
  int Upart,Ubis;
  ADCON0bits.GO_nDONE = 1;
  while(ADCON0bits.GO_nDONE);
  res_particules=ADRESH;
  U1 = (float)res_particules*5/255; // conversion
  Upart = (int)U1;
  U2 = (float)((U1-Upart)*1000);
  Ubis=(int)U2;  
  if(U2>0)                                // condition sur la présence de particules
    {sprintf(ligne,"particules\n");}
  else
    {sprintf(ligne,"pas de particules\n");}
  return;
}

 

void changeDC1(char val){    // fonction qui permet de paramétrer le créneau envoyé en entrée de la diode IR
  int temp=((val*(PR2+1))/100)*4;
  PWM1DCL=(temp & 3) <<6;
  PWM1DCH= temp >>2;
  return;
}

 

int pression_CAN(char * ligne){
  int P;  
  char res_pression;
  ADCON0bits.GO_nDONE = 1; //on attend que la conversion se fasse
  while(ADCON0bits.GO_nDONE);
  res_pression=ADRESH;
  P=(((res_pression*100)/255-4)*111+1750)/10; //calcul pression selon les courbes d'etalonnage du constructeur + calibration
  sprintf(ligne,"P=%d hPa\n",P);

  return P;
}

bottom of page