Réorganisation de la bibliothèque MeasureUnit

This commit is contained in:
anschrammh 2020-05-11 12:38:45 +02:00
parent 44e40b8ab3
commit ebba78c49b
13 changed files with 0 additions and 1128 deletions

View File

@ -1,43 +0,0 @@
#include "Adc.h"
Adc::Adc() : _lastChannel(0), _adcSetting(0,0), _state(IDLING), _sampledValue(0), _numOfSamples(0), _elapsedTime(0)
{
//Serial.println("Adc constructor called");
}
Adc::~Adc()
{
}
void Adc::setAdcSetting(AdcSetting adcSetting)
{
_adcSetting = adcSetting;
}
AdcSetting Adc::getAdcSetting()
{
return _adcSetting;
}
boolean Adc::isSampleReady()
{
return _state == RESULT_READY;
}
double Adc::getQuantum()
{
return _adcSetting.getQuantum();
}
double Adc::getSampleValue()
{
double ret(0);
if(_state == RESULT_READY)
{
ret = _sampledValue;
_state = IDLING;
}
return ret;
}

View File

@ -1,42 +0,0 @@
#ifndef ADC_H
#define ADC_H
#include "AdcSetting.h"
class Adc
{
public:
virtual ~Adc() = 0;
virtual void begin() = 0;
virtual double getQuantum();
virtual double sampleValue(int16_t channel, boolean sgl = true) = 0;
virtual double sampleValue() = 0;
virtual double sampleVoltage(int16_t channel, boolean sgl = true) = 0;
virtual double sampleVoltage() = 0;
//Async methods
enum STATE {STARTED = 0, RESULT_READY, IDLING, SAMPLING};
virtual void startSample(int16_t channel, boolean sgl = true) = 0;
virtual void startSample() = 0;
virtual double getSampleVoltage() = 0;
boolean isSampleReady();
double getSampleValue();
//End of async methods
void setAdcSetting(AdcSetting adcSetting);
AdcSetting getAdcSetting();
protected:
Adc();
int16_t _lastChannel;
AdcSetting _adcSetting;
//Async part
STATE _state;
double _sampledValue;
uint8_t _numOfSamples;
unsigned long _elapsedTime;
private:
};
#endif //ADC_H

View File

@ -1,19 +0,0 @@
#include "AdcSetting.h"
AdcSetting::AdcSetting(double vref,
uint8_t adcResolution,
uint8_t measureIteration,
uint16_t delayBetweenIteration) : _vref(vref), _adcResolution(adcResolution), _measureIteration(measureIteration), _delayBetweenIteration(delayBetweenIteration), _quantum(vref/(pow(2.0,(double) adcResolution)-1))
{
}
uint8_t AdcSetting::getMeasureIteration()
{
return _measureIteration;
}
double AdcSetting::getQuantum()
{
return _quantum;
}

View File

@ -1,25 +0,0 @@
#ifndef ADCSETTING_H
#define ADCSETTING_H
#include <Arduino.h>
#include <math.h>
class AdcSetting
{
public:
AdcSetting(double vref, uint8_t adcResolution, uint8_t measureIteration = 5, uint16_t delayBetweenIteration = 5);
~AdcSetting(){}
uint8_t getMeasureIteration();
uint16_t getDelayBetweenIteration(){ return _delayBetweenIteration;}
double getQuantum();
double getVref(){return _vref;}
protected:
private:
double _vref;
uint8_t _adcResolution;
double _quantum;
uint8_t _measureIteration;
uint16_t _delayBetweenIteration;
};
#endif //ADCSETTING_H

View File

