Micros et PicosPico Arduino/Raspberry Pi

Les constructions maison de micro, pico, nano brasseries... de nos leonard de vinci en herbe !
Règles du forum
Chers membres, merci de prendre connaissance et respecter les quelques règles de bon sens suivantes avant de poster votre message :
- Vous assurer que vous postez dans la bonne rubrique
- Vérifier qu'il n’existe pas déjà une réponse à votre question ou un sujet identique
- Prendre conscience que vos propos n’engagent que vous et que vous devrez en assumer la paternité
- Vérifier les sources des informations que vous diffusez, en vous assurant le cas échéant de respecter les droits d’auteur qui peuvent être liés aux informations, images ou documents cités
- Prendre soin de respecter vos interlocuteurs et bannir les insultes et autres propos diffamatoires ou dégradants
- Vous assurer de rester autant que faire se peut dans le sujet exposé
- Prendre le temps de vérifier l’orthographe et la grammaire de votre message
Merci par avance de votre contribution à préserver le bon esprit de ce forum.
Avatar de l’utilisateur
Penn-Maen
Maître Brasseur
Maître Brasseur
Messages : 12678
Inscrit depuis : 14 ans 2 mois
Je suis tuteur : oui
Mon équipement : viewtopic.php?t=39535
Miss Vilaine ¯\_(ツ)_/¯
Brasseur : Amateur
Localisation : Morbihan centre
1 recettes partagées
A remercié : 777 fois
A été remercié : 1473 fois

Re: Pico Arduino/Raspberry Pi

Message par Penn-Maen »

en tant que logiciel open source (donc gratuit dans notre cas)
il ne faut pas confondre open-source et freeware... Beaucoup des softs open-source sont freeware, l'inverse est moins vrai. Et il peut y avoir des softs opensource payants (peut-être pas le soft en soi, mais on te fait payer une assistance ou un "bonus" : exemple Mandriva qui, a une époque, distribuait des versions boites avec un bon gros "guide utilisateur" pour une 30aines d'euro - je ne sais pas s'ils le font encore).

Il me semble même que UNIX est/était payant, que ça coute/coutait une blinde, et que c'est pour cela que Torvalds a développé GNU/Linux, 100% compatible UNIX mais open-source (c'est peut-être une légende, je n'en sais rien)
Regarde, écoute, questionne, apprend, transmet, recommence sans cesse
Disclaimer : je dis certainement plus de conneries que la moyenne, alors vérifiez !

SE PRESENTER ...et... Guide pour débutants
Avatar de l’utilisateur
kenypixel
Arpette
Arpette
Messages : 396
Inscrit depuis : 13 ans 10 mois
Mon équipement : Grainfather 20L
Moulin 3 rouleaux
Frigo thermos-reguler
Pleins d'autres trucs....
Kegerator
5 Kegs 19L
Microscope
Erlen toutes tailles..
Etc...
Brasseur : Amateur
Localisation : Paris
A remercié : 13 fois
A été remercié : 15 fois

Re: Pico Arduino/Raspberry Pi

Message par kenypixel »

Oui je suis totalement d'accord avec toi, mais je me suis mal exprimé. J'avais consciemment m'y "dans notre cas" pour expliquer la gratuité du soft, mais je reconnais que c'est sujet à diverses interprétations :mrgreen:
Avatar de l’utilisateur
Le nain brasseur
Maître Brasseur
Maître Brasseur
Messages : 8015
Inscrit depuis : 20 ans 8 mois
Mon équipement : Grainfather 30L
Brasseur : Amateur
Localisation : Noisy le Grand
A remercié : 96 fois
A été remercié : 250 fois

Re: Pico Arduino/Raspberry Pi

Message par Le nain brasseur »

Un collègue m'a parlé d'un site où un brassam allemand explique son install Raspberry Pi

http://www.fangobräu.de/raspio.shtml
http://fangobräu.de/web20mash.shtml

Je ne sais pas si ça peut aider, mais au cas où.
Le site du Nain : http://univers-biere.net
TheDude
Ch'ti nouveau
Messages : 27
Inscrit depuis : 16 ans 5 mois
Brasseur : Amateur
Localisation : Thionville
A été remercié : 2 fois

Re: Pico Arduino/Raspberry Pi

Message par TheDude »

