Translate

dimanche 25 septembre 2016

Dialoguer a distance entre deux arduino avec APC220 portée 1km

Télécommande APC220 portée 1000m

Après plusieurs demandes, je met ce petit tuto concernant les module émetteur récepteur APC220. Permettant de communiquer soit entre PC et arduino ou entre deux arduino. Je vais me pencher sur cette dernière config.


D'après les spécifications technique ce petit module a une portée d'environ 1km en zone dégagée (pas testé)

Il est possible de configurer le module par le biais d'un petit soft (fréquence, ID, ....), j'y reviendrai plus tard.

Le câblage


Le câblage reste ultra simple !!


Il n'y a pas de module APC220 dans la bibliothèque Frizing j'ai donc pris un module approchant!
Je n'ai pas mis de led sur le récepteur car dans le sketch en exemple j'utilise celle de la carte. Vous remarquerez également que j'ai branché les bornes RX et TX des APC220 sur les bornes 10 et 11 de l'arduino ceci car j'utilise SoftwareSerial et donc je laisse la port série libre.

Les sketchs

Comme je l'ai dit plus haut, j'utilise la librairie SoftwareSerial.

Le programme reste simple:

L'émetteur

"mySerial.begin(9600);"

création d'un flag  "flag='a'; "

et envoie vers le récepteur
mySerial.print(flag);

Le récepteur

Ouverture du port virtuel
 "mySerial.begin(9600);"

Configuration en mode réception
 if(mySerial.available() > 0)
state = mySerial.read();

