Go Down

Topic: point de rosée pour astronomie (Read 3177 times) previous topic - next topic

infobarquee

bonjour tout le monde,
pour une fois, ce n'est pas un projet inutile donc indispensable :) quoi que....
arrivant dans les périodes où en théorie la température devrait baisser franchement (on peut pas dire que ca soit le cas), je me penche sur un petit module pour mon télescope.

cahier des charges :
écran LCD
avoir la temp de 2 sondes
hygrométrie du tube
connaitre le point de rosée (formation de buée par condensation sur les miroirs)
activer une résistance chauffante
activer un ventilo pour plus de rapidité
prix au ras des paquerettes
en option :
altitude et pression
GPS avec boussole (a venir)

je suis donc partit sur ce que j'avais sous la mimine
un nono
un lcd4884 sainsmart
un dht22
un gy-65

le principe est le suivant
menu qui affiche les options (temp, hygro, altitude, point de rosée, ventilo)
en allumant le module, on calcul la temp, l'hygro et donc en découle le point de rosée ainsi que le point de rosée immédiat.
si tout va bien, rien ne se passe
si le point de rosée est égal à la temp, on met en route la résistance chauffante et le ventilo.

j'ai encore quelques trucs a paufiner et optimiser le code

je vais m'atteler a simplifier le code pour le rendre plus compact et surtout trouver le moyen de mettre les temp avec les décimales
transformer un float en char*, une grosse flemme m'envahie d'un coup :)
si cela vous tente, voici la première mouture, amusez vous bien.


infobarquee

Quote
/*infobarquee 26/10/2013
projet pare buée télescope
*/
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>  // Adafruit BMP085 libary

Adafruit_BMP085 bmp;
#define DHTTYPE DHT22 
#define DHTPIN A1
DHT dht(DHTPIN, DHTTYPE);

#include "LCD4884.h"
#include "DFrobot_bmp.h"
#include "DFrobot_chinese.h"

//keypad debounce parameter
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON  10
#define DEBOUNCE_OFF 3

#define NUM_KEYS 5

#define NUM_MENU_ITEM   5

// joystick number
#define LEFT_KEY 0
#define CENTER_KEY 1
#define DOWN_KEY 2
#define RIGHT_KEY 3
#define UP_KEY 4

// menu starting points

#define MENU_X   10      // 0-83
#define MENU_Y   1      // 0-5


int  adc_key_val[5] ={
  50, 200, 400, 600, 800 };

// debounce counters
byte button_count[NUM_KEYS];
// button status - pressed/released
byte button_status[NUM_KEYS];
// button on flags for user program
byte button_flag[NUM_KEYS];

// menu definition
char menu_items[NUM_MENU_ITEM][12]={
  "TEMPERATURE",
  "HYGROMETRIE",
  "ALTITUDE",
  "POINT_ROSEE",
  "VENTILO"   
};

void (*menu_funcs[NUM_MENU_ITEM])(void) = {
  temperature,
  hygrometrie,
  altitude,
  about,
  ventilo
};

char current_menu_item;

#define led 13
#define led1 12
void setup()
{
pinMode(led,OUTPUT);
pinMode(led1,OUTPUT);

  // setup interrupt-driven keypad arrays 
  // reset button arrays
  for(byte i=0; i<NUM_KEYS; i++){
    button_count=0;
    button_status=0;
    button_flag=0;
  }

  // Setup timer2 -- Prescaler/256
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  TCCR2B &= ~(1<<WGM22);
  TCCR2B = (1<<CS22)|(1<<CS21);     

  ASSR |=(0<<AS2);

  // Use normal mode 
  TCCR2A =0;   
  //Timer2 Overflow Interrupt Enable 
  TIMSK2 |= (0<<OCIE2A);
  TCNT2=0x6;  // counting starts from 6; 
  TIMSK2 = (1<<TOIE2);   



  SREG|=1<<SREG_I;

  lcd.LCD_init();
  lcd.LCD_clear();

  //menu initialization
  init_MENU();
  current_menu_item = 0;   

  lcd.backlight(ON);//Turn on the backlight
  //lcd.backlight(OFF); // Turn off the backlight 
      dht.begin();
  // Sensor init
if (!bmp.begin()) {
  Serial.println("No valid BMP085 sensor found!");
  while (true) {}
}
}


/* loop */