@ -1,127 +0,0 @@
#include "Ads1115.h"
#define ADS_DEBUG
Ads1115::Ads1115() : ads1(0x48), ads2(0x49)
{
#ifdef ADS_DEBUG
Serial.println("Ads1115 constructor called");
#endif
//We set the adcs up:
ads1.setGain(GAIN_ONE);
ads2.setGain(GAIN_ONE);
}
Ads1115::~Ads1115()
{
}
void Ads1115::begin()
{
#ifdef ADS_DEBUG
Serial.println("Ads1115 : begin");
#endif
ads1.begin();
ads2.begin();
}
double Ads1115::getQuantum()
{
return 0.125;
}
double Ads1115::sampleValue(int16_t channel, boolean sgl)
{
double total(0);
for(int i(0); i < getAdcSetting().getMeasureIteration(); i++)
{
delay(getAdcSetting().getDelayBetweenIteration());
total += getReading(channel, sgl);
}
//We divide
total /= (double)getAdcSetting().getMeasureIteration();
//We return
return total;
}
double Ads1115::sampleValue()
{
return sampleValue(-1);
}
double Ads1115::sampleVoltage(int16_t channel, boolean sgl)
{
return sampleValue(channel, sgl)*0.125;
}
double Ads1115::sampleVoltage()
{
return sampleValue()*0.125;
}
uint16_t Ads1115::getReading(int16_t channel, boolean sgl)
{
int16_t chan(channel == -1 ? _lastChannel : channel);
_lastChannel = chan > 8 ? 0 : chan;
if(chan < 4)
{
return ads1.readADC_SingleEnded(chan);
}
else if(chan < 8)
{
return ads2.readADC_SingleEnded(chan - 4);
}
else return 0;
}
//Async part
void Ads1115::startSample(int16_t channel, boolean sgl)
{
switch(_state)
{
case IDLING:
_state = SAMPLING;
_elapsedTime = millis();
_sampledValue = 0.0;
_numOfSamples = 0;
//We set the last channel attribute
if(channel != -1)
{
_lastChannel = channel > 8 ? _lastChannel : channel;
}
break;
case SAMPLING:
//If enough time elapsed, we can sample a value again
if(millis() - _elapsedTime > getAdcSetting().getDelayBetweenIteration())
{
_sampledValue += getReading(channel, sgl);
_elapsedTime = millis();
_numOfSamples ++;
}
//All samples are done:
if(_numOfSamples == getAdcSetting().getMeasureIteration())
{
_sampledValue /= (double)_numOfSamples;
_sampledValue += channel > 3 ? 82.0 : 0.0;
_state = RESULT_READY;
}
break;
}
}
void Ads1115::startSample()
{
startSample(-1);
}
double Ads1115::getSampleVoltage()
{
return getSampleValue() * 0.125;
}

View File

@ -1,31 +0,0 @@
#ifndef ADS1115_H
#define ADS1115_H
#include "Adc.h"
#include <Wire.h>
#include <Adafruit_ADS1015.h>
class Ads1115 : public Adc
{
public:
Ads1115();
~Ads1115();
virtual void begin();
virtual double getQuantum();
virtual double sampleValue(int16_t channel, boolean sgl = true);
virtual double sampleValue();
virtual double sampleVoltage(int16_t channel, boolean sgl = true);
virtual double sampleVoltage();
//Async methods
virtual void startSample(int16_t channel, boolean sgl = true);
virtual void startSample();
virtual double getSampleVoltage();
//End of async methods
protected:
private:
uint16_t getReading(int16_t channel = -1, boolean sgl = true);
Adafruit_ADS1115 ads1, ads2;
};
#endif //ADS1115_H

View File