Réception du flag
if (state == 'a') {// (ici ce sera state car dans le programme final je force l'état du flag)
 digitalWrite(ld,HIGH);

 Les codes

Emetteur


//EMETTEUR by arduino-creations.blogspot.fr

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX
int button_open =4;
int button_close =3;
int mes = 0;
char flag;

void setup()
{
  pinMode(button_open, INPUT_PULLUP);
  pinMode(button_close, INPUT_PULLUP);
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop()
{
  if( digitalRead(button_open)==LOW)
  {
    flag='a';
    mySerial.print(flag);
  }
  else
if( digitalRead(button_open)==HIGH)
{
    flag='A';
    mySerial.print(flag);
  }
 
 if(digitalRead(button_close)==LOW)
  {
    flag='b';
    mySerial.print(flag);
  }

   
  delay(20);
}

Récépteur

//RECEPTEUR by arduino-creations.blogspot.fr

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX
int ld = 13;

int state;
int flag=0;

void setup() {
   Serial.begin(9600);
   mySerial.begin(9600);
    pinMode(ld, OUTPUT);
    digitalWrite (ld,LOW);
}

void loop() {
  if(mySerial.available() > 0){
  state = mySerial.read();
  flag=0;
  }
  if (state == 'a') {
  digitalWrite(ld,HIGH);
 Serial.print(state);
  if(flag == 0){
  flag=1;
  }
  }
  else if (state == 'A'){
  digitalWrite(ld,LOW);
  Serial.print(state);
  if(flag == 0){
  flag=1;
  }
  }
 delay(10);
 
}







mercredi 4 novembre 2015

Fraiseuses CNC sur mesure



Réalisations de fraiseuses CNC sur mesure

Après avoir eu plusieurs demandes de réalisations de machine CNC, j'ai décidé de proposer mes services pour la fabrication de machines sur mesure. 
Il est évident que cela ne m'empêchera pas de continuer a vous aider en cas de besoins.


Quelques machines réalisées






Usinage des pièces alu et assemblage précis






















 Vidéo d'usinage avec ma machine

 Caractéristiques de celle-ci:
  • Surface du plateau 900x600
  • Surface d'usinage 600x400
  • hauteur Z = 200
  • Barres rondes en acier carbone X et Z diamètre  20
  • Barre ronde en acier carbone Z diamètre 16
  • Vis hélicoïdales 16x4
  • Moteurs NEMA 23 75mm
  • Drivers 2M542
  • Alimentation des moteurs 48V 15A
  • Broche chinoise 2.2KWrefroidie a l'eau
  • Vitesse max de la machine 3500mm/mn



Type de machines


Il existe plusieurs type de machines et d'entrainement.
  1. L'entrainement par vis celui-ci nécessite une vis au centrée sous le portique en X donc le plateau martyre est au dessus de la structure. 
  2. L'entrainement par courroies a l'avantage de pouvoir bénéficier d'un fond creux ce qui permet de poser la machine sur la surface a usiner comme une porte par exemple.
  3. Portique mobile
  4. Plateau mobile (je déconseille cette solution car la machine nécessite beaucoup plus de place du fait que le plateau avance et recule au delà du châssis)

La vitesse d'avance en entrainements par courroies est plus rapide qu'avec des vis mais nécessite 1 moteur supplémentaire. Sur la machine décrite ci-dessous j'arrive a des vitesses jusqu’à 4500mm/mn contre 900mm/mn pour une vis de 8x1.5 (vis sur le Z).

Ma dernière réalisation

La dernière machine réalisées (terminée, testée et rodée aujourd'hui) entraînement par courroies, la machine est posée et bridée sur la planche a usiner. La planche ou de rails alu peuvent être facilement fixées sous la machine.

Caractéristique:
  • Dimensions 660x590
  • Surface d'usinage 400x400 (réel 445 x 410)
  • Hauteur du Z 80 sur plateau fixe plongée maximum 160 (suivant l'utilisation)
  • Barres rondes X,Y et Z en acier carbone diamètre 12
  • Entrainement par courroies GT2
  • Z entrainement par vis 8X1.5
  • Moteur NEMA 23 de 56mm
  • Drivers 2M542
  • Alimentation moteurs 36V / 10A
  • Broche 400W / 48V sur variateur 12000 tr/mn
  • Vitesse bridée a 4000mm/mn possible jusqu’à 4500mm/mn



A l'arrière le coffret de commande de dimensions 300x400 dans lequel se trouve l'électronique, la liaison machine coffret se fait a l'aide d'un seul connecteur.


 Pilotage

Le pilotage de la machine se fait en USB a l'aide d'un simple PC sous windows, linux ou mac. Pas besoin d'une bête de guerre, un vieux PC 1Ghz fait largement l'affaire. Il suffit d'installer GRBL Controler adapté au système d'exploitation.
Je viens de commander une tablette sous windows pour faire des tests, je vous ferai par de mes essais dès réception de celle-ci, a mon avis ce sera pas mal, car plus besoin de trimbaler un PC si on déplace la machine et la tablette peut être fixée sur le coffret de commande.La tablette commandée est a 110 Euros en dual BOOT Windows et Android!

Les broches

Il y a plusieurs type de broche
  • Les défonceuses que je n'installe pas car pour ma part ce n'est pas adaptée 
  • Les broches chinoises de puissances diverses la puissance mini que je conseille est 800W pour 24000 tr/mn. J'ai testé une 400w, une 600W et une 2.2KW ces machines fonctionnent a merveille, le 2.2KW.
  • Les broches KRESS que j'ai testé et qui sont de super machine
  • Les DREMEL elles sont bien pour des petites gravure qui ne nécessite pas de couple.

Renseignements


Pour plus d'infos, contactez moi via le formulaire de contact et exposez moi votre demande.

Afin de vous proposer une machine adaptée a vos besoins il me faut le éléments suivants:
  • Surface utile d'usinage
  • Hauteur du Z
  • Matière a usiner je précise qu'avec ce type de machine il est impossible d'usiner de l'acier!!!
  • Type de machine (courroies ou vis) 
  • Puissance de la broche, fournie ou non








mardi 11 novembre 2014

Automate pour aquarium

 Fonctionnement


Le but de ce petit automate permet la gestion de la température, de l'éclairage et affichage d'alarmes de température.
Il est possible d'y ajouter quelques lignes pour le Ph par exemple mais le programme risque de ne plus tenir dans un UNO, il faudra passer par une méga.
Tous les paramètre sont configurables via un clavier analogique de 3 touches et l'affichage se fait sur un LCD 128X64 SPI.
Pour la mesure de température, j'ai opté pour une LM35 afin de ne pas surcharger le programme.
 La température varie de +/- 0.5° ( précision de la sonde),l'alarme se déclenche a +/-2° par rapport a la consigne, exemple: si consigne = 20° alarme basse a 18° et alarme haute a 22°

L'écran prinipal


L'écran principal n'est pas encore terminé, il reste a faire la mise en page que je ferai dans la foulée


On y trouve une horloge analogique (un petit plus visuel lol)
La date
L'heure, la température
La programmation horaire
L'état du chauffage - marche - arrêt - alarme basse - alarme haute
La consigne de température (en cas de coupure de courant, celle-ci est configurée pour revenir a 20° et pas a 0°, cela permet de ne pas descendre trop bas en température)

Le menu de programmation




A chaque appui sur la touche menu, les réglages défileront de la manière suivante

- Le jour - Le mois - l'année - l'heure - les minutes - les secondes- heure de mise en marche - minutes de mise en marche - heure de mise a l' arrêt - minute de mise a l' arrêt - la consigne de température et l'enregistrement.
En cas de coupure de courant, les seuls paramètre enregistré sont la date et l'heure!!!

A noter:  A partir du moment ou vous rentrer dans le menu de programmation, l'horloge s'arrête jusqu'à ce que vous sortez du menu!!!!!

Le programme



//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//
//                                                                                                                                                    //
//        AUTOMATE POUR AQUARIUM                                                                                 //
//        BY JOJO BRICOLO                                                                                                     //
//          Sonde LM35DZ                                                                                                        //
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//



#include <U8glib.h>
#include <Wire.h>
#include <Math.h>
#include <DS1307new.h>

U8GLIB_ST7920_128X64_4X u8g(2, 5, 4);


int angles,anglem,angleh,xs, ys, xm, ym, xh, yh;
float rad;

uint16_t startAddr = 0x0000;    
uint16_t lastAddr;              
uint16_t TimeIsSet = 0xaa55;

#define DDS_LOAD  12 
#define DDS_CLOCK 3
#define DDS_DATA  2

#define Touche_PIN  A0
int sensorPin = A0; 
int sensorValue = 0;
int val_key;
int Select;
int Heure;
int Minute;
int Seconde;
int Jour;
int Mois;
int Annee;

int heurM = 0;
int minM = 0;
int heurA = 0;
int minA = 0;

int val1;
int val2;
int val3;
int val4;

int setTemp = 20;
int Chauff= 12;
int eclairage = 13;

int tempsensor =A1;

float ma_tempetf=0.0;
 const uint8_t rook_bitmap[] PROGMEM = { // signe degré
  0x10,         // 00010000
  0x28,         // 00101000
  0x28,         // 00101000
  0x10,         // 00010000
  0x00,         // 00000000
  0x00,         // 00000000
  0x00,         // 00000000
  0x00          // 00000000
};  

void setup () {
                
  pinMode(Chauff, OUTPUT); // Relai chauffage
  pinMode (eclairage,OUTPUT); // Relai eclairage

  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// RAM horloge
  TimeIsSet = 0xffff;
  RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); 
  RTC.ctrl = 0x00;    
                      
  RTC.setCTRL();

   u8g.setFont(u8g_font_5x8); // ecriture de base
   
  rad = ((2 * 3.1415926536) / 360);
}
//////////////////////////   Fonctions Void

 void Principal()
 {
   sensorValue = analogRead(sensorPin);
  val_key = int(sensorValue/100);     

 if  (Select == 0) 
 { 
 RTC.getTime();
 Heure = RTC.hour;
 Minute = RTC.minute;
 Seconde = RTC.second;
 Jour = RTC.day;
 Mois = RTC.month;
 Annee = RTC.year; 

  //Logo By mi
  u8g.setFont(u8g_font_timB08);
  u8g.drawStr( 50,60, " By Jojo Bricolo");
 
  ////////////////////////////////////     Affichage de l'Heure
 
   u8g.setFont(u8g_font_timB08);

  u8g.setPrintPos(56,18);
  u8g.print(Heure);
  u8g.drawStr( 68,18, "h");
  if (Minute < 10){ u8g.drawStr( 74, 18, "0");
  u8g.setPrintPos( 81, 18);
  u8g.print(Minute);}
  else
  {u8g.setPrintPos( 76, 18);
  u8g.print(Minute);} 
  u8g.drawStr( 90,17, "-");
 
  ////////// Affichage de la date
 
  u8g.setFont(u8g_font_5x7);
  {
    u8g.setPrintPos(60,8);
    u8g.print(Jour);
  }

    switch (RTC.month){
    case 1:
         u8g.drawStr( 69, 8, "Janv.");
     break;
    case 2:
         u8g.drawStr( 71, 8, "fev.");
    break;
    case 3:
        u8g.drawStr( 72, 8, "  mars");
    break;
     case 4:
        u8g.drawStr( 72, 8, " avr. ");
    break;
     case 5:
        u8g.drawStr( 73, 8, "  mai  ");
    break;
     case 6:
        u8g.drawStr( 72, 8, " juin  ");
    break;
    case 7:
        u8g.drawStr( 69, 8, "Juil.");
    break;
     case 8:
        u8g.drawStr( 72, 8, "  aout  ");
    break;
     case 9:
        u8g.drawStr( 69, 8, " sept.");
    break;
     case 10:
        u8g.drawStr( 72, 8, "oct.");
    break;
     case 11:
        u8g.drawStr( 72, 8, "nov.");
    break;
     case 12:
        u8g.drawStr( 72, 8, "dec.");
    break;
    }
  u8g.setPrintPos(96,8); //Année
  u8g.print(Annee);
 
  ///////////////////////////////////////////   Temperature  
  int reading = analogRead(tempsensor);
  float voltage = reading * 5.0 / 1024;
  float ma_tempetf = voltage * 100 ;
     
  /////////////////////////////////////// Affichage Temperature ////
  u8g.setFont(u8g_font_timB08);
  u8g.setPrintPos( 98, 18);
  u8g.print(ma_tempetf);
  u8g.drawBitmapP( 120, 11, 1, 8, rook_bitmap);
 
  /////////////////////////  Affichage consigne//////////////
   
  u8g.setFont(u8g_font_4x6);
  u8g.drawStr( 64, 45,"Consigne");
  u8g.setPrintPos( 111, 45);
  u8g.print(setTemp);
  u8g.drawBitmapP( 120, 39, 1, 8, rook_bitmap);
   
  ////////////// Commade chauffage
 
   u8g.setFont(u8g_font_4x6);
   if (ma_tempetf > setTemp)
    {
    digitalWrite(Chauff, LOW);
    u8g.drawStr( 65, 37,"Chauff Arret");
   
    }
  if (ma_tempetf <= (setTemp-0.5))
    {
    digitalWrite(Chauff, HIGH);
    u8g.drawStr( 65, 37,"Chauff Marche");
    }
 
  /////////////////////// Commande eclairage
  val1 = (Heure*100)+Minute;
  val2 = (heurM*100)+minM;
  val3 = (heurA*100)+minA-1;
   
  if ((val1 >= val2) && (val1 <= val3))
   {
    digitalWrite(eclairage, HIGH);
  }
     else
    
 //if ((Heure >= heurA) && (Minute >= minA))
  {
  digitalWrite(eclairage, LOW);
  }
  ////////////////////// Affichage consignes éclarage
  u8g.setFont(u8g_font_4x6);
  u8g.drawStr( 56, 27,"Ecl");
  u8g.setPrintPos( 71, 27);
  u8g.print(heurM);
  u8g.drawStr( 80, 27,"h");
  u8g.setPrintPos( 85, 27);
  u8g.print(minM);
 
  //u8g.setFont(u8g_font_5x8);
  u8g.drawStr( 96, 27,"a");
  u8g.setPrintPos( 103, 27);
  u8g.print(heurA);
  u8g.drawStr( 113, 27,"h");
  u8g.setPrintPos( 118, 27);
  u8g.print(minA);
 
  //////////////////  Affichage alarme température
 
  // u8g.setFont(u8g_font_4x6);
  
   //if (ma_tempetf > (setTemp + 2))
  
  //u8g.drawStr( 65, 37,"Temp Haute");
 
  //else
 
 // if (ma_tempetf < (setTemp - 2))
  
  //u8g.drawStr( 65, 37,"Temp Basse");
 
  //else
 
  //u8g.drawStr( 65, 37,"            ");

 }
  /////////////////////////////// Horloge analogique
  angles = (Seconde * 6)-90; 
  anglem = (Minute * 6)-90; 
  angleh = ((Heure * 30)-90) + ((anglem/12)+6);
  Serial.println (angleh);
 
  u8g.drawCircle(31,32,21);
  u8g.drawCircle(31,32,19);
  
  u8g.setFont(u8g_font_micro);
  u8g.drawStr( 54, 35, "3");
  u8g.drawStr( 30, 60, "6");
  u8g.drawStr( 5, 35, "9");
  u8g.drawStr( 28, 10, "12");
 
  u8g.drawStr( 40, 16, "."); //1
  u8g.drawStr( 47, 24, "."); //2
  u8g.drawStr( 50, 33, "."); //3
  u8g.drawStr( 47, 42, ".");  //4
  u8g.drawStr( 41, 50, ".");  //5
  u8g.drawStr( 31, 53, ".");  //6
  u8g.drawStr( 21, 50, ".");  //7
  u8g.drawStr( 14, 42, ".");  //8
  u8g.drawStr( 11, 33, ".");  //9
  u8g.drawStr( 14, 24, ".");  //10
  u8g.drawStr( 21, 16, ".");  //11
  u8g.drawStr( 31, 14, "."); //12

  xs = 31 + (cos(angles * rad)*18);
  ys = 32 + (sin(angles * rad)*18);
  u8g.drawLine(31, 32, xs, ys);

  
   xm = 31 + (cos(anglem * rad)*16);
   ym = 32 + (sin(anglem * rad)*16);
   u8g.drawLine(31, 32, xm, ym);
   u8g.drawLine(32, 31, xm, ym);
   
    
   xh = 31 + (cos(angleh * rad)*10);
   yh = 32 + (sin(angleh * rad)*10);
   u8g.drawLine(31, 32, xh, yh);
   u8g.drawLine(32, 31, xh, yh);

//////////////////////////////////////  Menu et règlages
  
  if ((Select > 0) and (Select < 13))
  {
  u8g.drawStr(80,8,"REGLAGES");
   
  if (Jour < 10) 
  {
  u8g.drawStr( 73, 15, "0");
  u8g.setPrintPos(77,15);
  u8g.print(Jour);
  }
  else
  {
  u8g.setPrintPos(73,15);
  u8g.print(Jour);
  }
 
  u8g.drawStr( 83,15, ":"); 

  if (Mois < 10)
  { 
  u8g.drawStr( 89, 15, "0");
  u8g.setPrintPos( 94, 15);
  u8g.print(Mois);
  }
    else
  {
  u8g.setPrintPos(89,15);
  u8g.print(Mois);
  }
 
  u8g.drawStr( 100, 15, ":");
 
  u8g.setPrintPos( 105, 15);
  u8g.print(Annee);
 
  //xxxxxxxxxxxxxxxxxxxx

  if (Heure < 10)
  {  
  u8g.drawStr( 78, 25, "0");
  u8g.setPrintPos(82,25);
  u8g.print(Heure);
  }
  else
  {
  u8g.setPrintPos(78,25);
  u8g.print(Heure);
  }
 
  u8g.drawStr( 88,25, ":");
 
  if (Minute < 10)
  {  
  u8g.drawStr(93, 25, "0");
  u8g.setPrintPos( 98, 25);
  u8g.print(Minute);
  }
  else
  {
  u8g.setPrintPos( 93, 25);
  u8g.print(Minute);
  } 
 
  u8g.drawStr( 105, 25, ":");
 
  if (Seconde < 10)
  {  
  u8g.drawStr(110, 25, "0");
  u8g.setPrintPos( 115, 25);
  u8g.print(Seconde);
  }
  else
  {
    u8g.setPrintPos( 110, 25);
    u8g.print(Seconde);
  }

  //xxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
  u8g.drawStr(65,35,"Marche");
  {
  u8g.setPrintPos( 100, 35);
  u8g.print(heurM);
  }
 
  u8g.drawStr( 110, 35, ":");
  {
  u8g.setPrintPos( 115, 35);
  u8g.print(minM);
  }
 
  u8g.drawStr(65,45,"Arret");
  {
  u8g.setPrintPos( 100, 45);
  u8g.print(heurA);
  }
 
  u8g.drawStr( 110, 45, ":");
 
  {
  u8g.setPrintPos( 115, 45);
  u8g.print(minA);
  }
 
  u8g.drawStr(65,55,"Consigne");
  {
  u8g.setPrintPos( 105, 55);
  u8g.print(setTemp);
  }
  u8g.drawBitmapP( 113, 50, 1, 8, rook_bitmap);
 
  }
 
  val_key = 0;                        
  sensorValue = analogRead(sensorPin);
  val_key = int(sensorValue/100);     

//////////////////////////////////////////////   Selection des reglages

   switch (val_key)
       {
          case 7 :
       {
         Select = (Select + 1);
         delay (200);
        }
         break;
       }     
         
        if (Select == 1) u8g.drawStr(65,62," Reglage jour");
  
        if (Select == 2) u8g.drawStr(65,62," Reglage mois");

        if (Select == 3) u8g.drawStr(65,62," Reglage annee");

        if (Select == 4) u8g.drawStr(65,62,"Reglage heures");

        if (Select == 5) u8g.drawStr(65,62,"Reglage minutes");

        if (Select == 6) u8g.drawStr(65,62,"Reglage Secondes");
       
        if (Select == 7) u8g.drawStr(65,62,"Heure marche");
       
        if (Select == 8) u8g.drawStr(65,62,"Minutes marche");
       
        if (Select == 9) u8g.drawStr(65,62,"Heure arret");
       
        if (Select == 10) u8g.drawStr(65,62,"Minutes arret");
       
        if (Select == 11) u8g.drawStr(45,62, "Consigne temperature");
       
        if (Select == 12) u8g.drawStr(65,62, "Enregistrer !");
 
        if (Select == 13)
        {
           (Select = 0);
            RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Entrée startAddr dans NV-RAM address 0x08
            TimeIsSet = 0xffff;
            RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));        
            if (TimeIsSet != 0xaa55)
            {
             RTC.stopClock();       
             RTC.fillByYMD(Annee,Mois,Jour);
             RTC.fillByHMS(Heure,Minute,Seconde);
   
             RTC.setTime();
             TimeIsSet = 0xaa55;
             RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
             RTC.startClock();
            }
            else
            {
             RTC.getTime();
            } 
          
       }
   //////////////// Touches +/-        
   switch (val_key)
 
       {  
   case 3://-
        {   
        delay (200);    
        if (Select == 1)
          {
            Jour = (Jour - 1);
          } 
        if (Jour < 1)
          {
          (Jour = 31);
          }
        if (Select == 2)
          {
          Mois = (Mois - 1);
          }
        if (Mois < 1)
          {
          (Mois = 12);
          }
        if (Select == 3)
          {
          Annee = (Annee - 1);
          }
      
        if (Select == 4)
          {
          Heure = (Heure - 1);
          } 
        if (Heure < 1)
          {
           (Heure = 23);
          }
        if (Select == 5)
          {
          Minute = (Minute - 1);
          }
        if (Minute < 1)
          {(
            Minute = 59);
          }
        if (Select == 6)
          {
          Seconde = (Seconde - 1);
          }
        if (Seconde < 1)
          {
          (Seconde = 59);
          }
       
        if (Select == 7)
          {
          heurM = (heurM - 1);
          }
        if (heurM < 1)
          {
          (heurM = 0);
          }
        if (heurM > 23)
          {
          (heurM = 0);
          }
       
        if (Select == 8)
          {
            minM = (minM - 1);
          }
        if (minM < 1)
          {
          (minM = 0);
          }
        if (minM >59)
          {
          (minM = 0);
          }
       
        if (Select == 9)
          {
          heurA = (heurA - 1);
          }
        if (heurA < 1)
          {
            (heurA = 0);
          }
        if (heurA> 23)
          {
          (heurA = 0);
          }
       
        if (Select == 10)
          {
          minA = (minA - 1);
          }
        if (minA < 1)
          {
          (minA = 0);
          }
        if (minA >59)
          {
          (minA = 0);
          }
       
        if (Select == 11)
          {
          setTemp = (setTemp - 1);
          }
        if (setTemp > 32)
          {
          (setTemp = 0);
          }   
        }
        break;
       
  case 1: //+
        {
         delay (200);
        if (Select == 1)
          {
          Jour = (Jour + 1);
          } 
        if (Jour > 31)
          {
          (Jour = 1);
          }
        if (Select == 2)
          {
          Mois = (Mois + 1);
          }
        if (Mois > 12)
          {
          (Mois = 1);
          }
        if (Select == 3)
          {
          Annee = (Annee + 1);
          }
      
        if (Select == 4)
          {
          Heure = (Heure + 1);
          } 
        if (Heure > 23)
          {
          (Heure = 0);
          }
        if (Select == 5)
          {
          Minute = (Minute + 1);
          }
        if (Minute > 59 )
          {
          (Minute = 0);
          }
        if (Select == 6)
          {
          Seconde = (Seconde + 1);
          }
        if (Seconde > 59)
          {
          (Seconde = 0);
          }
       
        if (Select == 7)
          {
          heurM = (heurM + 1);
          }
        if (heurM < 1)
          {
          (heurM = 0);
          }
        if (heurM> 23)
          {
          (heurM = 0);
          }
       
        if (Select == 8)
          {
          minM = (minM + 1);
          }
        if (minM < 1)
          {
          (minM = 0);
          }
        if (minM >59)
          {
          (minM = 0);
          }
       
        if (Select == 9)
          {
          heurA = (heurA + 1);
          }
        if (heurA < 1)
          {
          (heurA = 0);
          }
        if (heurA> 23){ (heurA = 0);}
       
        if (Select == 10)
          {
          minA = (minA + 1);
          }
        if (minA < 1)
          {
          (minA = 0);
          }
        if (minA >59)
          {
          (minA = 0);
          }
       
        if (Select == 11)
          {
          setTemp = (setTemp + 1);
          }
        if (setTemp > 32)
          {
          (setTemp = 0);
          }
        }
        break;
   }
 }
 
 void loop()
 {
   u8g.firstPage(); 
   do
  Principal();
  while( u8g.nextPage());

 }

Modifications en cours!!

Ajout de deux touches supplémentaire pour le réglage de la consigne pour ne pas avoir a rentrer dans le menu de programmation.

Schéma de câblage en cours


Version finale





Les modifications:

  • Ajout de deux boutons pour réglage de la consigne sans entrer dans le menu mais le paramétrage en mode programmation reste
  • Consigne de température après coupure de courant 24° mini 
  • Consigne éclairage après coupure de courant 10h30 a 20h30 
  • Adjonction d'un relai d'alarme

 Le programme final (mais peut être modifié si vous avez des idées a me soumettre)



//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//
//                                                  //
//        AUTOMATE POUR AQUARIUM                   //
//        BY JOJO BRICOLO                         //
//          Sonde LM35DZ                         //
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX//



#include <U8glib.h>
#include <Wire.h>
#include <Math.h>
#include <DS1307new.h>

U8GLIB_ST7920_128X64_4X u8g(2, 5, 4);


int angles,anglem,angleh,xs, ys, xm, ym, xh, yh;
float rad;

uint16_t startAddr = 0x0000;    
uint16_t lastAddr;              
uint16_t TimeIsSet = 0xaa55;   
//
#define DDS_LOAD  12 
#define DDS_CLOCK 3
#define DDS_DATA  2

#define Touche_PIN  A0
int sensorPin = A0; 
int sensorValue = 0;
int val_key;
int Select;
int Heure;
int Minute;
int Seconde;
int Jour;
int Mois;
int Annee;

int heurM = 10;
int minM = 30;
int heurA = 20;
int minA = 30;

int val1;
int val2;
int val3;
int val4;

int setTemp = 24;
int Chauff = 11;
int eclairage = 12;
int alarme = 13;

int bplus = 5;
int bmoins = 6;

int tempsensor =A1;

float ma_tempetf=0.0;
 const uint8_t rook_bitmap[] PROGMEM = { // signe degré
  0x10,         // 00010000
  0x28,         // 00101000
  0x28,         // 00101000
  0x10,         // 00010000
  0x00,         // 00000000
  0x00,         // 00000000
  0x00,         // 00000000
  0x00          // 00000000
};  

void setup () {
 
              
  pinMode(Chauff, OUTPUT); // Relai chauffage
  pinMode (eclairage,OUTPUT); // Relai eclairage
   pinMode (alarme,OUTPUT); // Relai alarme

  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// RAM horloge
  TimeIsSet = 0xffff;
  RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t)); 
  RTC.ctrl = 0x00;    
                      
  RTC.setCTRL();

        
 u8g.setFont(u8g_font_5x8); // ecriture de base
   
  rad = ((2 * 3.1415926536) / 360);
}
//////////////////////////   Fonctions Void

 void Principal()
 {
   sensorValue = analogRead(sensorPin);
  val_key = int(sensorValue/100);     

 if  (Select == 0) 
 { 
 RTC.getTime();
 Heure = RTC.hour;
 Minute = RTC.minute;
 Seconde = RTC.second;
 Jour = RTC.day;
 Mois = RTC.month;
 Annee = RTC.year; 

  //Logo By mi
  u8g.setFont(u8g_font_timB08);
  u8g.drawStr( 50,60, " By Jojo Bricolo");
 
  ////////////////////////////////////     Affichage de l'Heure
 
   u8g.setFont(u8g_font_timB08);

  u8g.setPrintPos(56,18);
  u8g.print(Heure);
  u8g.drawStr( 68,18, "h");
  if (Minute < 10){ u8g.drawStr( 74, 18, "0");
  u8g.setPrintPos( 81, 18);
  u8g.print(Minute);}
  else
  {u8g.setPrintPos( 76, 18);
  u8g.print(Minute);} 
  u8g.drawStr( 90,17, "-");
 
  ////////// Affichage de la date
 
  u8g.setFont(u8g_font_5x7);
  {
    u8g.setPrintPos(60,8);
    u8g.print(Jour);
  }

    switch (RTC.month){
    case 1:
         u8g.drawStr( 69, 8, "Janv.");
     break;
    case 2:
         u8g.drawStr( 71, 8, "fev.");
    break;
    case 3:
        u8g.drawStr( 72, 8, "  mars");
    break;
     case 4:
        u8g.drawStr( 72, 8, " avr. ");
    break;
     case 5:
        u8g.drawStr( 73, 8, "  mai  ");
    break;
     case 6:
        u8g.drawStr( 72, 8, " juin  ");
    break;
    case 7:
        u8g.drawStr( 69, 8, "Juil.");
    break;
     case 8:
        u8g.drawStr( 72, 8, "  aout  ");
    break;
     case 9:
        u8g.drawStr( 69, 8, " sept.");
    break;
     case 10:
        u8g.drawStr( 72, 8, "oct.");
    break;
     case 11:
        u8g.drawStr( 72, 8, "nov.");
    break;
     case 12:
        u8g.drawStr( 72, 8, "dec.");
    break;
    }
  u8g.setPrintPos(96,8); //Année
  u8g.print(Annee);
 
  ///////////////////////////////////////////   Temperature  
  int reading = analogRead(tempsensor);
  float voltage = reading * 5.0 / 1024;
  float ma_tempetf = voltage * 100 ;
     
  /////////////////////////////////////// Affichage Temperature ////
  u8g.setFont(u8g_font_timB08);
  u8g.setPrintPos( 98, 18);
  u8g.print(ma_tempetf);
  u8g.drawBitmapP( 120, 11, 1, 8, rook_bitmap);
 
  //////////////////////////Commande consigne hors menu
 
  if ((val_key == 0)&&(setTemp ) <=99)
 
  {
    (setTemp ++);
    delay(100);
    }
   
     if ((setTemp)==32)
           {
       (setTemp=0);
    }
   
  if ((val_key == 5)&&(setTemp ) >=1)
  {
    (setTemp --);
    delay(100);
    } 
 
  /////////////////////////  Affichage consigne///////////////////////////////////////////////////
   
  u8g.setFont(u8g_font_4x6);
  u8g.drawStr( 64, 50,"Consigne");
  u8g.setPrintPos( 111, 50);
  u8g.print(setTemp);
  u8g.drawBitmapP( 120, 44, 1, 8, rook_bitmap);
   
  ////////////// Commade chauffage
 
   u8g.setFont(u8g_font_4x6);
   if (ma_tempetf > setTemp)
    {
    digitalWrite(Chauff, LOW);
    u8g.drawStr( 65, 35,"Chauff Arret");
   
    }
  if (ma_tempetf <= (setTemp-0.5))
    {
    digitalWrite(Chauff, HIGH);
    u8g.drawStr( 65, 35,"Chauff Marche");
    }
 
  /////////////////////// Commande eclairage
  val1 = (Heure*100)+Minute;
  val2 = (heurM*100)+minM;
  val3 = (heurA*100)+minA-1;
   
  if ((val1 >= val2) && (val1 <= val3))
   {
    digitalWrite(eclairage, HIGH);
  }
     else
    
  {
  digitalWrite(eclairage, LOW);
  }
  ////////////////////// Affichage consignes éclarage
  u8g.setFont(u8g_font_4x6);
  u8g.drawStr( 56, 26,"Ecl");
  u8g.setPrintPos( 71, 26);
  u8g.print(heurM);
  u8g.drawStr( 80, 26,"h");
  u8g.setPrintPos( 85, 26);
  u8g.print(minM);
 
  //u8g.setFont(u8g_font_5x8);
  u8g.drawStr( 96, 26,"a");
  u8g.setPrintPos( 103, 26);
  u8g.print(heurA);
  u8g.drawStr( 113, 26,"h");
  u8g.setPrintPos( 118, 26);
  u8g.print(minA);
 
  //////////////////  Affichage alarme température
 
   u8g.setFont(u8g_font_4x6);
  
   if (ma_tempetf > (setTemp + 2))
   {
  u8g.drawStr( 59, 43,"Temperature Haute");
  digitalWrite (alarme,HIGH);
  }
  else
 
  if (ma_tempetf < (setTemp - 2))
   {
  u8g.drawStr( 59, 43,"Temperature Basse");
  digitalWrite (alarme,HIGH);
  }
  else
  {
  u8g.drawStr( 59, 43,"Temperature OK");
  digitalWrite (alarme,LOW);
  }

 }
  /////////////////////////////// Horloge analogique
  angles = (Seconde * 6)-90; 
  anglem = (Minute * 6)-90; 
  angleh = ((Heure * 30)-90) + ((anglem/12)+6);
  Serial.println (angleh);
 
  u8g.drawCircle(31,32,21);
  u8g.drawCircle(31,32,19);
  
  u8g.setFont(u8g_font_micro);
  u8g.drawStr( 54, 35, "3");
  u8g.drawStr( 30, 60, "6");
  u8g.drawStr( 5, 35, "9");
  u8g.drawStr( 28, 10, "12");
 
  u8g.drawStr( 40, 16, "."); //1
  u8g.drawStr( 47, 24, "."); //2
  u8g.drawStr( 50, 33, "."); //3
  u8g.drawStr( 47, 42, ".");  //4
  u8g.drawStr( 41, 50, ".");  //5
  u8g.drawStr( 31, 53, ".");  //6
  u8g.drawStr( 21, 50, ".");  //7
  u8g.drawStr( 14, 42, ".");  //8
  u8g.drawStr( 11, 33, ".");  //9
  u8g.drawStr( 14, 24, ".");  //10
  u8g.drawStr( 21, 16, ".");  //11
  u8g.drawStr( 31, 14, "."); //12

  xs = 31 + (cos(angles * rad)*18);
  ys = 32 + (sin(angles * rad)*18);
  u8g.drawLine(31, 32, xs, ys);

  
   xm = 31 + (cos(anglem * rad)*16);
   ym = 32 + (sin(anglem * rad)*16);
   u8g.drawLine(31, 32, xm, ym);
   u8g.drawLine(32, 31, xm, ym);
   
    
   xh = 31 + (cos(angleh * rad)*10);
   yh = 32 + (sin(angleh * rad)*10);
   u8g.drawLine(31, 32, xh, yh);
   u8g.drawLine(32, 31, xh, yh);

//////////////////////////////////////  Menu et règlages
  
  if ((Select > 0) and (Select < 13))
  {
  u8g.drawStr(80,8,"REGLAGES");
   
  if (Jour < 10) 
  {
  u8g.drawStr( 73, 15, "0");
  u8g.setPrintPos(77,15);
  u8g.print(Jour);
  }
  else
  {
  u8g.setPrintPos(73,15);
  u8g.print(Jour);
  }
 
  u8g.drawStr( 83,15, ":"); 

  if (Mois < 10)
  { 
  u8g.drawStr( 89, 15, "0");
  u8g.setPrintPos( 94, 15);
  u8g.print(Mois);
  }
    else
  {
  u8g.setPrintPos(89,15);
  u8g.print(Mois);
  }
 
  u8g.drawStr( 100, 15, ":");
 
  u8g.setPrintPos( 105, 15);
  u8g.print(Annee);
 
  //xxxxxxxxxxxxxxxxxxxx

  if (Heure < 10)
  {  
  u8g.drawStr( 78, 25, "0");
  u8g.setPrintPos(82,25);
  u8g.print(Heure);
  }
  else
  {
  u8g.setPrintPos(78,25);
  u8g.print(Heure);
  }
 
  u8g.drawStr( 88,25, ":");
 
  if (Minute < 10)
  {  
  u8g.drawStr(93, 25, "0");
  u8g.setPrintPos( 98, 25);
  u8g.print(Minute);
  }
  else
  {
  u8g.setPrintPos( 93, 25);
  u8g.print(Minute);
  } 
 
  u8g.drawStr( 105, 25, ":");
 
  if (Seconde < 10)
  {  
  u8g.drawStr(110, 25, "0");
  u8g.setPrintPos( 115, 25);
  u8g.print(Seconde);
  }
  else
  {
    u8g.setPrintPos( 110, 25);
    u8g.print(Seconde);
  }

  //xxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
  u8g.drawStr(65,35,"Marche");
  {
  u8g.setPrintPos( 100, 35);
  u8g.print(heurM);
  }
 
  u8g.drawStr( 110, 35, ":");
  {
  u8g.setPrintPos( 115, 35);
  u8g.print(minM);
  }
 
  u8g.drawStr(65,45,"Arret");
  {
  u8g.setPrintPos( 100, 45);
  u8g.print(heurA);
  }
 
  u8g.drawStr( 110, 45, ":");
 
  {
  u8g.setPrintPos( 115, 45);
  u8g.print(minA);
  }
 
  u8g.drawStr(65,55,"Consigne");
  {
  u8g.setPrintPos( 105, 55);
  u8g.print(setTemp);
  }
  u8g.drawBitmapP( 113, 50, 1, 8, rook_bitmap);
 
  }
 
  val_key = 0;                        
  sensorValue = analogRead(sensorPin);
  val_key = int(sensorValue/100);     

//////////////////////////////////////////////   Selection des reglages

   switch (val_key)
       {
          case 7 :
       {
         Select = (Select + 1);
         delay (200);
        }
         break;
       }     
         
        if (Select == 1) u8g.drawStr(65,62," Reglage jour");
  
        if (Select == 2) u8g.drawStr(65,62," Reglage mois");

        if (Select == 3) u8g.drawStr(65,62," Reglage annee");

        if (Select == 4) u8g.drawStr(65,62,"Reglage heures");

        if (Select == 5) u8g.drawStr(65,62,"Reglage minutes");

        if (Select == 6) u8g.drawStr(65,62,"Reglage Secondes");
       
        if (Select == 7) u8g.drawStr(65,62,"Heure marche");
       
        if (Select == 8) u8g.drawStr(65,62,"Minutes marche");
       
        if (Select == 9) u8g.drawStr(65,62,"Heure arret");
       
        if (Select == 10) u8g.drawStr(65,62,"Minutes arret");
       
        if (Select == 11) u8g.drawStr(45,62, "Consigne temperature");
       
        if (Select == 12) u8g.drawStr(65,62, "Enregistrer !");
 
        if (Select == 13)
        {
           (Select = 0);
            RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Entrée startAddr dans NV-RAM address 0x08
            TimeIsSet = 0xffff;
            RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));        
            if (TimeIsSet != 0xaa55)
            {
             RTC.stopClock();       
             RTC.fillByYMD(Annee,Mois,Jour);
             RTC.fillByHMS(Heure,Minute,Seconde);
   
             RTC.setTime();
             TimeIsSet = 0xaa55;
             RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
             RTC.startClock();
            }
            else
            {
             RTC.getTime();
            } 
          
       }
   //////////////// Touches +/-        
   switch (val_key)
 
       {  
   case 3://-
        {   
        delay (200);    
        if (Select == 1)
          {
            Jour = (Jour - 1);
          } 
        if (Jour < 1)
          {
          (Jour = 31);
          }
        if (Select == 2)
          {
          Mois = (Mois - 1);
          }
        if (Mois < 1)
          {
          (Mois = 12);
          }
        if (Select == 3)
          {
          Annee = (Annee - 1);
          }
      
        if (Select == 4)
          {
          Heure = (Heure - 1);
          } 
        if (Heure < 1)
          {
           (Heure = 23);
          }
        if (Select == 5)
          {
          Minute = (Minute - 1);
          }
        if (Minute < 1)
          {(
            Minute = 59);
          }
        if (Select == 6)
          {
          Seconde = (Seconde - 1);
          }
        if (Seconde < 1)
          {
          (Seconde = 59);
          }
       
        if (Select == 7)
          {
          heurM = (heurM - 1);
          }
        if (heurM < 1)
          {
          (heurM = 0);
          }
        if (heurM > 23)
          {
          (heurM = 0);
          }
       
        if (Select == 8)
          {
            minM = (minM - 1);
          }
        if (minM < 1)
          {
          (minM = 0);
          }
        if (minM >59)
          {
          (minM = 0);
          }
       
        if (Select == 9)
          {
          heurA = (heurA - 1);
          }
        if (heurA < 1)
          {
            (heurA = 0);
          }
        if (heurA> 23)
          {
          (heurA = 0);
          }
       
        if (Select == 10)
          {
          minA = (minA - 1);
          }
        if (minA < 1)
          {
          (minA = 0);
          }
        if (minA >59)
          {
          (minA = 0);
          }
       
        if (Select == 11)
          {
          setTemp = (setTemp - 1);
          }
        if (setTemp > 32)
          {
          (setTemp = 0);
          }   
        }
        break;
       
  case 1: //+
        {
         delay (200);
        if (Select == 1)
          {
          Jour = (Jour + 1);
          } 
        if (Jour > 31)
          {
          (Jour = 1);
          }
        if (Select == 2)
          {
          Mois = (Mois + 1);
          }
        if (Mois > 12)
          {
          (Mois = 1);
          }
        if (Select == 3)
          {
          Annee = (Annee + 1);
          }
      
        if (Select == 4)
          {
          Heure = (Heure + 1);
          } 
        if (Heure > 23)
          {
          (Heure = 0);
          }
        if (Select == 5)
          {
          Minute = (Minute + 1);
          }
        if (Minute > 59 )
          {
          (Minute = 0);
          }
        if (Select == 6)
          {
          Seconde = (Seconde + 1);
          }
        if (Seconde > 59)
          {
          (Seconde = 0);
          }
       
        if (Select == 7)
          {
          heurM = (heurM + 1);
          }
        if (heurM < 1)
          {
          (heurM = 0);
          }
        if (heurM> 23)
          {
          (heurM = 0);
          }
       
        if (Select == 8)
          {
          minM = (minM + 1);
          }
        if (minM < 1)
          {
          (minM = 0);
          }
        if (minM >59)
          {
          (minM = 0);
          }
       
        if (Select == 9)
          {
          heurA = (heurA + 1);
          }
        if (heurA < 1)
          {
          (heurA = 0);
          }
        if (heurA> 23){ (heurA = 0);}
       
        if (Select == 10)
          {
          minA = (minA + 1);
          }
        if (minA < 1)
          {
          (minA = 0);
          }
        if (minA >59)
          {
          (minA = 0);
          }
       
        if (Select == 11)
          {
          setTemp = (setTemp + 1);
          }
        if (setTemp > 32)
          {
          (setTemp = 0);
          }
        }
        break;
   }
 }
 
 void loop()
 {
   u8g.firstPage(); 
   do
  Principal();
  while( u8g.nextPage());

 }