void loop()
{
  byte i;
  for(i=0; i<NUM_KEYS; i++){
    if(button_flag !=0){

      button_flag=0;  // reset button flag
      switch(i){

      case UP_KEY:
        // current item to normal display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
        current_menu_item -=1;
        if(current_menu_item <0)  current_menu_item = NUM_MENU_ITEM -1;
        // next item to highlight display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
        break;
      case DOWN_KEY:
        // current item to normal display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
        current_menu_item +=1;
        if(current_menu_item >(NUM_MENU_ITEM-1))  current_menu_item = 0;
        // next item to highlight display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
        break;
      case LEFT_KEY:
        init_MENU();
        current_menu_item = 0;
        break;   
      case CENTER_KEY:
        lcd.LCD_clear();
        (*menu_funcs[current_menu_item])();
        lcd.LCD_clear();
        init_MENU();
        current_menu_item = 0;           
        break;   
      }

    }
  }
 
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  int pointrosee = dewPoint(t, h);
  char pointroseeBuf[8];
  sprintf(pointroseeBuf, "%d",pointrosee);
  int temp = dht.readTemperature();
  char tempBuf[8];
  sprintf(tempBuf, "%d",temp);
  int hum = dht.readHumidity();
  char humBuf[8];
  sprintf(humBuf, "%d",hum);
 
  if(tempBuf == pointroseeBuf || hum > 90 ){
//lcd.backlight(OFF);
digitalWrite(led,1);
digitalWrite(led1,0);
lcd.LCD_write_string(10, 1, tempBuf, MENU_NORMAL);
  lcd.LCD_write_string(10, 2, humBuf, MENU_NORMAL);

    lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );


  } else {lcd.backlight(ON);digitalWrite(led,0);digitalWrite(led1,1);}
}

/* menu functions */

void init_MENU(void){

  byte i;

  lcd.LCD_clear();

  lcd.LCD_write_string(MENU_X, MENU_Y, menu_items[0], MENU_HIGHLIGHT );

  for (i=1; i<NUM_MENU_ITEM; i++){
    lcd.LCD_write_string(MENU_X, MENU_Y+i, menu_items, MENU_NORMAL);
  }


}

// waiting for center key press
void waitfor_OKkey(){
  byte i;
  byte key = 0xFF;
  while (key!= CENTER_KEY){
    for(i=0; i<NUM_KEYS; i++){
      if(button_flag !=0){
        button_flag=0;  // reset button flag
        if(i== CENTER_KEY) key=CENTER_KEY;
      }
    }
  }

}

void temperature()
{
    float t = dht.readTemperature();
   
  char tempBuf[6]="";
  sprintf(tempBuf, "%d",(int)t);
 
  lcd.LCD_write_string_big(10, 1,tempBuf, MENU_NORMAL);
  lcd.LCD_write_string(78, 2, "C", MENU_NORMAL);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();
}

void hygrometrie(){
    float h = dht.readHumidity();
  char humBuf[6];
  sprintf(humBuf, "%d",(int)h);
 
  lcd.LCD_write_string_big(10, 1,humBuf, MENU_NORMAL);
  lcd.LCD_write_string(78, 2, "%", MENU_NORMAL);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();
  }


void altitude(){
     int pression = bmp.readAltitude();
  char pressionBuf[8];
  sprintf(pressionBuf, "%d",pression); 
  lcd.LCD_write_string_big(1, 1,pressionBuf, MENU_NORMAL);
  lcd.LCD_write_string(78, 2, "M", MENU_NORMAL);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();
}


void about(){
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  int point_rosee = dewPoint(t, h);
  char point_roseeBuf[8];
  sprintf(point_roseeBuf, "%d",point_rosee);
 
  int point_rosee_fast = dewPointFast(t, h);
  char point_rosee_fastBuf[8];
  sprintf(point_rosee_fastBuf, "%d",point_rosee_fast);
 
  lcd.LCD_write_string( 0, 20, point_rosee_fastBuf, MENU_NORMAL);
  lcd.LCD_write_string( 15, 20, "C", MENU_NORMAL);
    lcd.LCD_write_string( 23, 20, "PR Fast", MENU_NORMAL);
 
  lcd.LCD_write_string( 0, 1, point_roseeBuf, MENU_NORMAL);
  lcd.LCD_write_string( 15, 1, "C", MENU_NORMAL);
    lcd.LCD_write_string( 23, 1, "P.rosee", MENU_NORMAL);
   

   
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();


}

void ventilo(){
   lcd.LCD_write_string(0, 1,"Ventilo", MENU_NORMAL);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  digitalWrite(led,1);
digitalWrite(led1,0);
  waitfor_OKkey();
}

// The followinging are interrupt-driven keypad reading functions
// which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection


// Convert ADC value to key number
char get_key(unsigned int input)
{
  char k;

  for (k = 0; k < NUM_KEYS; k++)
  {
    if (input < adc_key_val[k])
    {

      return k;
    }
  }

  if (k >= NUM_KEYS)
    k = -1;     // No valid key pressed

  return k;
}