@ -1,134 +0,0 @@
#include "Ads1115V2.h"
#define ADSV2_DEBUG
Ads1115V2::Ads1115V2() : ads1(ADS1115_ADDRESS_ADDR_GND), ads2(ADS1115_ADDRESS_ADDR_VDD)
{
#ifdef ADSV2_DEBUG
Serial.println("Ads1115 constructor called");
#endif
}
Ads1115V2::~Ads1115V2()
{
}
void Ads1115V2::begin()
{
#ifdef ADSV2_DEBUG
Serial.println("Ads1115V2 : begin");
#endif
Wire.begin();
//We set the adcs up:
ads1.initialize();
ads2.initialize();
ads1.setMode(ADS1115_MODE_SINGLESHOT);
ads2.setMode(ADS1115_MODE_SINGLESHOT);
ads1.setRate(ADS1115_RATE_250);
ads2.setRate(ADS1115_RATE_250);
ads1.setGain(ADS1115_PGA_4P096);
ads2.setGain(ADS1115_PGA_4P096);
}
double Ads1115V2::getQuantum()
{
return 0.125;
}
double Ads1115V2::sampleValue(int16_t channel, boolean sgl)
{
double total(0);
for(int i(0); i < getAdcSetting().getMeasureIteration(); i++)
{
delay(getAdcSetting().getDelayBetweenIteration());
total += getReading(channel, sgl);
}
//We divide
total /= (double)getAdcSetting().getMeasureIteration();
//We return
return total;
}
double Ads1115V2::sampleValue()
{
return sampleValue(-1);
}
double Ads1115V2::sampleVoltage(int16_t channel, boolean sgl)
{
return sampleValue(channel, sgl)*0.125;
}
double Ads1115V2::sampleVoltage()
{
return sampleValue()*0.125;
}
uint16_t Ads1115V2::getReading(int16_t channel, boolean sgl)
{
int16_t chan(channel == -1 ? _lastChannel : channel);
_lastChannel = chan > 8 ? 0 : chan;
if(chan < 4)
{
ads1.setMultiplexer(chan+4);
return ads1.getConversion(true);
}
else if(chan < 8)
{
ads2.setMultiplexer(chan);
return ads2.getConversion(true);
}
else return 0;
}
//Async part
void Ads1115V2::startSample(int16_t channel, boolean sgl)
{
switch(_state)
{
case IDLING:
_state = SAMPLING;
_elapsedTime = millis();
_sampledValue = 0.0;
_numOfSamples = 0;
//We set the last channel attribute
if(channel != -1)
{
_lastChannel = channel > 8 ? _lastChannel : channel;
}
break;
case SAMPLING:
//If enough time elapsed, we can sample a value again
if(millis() - _elapsedTime > getAdcSetting().getDelayBetweenIteration())
{
_sampledValue += getReading(channel, sgl);
_elapsedTime = millis();
_numOfSamples ++;
}
//All samples are done:
if(_numOfSamples == getAdcSetting().getMeasureIteration())
{
_sampledValue /= (double)_numOfSamples;
_sampledValue += channel > 3 ? 82.0 : 0.0;
_state = RESULT_READY;
}
break;
}
}
void Ads1115V2::startSample()
{
startSample(-1);
}
double Ads1115V2::getSampleVoltage()
{
return getSampleValue() * 0.125;
}

View File

@ -1,31 +0,0 @@
#ifndef ADS1115V2_H
#define ADS1115V2_H
#include "Adc.h"
#include <Wire.h>
#include <ADS1115x.h>
class Ads1115V2 : public Adc
{
public:
Ads1115V2();
~Ads1115V2();
virtual void begin();
virtual double getQuantum();
virtual double sampleValue(int16_t channel, boolean sgl = true);
virtual double sampleValue();
virtual double sampleVoltage(int16_t channel, boolean sgl = true);
virtual double sampleVoltage();
//Async methods
virtual void startSample(int16_t channel, boolean sgl = true);
virtual void startSample();
virtual double getSampleVoltage();
//End of async methods
protected:
private:
uint16_t getReading(int16_t channel = -1, boolean sgl = true);
ADS1115 ads1, ads2;
};
#endif //ADS1115V2_H

View File