Le schéma


Le câblage du clavier


Schéma trouvé sur le net!



dimanche 4 mai 2014

Régulation en température d'une vanne 3 voies


Le principe de cette régulation est assez simple,  la vanne s'ouvre ou se ferme suivant une consigne de température une fois celle-ci atteinte, elle s'arrête. Le consigne sera donnée par un potentiomètre multi-tours de 10Kohms et la mesure de température se fera a l'aide d'un LM35Z

Le moteur étant piloté en ouverte et fermeture, j'ai donc mis deux relais.

Il est prévu un affichage LCD indiquant
  •  la température de consigne 
  • la température de sortie 
  • l'état de la vanne (ouverture, fermeture ou arrêt).
  • le débit en L/min

Le schéma

 Comme toujours, avec arduino rien de compliqué !!!!

Les transistors sont des BC 547, les résistances pour la base des 1Kohms et les relais sont en 5V.


Le débitmètre est un modèle a effet hall, une impulsion représente 2,25ml.

Le programme

Le programme est assez simple, si on retire la partie gestion de la vanne, cela se résume a une trentaine lignes.

/*
**
** Debit Meter
**
** http://www.arduino-creations.blogspot.fr
*/

#include "Debit.h"
#include "LiquidCrystal.h"

LiquidCrystal lcd(3, 4, 5, 6, 7, 8);
int sensorPin = A0;
int PotPin = A1;    // Entree potentiometre 10K
int PotValue = 0;  // variable de stockage consigne
int setTemp = 0; // variable de stockage sonde
int Vouv = 11;
int Vfer = 12;

