Interrupteur lever/coucher du Soleil

Interrupteur lever/coucher du Soleil

Message par Stéphane » 08 Juin 2013, 22:02

L'interrupteur permet de mettre sous tension et hors tension tout appareil suivant l'heure du lever et du coucher du Soleil. Ici, il est utilisé pour mettre en marche les cameras des détections des météores de façon automatique.

L'interrupteur est basé sur la plateforme de prototypage <<open source>> Arduino UNO (http://www.arduino.cc) associée à un module GPS. Ce dernier permet de récupérer l'heure, la latitude et la longitude de l'endroit ou est utilisé l’interrupteur, permettant le calcul de l'heure du lever et du coucher du Soleil.

Schéma de principe:
Image

Simulation sur platine d'essai:
Image

Vue réelle (sans la partie relais):
Image

Vue du prototype fini:
Image
  • Il est conseillé d'utiliser une boîtier plus gros.
  • Un câble Ethernet est utilisé pour deporter le module GPS.
Niveau réception GPS:
Les 4 DELs indiques le nombre des satellites détectés par le module GPS.
    Aucune DELs allumées: lecture du nombre de satellites impossible.
    DEL rouge: nombre de satellites détectés inférieur à 2. Changer l'interrupteur d'endroit pour une meilleure réception.
    DEL orange: nombre de satellites détectés entre 2 et 3. Changer l'interrupteur d'endroit pour une meilleure réception.
    DEL jaune: nombre de satellites détectés entre 4 et 5.
    DEL vert: réception optimal
Lecture GPS:
L'état de la DEL indique l'état de réception des données GPS:
    DEL rouge couleur fixe: acquisition des données GPS impossible. État normal à la mise sous tension de l'interrupteur, pouvant durée 3 minutes. Si au bout de ce temps, la DEL reste toujours allumé de façon permanente, changer l’interrupteur d'endroit pour une meilleure réception du signal GPS.
    DEL rouge clignotante: indique la lecture, toutes les 0.5 seconde des données provenant du module GPS. Ceci indique le bon fonctionnement de l'interrupteur.
Commande:
La DEL bleu indique l'état du relais. Si celle-ci est éclairé, l'appareil connecté à l'interrupteur est alimenté. Au démarrage de l’interrupteur lever/coucher du Soleil, l'appareil connecté est alimenté jusqu’à ce qu'un signal GPS valide soit reçu (DEL lecture GPS clignotant).

Délai:
Permet d'ajouter et de soustraire un durée sur l'heure du coucher et du lever du Soleil.
Interrupteurs gauche et droite reliés à la masse (position de la simulation sur platine d'essai): la mise en marche de l'appareil connecté se fera au coucher du Soleil et la mise à l’arrêt, au lever su Soleil.
Interrupteur gauche relié à l'alimentation, interrupteur droite relié à la masse: la mise en marche de l'appareil connecté se fera 15 minutes avant le coucher du Soleil et la mise à l’arrêt 15 minutes après le lever du Soleil.
Interrupteur gauche relié à la masse, interrupteur droite relié à l'alimentation: la mise en marche de l'appareil connecté se fera 30 minutes avant le coucher du Soleil et la mise à l’arrêt 30 minutes après le lever du Soleil.
Interrupteurs gauche et droite reliés à l'alimentation: la mise en marche de l'appareil connecté se fera 45 minutes avant le coucher du Soleil et la mise à l’arrêt 45 minutes après le lever du Soleil.
Nota: Ceci est valable uniquement si l'interrupteur inversion est relié à la masse (position de la simulation sur platine d'essai).

Inversion:
Permet d'inverser l’état de la commande du relais. L'interrupteur fonctionne uniquement si la lecture du module GPS est valide (DEL lecture GPS clignotant).