Allez-hop!!!
Vu que le projet open source n'a pas encore démarré et qu'il sera surement différent de ce que j'ai fait, voilà les codes de ma pico :wink:
Ça fonctionne chez moi mais vu que j'ai jamais pris de cours de programmation, ça risque de piquer les yeux :lol:

Code Arduino

Code : Tout sélectionner

#include <avr/wdt.h>
#include <CmdMessenger.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <PID_v1.h>
#include <TimerOne.h>

#define DS18B20 0x28     // Famille 1-Wire du DS18B20
#define PIN_ONEWIRE 12 // Broche utilisée pour le bus 1-Wire
#define TEMPERATURE_PRECISION 11// entre 9 et 12
#define RelayPin 10
#define Pompe_1_Pin 9
#define Pompe_2_Pin 8

int nb_paliers = 0;
int Temperatures[5];
unsigned long Temps[5]; 
unsigned long start_time;
unsigned long logtimer;
boolean palier_actif = 0;
int palier_en_cours = 0;
int mode = 0;                 // 0:init  1:Auto  2:Manu  3:Ebu
boolean pompe_1 = false;
boolean pompe_2 = false;
double power = 0;

int TimerInterrupt = 15000;   //requête d'interruption toute les 15000 ms
int WindowSize = 2000;        //fenêtre de sortie relais 2000ms
unsigned long windowStartTime;
volatile double OutputRelay;

//Variables du PID
double Setpoint, Input, Output;

//définition des pointeurs et des paramètres du PID
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

// initialisation du lcd
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

//adresses des capteurs
DeviceAddress Capteur_Mash_In = {0x28, 0x55, 0x6A, 0x23, 0x05, 0x00, 0x00, 0xBA};
//DeviceAddress Capteur_2 = {0x28, 0x56, 0x64, 0x23, 0x05, 0x00, 0x00, 0x41};
DeviceAddress Capteur_Mash_Out = {0x28, 0x63, 0xC1, 0x23, 0x05, 0x00, 0x00, 0xA6};
//DeviceAddress Capteur_4 = {0x28, 0xAE, 0x56, 0x23, 0x05, 0x00, 0x00, 0x95};
DeviceAddress Capteur_Ebu = {0x28, 0xBF, 0xF6, 0x23, 0x05, 0x00, 0x00, 0xCA};
//DeviceAddress Capteur_6 = {0x28, 0x06, 0x84, 0x23, 0x05, 0x00, 0x00, 0xB5};

OneWire Bus_Temperature(PIN_ONEWIRE); // Création de l'objet OneWire Bus_Temperature

DallasTemperature Capteurs_Temperature(&Bus_Temperature); // Passage de la référence du Bus OneWire à DallasTemperature


// rattachement de CmdMessenger au port série
// CmdMessenger cmdMessenger = CmdMessenger(Serial, '$', ';', '/');
CmdMessenger cmdMessenger = CmdMessenger(Serial);

// Liste des commandes (envoyées ou reçues). 
// Pour les commandes reçues, il faut attacher un callback
enum
{
  // Commandes
  kAcknowledge ,  // 0 Command de vérif de réception de données
  kError ,        // 1 Command de report d'erreurs
  kLoadProcess ,  // 2 Commande de chargement des paramètres du process
  kAuto ,         // 3 Commande mode automatique
  kManu ,         // 4 Commande mode manuel
  kPompe,         // 5 Commande pompe
  kMode      ,    // 6 Commande mode
  kEbu ,          // 7 Commande ébullition
  kStop ,         // 8 Commande Stop
  kLog ,          // 9 Commande de log
  
};

// Commandes envoyées du Raspberry vers l'Arduino.
void attachCommandCallbacks()
{
  // rattachement des commandes aux callbacks
  cmdMessenger.attach(OnUnknownCommand);
  cmdMessenger.attach(kLoadProcess, OnLoadProcess);  // 2
  cmdMessenger.attach(kAuto, OnAuto);                // 3
  cmdMessenger.attach(kManu, OnManu);                // 4
  cmdMessenger.attach(kPompe, OnPompe);              // 5
//  cmdMessenger.attach(kMode, OnMode);                // 6
  cmdMessenger.attach(kEbu, OnEbu);                  // 7
  cmdMessenger.attach(kStop, OnStop);                // 8
//  cmdMessenger.attach(kLog, OnLog);                  // 9
}


// ------------------  C A L L B A C K S -----------------------

// Appelées quand une commande est reçue