const byte pinDebitMeter = 2;    // Broche d'entrée du detecteur de débit
const byte numInterrupt = 0;    // Interruption
const int period = 100;        // Periode de base en millisecondes 1000

const float CoefLitMin = 7.4;


// Declaration du débimetre
Debit myDebit(numInterrupt, pinDebitMeter, period);


void setup() {
  myDebit.begin();         // Initialisation du comptage pour le bébimètre
 
    lcd.begin(20, 4);
    lcd.setCursor(4,1);
    lcd.print("  Mitigeur");
    lcd.setCursor(0,2);
    lcd.print("     Jojo  ");
    lcd.setCursor(0,3);
    lcd.print("      Bricolo  ");
    delay(4000);
    lcd.clear();
}

void loop() {
 
delay(10);
 
   int reading = analogRead(sensorPin); 
  float voltage = reading * 4.5 / 1024;
  int temp = voltage * 1000 ;
 
  //Récupération de la valeur du potentiomètre //******************************************************
  PotValue = analogRead(PotPin); 
 
  setTemp = PotValue / 10.24; //Parametre consigne de 0 a 99 degres ici je n'utilise pas la fonction MAP car une simple division suffit.
 
  lcd.setCursor(0,0);
  lcd.print("Temperature : ");
  delay(10);
  lcd.print(temp);
  lcd.print("C ");
 
  // Affichage de la consigne *********************************************
 lcd.setCursor(0,1);
  lcd.print("Consigne    : ");
  delay(10);
  lcd.print(setTemp);
  lcd.print("C ");  

  myDebit.operate();       // Comptage
 
    if ((myDebit.DebiRate25Period()) == 0)
    {
     lcd.setCursor(0,2);
  lcd.print("Debit : ");

  lcd.print("0.00");
  lcd.print(" l/min ");
  }
    else
    {
   lcd.setCursor(0,2);
  lcd.print("Debit :  ");
  lcd.print(CoefLitMin * myDebit.DebiRate25Period(), 2);
  lcd.print(" l/mn ");
 }

 

 if (temp < setTemp)
{
 digitalWrite (Vouv,HIGH);
 digitalWrite (Vfer,LOW);
  lcd.setCursor(0,3);
  lcd.print("Ouverture vanne  ");
 }

 else

   if (temp > setTemp)
{
 digitalWrite (Vouv,LOW);
 digitalWrite (Vfer,HIGH);
   lcd.setCursor(0,3);
  lcd.print("Fermeture vanne  ");
 }
  else

  if (temp == setTemp)
{
 digitalWrite (Vouv,LOW);
 digitalWrite (Vfer,LOW);
  lcd.setCursor(0,3);
  lcd.print("Arret vanne    ");
  }
 

  delay(100);
}