@ -1,375 +0,0 @@
#include "MeasureUnit.h"
//#define DEBUG
MeasureUnit::MeasureUnit(uint8_t *analogInput,
uint16_t thermistorCount,
uint64_t precResistor,
ThermistorSetting thermistorSetting,
Adc &adc) : _analogInput(analogInput),
_thermistorCount(thermistorCount),
_precResistor(precResistor),
_thermistorSetting(thermistorSetting),
_adc(adc),
_globalOffset(0),
_error(OK),
_state(IDLING),
_channel(0),
_offsetComputeIte(7),
_offsetCounter(7),
_courant(0.0),
_tension(0.0),
_triggerLevelOff(false)
{
//Allocation dynamique des différent tableaux
_temperatures = (double*) calloc(_thermistorCount, sizeof(double));
_rOffsetMap = (double*) calloc(_thermistorCount, sizeof(double));
_resistanceMap = (double*) malloc(_thermistorCount * sizeof(double));
_rOffsetBuffer = (double*) malloc(_thermistorCount * sizeof(double));
if(_temperatures == NULL || _rOffsetMap == NULL || _resistanceMap == NULL || _rOffsetBuffer == NULL)
{
_error = MALLOC_ERR;
_temperatures != NULL ? free(_temperatures):(void)_temperatures;
_rOffsetMap != NULL ? free(_rOffsetMap):(void)_rOffsetMap;
_resistanceMap != NULL ? free(_resistanceMap):(void)_resistanceMap;
_rOffsetBuffer != NULL ? free(_rOffsetBuffer):(void)_rOffsetBuffer;
_temperatures = NULL;
_rOffsetMap = NULL;
_resistanceMap = NULL;
_rOffsetBuffer = NULL;
}
_adc.begin();
}
MeasureUnit::~MeasureUnit()
{
if(_error != MALLOC_ERR)
{
free(_temperatures);
free(_rOffsetMap);
free(_resistanceMap);
free(_rOffsetBuffer);
}
}
void MeasureUnit::run()
{
switch(_state)
{
case MEASURING:
_adc.startSample(_channel);
if(_channel == 0) //Calcule du courant
{
if(_adc.isSampleReady())
{
_tension = _adc.getSampleVoltage();
_courant = _tension / (double) _precResistor;
#ifdef DEBUG
Serial.print("Tension prec : ");Serial.println(_tension);
#endif
_channel++;
}
}
else //Calcule des niveaux de tensions
{
if(_adc.isSampleReady())
{
_resistanceMap[_channel-1] = _adc.getSampleVoltage();
#ifdef DEBUG
Serial.print("Tension thermistances : ");Serial.println(_resistanceMap[_channel-1]);
#endif
_channel++;
}
}
//Fin de la partie d'acquisition
if(_channel == _thermistorCount)
{
_state = COMPUTING;
_resistanceMap[_channel-1] = _adc.getAdcSetting().getVref();
}
break;
case COMPUTING :
//Ici nous calculons les temperatures
for(int i(_thermistorCount-1); i > 0; i--)
{
//Calcule de delta :
_resistanceMap[i] -= _resistanceMap[i-1];
#ifdef DEBUG
Serial.printf("Debug voltage delta : %u -> ",i);Serial.println(_resistanceMap[i]);
#endif
}
//Ne pas oublier de déduire la chute de tension de la resistance de precision pour la première thermistance
_resistanceMap[0] -= _tension;
#ifdef DEBUG
Serial.printf("Debug voltage delta : 0 -> ");Serial.println(_resistanceMap[0]);
#endif
for(int i(0); i < _thermistorCount; i++)
{
//3) Nous en déduisons la résistance
//Serial.print("Resistance ");Serial.print(i);Serial.print(" ");Serial.println(_resistanceMap[i]);
_resistanceMap[i] /= _courant;
//4) Nous en déduisons la temperature
_temperatures[i] = computeTemperature(_thermistorSetting.getBeta(), _resistanceMap[i], _thermistorSetting.getRat25());
//On effectue un étalonnage
if(_triggerLevelOff)
{
double averageTemp(0);
//We reset the offset
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetMap[i] = 0;
}
for(int i(0); i < _thermistorCount; i++)
{
averageTemp += _temperatures[i];
}
averageTemp /= (double)_thermistorCount;
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetMap[i] = averageTemp - _temperatures[i];
}
_triggerLevelOff = false;
}
_temperatures[i] += _rOffsetMap[i] + _globalOffset;
#ifdef DEBUG_TEMP
Serial.print("Temperature ");Serial.print(i);Serial.print(" : ");Serial.println(_temperatures[i]);
#endif
}
_state = MEASUREMENT_READY;
break;
}
if(_offsetCounter < _offsetComputeIte && isMeasurementReady())
{
//We reset the offset array
if(_offsetCounter == 0)
{
Serial.printf("Initiating average \n");
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetBuffer[i] = 0;
_rOffsetMap[i] = 0;
}
}
else if(_offsetCounter == _offsetComputeIte-1)
{
double averageTemp(0);
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetBuffer[i] += _temperatures[i];
}
//We compute the average for each thermistor:
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetBuffer[i] /= _offsetCounter;
averageTemp += _rOffsetBuffer[i];
}
averageTemp /= _thermistorCount;
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetMap[i] = averageTemp - _rOffsetBuffer[i];
}
Serial.println("Offset done");
Serial.print("|");
for(int i(0); i < _thermistorCount; i++)
{
if(i != 7)
{
Serial.print(" ");Serial.print(_rOffsetMap[i],2);Serial.print(" |");
}
else
{
Serial.print(" ");Serial.print(_rOffsetMap[i],2);Serial.print(" |");
}
}
Serial.println("");
}
else
{
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetBuffer[i] += _temperatures[i];
}
}
_offsetCounter++;
}
}
void MeasureUnit::setOffsetIteration(uint8_t iteration)
{
_offsetComputeIte = iteration;
_offsetCounter = iteration;
}
void MeasureUnit::startOffsetComputing()
{
_offsetCounter = 0;
}
/**
* Methode permettant d'effectuer les mesures de température et de les récupérer
*/
double *MeasureUnit::getTemperatures()
{
double courant(0), rPrecTension(0);
//1) Nous calculons le courant présent dans la branche grace à la résistance de précision
#ifdef DEBUG
Serial.println("-------------");
#endif
rPrecTension = _adc.sampleVoltage(0);
#ifdef DEBUG
Serial.println("-------------");
Serial.print("R prec voltage mV : ");Serial.println(rPrecTension,6);
#endif
courant = rPrecTension / (double) _precResistor;
#ifdef DEBUG
Serial.print("R prec current mA : ");Serial.println(courant,6);
#endif
//2) Nous calculons le delta de tensions pour chaque thermistances
for(int i(1); i < _thermistorCount; i++)
{
_resistanceMap[i-1] = _adc.sampleVoltage(_analogInput[i]);
#ifdef DEBUG
Serial.print("Voltage steps ");Serial.print(i-1);Serial.print(" : ");Serial.println(_resistanceMap[i-1]);
#endif
}
_resistanceMap[7] = _adc.getAdcSetting().getVref();
#ifdef DEBUG
Serial.print("Voltage steps 7 : ");Serial.println(_resistanceMap[7]);
#endif
for(int i(_thermistorCount-1); i > 0; i--)
{
//Calcule de delta :
_resistanceMap[i] -= _resistanceMap[i-1];
#ifdef DEBUG
Serial.print("Debug voltage delta : ");Serial.println(_resistanceMap[i]);
#endif
}
//Ne pas oublier de déduire la chute de tension de la resistance de precision pour la première thermistance
_resistanceMap[0] -= rPrecTension;
Serial.printf("Debug voltage delta : 0 -> ");Serial.println(_resistanceMap[0]);
for(int i(0); i < _thermistorCount; i++)
{
//3) Nous en déduisons la résistance
//Serial.print("Resistance ");Serial.print(i);Serial.print(" ");Serial.println(_resistanceMap[i]);
_resistanceMap[i] /= courant;
//4) Nous en déduisons la temperature
_temperatures[i] = computeTemperature(_thermistorSetting.getBeta(), _resistanceMap[i], _thermistorSetting.getRat25());
_temperatures[i] += _rOffsetMap[i] + _globalOffset;
#ifdef DEBUG_TEMP
Serial.print("Temperature ");Serial.print(i);Serial.print(" : ");Serial.println(_temperatures[i]);
#endif
}
return _temperatures;
}
double MeasureUnit::computeTemperature(double beta, double resistance, double rAt25)
{
return (((25.0+273.15) * beta) / (beta + (25.0+273.15)*log(resistance / rAt25))) - 273.15;
}
void MeasureUnit::setGlobalTempOffset(double offset)
{
_globalOffset = offset;
}
double MeasureUnit::getGlobalTempOffset()
{
return _globalOffset;
}
/**
* Cette méthode permet de calibrer toutes les temperatures en faisans la moyenne et appliquant un offset individuel
*/
void MeasureUnit::levelTemperaturesOff()
{
double averageTemp(0);
//We reset the offset
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetMap[i] = 0;
}
getTemperatures();
for(int i(0); i < _thermistorCount; i++)
{
averageTemp += _temperatures[i];
}
averageTemp /= _thermistorCount;
for(int i(0); i < _thermistorCount; i++)
{
_rOffsetMap[i] = averageTemp - _temperatures[i];
}
}
double *MeasureUnit::getROffsetMap()
{
return _rOffsetMap;
}
boolean MeasureUnit::startTemperatureMeasurement()
{
if(_state == IDLING)
{
_state = MEASURING;
_channel = 0;
return true;
}
return false;
}
void MeasureUnit::levelAsyncTemperaturesOff()
{
_triggerLevelOff = true;
}
boolean MeasureUnit::isMeasurementReady()
{
return _state == MEASUREMENT_READY;
}
double *MeasureUnit::getAsyncTemperatures()
{
double *p(NULL);
if(_state == MEASUREMENT_READY)
{
p = _temperatures;
_state = IDLING;
}
return p;
}
void MeasureUnit::init()
{
Serial.println(computeTemperature(3380, 18000, 10000));
Serial.println(computeTemperature(3380, 11700, 10000));
}

