Bonjour à tous,
voilà plusieurs années que je m'amuse avec des arduino et l'impression 3D.
J'ai par le passé fait beaucoup de projet dont un ici sur un FlipFlat pas cher.
La seule chose que je n'ai pas faite est un driver ASCOM car celui ci existait déjà et seule la partie arduino était à faire.
J'ai, il y a quelques années, réalisé un petit driver isafetymonitor ASCOM en VB. Pour cela j'avais conçu une petite station météo constituée d'un capteur BME280, d'un MLX90614 et un TSL2591.
J'ai dans l'idée aujourd'hui de me faire un petit driver ASCOM ObservingConditions dans le but de l'utiliser avec NINA. J'aimerai par ailleurs que ce driver ASCOM permette aussi d'étre utilisé en simultané en tant que driver safetymonitor (pas encore implanté dans mon code arduino). J'ai lu que c'était possible.
Et c'est là que les problèmes commencent!!
J'ai installé VS2022 et installé les templates ASCOM qui sont au nombre de 3.
Bon, déjà ici tout est bien différent de l'époque en VB où j'avais pu suivre le tuto de la roue à filtre de Tom Haw sur Youtube.
La maintenant il faut créer un code en C#. Bon allez, on reprends les bases mais ca va le faire.
Nouvelle complexité: On parle maintenant d'un driver en mode LocalServer.... ok.... bon je lis toute la documentation en anglais mais je pige pas tout.
Bref, je commence à regarder dans VS2022.
J'ouvre le premier template et dans l'arboresence je me retoruve avec plein de nouveaux fichiers dont:
-observingconditions.cs et observingconditionhardware.cs
Je me suis arrêter ici car forcément je ne vois pas du tout par où aller, ni commencer.
Je vous joins ci après mon firmware arduino avec son protocole série.
Je vous joins également les éléments sous forme de fichier C# que je pense devoir integrer dans le driver ASCOM.
Pourriez vous m'aider sur la conception de ce driver ASCOM?
je sais qu'il existe des projets un peu identique mais j'aimerai réellement le faire de 1 à Z ce projet! cela me rendrait fier et j'ai d'autres idées en tête.
Donc plutôt que de copier, si je peux comprendre comment tout cela marche et s'implémente alors ce serait génial.
Code arduino:
// librairies de base
#include <Wire.h>
#include <Adafruit_Sensor.h>
//#include <math.h>
#define delais 1000 //temps entre deux maj des valeurs en ms
#define SerialSpeed 9600 // vitesse de communication sur le port série
// utilisation d'un BME280 Velleman WPSE335
#include <BME280I2C.h>
BME280I2C bme;
float temperature_ambiante_BME;
float pression_locale;
float correction_altitude_pression = 0.00; //facteur de correction lié à l'altitude locale
float humidite;
float dewpoint;
// utilisation d'un MLX90614
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
float temperature_ambiante_MLX;
float temperature_ciel;
float correction_temperature;
float temperature_ciel_corrigee;
#define K1 33.
#define K2 0.
#define K3 4.
#define K4 100.
#define K5 100.
#define K6 0.
#define K7 0.
float CWT; //CWT = Cold Weather correction en cas de basse temperature (<1°C)
// température ciel completement clair
#define temperature_ciel_clair -8
// température ciel completement couvert
#define temperature_ciel_couvert 0
//Activation treshold for cloudFlag (%)
// utilisation d'un TSL2591
#include <Adafruit_TSL2591.h>
Adafruit_TSL2591 tsl = Adafruit_TSL2591();
struct {
bool status;
uint32_t full;
uint16_t ir;
uint16_t visible;
int gain;
int timing;
float lux;
} tsl2591Data {false, 0, 0, 0, 0, 0, 0.0};
/**
tsl.begin() always returns true, hence we need to check the I2C adress
*/
bool isTSL2591Present() {
Wire.beginTransmission(TSL2591_ADDR);
byte error = Wire.endTransmission();
return (error == 0);
}
void configureSensorTSL2591(tsl2591Gain_t gainSetting, tsl2591IntegrationTime_t timeSetting)
{
// You can change the gain on the fly, to adapt to brighter/dimmer light situations
tsl.setGain(gainSetting);
// Changing the integration time gives you a longer time over which to sense light
// longer timelines are slower, but are good in very low light situtations!
tsl.setTiming(timeSetting);
}
// calibrate TSL2591 gain and integration time
bool calibrateTSL2591() {
if (tsl2591Data.visible < 100) { //Increase GAIN (and INTEGRATIONTIME) if light level too low
switch (tsl2591Data.gain)
{
case TSL2591_GAIN_LOW :
configureSensorTSL2591(TSL2591_GAIN_MED, TSL2591_INTEGRATIONTIME_200MS);
break;
case TSL2591_GAIN_MED :
configureSensorTSL2591(TSL2591_GAIN_HIGH, TSL2591_INTEGRATIONTIME_200MS);
break;
case TSL2591_GAIN_HIGH :
configureSensorTSL2591(TSL2591_GAIN_MAX, TSL2591_INTEGRATIONTIME_200MS);
break;
case TSL2591_GAIN_MAX :
switch (tsl2591Data.timing)
{
case TSL2591_INTEGRATIONTIME_200MS :
configureSensorTSL2591(TSL2591_GAIN_MAX, TSL2591_INTEGRATIONTIME_300MS);
break;
case TSL2591_INTEGRATIONTIME_300MS :
configureSensorTSL2591(TSL2591_GAIN_MAX, TSL2591_INTEGRATIONTIME_400MS);
break;
case TSL2591_INTEGRATIONTIME_400MS :
configureSensorTSL2591(TSL2591_GAIN_MAX, TSL2591_INTEGRATIONTIME_500MS);
break;
case TSL2591_INTEGRATIONTIME_500MS :
configureSensorTSL2591(TSL2591_GAIN_MAX, TSL2591_INTEGRATIONTIME_600MS);
break;
case TSL2591_INTEGRATIONTIME_600MS :
// no higher sensitivity level available
return false;
break;
default:
configureSensorTSL2591(TSL2591_GAIN_MAX, TSL2591_INTEGRATIONTIME_600MS);
break;
}
break;
default:
configureSensorTSL2591(TSL2591_GAIN_MED, TSL2591_INTEGRATIONTIME_200MS);
break;
}
// calibration changed
return true;
}
if (tsl2591Data.visible > 30000) { //Decrease GAIN (and INTEGRATIONTIME) if light level too high
switch (tsl2591Data.gain)
{
case TSL2591_GAIN_LOW :
switch (tsl2591Data.timing)
{
case TSL2591_INTEGRATIONTIME_500MS :
configureSensorTSL2591(TSL2591_GAIN_LOW, TSL2591_INTEGRATIONTIME_400MS);
break;
case TSL2591_INTEGRATIONTIME_400MS :
configureSensorTSL2591(TSL2591_GAIN_LOW, TSL2591_INTEGRATIONTIME_300MS);
break;
case TSL2591_INTEGRATIONTIME_300MS :
configureSensorTSL2591(TSL2591_GAIN_LOW, TSL2591_INTEGRATIONTIME_200MS);
break;
case TSL2591_INTEGRATIONTIME_200MS :
// no higher sensitivity level available
return false;
break;
default:
configureSensorTSL2591(TSL2591_GAIN_LOW, TSL2591_INTEGRATIONTIME_200MS);
break;
}
break;
case TSL2591_GAIN_MED :
configureSensorTSL2591(TSL2591_GAIN_LOW, TSL2591_INTEGRATIONTIME_200MS);
break;
case TSL2591_GAIN_HIGH :
configureSensorTSL2591(TSL2591_GAIN_MED, TSL2591_INTEGRATIONTIME_200MS);
break;
case TSL2591_GAIN_MAX :
configureSensorTSL2591(TSL2591_GAIN_HIGH, TSL2591_INTEGRATIONTIME_200MS);
break;
default:
configureSensorTSL2591(TSL2591_GAIN_MED, TSL2591_INTEGRATIONTIME_200MS);
break;
}
// calibraton changed
return true;
}
// no calibration change necessary
return false;
}
void setup() {
Serial.begin(SerialSpeed);
Wire.begin();
bme.begin();
mlx.begin();
}
void updateBME() {
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_hPa);
bme.read(pres, temp, hum, tempUnit, presUnit);
temperature_ambiante_BME = temp;
pression_locale = pres+correction_altitude_pression;
humidite = hum;
}
void updateMLX() {
temperature_ambiante_MLX = mlx.readAmbientTempC();
temperature_ciel = mlx.readObjectTempC();
}
void updateTSL2591() {
tsl.begin();
// Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
tsl2591Data.full = tsl.getFullLuminosity();
tsl2591Data.ir = tsl2591Data.full >> 16;
tsl2591Data.visible = tsl2591Data.full & 0xFFFF;
tsl2591Data.lux = tsl.calculateLux(tsl2591Data.visible, tsl2591Data.ir);
tsl2591Data.gain = tsl.getGain();
tsl2591Data.timing = tsl.getTiming();
bool changed = calibrateTSL2591();
if (changed) updateTSL2591();
}
void loop() {
String cmd;
if (Serial.available() > 0)
{
updateBME();
updateMLX();
correction_temperature = (K1 / 100) * (temperature_ambiante_MLX - K2 / 10) + (K3 / 100) * pow((exp (K4 / 1000* temperature_ambiante_MLX)) , (K5 / 100))+CWT;
temperature_ciel_corrigee = temperature_ciel - correction_temperature;
dewpoint = ((sqrt(sqrt(sqrt(humidite/100))))*(110+temperature_ambiante_BME))-110;
updateTSL2591();
cmd = Serial.readStringUntil('\n');
if(cmd =="GETDATA")
{
Serial.print("T:");
Serial.print(temperature_ambiante_BME,1);
Serial.print(",C:");
Serial.print(temperature_ciel_corrigee,1);
Serial.print(",P:");
Serial.print(pression_locale,1);
Serial.print(",H:");
Serial.print(humidite,1);
Serial.print(",D:");
Serial.print(dewpoint,1);
Serial.print(",L:");
Serial.println(tsl2591Data.lux,1);
}
}
delay(delais);
}
Code a integrer je sais pas ou dans driver ASCOM ObservingConditions:
using ASCOM;
using System.IO.Ports;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Threading;
using ASCOM.Astrometry.AstroUtils;
using ASCOM.DeviceInterface;
using ASCOM.Utilities;
namespace ASCOM.MyObservingConditions
{
public class ObservingConditions : IObservingConditions
{
private double temperature;
private double skytemperature;
private double pression;
private double humidity;
private double dewpoint;
private double skyluminosite;
private SerialPort arduinoPort;
public ObservingConditions(string comPort)
{
arduinoPort = new SerialPort(comPort, 9600);
arduinoPort.Open();
}
public double AveragePeriod { get; set; }
public void Refresh()
{
arduinoPort.Write("GETDATA");
string response = arduinoPort.ReadLine();
string[] values = response.Split(',');
if (values.Length == 6 && double.TryParse(values[0].Substring(2), out double temp) && double.TryParse(values[1].Substring(2), out double skyT)&& double.TryParse(values[2].Substring(2), out double pres)&& double.TryParse(values[3].Substring(2), out double hum)&& double.TryParse(values[4].Substring(2), out double dew)&& double.TryParse(values[5].Substring(2), out double skyL))
{
temperature = temp;
skystemperature = skyT;
pression = pres;
humidity = hum;
dewpoint = dew;
skyluminosite = skyL;
}
else
{
temperature = 0;
skystemperature = 0;
pression = 0;
humidity = 0;
dewpoint = 0;
skyluminosite = 0;
}
}
public double Temperature
{
get { return temperature; }
private set { temperature = value; }
}
public double SkyTemperature
{
get { return skytemperature; }
private set { skytemperature = value; }
}
public double Pressure
{
get { return pression; }
private set { pression = value; }
}
public double Humidity
{
get { return humidity; }
private set { humidity = value; }
}
public double DewPoint
{
get { return dewpoint; }
private set { dewpoint = value; }
}
public double SkyBrightness
{
get { return skyluminosite; }
private set { skyluminosite = value; }
}
~ObservingConditions()
{
arduinoPort.Close();
}
}
}
Merci pour votre aide.
Olivier