ATTENTION !!!! Pour faire fonctionner ce programme, il vous faut la librairie Debit.h que j'ai crée. Si ce montage vous intéresse, je vous envoie celle-ci.

Le lien ci-dessous est un essai, merci de me dire si cela fonctionne car avec Blogger, on ne peut pas héberger des fichiers

Téléchargement


Si cela vous intéresse, je suis en mesure de vous faire un kit ou même vous réaliser ce montage !!!
N'hésitez pas a me contacter.

jeudi 27 mars 2014

CNC avec Arduino et GRBL

Je vous propose de vous donner quelques tuyaux pour la réalisation d'une CNC avec Arduino et GRBL.  J'ai déjà réalisé ma CNC, mon graveur laser et mon imprimante 3D e vous mettrait donc quelques photos.

La mécanique


Concernant la partie mécanique, je pense que vous avez tous votre idée et surement un budget.
Voici des idées de montage

Ma première CNC bois, alu et tôle



(ne faites pas attention au bordel lol)

Pour la réalisation de celle-ci, j'ai utilisé des coulisses de tiroirs supportant 35Kgrs, des tiges filetées standard de 8, des moteurs NEMA 23 basiques et des 2M542 et drivers. La broche est une KRESS FME1, malgré une ossature et des guides pas vraiment prévus pour ce genre d'utilisation, j'ai fait des tas de choses comme la structure de mon laser en plexy.