void OnUnknownCommand()
{
  cmdMessenger.sendCmdStart(kError);
  cmdMessenger.sendCmdArg("Commande inconnue");
  cmdMessenger.sendCmdArg("");
  cmdMessenger.sendCmdEnd();}

// Boot terminé
void OnArduinoReady()
{
  cmdMessenger.sendCmdStart(kAcknowledge);
  cmdMessenger.sendCmdArg("Arduino ready");
  cmdMessenger.sendCmdArg("");
  cmdMessenger.sendCmdEnd();
}

void OnLoadProcess()  //2
{
  // Recup du nombre de paliers
    nb_paliers  = cmdMessenger.readIntArg();

  // Recup des températures
  for (int i=0; i< nb_paliers; i++){
    Temperatures[i]= cmdMessenger.readIntArg();
  }
  
  // Recup des temps
  for (int i=0; i< nb_paliers; i++){
    Temps[i]= cmdMessenger.readIntArg();
  }
 
  cmdMessenger.sendCmdStart(kLoadProcess); //log "load process ok"
  cmdMessenger.sendCmdArg("Load process");
  cmdMessenger.sendCmdArg("OK");
  cmdMessenger.sendCmdEnd();
}

void OnAuto()  //3
{
  noInterrupts();
  mode = 1;
  lcd.clear();
  lcd.home();
  lcd.print("Auto  ");
  lcd.setCursor(4,1);
  lcd.print(char(223));
  lcd.print("C");
  lcd.setCursor(14,1);
  lcd.print(char(223));
  lcd.print("C");
  
  cmdMessenger.sendCmdStart(kMode); // log mode auto
  cmdMessenger.sendCmdArg("Auto");
  cmdMessenger.sendCmdArg("");
  cmdMessenger.sendCmdEnd();
}

void OnManu()  //4
{
  noInterrupts();
  mode = 2;
  Setpoint = cmdMessenger.readIntArg();
  lcd.home();
  lcd.print("Manuel");
  lcd.setCursor(10,1);
  lcd.print(Setpoint,1);
  
  cmdMessenger.sendCmdStart(kMode); //log mode manu , consigne
  cmdMessenger.sendCmdArg("Manu");
  cmdMessenger.sendCmdArg(Setpoint);
  cmdMessenger.sendCmdEnd();
}

void OnPompe()  //5
{
  noInterrupts();
  switch (cmdMessenger.readIntArg()){
    case 1:
      pompe_1 = !pompe_1;
      cmdMessenger.sendCmdStart(kPompe); //log état de la pompe 1
      cmdMessenger.sendCmdArg("pompe_1");
      cmdMessenger.sendCmdArg(pompe_1);
      cmdMessenger.sendCmdEnd();
      digitalWrite(Pompe_1_Pin, pompe_1);
    break;
    case 2: 
      pompe_2 = !pompe_2;
      cmdMessenger.sendCmdStart(kPompe); //log état de la pompe 2
      cmdMessenger.sendCmdArg("pompe_2");
      cmdMessenger.sendCmdArg(pompe_2);
      cmdMessenger.sendCmdEnd();
      digitalWrite(Pompe_2_Pin, pompe_2);
    break;      
  }
}

void OnEbu()  //7
{
  noInterrupts();
  mode = 3;
  power = cmdMessenger.readIntArg();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Puissance ");
  lcd.print((int)power);
  lcd.print("%");

  OutputRelay = power/100*WindowSize; //sortie relais 0-100% de windowsize
//  lcd.setCursor(0,1);
//  lcd.print(OutputRelay);


  cmdMessenger.sendCmdStart(kMode);
  cmdMessenger.sendCmdArg("Ebu");
  cmdMessenger.sendCmdArg(power);
  cmdMessenger.sendCmdEnd();
  
}

void OnStop()  //8
{
  noInterrupts();
  stopprg ();
}


/***************************************************************/