Programme:
Code : Tout sélectionner
//Project: Relay command for meteor video station based on sunset/sunrise
//version 1.0
//Stéphane Jouin
//(c)06/2012
//
//http://arduiniana.org
#include <SoftwareSerial.h>
#include <TinyGPS.h>
//http://swfltek.com/arduino/timelord.html
#include <TimeLord.h>
//
#define GPSBAUD 4800
#define SERIAL 9600
#define RXPIN 2
#define TXPIN 3
#define GPSLOW 4
#define GPSMEDIUMLOW 5
#define GPSMEDIUMHIGH 6
#define GPSHIGH 7
#define GPS 8
#define DELAY1 9
#define DELAY2 10
#define RELAY1 11
//
TinyGPS gps;
TimeLord lord;
SoftwareSerial uart_gps(RXPIN,TXPIN);
void getgps(TinyGPS &gps);
int strelay;
//
void setup()
{
  uart_gps.begin(GPSBAUD);
  pinMode(GPS,OUTPUT);
  pinMode(RELAY1,OUTPUT);
  pinMode(GPSLOW,OUTPUT);
  pinMode(GPSMEDIUMLOW,OUTPUT);
  pinMode(GPSMEDIUMHIGH,OUTPUT);
  pinMode(GPSHIGH,OUTPUT);
  pinMode(DELAY1,INPUT);
  pinMode(DELAY2,INPUT);
  digitalWrite(GPS,HIGH);
  digitalWrite(GPSLOW,LOW);
  digitalWrite(GPSMEDIUMLOW,LOW);
  digitalWrite(GPSMEDIUMHIGH,LOW);
  digitalWrite(GPSHIGH,LOW);
  digitalWrite(RELAY1,HIGH);
  Serial.println("wait");  //
  Serial.begin(SERIAL);  //
  //test
  digitalWrite(GPSLOW,HIGH);
  digitalWrite(GPSMEDIUMLOW,HIGH);
  digitalWrite(GPSMEDIUMHIGH,HIGH);
  digitalWrite(GPSHIGH,HIGH);
  delay(1000);
  digitalWrite(GPSLOW,LOW);
  digitalWrite(GPSMEDIUMLOW,LOW);
  digitalWrite(GPSMEDIUMHIGH,LOW);
  digitalWrite(GPSHIGH,LOW);
}
//
void loop()
{
  strelay=analogRead(0);
  if(uart_gps.available())
  {
    int c=uart_gps.read();
    if(gps.encode(c))
    {
      digitalWrite(GPS,HIGH);
      getgps(gps);
      delay(500); //wait 0.5 seconds
      digitalWrite(GPS,LOW);
      delay(500); //wait 0.5 seconds
    }
  }
  digitalWrite(GPS,HIGH);
}
//function
void getgps(TinyGPS &gps)
{
  float gpslongitude,gpslatitude;
  int gpsyear;
  byte gpsmonth,gpsday,gpshour,gpsminute,gpssecond,gpshundredths;
  gps.f_get_position(&gpslatitude,&gpslongitude);
  gps.crack_datetime(&gpsyear,&gpsmonth,&gpsday,&gpshour,&gpsminute,&gpssecond,&gpshundredths);
  byte day[]={0,0,12,gpsday,gpsmonth,gpsyear};
  lord.Position(gpslatitude,gpslongitude);
  int sunrise,sunset;
  int time,timezone;
  int gpssat;
  int quarter=30*digitalRead(DELAY2)+15*digitalRead(DELAY1);
  timezone=1;
  //Serial.print("quarter:");
  //Serial.print(quarter,DEC);
  //Serial.print("latitude:");
  //Serial.print(gpslatitude,5);
  //Serial.print("longitude:");
  //Serial.print(gpslongitude,5);
  //Serial.print("date:");
  //Serial.print(gpsday,DEC);
  //Serial.print("/");
  //Serial.print(gpsmonth,DEC);
  //Serial.print("/");
  //Serial.print(gpsyear,DEC);
  time=60*(gpshour+timezone)+gpsminute; //time converted in minutes from 00:00
  Serial.print("time:");
  Serial.print(gpshour+timezone,DEC);
  Serial.print(":");
  Serial.print(gpsminute,DEC);
  Serial.print(":");
  //Serial.print(gpssecond,DEC);
  //Serial.print("  ");
  //
  lord.TimeZone(timezone*60);
  //lord.GMT(day);
  //lord.DstRules(3,4,10,4,60);
  //lord.DST(day);
  if (lord.SunRise(day))
  {
    sunrise=60*day[tl_hour]+day[tl_minute];  //nomber of minute from 00:00
    Serial.print(" SunRise:");
    Serial.print((int)day[tl_hour]);
    Serial.print(":");
    Serial.print((int)day[tl_minute]);
  }
  if (lord.SunSet(day))
  {
    sunset=60*day[tl_hour]+day[tl_minute]; //nomber of minute from 00:00
    Serial.print(" SunSet:");
    Serial.print((int)day[tl_hour]);
    Serial.print(":");
    Serial.print((int)day[tl_minute]);
  }
  Serial.print("sunrise:");
  Serial.print(sunrise,DEC);
  Serial.print(" sunset:");
  Serial.print(sunset,DEC);
  Serial.print(" time:");
  Serial.print(time,DEC); 
//
  if (sunrise+quarter<time and time<sunset-quarter)
  {
    if (strelay<=350)
    {
      digitalWrite(RELAY1,LOW);
    }
    else
    {
      digitalWrite(RELAY1,HIGH);
    }
  }
  else
  {
    if (strelay<=350)
    {
      digitalWrite(RELAY1, HIGH);
    }
    else
    {
      digitalWrite(RELAY1, LOW);
    }
  }
  gpssat=gps.satellites();
  if (gpssat<2)
  {
    digitalWrite(GPSLOW,HIGH);
    digitalWrite(GPSMEDIUMLOW,LOW);
    digitalWrite(GPSMEDIUMHIGH,LOW);
    digitalWrite(GPSHIGH,LOW);
  }
  else if (gpssat<4)
  {
    digitalWrite(GPSLOW,LOW);
    digitalWrite(GPSMEDIUMLOW,HIGH);
    digitalWrite(GPSMEDIUMHIGH,LOW);
    digitalWrite(GPSHIGH,LOW);
  }
  else if (gpssat<6)
  {
    digitalWrite(GPSLOW,LOW);
    digitalWrite(GPSMEDIUMLOW,LOW);
    digitalWrite(GPSMEDIUMHIGH,HIGH);
    digitalWrite(GPSHIGH,LOW);
  }
  else if (gpssat<255)
  {
    digitalWrite(GPSLOW,LOW);
    digitalWrite(GPSMEDIUMLOW,LOW);
    digitalWrite(GPSMEDIUMHIGH,LOW);
    digitalWrite(GPSHIGH,HIGH);
  }
}