void update_adc_key(){
  int adc_key_in;
  char key_in;
  byte i;

  adc_key_in = analogRead(0);
  key_in = get_key(adc_key_in);
  for(i=0; i<NUM_KEYS; i++)
  {
    if(key_in==i)  //one key is pressed
    {
      if(button_count<DEBOUNCE_MAX)
      {
        button_count++;
        if(button_count>DEBOUNCE_ON)
        {
          if(button_status == 0)
          {
            button_flag = 1;
            button_status = 1; //button debounced to 'pressed' status
          }

        }
      }

    }
    else // no button pressed
    {
      if (button_count >0)
      { 
        button_flag = 0;   
        button_count--;
        if(button_count<DEBOUNCE_OFF){
          button_status=0;   //button debounced to 'released' status
        }
      }
    }

  }
}

// Timer2 interrupt routine -
// 1/(160000000/256/(256-6)) = 4ms interval

ISR(TIMER2_OVF_vect) { 
  TCNT2  = 6;
  update_adc_key();
}


double dewPoint(double t, double h)
{
        // (1) Saturation Vapor Pressure = ESGG(T)
        double RATIO = 373.15 / (273.15 + t);
        double RHS = -7.90298 * (RATIO - 1);
        RHS += 5.02808 * log10(RATIO);
        RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
        RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
        RHS += log10(1013.246);

        // factor -3 is to adjust units - Vapor Pressure SVP * humidity
        double VP = pow(10, RHS - 3) * h;

        // (2) DEWPOINT = F(Vapor Pressure)
        double T = log(VP/0.61078);   // temp var
        return (241.88 * T) / (17.558 - T);
}

// delta max = 0.6544 wrt dewPoint()
// 6.9 x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double t, double h)
{
        double a = 17.271;
        double b = 237.7;
        double temp = (a * t) / (b + t) + log(h*0.01);
        double Td = (b * temp) / (a - temp);
        return Td;
}

zoroastre

#2
Oct 26, 2013, 08:15 pm Last Edit: Oct 26, 2013, 08:31 pm by zoroastre Reason: 1
Yep!

Quote
.../... le moyen de mettre les temp avec les décimales transformer un float en char*,


Quelque chose dans le genre...

Code: [Select]
char* update_temp1() {
 char ibuff1[6] = { '\0' };
 static char obuff1[20] = { '\0' };                                       // static = conserver en memoire, non detruite a la fin de la fonction.
 dtostrf(temperature1,5,2,ibuff1);                                    // temperature1 est une variable de type [i]float[/i]
 snprintf(obuff1, 20, "T: %s", ibuff1);
 return obuff1;
}


J'utilisais une classe avec comme attribut d'un objet un texte pour redessiner la variable 'objet.text' appeler toutes les minutes. Je ne me rappelle plus pourquoi j'avais d'ailleurs créer une taille aussi importante pour le buffer de sortie, obuff[20].

Ex : IHM_temp1.text = update_temp1(); IHM_temp1.draw();

Je n'ai pas lu ton code  :*

@+

Zoroastre.
Gné! ;)

infobarquee


icare

Bonsoir,
Sympa le projet.
Tu vas pouvoir vérifier les théories de Jean Meeus par tout temps.
:)
2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

Artouste


bonjour tout le monde,
...
si le point de rosée est égal à la temp, on met en route la résistance chauffante et le ventilo.

j'ai encore quelques trucs a paufiner et optimiser le code



Bonsoir
Tu aurais du mettre ton post dans la section générale  8)

dans ce genre de problème il peut y avoir plusieurs méthodes d'approche de détections et d'actions

Il n'est pas toujours necessaire de "chauffer" pour evacuer, et meme en restant sur du DIY
- La méthode psychométrique associée à l'effet peltier , semble donner  aussi des bons résultats  



infobarquee


Bonsoir,
Sympa le projet.
Tu vas pouvoir vérifier les théories de Jean Meeus par tout temps.
:)


hoooo, pas si vite, j'ai pas un mauvais matos, mais de là a lui arriver au petit doigt de pied :)

si vous voulez vous amuser ou avoir mal au crane, un pote de longue date a fait ce site
http://www.fractaledelunivers.net/
il a même une constante qui porte son nom maintenant dans le domaine, c'est tout dire, et fou d'astro par dessus le marcher.

icare

Re,
Site intéressant et à approfondir.
Pour ma part, j'ai bien l'astronomie mais pas en terme d'observation et en terme de calcul de position des astres d'où mes références à Jean Meeus.
2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

infobarquee

Quote
Tu aurais du mettre ton post dans la section générale  smiley-cool

c'est une réalisation en cours, donc je pense que la section est la mieux adaptées, puisqu'elle va finaliser le projet.

Quote
Il n'est pas toujours necessaire de "chauffer" pour evacuer, et meme en restant sur du DIY
- La méthode psychométrique associée à l'effet peltier , semble donner  aussi des bons résultats