void setup() {
  
  pinMode(Pompe_1_Pin, OUTPUT);      
  pinMode(Pompe_2_Pin, OUTPUT);      
  pinMode(RelayPin, OUTPUT);      
  
  Serial.begin(9600); // Initialisation du port série
//  while (!Serial){} //attente serial monitor debug (bug leonardo)
  
  // ajoute une nouvelle ligne à chaque commande
  cmdMessenger.printLfCr();   

  // Rattachement des callbacks
  attachCommandCallbacks();

//  Envoi l'etat de l'arduino (boot Ok)
//  cmdMessenger.sendCmdStart(kAcknowledge);
//  cmdMessenger.sendCmdArg("Arduino has started!");
//  cmdMessenger.sendCmdArg("");
//  cmdMessenger.sendCmdEnd(); 
  
  lcd.begin(16, 2); // Création du LCD (nombre de colonnes et de lignes)

  Capteurs_Temperature.begin(); // Initialisation des capteurs de température
    
  Capteurs_Temperature.setResolution(Capteur_Mash_In, TEMPERATURE_PRECISION);
  Capteurs_Temperature.setResolution(Capteur_Mash_Out, TEMPERATURE_PRECISION);
  Capteurs_Temperature.setResolution(Capteur_Ebu, TEMPERATURE_PRECISION);
//  Capteurs_Temperature.setResolution(Capteur_2, TEMPERATURE_PRECISION); 
//  Capteurs_Temperature.setResolution(Capteur_3, TEMPERATURE_PRECISION); 
  
//  Serial.println(Capteurs_Temperature.getResolution(Capteur_Mash_In), DEC);
//  Serial.println(Capteurs_Temperature.getResolution(Capteur_Mash_Out), DEC);
//  Serial.println(Capteurs_Temperature.getResolution(Capteur_2), DEC);
//  Serial.println(Capteurs_Temperature.getResolution(Capteur_3), DEC);
//  
//  Serial.print("Parasite power is: "); 
//  if (Capteurs_Temperature.isParasitePowerMode()) Serial.println("ON");
//  else Serial.println("OFF");
  
    lcd.clear();
    lcd.setCursor(2,0);
    lcd.print("votre brasserie");
    lcd.setCursor(0,1);
    lcd.print("Attente process.");
    
do
{   
  if (nb_paliers > 0){
    affichage_process(1500, 1500);
  }
  // traite les entrées sur le port série et lance les callbacks
  cmdMessenger.feedinSerialData();
  
} while (mode == 0);
  
  if (mode != 3){
//    for (int i=1; i<nb_paliers; i++){
//      Temps[i]+=Temps[i-1];
//    }

  // sortie du PID entre 0 et WindowSize
  myPID.SetOutputLimits(0, WindowSize);

  // démarrage du PID
  myPID.SetMode(AUTOMATIC);
  }

  cmdMessenger.sendCmdStart(kPompe); //log état de la pompe 1
  cmdMessenger.sendCmdArg("pompe_1");
  cmdMessenger.sendCmdArg(pompe_1);
  cmdMessenger.sendCmdEnd();
  
  cmdMessenger.sendCmdStart(kPompe); //log état de la pompe 2
  cmdMessenger.sendCmdArg("pompe_2");
  cmdMessenger.sendCmdArg(pompe_2);
  cmdMessenger.sendCmdEnd();

  start_time = millis();
  logtimer = millis();
  windowStartTime = millis();

  Timer1.initialize(TimerInterrupt);
  Timer1.attachInterrupt(DriveOutput);

}

/***************************************************************/