ATTENTION: l'appareil à connecté sur l'interrupteur lever/coucher du Soleil ne doit en aucun cas être essayé sur la platine d'essai mais uniquement sur un circuit imprimé approprié. Respecter également les consignes de sécurité liées au réseau EDF: il y va de votre vie!

Deux options sont à l'étude:
  • remplacement des DELs et des interrupteurs par un afficheur et un mini joystick afin d'avoir des possibilités étendues de l'Interrupteur lever/coucher du Soleil.
  • ajout d'une carte Ethernet afin d'allumer/d'éteindre un ordinateur.

Les options:
Vue de l'ensemble (afficheur, mini joystick et carte Ethernet):
Image

Les écrans:
Ecran principal:
Image
Toutes les heures sont en temps universel (UT).
    Image: heure du lever du Soleil. Cette heure est modifiée si un délai a été ajouté ou retranché à l'heure du lever du Soleil.
    Image: heure du coucher du Soleil. Cette heure est modifiée si un délai a été ajouté ou retranché à l'heure du coucher du Soleil.
    Image: date récupérée par le GPS.
    Image: heure récupéré par le GPS.
    Image: latitude/longitude récupéré par le GPS.
    Image: réception de la trame provenant du GPS.
    Image: indicateur du nombre de satellite capté par le GPS, içi 3 (jusqu'a 12).
    Image: indicateur de l'état du relais, ici arrêté. L'indicateur est bleu quand le relais est en marche.
    Image: commande d'arrêt du relais. Içi est associé a l'heure du lever du Soleil. Le relais s’arrêtera à l'heure affiché.
    Image: commande de mise en marche du relais. Içi est associé a l'heure du coucher du Soleil. Le relais se mettra en marche à l'heure affiché. Pour inversé la commande d’arrêt et de mise en marche, c'est à dire associé la mise en marche à l'heure du lever du Soleil et l’arrêt à l'heure du coucher du Soleil, appuyer sur le mini joystick.
Ecran de réglage du delai (-55 à +55 minutes) à ajouter à l'heure du lever et du coucher du Soleil:
Image
En appuyant une fois sur le mini joystick, la valeur en dessous de <<sunrise>> (lever du Soleil) change de couleur et le reglage est possible. Pour ajouter un délai, mettre le mini joystick en position verticale haute. Pour retirer un délai, mettre le mini joystick en position verticale basse. La valeur est prise en compte uniquement quand le mini jostick retrouve sa position.
Une fois la valeur choisie, appuyer sur le mini joystick. La valeur en dessous de <<sunset>> (coucher du Soleil) change de couleur et le reglage est possible. Effectuer la même operation que pour le <<sunrise>>. A la fin appuyer sur le mini joystick pour pouvoir naviguer dans le menu général.
Les delais sont enregistrées dans l'EEPROM de l'Arduino UNO.

Ecran pour la mise en route d'un PC via la carte Ethernet (<<Magic Packet>>):
Image
Le même principe est utilisé pour changer l'adresse MAC du PC à mettre en marche à travers la commande <<Wake-on-LAN>>:
Image
L'adresse MAC est enregistrée dans l'EEPROM de l'Arduino UNO.
Vérifier que le PC permet ce type de commande.
Il n'y a pas (pour l'instant?) une fonction d'arret du PC.

Ecran d'information sur le projet:
Image
Merci à Jean Brunet pour ses conseils en programmation.