le but n'est pas d'évacuer, mais d'éviter le point de rosée dans le tube, sur les miroirs, etc...
donc on peut chauffer et ventiler pour augmenter juste de 0.5-0.2C et encore, pour ne pas l'atteindre, ce fameux point.
trop chauffer, peut être néfaste pour différentes raisons :
déformation des miroirs ou de la collimation
effet parasite pour les prises de vue photo ou l'observation (perturbation comme quand il fait chaud au dessus d'une route)
consommation de la batterie aussi qui sert pour la monture (azimutale pour ma part avec raquette cablée sur un pc)

pour la résistance, plusieurs systèmes peuvent être utilisés suivant le diamètre de la bête, en générale, on compte 1w par cm :
résistances en série (8-10 R de 10-20ohms)
cable chauffant (comme dans les couveuses, ha ca me dit quelque chose :) )
d'autres modèles sur le marcher, mais à prix de ouf

certains utilisent aussi un sèche cheveux pour aller plus vite, mais pas la meilleure solution.

Artouste

#9
Oct 26, 2013, 10:35 pm Last Edit: Oct 26, 2013, 10:40 pm by Artouste Reason: 1

...
pour la résistance, plusieurs systèmes peuvent être utilisés suivant le diamètre de la bête, en générale, on compte 1w par cm :
résistances en série (8-10 R de 10-20ohms)
...

Alors si tu veux jouer seulement avec des résistances  pour valider,  je dois avoir des bonnes candidates  :smiley-mr-green: ... reformées

à suivre à compter de lundi


infobarquee

arf :)
si je ne m'abuse, 10w correspondent à +0.31C et des cahuettes par minute

de plus j'ai mis 2 param en compte.
le point de rosée (temp = PR), mais aussi l'humidité (h>90%).
au moins je suis certain (dans la théorie évidemment), de palier à un défaut d'une sonde de temp.

de plus, je vais coupler une autre chauferette sur l'occulaire, car rien que de regarder peut aussi provoquer une condensation sur la lentille.
quand on joue sur le ciel profond (même si mon bébé est limite pour ca), la moindre perturbation et c'est la cata.

demain, j'attaque le pare buée et je mettrais des photos

Artouste

#11
Oct 27, 2013, 08:04 pm Last Edit: Oct 27, 2013, 08:23 pm by Artouste Reason: 1


...
pour la résistance, plusieurs systèmes peuvent être utilisés suivant le diamètre de la bête, en générale, on compte 1w par cm :
résistances en série (8-10 R de 10-20ohms)
...

Alors si tu veux jouer seulement avec des résistances  pour valider,  je dois avoir des bonnes candidates  :smiley-mr-green: ... reformées

à suivre à compter de lundi



je savais bien que je devais en avoir une ou deux dans mes tiroirs perso  :smiley-mr-green:
ce genre de resistance etait utilisée   pour stabiliser en T° des enceintes base de temps.
Comme ce sont des tubes , la convection forcée par ventilateur était facile.
Il faudrait que je retrouve les docs , mais de memoire il y avait de la gestion serie //.


infobarquee

oui on peut mettre des R en série.
par contre ta photo, ben ca ira pas, cat il faut que ca fasse le tour du tube pour faire homogène, sans pour autant "boucher la vue".
j'ai ce genre de chose dans mon bordelum


50w en 220v pour 50cm, si mes calculs sont bons et si c'est possible, je dois sortir dans les 5-8w en 12v
donc une élévation de la temp d'environ 0.25C/mn largement de quoi empêcher le point de rosée.

Artouste


oui on peut mettre des R en série.
par contre ta photo, ben ca ira pas, cat il faut que ca fasse le tour du tube pour faire homogène, sans pour autant "boucher la vue".
j'ai ce genre de chose dans mon bordelum


50w en 220v pour 50cm, si mes calculs sont bons et si c'est possible, je dois sortir dans les 5-8w en 12v
donc une élévation de la temp d'environ 0.25C/mn largement de quoi empêcher le point de rosée.

Comme c'est surement du résistif quasi pur , la courbe ne sera pas linéaire , mais ça peut etre suffisant, de toutes façon le test est facile à faire

infobarquee

#14
Oct 28, 2013, 12:56 pm Last Edit: Oct 28, 2013, 01:15 pm by infobarquee Reason: 1
oui c'est du résistif, je viens de la connecter sur une batterie, mais ca chauffe que dalle en 12v.
ohmmetre 1K, donc c'est un peu mort avec ca je dirais.

EDIT :
après quelques minutes, je monte d'un tout petit degré avec une temp ambiante de 21C, a tester dans mon tube en mousse pour vérifier si ca monte un peu plus.
mais si ca monte ne serait ce que de 0.5C maxi dans le tube, le tour est joué quand même.
je ferais des tests ce soir pour vérifier la chose

Go Up