void loop() {
  
  //Récupération de températures  
  Capteurs_Temperature.requestTemperatures();
  float Temp_Mash_In = Capteurs_Temperature.getTempC(Capteur_Mash_In);
  float Temp_Mash_Out = Capteurs_Temperature.getTempC(Capteur_Mash_Out);
  float Temp_Ebu = Capteurs_Temperature.getTempC(Capteur_Ebu);

  // traite les entrées sur le port série et lance les callbacks
    noInterrupts();
   cmdMessenger.feedinSerialData();
    interrupts();

  if (mode == 1){  // Mode Auto
    Setpoint = Temperatures[palier_en_cours];
    
    lcd.setCursor(0,1);
    lcd.print(Temp_Mash_In,1);
    lcd.setCursor(10,1);
    lcd.print(Setpoint,1);
    
//    if ((millis()-start_time)/1000 > Temps[palier_en_cours]*60){
//      palier_en_cours++;
//    }

    if (Temp_Mash_In > Temperatures[palier_en_cours] && palier_actif ==0 ){
      palier_actif = 1;
      Temps[palier_en_cours] = Temps[palier_en_cours]*60000 + millis();
    }
    if (millis() > Temps[palier_en_cours] && palier_actif == 1){
     palier_actif = 0;
     palier_en_cours++;
    }   
      
    if (palier_en_cours >= nb_paliers){
      stopprg();
    }
  
    Input = Temp_Mash_In;
    myPID.Compute();
    noInterrupts();
    temperature_log(Temp_Mash_In, Temp_Mash_Out, Setpoint, 1000);
    OutputRelay = Output;
    interrupts();
  }  


  if (mode == 2){   // Mode Manu
    lcd.setCursor(0,1);
    lcd.print(Temp_Mash_In,1);
    
//    if ((millis()-start_time)/1000 > Temps[palier_en_cours]*60){
//      palier_en_cours++;
//    }
    if (Temp_Mash_In > Temperatures[palier_en_cours] && palier_actif ==0 ){
      palier_actif = 1;
      Temps[palier_en_cours] = Temps[palier_en_cours]*60000 + millis();
    }
    if (millis() > Temps[palier_en_cours] && palier_actif == 1){
     palier_actif = 0;
     palier_en_cours++;
    }     
  
      Input = Temp_Mash_In;
      myPID.Compute();
      noInterrupts();
      temperature_log(Temp_Mash_In, Temp_Mash_Out, Setpoint, 1000);
      OutputRelay = Output;
      interrupts();
  
  }

  if (mode == 3){  // Mode Ebu
  unsigned long now = millis();

    int minutes = (now - start_time)/60000;
    lcd.setCursor(0,1);
    lcd.print(minutes);
    lcd.print("min");
    lcd.setCursor(9,1);
    lcd.print(Temp_Ebu,1);
    lcd.print(char(223));
    lcd.print("C");
  }

}

/***************************************************************/

// Fonction de log
void temperature_log(float mash_in, float mash_out, float consigne, unsigned int intervalle){

  if  (millis()-logtimer >=intervalle){
   cmdMessenger.sendCmdStart(kLog); 
   cmdMessenger.sendCmdArg(mash_in);   
   cmdMessenger.sendCmdArg(mash_out);   
   cmdMessenger.sendCmdArg(consigne);   
   cmdMessenger.sendCmdEnd();
   logtimer = millis();
  }
}


// affichage du process
void affichage_process(unsigned int timer_palier, unsigned int timer_temperatures){
  unsigned long time = millis();
  lcd.clear();
  lcd.home();
  lcd.print(nb_paliers);
  lcd.print(" Paliers");
  while (millis() - time < timer_palier){
    if (Serial.available() != 0){
    return;}
  }
  
  for (int i=0; i<nb_paliers; i++){
    time = millis();
    lcd.clear();
    lcd.home();
    lcd.print("Palier ");
    lcd.print(i+1);
    lcd.setCursor(0, 1);
    lcd.print(Temperatures[i]);
    //lcd.print(" ");
    lcd.print(char(223));
    lcd.print("C");
    lcd.setCursor(8, 1);
    lcd.print(Temps[i]);
    lcd.print(" min");
    
    while (millis() - time < timer_temperatures){
      if (Serial.available() != 0){
        return;}
    }
  }
}

void stopprg () {
  cmdMessenger.sendCmdStart(kStop);
  cmdMessenger.sendCmdArg("Reboot");
  cmdMessenger.sendCmdArg("");
  cmdMessenger.sendCmdEnd();
  
  lcd.clear();
  lcd.home();
  lcd.print("STOP");
  wdt_enable(WDTO_4S);
  while(1) {}
}

// ************************************************
//    Appelé toutes les 15000ms (TimerInterrupt)
// ************************************************
void DriveOutput()
{  
  unsigned long now = millis();

  // temps de commutation proportionnel à la sortie du PID
  if(now - windowStartTime>WindowSize)
  { 
     windowStartTime += WindowSize;
  }
  if(OutputRelay > (now - windowStartTime))
  {
     digitalWrite(RelayPin,HIGH);
  }
  else
  {
     digitalWrite(RelayPin,LOW);
  }
}

Sur le raspberry (raspbian wheezy), il faut installer Enjoy :wink:

edit : je suis en train de regrouper au maximum les différents bouts de code coté rasp, c’était la jungle et complètement incompréhensible...
Je posterai au fur et à mesure...
pleymob
Ch'ti nouveau
Messages : 4
Inscrit depuis : 12 ans
Brasseur : Amateur
Localisation : cambrai

Re: Pico Arduino/Raspberry Pi

Message par pleymob »

Je suis impressionné !
moi qui voulais m’intéresser à l'arduino dans le cadre de mon boulot , je suis doublement motivé maintenant ;)