Quelques réalisations avec cette machine



Voici quelques détails mécaniques de ma dernière fraiseuse CNC




























Désolé pour les clopes lol !!!








J'éspère que cela va vous donner des idées !!!

L'électronique


Le choix concernant cette partie est assez délicat car les drivers doivent supporter la puissance des moteurs, certains drivers ont tendance a sauter des pas lorsque la machine force un peu.
Voici le modèles les plus répandus pour arduino

Très connu, il est constitué d'un circuit ULN2003 qui ne sert qu'a permettre a Arduino de piloter des sorties jusqu'a 500mA.
Le code permute les deux enroulement l'un après l'autre a une certaine fréquence. On peut réaliser des choses sympa mais ne conviens pas pour une CNC.


Celui-ci est semblable a celui-ci dessus mais plus puissant donc idem pas top pour une CNC a moins de lui adjoindre un deuxième module.



Easy driver est déjà un bon départ pour des petits moteurs jusqu'a 0.7A. Il est composé d'un circuit de puissance et permet de gérer les moteurs pas a pas avec simplement deux fils DIR et STEPS

Le dernier né qu'on retrouve actuellement un peu partout et surtout sur les imprimantes 3D. Il existe également avec un petit dissipateur de température. Malgré sa petite taille, il permet de piloter des moteurs jusqu’à 2A.