View File

@ -1,57 +0,0 @@
#ifndef MEASUREUNIT_H
#define MEASUREUNIT_H
#include "Ads1115.h"
#include "ThermistorSetting.h"
//#define DEBUG_TEMP
class MeasureUnit
{
public:
enum ERROR {OK = 0, MALLOC_ERR = 1};
MeasureUnit(uint8_t *analogInput, uint16_t thermistorCount, uint64_t precResistor, ThermistorSetting thermistorSetting, Adc &adc);
~MeasureUnit();
void init();
void run();
void startOffsetComputing();
void setOffsetIteration(uint8_t iteration);
void setGlobalTempOffset(double offset);
void levelTemperaturesOff();
double getGlobalTempOffset();
double *getTemperatures();
double *getROffsetMap();
//Async methods
enum STATE {IDLING, MEASURING, COMPUTING, MEASUREMENT_READY};
boolean startTemperatureMeasurement();
boolean isMeasurementReady();
double *getAsyncTemperatures();
void levelAsyncTemperaturesOff();
//End of assync methods
ERROR getError(){return _error;}
protected:
private:
double computeTemperature(double beta, double resistance, double rAt25);
double _globalOffset; //Correspond à l'offset global nécessaire afin d'avoir une température qui corresponde à la réalité
double *_temperatures; //Tableau contenant toutes les températures
double *_rOffsetMap,*_rOffsetBuffer; //Tableau qui contient les offsets individuels pour chaque thermistance
double *_resistanceMap; //Tableau qui contient les resistances associées aux thermistances (pour debug seulement)
uint8_t *_analogInput; //Pointeur qui garde l'adresse du tableau contenant le nom des entrées analogiques
uint16_t _thermistorCount;
uint64_t _precResistor;
ERROR _error;
Adc &_adc;
ThermistorSetting _thermistorSetting;
//Async part
STATE _state;
uint8_t _channel, _offsetComputeIte,_offsetCounter;
double _courant, _tension;
boolean _triggerLevelOff; //Attribut permettant de savoir si un étalonnage a été demandé
};
#endif //MEASUREUNIT_H