Programme:
Code : Tout sélectionner
/Project: Relay command for meteor video station based on sunset/sunrise
//version 2.0
//Stéphane Jouin
//Thanks to Jean Brunet for his help
//(CC BY-NC-SA 3.0)10/2012
//
//Board Arduino Uno
//
#include <SPI.h>
#include <Ethernet.h>
#include <utility/w5100.h>
//
#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <TimeLord.h>
#include "oled128drv.h"
//
//µOLED-128
#define OLEDRST 8
//
#define GPSRX 2
#define GPSTX 3
//
#define JOYVER A0
#define JOYHOR A1
#define JOYSEL A2
//
#define OUT 9
//
TinyGPS gps;
SoftwareSerial uart_gps(GPSRX,GPSTX);
void getgps(TinyGPS &gps);
TimeLord lord;
//
byte thr=200;
unsigned int jch,jcv;
int joy,jos;
int jpo;
int sel;
boolean rev;
boolean wai;
boolean tb1;
boolean ethset;
int sridel,ssedel;
//Ethernet
SOCKET s;
byte mac[]={0x90,0xA2,0xDA,0x0D,0x  ,0x  }; // Arduino's MAC address
byte pcmac[6]; // PC's MAC address
//EEPROM's address
byte addsridel=0; //delay sunrise
byte addssedel=1; //delay sunset
byte addpcmac=2; //PC's MAC address
//
void setup()
{
  //µOLED-128
  pinMode(OLEDRST,OUTPUT);
  Serial.begin(19200);
  OLED_Init();
  OLED_Clear();
  delay(1000);
  //
  pinMode(OUT,OUTPUT);
  //
  //boam();
  //delay(2000);
  //OLED_Clear();
  OLED_Opacity(1);
  OLED_DrawRectangle(0,14,127,113,0,65535);
  //Tab n°1
  OLED_DrawRectangle(0,0,32,14,0,65535);
  inton();
  //Tab n°2
  OLED_DrawRectangle(32,0,32,14,0,65535);
  OLED_DrawStringText(40,4,0,65535,1,1,"+/-");
  //Tab n°3
  OLED_DrawRectangle(64,0,32,14,0,65535);
  OLED_DrawRectangle(78,2,4,3,0,65535);
  OLED_DrawLine(80,5,80,7,65535);
  OLED_DrawLine(75,7,85,7,65535);
  OLED_DrawRectangle(73,9,4,3,0,65535);
  OLED_DrawLine(75,7,75,9,65535);
  OLED_DrawRectangle(83,9,4,3,0,65535);
  OLED_DrawLine(85,7,85,9,65535);
  //Tab n°4
  OLED_DrawRectangle(96,0,31,14,0,65535);
  OLED_DrawStringText(109,4,0,65535,1,1,"?");
  //
  OLED_DrawStringText(37,58,2,33808,1,1,"Wait...");
  //
  W5100.init();
  W5100.writeSnMR(s,SnMR::MACRAW);
  W5100.execCmdSn(s,Sock_OPEN);
  delay(5000);
  //
  uart_gps.begin(4800);
  jch=analogRead(JOYHOR);
  jcv=analogRead(JOYVER);
  //Tab n°1 first
  jpo=0;
  rev=false;
  reversal(rev);
  wai=false;
  tb1=true;
  sridel=128-EEPROM.read(addsridel);
  ssedel=128-EEPROM.read(addssedel);
  ethEEPROM();
  ethset=true;
  wol();
  //
  OLED_DrawStringText(37,58,2,0,1,1,"Wait...");
}
//
void loop()
{
  //Tab n°1 ***********************************************************************
  while(jpo==0)
  {
    OLED_DrawLine(1,14,31,14,0);
    if (tb1==true)
    {
      OLED_DrawStringText(24,28,1,65535,2,2,"00:00");
      OLED_DrawStringText(28,56,0,65535,1,1,"00/00/0000");
      OLED_DrawStringText(34,66,0,65535,1,1,"00:00:00");
      OLED_DrawStringText(16,76,0,65535,1,1,"+90.00/+180.00");
      OLED_DrawStringText(24,99,1,65535,2,2,"00:00");
      reversal(rev);
      tb1=false;
    }
    //
    while (wai==false)
    {
      if (uart_gps.available())
      {
        int c=uart_gps.read();
        if (gps.encode(c))
        {
          OLED_DrawCircle(122,19,3,1,2016); 
          getgps(gps);   
        }
      }
      else
      {
        OLED_DrawCircle(122,19,3,1,0);
      } 
      //
      jos=analogRead(JOYSEL);
      if (jos<511)
      {
        rev=!rev;
        reversal(rev);
        while (jos<511)
        {
          jos=analogRead(JOYSEL);
        }
      }
      //
      jpo=joystick(jpo);
    } 
    wai=false;
  }
  //Tab n°2 ***********************************************************************
  while(jpo==1)
  {
    OLED_DrawLine(33,14,63,14,0);
    //
    sel=0;
    jos=analogRead(JOYSEL);
    OLED_DrawStringText(36,24,1,65535,1,1,"sunrise");
    sundel(sridel,54,34,33808);
    OLED_DrawStringText(40,80,1,65535,1,1,"sunset");
    sundel(ssedel,54,90,33808);
    if (jos<511)
    {
      sel=sel+1;
      while (jos<511)
      {
        jos=analogRead(JOYSEL); 
      }
    }
    while(sel==1)
    {
      joy=analogRead(JOYVER);
      if (joy<jcv-thr)
      {
        if (sridel>=-60)
        {
          sridel=sridel-5;
        }
        while (joy<jcv-thr)
        {
          joy=analogRead(JOYVER);
        }
      }
      else if (joy>jcv+thr)
      {
        if (sridel<60)
        {
         sridel=sridel+5;
        }
        while (joy>jcv+thr)
        {
          joy=analogRead(JOYVER);
        }
      }
      sundel(sridel,54,34,65535);
      jos=analogRead(JOYSEL);
      if (jos<511)
      {
        EEPROM.write(addsridel,128-sridel);
        sel=sel+1;
        while (jos<511)
        {
          jos=analogRead(JOYSEL); 
        }
      } 
    }
    while(sel==2)
    {
      sundel(sridel,54,34,33808);
      joy=analogRead(JOYVER);
      if (joy<jcv-thr)
      {
        if (ssedel>-60)
        {
          ssedel=ssedel-5;
        }
        while (joy<jcv-thr)
        {
          joy=analogRead(JOYVER);
        }
      }
      else if (joy>jcv+thr)
      {
        if (ssedel<60)
        {
         ssedel=ssedel+5;
        }
        while (joy>jcv+thr)
        {
          joy=analogRead(JOYVER);
        }
      }
      sundel(ssedel,54,90,65535);
      jos=analogRead(JOYSEL);
      if (jos<511)
      {
        EEPROM.write(addssedel,128-ssedel);
        sel=0;
        while (jos<511)
        {
          jos=analogRead(JOYSEL); 
        }
      } 
    }
    //
    jpo=joystick(jpo);
  }
  //Tab n°3 ***********************************************************************
  while(jpo==2)
  {
    OLED_DrawLine(65,14,95,14,0);
    //
    sel=0;
    ethEEPROM();
    OLED_DrawStringText(30,56,1,65535,1,1,"PC's MAC");
    for (byte inc=0;inc<5;inc++)
    {
      OLED_DrawStringText(26+inc*18,66,0,33808,1,1,"-");
    }
    //
    jos=analogRead(JOYSEL);
    if (jos<511)
    {
      sel=sel+1;
      while (jos<511)
      {
        jos=analogRead(JOYSEL); 
      }
    }
    //PC'S MAC address
    for (byte inc=0;inc<=5;inc++)
    {
      while(sel==inc+1)
      {
        joy=analogRead(JOYVER);
        if (joy<jcv-thr)
        {
          if (pcmac[inc]>0)
          {
            pcmac[inc]=pcmac[inc]-1;
          }
          delay(80);
        }
        else if (joy>jcv+thr)
        {
          if (pcmac[inc]<255)
          {
            pcmac[inc]=pcmac[inc]+1;
          }
          delay(80);
        }
        macshow(pcmac[inc],14+inc*18,66,65535);
        jos=analogRead(JOYSEL);
        if (jos<511)
        {
          EEPROM.write(addpcmac+inc,pcmac[inc]);
          sel=sel+1;
          while (jos<511)
          {
            jos=analogRead(JOYSEL); 
          }
          if (sel==7)
          {
            sel=0;
            ethset=true;
          }
        }
      }
      macshow(pcmac[inc],14+inc*18,66,33808); 
    }
    jpo=joystick(jpo);
  }
  //Tab n°4 ***********************************************************************
  while(jpo==3)
  {
    OLED_DrawLine(97,14,126,14,0);
    //
    OLED_DrawStringText(28,26,2,65504,1,1,"Sunswitch");
    OLED_DrawStringText(40,47,0,65535,1,1,"Ver. 2.0");
    OLED_DrawStringText(21,61,0,33808,1,1,"Stephane Jouin");
    OLED_DrawStringText(24,71,0,33808,1,1,"(Jean Brunet)");
    OLED_DrawStringText(11,81,0,31,1,1,"http://www.boam.fr");
    OLED_DrawStringText(14,95,0,65535,1,1,"(CC BY-NC-SA)2012");
   
    //OLED_DrawText(4,2,2,"Sunswitch",65504);
    //OLED_DrawText(7,6,0,"Ver. 2.0",65535);
    //OLED_DrawText(4,8,0,"Stephane Jouin",33808);
    //OLED_DrawText(5,9,0,"Jean Brunet",33808);
    //OLED_DrawText(2,10,0,"http://www.boam.fr",33808);
    //OLED_DrawText(7,12,0,"(c)2012",65535);
    //
    jpo=joystick(jpo);
  }
}
//
void getgps(TinyGPS &gps)
{
  byte gpssat;
  int gpsyea;
  int sri,sse;
  int mintim,minsri,minsse;
  float gpslon,gpslat;
  byte gpsmon,gpsday,gpshou,gpsmin,gpssec,gpshun;
  char buf[3],bufyea[4],bufmon[3],bufday[3],bufhou[3],bufmin[3],bufsec[3],buflat[6],buflon[7];
  char bufsri[5],bufsse[5];
  minsri=0;
  minsse=0;
  gps.f_get_position(&gpslat,&gpslon);
  gps.crack_datetime(&gpsyea,&gpsmon,&gpsday,&gpshou,&gpsmin,&gpssec,&gpshun);
  mintim=60*gpshou+gpsmin; //time converted in minutes from 00:00
  lord.Position(gpslat,gpslon);
  lord.TimeZone(0);
  byte day[]={0,0,12,gpsday,gpsmon,gpsyea};
  lord.GMT(day);
  //date
  itoa(gpsday,buf,10);
  if (gpsday<10)
    {
      strcpy(bufday,"0");
      strcat(bufday,buf);
    }
    else
    {
      strcpy(bufday,buf);
    }
  OLED_DrawStringText(28,56,0,65535,1,1,bufday);
  itoa(gpsmon,buf,10);
  if (gpsmon<10)
    {
      strcpy(bufmon,"0");
      strcat(bufmon,buf);
    }
    else
    {
      strcpy(bufmon,buf);
    }
  OLED_DrawStringText(46,56,0,65535,1,1,bufmon);
  itoa(gpsyea,bufyea,10);
  OLED_DrawStringText(64,56,0,65535,1,1,bufyea);
  //
  //time
  itoa(gpshou,buf,10);
  if (gpshou<10)
    {
      strcpy(bufhou,"0");
      strcat(bufhou,buf);
    }
    else
    {
      strcpy(bufhou,buf);
    }
  OLED_DrawStringText(34,66,0,65535,1,1,bufhou);
  itoa(gpsmin,buf,10);
  if (gpsmin<10)
    {
      strcpy(bufmin,"0");
      strcat(bufmin,buf);
    }
    else
    {
      strcpy(bufmin,buf);
    }
  OLED_DrawStringText(52,66,0,65535,1,1,bufmin);
  itoa(gpssec,buf,10);
  if (gpssec<10)
    {
      strcpy(bufsec,"0");
      strcat(bufsec,buf);
    }
    else
    {
      strcpy(bufsec,buf);
    }
  OLED_DrawStringText(70,66,0,65535,1,1,bufsec);
  //lat./lon.
  ftoalat(gpslat,buflat);
  OLED_DrawStringText(16,76,0,65535,1,1,buflat);
  ftoalon(gpslon,buflon);
  OLED_DrawStringText(58,76,0,65535,1,1,buflon);
  //sunrise/sunset
  if (lord.SunRise(day))
  {
    minsri=60*day[tl_hour]+day[tl_minute]+sridel; //number of minutes from 00:00
    int srihour=(minsri/60)%60;
    int srimin=(minsri-srihour*60);
    itoa(srihour,buf,10);
    if (srihour<10)
    {
      strcpy(bufsri,"0");
      strcat(bufsri,buf);
    }
    else
    {
      strcpy(bufsri,buf);
    }
    strcat(bufsri,":");
    itoa(srimin,buf,10);
    if (srimin<10)
    {
      strcat(bufsri,"0");
    }
    strcat(bufsri,buf);
    OLED_DrawStringText(24,28,1,65535,2,2,bufsri);
  }
  if (lord.SunSet(day))
  {
    minsse=60*day[tl_hour]+day[tl_minute]+ssedel; //number of minutes from 00:00
    int ssehour=(minsse/60)%60;
    int ssemin=(minsse-ssehour*60);
    itoa(ssehour,buf,10);
    if (ssehour<10)
    {
      strcpy(bufsse,"0");
      strcat(bufsse,buf);
    }
    else
    {
      strcpy(bufsse,buf);
    }
    strcat(bufsse,":");
    itoa(ssemin,buf,10);
    if (ssemin<10)
    {
      strcat(bufsse,"0");
    }
    strcat(bufsse,buf);
    OLED_DrawStringText(24,99,1,65535,2,2,bufsse);       
  }
  //
  if (minsri<mintim and mintim<minsse)
  {
    if (rev==false)
    {
      intoff();
    }
    else
    {
      inton();
    }   
  }
  else
  {
    if (rev==false)
    {
      inton();
    }
    else
    {
      intoff();
    } 
  }
  //nb of satellites
  gpssat=gps.satellites();
  bargraph(gpssat);
}
//
void bargraph(byte sat)
{
  int c;
  byte i,j;
  if (sat<=12)
  {
    for (i=1;i<=sat;i++)
    {
      if (i<4)
      {
        c=63488;  //Red
      }
      else if (i<7)
      {
        c=64480;  //Orange
      }
      else if (i<10)
      {
        c=65504;  //Yellow
      }
      else
      {
        c=2016;  //Green
      }
      OLED_DrawRectangle(119,127-i*8,6,6,1,c);
    }
    for (j=i;j<=12;j++)
    {
      OLED_DrawRectangle(119,127-j*8,6,6,1,0);
    } 
  }
}
//based on http://www.keil.com/forum/17514/
void ftoalat(float num,char *str)
{
  int intpar=num;
  int intdec;
  int inc;
  float decpar;
  char dec[6];
  char buf[2];
  memset(str,0x0,6);
  if (num<0)
  {
    strcpy(str,"-");
  }
  else
  {
    strcpy(str,"+");
  }
  if (num<10)
  {
    strcat(str,"0"); 
  }
  itoa(num,buf,10);
  strcat(str,buf);
  strcat(str,".");
  decpar=num-intpar;
  intdec=decpar*100;
  if(intdec<0)
  {
    intdec=-intdec;
  }
  itoa(intdec,dec,10);
  for(inc=0;inc<(0.001-strlen(dec));inc++)
  {
    strcat(str, "0");
  }
  strcat(str,dec);
}
void ftoalon(float num,char *str)
{
  int intpar=num;
  int intdec;
  int inc;
  float decpar;
  char dec[6];
  char buf[2];
  memset(str,0x0,6);
  if (num<0)
  {
    strcpy(str,"-");
  }
  else
  {
    strcpy(str,"+");
  }
  if (num<10)
  {
    strcat(str,"00"); 
  }
  else if (num<100)
  {
    strcat(str,"0");
  }
  itoa(num,buf,10);
  strcat(str,buf);
  strcat(str,".");
  decpar=num-intpar;
  intdec=decpar*100;
  if(intdec<0)
  {
    intdec=-intdec;
  }
  itoa(intdec,dec,10);
  for(inc=0;inc<(0.001-strlen(dec));inc++)
  {
    strcat(str, "0");
  }
  strcat(str,dec);
}
//
void reversal(boolean rev)
{
  if (rev==false)
  {
    OLED_DrawLine(17,32,17,40,0);
    OLED_DrawLine(18,32,18,40,0);
    OLED_DrawCircle(17,36,3,0,2016);
    OLED_DrawCircle(17,36,4,0,2016);
    OLED_DrawCircle(17,108,3,0,0);
    OLED_DrawCircle(17,108,4,0,0);
    OLED_DrawLine(17,104,17,112,63488);
    OLED_DrawLine(18,104,18,112,63488);
   
  }
  else
  {
    OLED_DrawCircle(17,36,3,0,0);
    OLED_DrawCircle(17,36,4,0,0);
    OLED_DrawLine(17,32,17,40,63488);
    OLED_DrawLine(18,32,18,40,63488);
    OLED_DrawLine(17,104,17,112,0);
    OLED_DrawLine(18,104,18,112,0);
    OLED_DrawCircle(17,108,3,0,2016);
    OLED_DrawCircle(17,108,4,0,2016);
  }
}
void inton()
{
  OLED_DrawCircle(16,7,4,0,31);
  OLED_DrawCircle(16,8,4,0,31);
  OLED_DrawLine(16,6,22,6,0);
  OLED_DrawLine(16,7,22,7,31);
  OLED_DrawLine(16,8,22,8,31);
  OLED_DrawLine(16,9,22,9,0);
  digitalWrite(OUT,HIGH);
  if (ethset)
  {
    wol();
    ethset=false;
  }
}
void intoff()
{
  OLED_DrawCircle(16,7,4,0,33808);
  OLED_DrawCircle(16,8,4,0,33808);
  OLED_DrawLine(16,6,22,6,0);
  OLED_DrawLine(16,7,22,7,33808);
  OLED_DrawLine(16,8,22,8,33808);
  OLED_DrawLine(16,9,22,9,0);
  digitalWrite(OUT,LOW);
  ethset=true;
}
void sundel(int del,byte x,byte y,int color)
{
  char buf[3];
  char out[4];
  if (del==0)
  {
    OLED_DrawStringText(x,y,0,0,1,1," ");
    x=x+6;
    OLED_DrawStringText(x+5,y,0,0,1,1," ");
  }
  else if (abs(del)<10)
  {
    OLED_DrawRectangle(x,y,2,7,1,0);
    x=x+3;
    OLED_DrawRectangle(x+11,y,2,7,1,0);
  }
  itoa(del,buf,10);
  if (del>0)
  {
    strcpy(out,"+");
    strcat(out,buf);
    OLED_DrawStringText(x,y,0,color,1,1,out);
  }
  else
  {
    OLED_DrawStringText(x,y,0,color,1,1,buf);
  }
}
void macshow(byte mac,byte x,byte y,int color)
{
  char buf[3];
  if (mac<15)
  {
    OLED_DrawStringText(x,y,0,color,1,1,"0");
    x=x+6;
  }
  itoa(mac,buf,16);
  OLED_DrawStringText(x,y,0,color,1,1,buf);
}
byte joystick(byte jpo)
{
  int joy=analogRead(JOYHOR);
  if (joy<jch-thr)
  {
    if (jpo<3)
    {
      OLED_DrawRectangle(1,15,125,111,1,0);
      jpo=jpo+1;
      if (jpo==1)
      {
        wai=true;
      }
      while (joy<jch-thr)
      {
        joy=analogRead(JOYHOR);
      }
      OLED_DrawLine(0,14,127,14,65535);
    }
  }
  else if (joy>jch+thr)
  {
    if (jpo>0)
    {
      OLED_DrawRectangle(1,15,125,111,1,0);
      jpo=jpo-1;
      while (joy>jch+thr)
      {
        joy=analogRead(JOYHOR);
      }
      OLED_DrawLine(0,14,127,14,65535);
    }
    if (jpo==0)
    {
      tb1=true;
    }   
  }
  return jpo;
}
void boam()
{
  Serial.write(byte(0x40));
  Serial.write(byte(0x49));
  Serial.write(byte(0x00));
  Serial.write(byte(0x00));
  Serial.write(byte(0x80));
  Serial.write(byte(0x80));
  Serial.write(byte(0x10));
  Serial.write(byte(0x00));
  Serial.write(byte(0x00));
  Serial.write(byte(0x10));
  OLED_GetResponse();
}
void ethEEPROM()
{
  for (byte inc=0;inc<=5;inc++)
    pcmac[inc]=EEPROM.read(addpcmac+inc);
}
void wol()
{
  byte buf[122];
  int bufIDX=0;
  for (byte i=0;i<=5;i++)
  {
    buf[bufIDX]=0xFF;
    bufIDX++;
  }
  for (byte i=0;i<=5;i++)
  {
     buf[bufIDX]=mac[i];
     bufIDX++;
  }
  buf[bufIDX]=0x08;
  bufIDX++;
  buf[bufIDX]=0x42;
  bufIDX++;
  for (byte i=0;i<=5;i++)
  {
    buf[bufIDX]=0xFF;
    bufIDX++;
  }
  for (byte repeats=0;repeats<=15;repeats++)
  {
    for (byte i=0;i<=5;i++)
    {
      buf[bufIDX]=pcmac[i];
      bufIDX++;
    } 
  }
  W5100.send_data_processing(s,buf,bufIDX);
  W5100.execCmdSn(s,Sock_SEND_MAC);
}