Pour ce dernier driver, il existe des cartes qui sont en fait des supports et adaptation pour carte Arduino MEGA, celle-ci évite simplement le câblage a réaliser entre les drivers et l'Arduino. Sur la photo on voit les drivers enfichés dessus et la MEGA en-dessous.


Un exemple de câblage de moteur avec easydriver





Nous verrons un peu plus tard les programmes de pilotage des moteurs pas a pas avec Arduino.
Allons directement a la partie la plus intéressante de ce sujet.


Le schéma de câblage

Ici, nous ne sommes pas dans le cas d'une imprimante 3D qui gère les différents élements chauffants ainsi que le moteur de l'extrudeur. Une carte UNO suffit donc amplement. pour la gestion de moteurs et fins de courses.



J'utilise des drivers A4988 avec des moteurs NEMA 17. Comme vous pouvez le constater, il n'y a pas beaucoup de câblage a réaliser. J'ai réalisé un petit circuit imprimé du style shield qui va s'enficher directement sur la carte UNO.


Le typon









Un petit double face et le tour est joué.

Programme

Test de GRBL

Dans la vidéo ci-dessous, vous pouvez voir le fonctionnement ( ce montage a été réalisé pour un laser donc pas de Z), la led représente le fonctionnement du laser.



Des tas de questions et problèmes !!

1) Le meilleur compromis pour le pilotage de la CNC avec GRBL est GRBLcontroler, je l'utilise depuis quelques années maintenant et je n'ai jamais eu de problèmes. La version la mieux aboutie est la 3.6.1

2) Pour configurer la machine, ne pas passer par le mode configuration de GRBLcontroler car souvent les paramètre ne sont pas envoyés dans la mémoire flash de l'arduino. Préférer d'envoyer les paramètres un par un en ligne de commande.

exemple : $0 = 40   (pas par mm axe x) etc....