View File

@ -1,205 +0,0 @@
/**
* Cet exemple correspond à l'application de test de la bibliothèque MeasureUnit qui
* permet de calculer la température qui est fonction de la résistance d'une matrice de thermistance
*
* Anatole SCHRAMM-HENRY
* 17/12/2019
*/
#include <Wire.h>
#include <WiFi.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "MeasureUnit.h"
#include "PayloadFormatter.h"
#include "Ads1115.h"
#include "LoRaRadio.h"
#define RADIO_ENABLED
#define PUSH_BUTTON 0
uint8_t analogInput[] = {0,1,2,3,4,5,6,7};
double *tempArray = NULL;
/*
* Liste des offsets trouvés
* | -0.49 | 0.36 | -0.29 | 0.38 | 0.44 | -0.35 | -0.21 | 0.14 |
* | -0.72 | 0.07 | -0.52 | -0.01 | 2.38 | -0.65 | -0.44 | -0.11 |
* | -0.99 | -0.06 | -0.74 | 2.24 | 0.73 | -0.86 | -0.68 | 0.35 |
*/
void downlinkHandler(u1_t length, u1_t dataBeg, u1_t *data)
{
Serial.println("Downlink received : ");
for(uint8_t i(0); i < length; i++)
{
Serial.print(data[dataBeg + i],HEX);
}
Serial.println();
//Action en fonction de l'octet de commande
switch(data[0])
{
case 0x01://Mise à jour de l'heure
//Octets suivants:
//2 jour 3 mois 4 année 5 heures 6 minutes
if(length == 6)
{
Serial.printf("dd: %u, m: %u, yyyy: %d, hh: %u, mm: %u\n", data[2], data[3], data[4]+2000, data[5], data[6]);
}
else
Serial.println("Action réglage RTC : paramètres insuffisants");
break;
default:
Serial.println("Action inconnnue");
}
}
//Objet de calcule de la temperature
//ThermistorSetting thermistorSetting(3380, 10000);
ThermistorSetting thermistorSetting(3650, 470);
//AdcSetting adcSetting(3300.0, 12, 310, 3);
AdcSetting adcSetting(3320, 15, 6, 10);
Ads1115 adc;
MeasureUnit measureUnit(analogInput, 8, 990, thermistorSetting, adc);
//MeasureUnit measureUnit(analogInput, 8, 99, thermistorSetting, adc);
//Objet de création des trames LoRa
PayloadFormatter payloadFormatter(2,4);
RTC_DS3231 rtc;
DateTime payloadDate;
TwoWire sc(1);
Adafruit_SSD1306 display(128,64,&sc, 16);
boolean data(false);
uint8_t *payload(NULL), _timeCounter(0), size(0), _channel(0);
boolean calibrer(false);
unsigned long _time(0);
/*
* Radio Part
*/
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
static u1_t NWKSKEY[16] = { 0x1F, 0x9E, 0xE2, 0x7A, 0xC8, 0xBA, 0xE8, 0xEA, 0xF5, 0xC2, 0x5E, 0x47, 0x5D, 0xE0, 0x77, 0x55 };
static u1_t APPSKEY[16] = { 0x3B, 0x89, 0x86, 0x96, 0xBB, 0xAA, 0x38, 0x1E, 0x1F, 0xC4, 0xAD, 0x03, 0xEF, 0x3F, 0x56, 0x12 };
static u4_t DEVADDR = 0x260113D3;//0x03FF0001 ; // <-- Change this address for every node!
u1_t dio[3] = {26,33,32};
PinMap pinMap(18, LMIC_UNUSED_PIN, 14, dio);
LoRaRadio radio(pinMap);
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("Start setup");
WiFi.mode(WIFI_OFF);
pinMode(PUSH_BUTTON, INPUT);
//Partie concernant l'initialisation de la radio
#ifdef RADIO_ENABLED
radio.init();
radio.setTTNSession(0x1, DEVADDR, NWKSKEY, APPSKEY);
radio.setRadioEUChannels();
/*
* La directive setMCUClockError() permet de laisser une fenêtre plus grande pour le slot de
* réception (Downlink). En effet ce slot doit durer 2 secondes et il peut durer moins en raison
* d'imprécisions d'horloge.
*/
radio.setMCUClockError();
radio.setDownlinkHandler(&(downlinkHandler));
#endif
//Adc init
adc.setAdcSetting(adcSetting);
//measureUnit.setGlobalTempOffset(-17);
_time = millis();
if(rtc.begin())Serial.println("RTC Ok!");
else Serial.println("RTC Fail!");
sc.begin(4, 15);
if(display.begin(SSD1306_SWITCHCAPVCC,0x3C))
{
Serial.println("SCREEN Ok!");
display.clearDisplay();
display.setTextColor(WHITE);
display.setCursor(0,15);
display.setTextSize(2);
display.print("LES ALEAS DU DIRECT");
display.display();
}
else Serial.println("SCREEN Fail!");
display.startscrollleft(0,16);
Serial.println("End setup");
measureUnit.init();
Serial.println("| T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 |");
}
void loop() {
//Version asynchrone :
measureUnit.startTemperatureMeasurement();
//On peut tester si la conversion est terminée avec :
//if(measureUnit.isMeasurementReady())
//measureUnit.getAsyncTemperatures() renvoie NULL si la recupération de la température n'est pas terminée
tempArray = measureUnit.getAsyncTemperatures();
if(tempArray != NULL)
{
Serial.print("|");
for(int i(0); i < 8; i++)
{
if(i != 7)
{
Serial.print(" ");Serial.print(tempArray[i],2);Serial.print(" |");
}
else
{
Serial.print(" ");Serial.print(tempArray[i],2);Serial.print(" |");
}
}
//On affiche la trame associée:
payloadFormatter.startSession(1);
payloadDate = rtc.now();
size = payloadFormatter.buildPayload(&payload, &payloadDate,tempArray);
if(size != 0)
{
//Serial.print("LoRa packet --> ");Serial.print("size : ");Serial.print(size);Serial.println(" bytes");
for(int i(0); i < size; i++)
{
payload[i] <= 0x0F ? Serial.print("0") : Serial.print(""); Serial.print(payload[i], HEX); Serial.print(" ");
}
Serial.printf("|%u-%u-%u %u:%u \n", payloadDate.day(),payloadDate.month(),payloadDate.year(),payloadDate.hour(),payloadDate.minute());
}
else
Serial.print("Failed to build LoRa packet");
payloadFormatter.endSession();
#ifdef RADIO_ENABLED
if(_timeCounter == 30 && size != 0)
{
_timeCounter = 0;
Serial.printf("Sending data\n");
radio.send(1, payload, size);
}
_timeCounter++;
#endif
}
//On effectue la calibration
if(digitalRead(PUSH_BUTTON) == 0)
{
delay(500);
measureUnit.startOffsetComputing();
}
#ifdef RADIO_ENABLED
radio.run();
#endif
measureUnit.run();
}

View File

@ -1,21 +0,0 @@
#include "ThermistorSetting.h"
ThermistorSetting::ThermistorSetting(uint16_t beta, uint64_t rAt25) : _beta(beta), _rAt25(rAt25)
{
}
ThermistorSetting::~ThermistorSetting()
{
}
uint16_t ThermistorSetting::getBeta()
{
return _beta;
}
uint64_t ThermistorSetting::getRat25()
{
return _rAt25;
}

View File

@ -1,18 +0,0 @@
#ifndef THERMISTORSETTING_H
#define THERMISTORSETTING_H
#include <Arduino.h> //Necessaire afin d'avoir les types : uintxx_t
class ThermistorSetting
{
public:
ThermistorSetting(uint16_t beta, uint64_t rAt25);
~ThermistorSetting();
uint16_t getBeta();
uint64_t getRat25();
protected:
private:
uint16_t _beta;
uint64_t _rAt25;
};
#endif //THERMISTORSETTING_H