//link:
//https://github.com/mindstorms6/Arduino-WOL
//http://arduiniana.org
//http://swfltek.com/arduino/timelord.html
//http://blog.bricogeek.com/
//E.O.F

oled128drv.h:
Code : Tout sélectionner
//uOLED-128-G1h Driver for Arduino
//
//from uOLED-160-GMD1 driver
//original code: Oscar Gonzalez
//www.bricogeek.com
//August 2007
//
//update: Stéphane Jouin
//www.jouin.eu
//Reference document: GOLDELOX-SGC-COMMANDS-SIS-Rev6.pdf
//August 2012
//work with Arduino 1.0.1
//
#define OLED_BAUDRATE 19200
#define OLED_RESETPIN 8 //reset pin
//
void OLED_ResetDisplay()
{
  digitalWrite(OLED_RESETPIN, LOW);
  delay(20);             
  digitalWrite(OLED_RESETPIN, HIGH);
  delay(20);
}
//
char OLED_GetResponse()
{
  byte incomingByte=0x06;
  while (!Serial.available())
  {
    delay(1);
  }
  incomingByte = Serial.read();
  return incomingByte;
}
//Initialisation display. Must be first activate a serial comunication!
void OLED_Init()
{
  OLED_ResetDisplay(); 
  delay(5000);
  Serial.write(0x55); //AutoBaud
  OLED_GetResponse();
}
// Clear Screen
void OLED_Clear()
{
  Serial.write(0x45);
  delay(20);
  OLED_GetResponse();
}
//
void OLED_PenSize(char filled)
{
  if (filled == 1)
  {
    Serial.write(0x70);
    Serial.write(byte(0x00)); //filled(solid)
  }
  else
  {
    Serial.write(0x70);
    Serial.write(0x01); //outline(wire-frame)
  }
  OLED_GetResponse(); 
}
//
void OLED_DrawCircle(char x,char y,char radius,char filled,int color)
{
  OLED_PenSize(filled);   
  Serial.write(0x43);
  Serial.write(byte(x));
  Serial.write(byte(y));
  Serial.write(radius);
  Serial.write(color>>8); //MSB         
  Serial.write(color&0xFF); //LSB
  OLED_GetResponse();
}
//
void OLED_DrawTriangle(char x1,char y1,char x2,char y2,char x3,char y3,char filled,int color) //Must be specified in an anti-clockwise fashion
{
  OLED_PenSize(filled);
  Serial.write(0x47);
  Serial.write(byte(x1));
  Serial.write(byte(y1));
  Serial.write(byte(x2));
  Serial.write(byte(y2));
  Serial.write(byte(x3));
  Serial.write(byte(y3));
  Serial.write(color>>8); //MSB         
  Serial.write(color&0xFF); //LSB
  OLED_GetResponse();
}
//
void OLED_DrawLine(char x1,char y1,char x2,char y2,int color)
{
  Serial.write(0x4C);
  Serial.write(x1);
  Serial.write(y1);
  Serial.write(x2);
  Serial.write(y2);
  Serial.write(color>>8); //MSB         
  Serial.write(color&0xFF); //LSB
  OLED_GetResponse();
}
//
void OLED_DrawRectangle(char x,char y,char width,char height,char filled,int color)
{
  OLED_PenSize(filled);
  Serial.write(0x72);
  Serial.write(x); //x1
  Serial.write(y); //y1
  Serial.write(x+width); //x2
  Serial.write(y+height); //y2
  Serial.write(color>>8); //MSB         
  Serial.write(color&0xFF); //LSB
  OLED_GetResponse();
}
//
void OLED_Opacity(char mode)
{
  Serial.write(0x4F);
  Serial.write(byte(mode));
  OLED_GetResponse();
}
//
void OLED_DrawStringText(char x,char y,char font,int stringColour,int width,int height,char *string)
{
  Serial.write(0x53);   
  Serial.write(byte(x));
  Serial.write(byte(y));
  Serial.write(font);
  Serial.write(stringColour>>8);  //MSB         
  Serial.write(stringColour&0xFF);  //LSB
  Serial.write(width);
  Serial.write(height);
  for (int i=0;i<strlen(string);i++)
  {
    Serial.write(string[i]);
  }
  Serial.write(byte(0x00));
  OLED_GetResponse();
}


Image
(utilisation commerciale interdite sans l'autorisation du concepteur)
Stéphane
Administrateur
 
Message(s) : 13
Inscription : 08 Juin 2013, 21:26

Retour vers Divers

Qui est en ligne ?

Utilisateur(s) parcourant ce forum : Aucun utilisateur inscrit et 1 invité

cron