régulation de chauffage

bonjour,

je suis nouveau sur ce forum et nouveau dans le monde d'arduino. J'ai pour l'instant réalisé deux petits montages simples : télécommande pour une sonorisation et commande de machine à laver. Je m'attaque à plus sérieux...
Il y a environ 15 ans, j'ai fait en électronique (pure) des régulations de chauffage multiplexée, 8 vannes motorisées. Arduino devrait me permettre de remplacer tous les ampli, sommateurs, soustracteur etc...
Je développerai plus tard.
Ma question de ce soir est :
Comment piloter simplement un multiplexeur bcd avec arduino ?
Dans mes tests, je passe par des tableaux ou des switch contenant les valeurs bdc à appliquer à mes sorties logiques mais il y a sans doute plus simple. Si vous aviez quelques doc à m'indiquer...

Merci
Gérard

Bonjour Gérard et bienvenue

Je suis pas sur de comprendre ce que tu veux faire avec du BCD.

Le BCD ou "Binary coded Decimal" (en français décimal codée en binaire") consiste a représenter un nombre décimal (par exemple 51) non pas en binaire pure (0011 0011) mais par quartet qui chacun représente un chiffre du nombre décimal ce qui donne pour 51 : 0101 0001 soit en hexa 0x51 ce qui n'a rien a voir avec 0x33 qui est la valeur hexa correspondant à la valeur décimale 51.

Après ce bref rappel, pourrais tu détailler ton problème ?

Merci

ok, c'est vrai que j'ai été un peu rapide et ma terminologie n'est pas forcément bonne car je suis du genre autodidacte.
Pour mes entrées capteurs, je n'aurai jamais assez d'entrées analogiques sur mon arduino, je compte donc passer par un multiplexeur, genre 4051 qui me permettra d'envoyer 8 entrées sur une seule broche que je lirai dans une boucle commandant les entrées BCD du multiplexeur.

for(i=0;i<8;i++){
switch(i){
case 0 :  digitalWrite(1, LOW);
          digitalWrite(2, LOW);
          digitalWrite(3, LOW);
          Temperature[0]=analogRead(A0);
 break;
case 1 :  digitalWrite(1, LOW);
          digitalWrite(2, LOW);
          digitalWrite(3, HIGH);
          Temperature[1]=analogRead(A0);
 break;
case 2 :  digitalWrite(1, LOW);
          digitalWrite(2, HIGH);
          digitalWrite(3, LOW);
          Temperature[2]=analogRead(A0);
 break;
}...

ça me parait un peu lourd !
Merci pour la rapidité de la réponse !

Gérard

Ok. Le rapport avec BCD est effectivement existant mais loin de la compréhension du besoin.

On peut effectivement simplifier tout cela :

for(i=0;i<8;i++)
{
          digitalWrite(1, i & 0x04);  // bit de poids fort, entrée C
          digitalWrite(2, i & 0x02);  // bit de poids moyen, entrée B
          digitalWrite(3, i & 0x01);  // bit de poids faible, entrée A
          Temperature[i]=analogRead(A0);
}

Ca devrait faire l'affaire :wink:

Effectivement, la notion de BCD n'est pas nécessaire ici, car il faudrait un multiplexeur à 4 entrées (ABCD) pour faire du BCD...

En fait, tu veut de l'octal (en base 8, donc sur trois bits...)

Juste une petite précision / question : ne faut-il pas prendre en compte un éventuel temps de réponse du multiplexeur?

j'ajouterais bien un autre code plus rapide (mais plus éloigné de l'arduino) :

for (i = 0; i < 8; i++){
  PORTD &= 0xF1;  // mets les pins 1 2 et 3 à 0;
  PORTD |= i << 1;  // copie i sur les pins 1 2 et 3
//  delay(25);  // délai 25 ms de stabilisation du multiplexeur (si besoin)
  Temperature[i] = analogRead(A0);
}

juste en passant, mais c'est pas obligatoire...

merci beaucoup,

j'aurais du préciser que mes connaissances en programmation se limite au php donc votre beau code ne me dit pas grand chose pour l'instant !
Le temps de réaction du multiplexeur est de quelques ns mais c'est plutôt les tensions qui risquent de poser problème. Dans ma réalisation électronique, j’amplifiais avant...
Je vais déjà tester vos codes dans la journée et je préciserai mon projet

Merci
Gérard

pas eut le temps de faire les tests de tension sur les multiplexeurs mais je vais quand même détailler le projet concret :

dans un premier temps, je ne cherche pas à gérer un affichage des températures. Comme j'utilise des LM35, la lecture est directe sur un voltmètre de panneau.

une sonde extérieur
1 sonde sur chacun des 6 circuits de chauffage
1 potentiomètre de correction pour chaque sonde
le température de l'eau de chauffage est calculée sur la température extérieur avec la formule TemperatureEau=43,3 -(TempExtérieur x 0,67) (on pourrait ajouter un réglage des deux paramètres de calcul mais ce sera pour plus tard !)

le programme :
une boucle principale de 7s
au début, on charge dans un tableau les valeurs des sondes, dans un autre tableau les valeurs des corrections.
On boucle sur ces tableaux pour comparer la valeur stockée+correction avec la valeur prévue
l'écart obtenu donne le temps d'ouverture/fermeture de la vanne stockée dans une variable et on mets la sortie correspondante à l'état haut. (5 vannes motorisées = 10 sorties, il y a suffisamment de sortie sur l'arduino pour ce cas sinon on pourrait par des circuits latched)
Dans les tours suivant de la boucle principale, je vérifie si le temps impartie pour chaque vanne est passé, si oui je passe la sortie à bas

La commande des vannes motorisées se fait sur un optotriac
tout est là et reste quand même très basique

Merci de votre attention et à très bientôt pour la suite

Gérard

je reviens sur ce post avec un début de code. Pour l'instant je ne cherche pas à lire une température exacte, je me contente de analogReference(INTERNAL) pour étalonner mon échelle : 1023 = 100° sur le lm35.
Voici donc la boucle principale avec le traitement du débordement de millis() puisque cela restera en marche pendant au moins 5 mois;

  int Temp[5];//valeur stockée des températures
  int Temp_prevue;//température de l'eau en fonction de la température extérieur extérieur
  int m;//compteur de la boucle
  unsigned long debut;
  int temporisation;
  int reinit; // drapeau indiquant la réinitialisation
  
void setup() {
    analogReference(INTERNAL);
    pinMode(15, OUTPUT);//A
    pinMode(16, OUTPUT);//B
    pinMode(17, OUTPUT);//C
    m=0;
    temporisation = 100;
}

void loop() {
if(m == 0){
  for(int i=0;i<5;i++)
          {//on actualise le tableau tes température
           digitalWrite(15, i & 0x04);  // bit de poids fort, entrée C
           digitalWrite(16, i & 0x02);  // bit de poids moyen, entrée B
           digitalWrite(17, i & 0x01);  // bit de poids faible, entrée A
          delay(100);
//les capteurs de températures sont sur un multiplexeur
          Temp[i]= analogRead(A0);         
          }
--------------------------------------------------
calcul et commande des vannes motorisées
--------------------------------------------------
    }

}
if(millis() < debut){//millis() à été réinitialisé
int ecart = 4294967295 - debut;
temporisation = 300 - ecart;
}

  if(millis()- debut > temporisation){

    m++;
      debut= millis();
  if(m==21){ m = -1;
    }
  }
 if( reinit == 1){
    temporisation = 300;
    reinit = 0;
  }  
}

la dernière partie du code est-elle nécessaire ? qu'est-ce qui prend le plus de temps "processeur" : attribuer une valeur à chaque tour ou vérifier et changer la valeur une fois par mois ?
Une dernière question pour ce soir :
J'aimerai bien visualiser mes température avec le module Ethernet mais je ne comprend pas trop le mode de brochage. La documentation indique

Remarque : bien que les broches 13, 12 et 11 du module soient directement connectées aux broches 13,12 et 11 de la carte Arduino, il faut bien comprendre que la connexion SPI entre le module et la carte Arduino se fait via le connecteur ICSP et pas par la connexion directe des broches 13,12 et 11.
Sur ces 2 cartes :
la broche 10 est utilisée pour sélectionner le W5100
et la broche 4 pour sélectionner la carte SD.

Puis-je utiliser toutes ces broches INPUT ou OUTPUT en particulier les 10 et 4 ?
Espérant avoir été assez clair
Merci
Gérard

fgland:
une sonde extérieur
1 sonde sur chacun des 6 circuits de chauffage
1 potentiomètre de correction pour chaque sonde
le température de l'eau de chauffage est calculée sur la température extérieur avec la formule TemperatureEau=43,3 -(TempExtérieur x 0,67) (on pourrait ajouter un réglage des deux paramètres de calcul mais ce sera pour plus tard !)

le programme :
une boucle principale de 7s
au début, on charge dans un tableau les valeurs des sondes, dans un autre tableau les valeurs des corrections.
On boucle sur ces tableaux pour comparer la valeur stockée+correction avec la valeur prévue
l'écart obtenu donne le temps d'ouverture/fermeture de la vanne stockée dans une variable et on mets la sortie correspondante à l'état haut. (5 vannes motorisées = 10 sorties, il y a suffisamment de sortie sur l'arduino pour ce cas sinon on pourrait par des circuits latched)
Dans les tours suivant de la boucle principale, je vérifie si le temps impartie pour chaque vanne est passé, si oui je passe la sortie à bas

La commande des vannes motorisées se fait sur un optotriac
tout est là et reste quand même très basique

Merci de votre attention et à très bientôt pour la suite

Gérard

bonsoir
Les applications de thermométrie "domestique" ne nécessite pas de grandes ressources de calcul.
la formule de calcul appliquée est un pseudo petit regulateur PID , plus I que D ou P d'ailleurs :grin:

Le potentiomètre de correction est/serait appliqué où dans la chaine , il corrige(rait) quoi ? , manipulé par "qui/circonstances)

Un temps de cycle d'acquisition de l'ordre de la 10zaine de secondes (7 evoquées) est dans ce type d'application déjà du luxe/superflu, les différentes inerties des milieux mis en jeux, s’accommodent sans problemes d'une acquisition par point (action/reaction) de l'ordre de la minute, en ce qui me concerne je situe la notion de luxe d'acquisition à ~ 30" . 8)

Yep!

Je rejoins complètement Artouste sur le timing, j'utilise depuis plus d'un an le sketch suivant : heater_lastVersion.pde - Pastebin.com

J'ai par contre utilisé la logique floue en lieu et place d'une régulation PID.

@+

Zoroastre.

@Artouste : oui et non. Il est vrai que je n'ai pas précisé que ma régulation est derrière une pompe à chaleur, ce qui veut dire qu'au démarrage de la pompe, j'ai instantanément +5 et je dois aussi géré le passage pompe à chaleur-> chaudière fuel(haute température).
De toute façon ce temps est un détail.

je complète mon code :

  int Correc[5];//valeur stockée des corrections

  void setup() {
    pinMode(2, INPUT);//high = inversion du demux
    digitalWrite(2, HIGH);//par defaut haut direct sur correction
    //inversion sur température extérieur par un transistor NPN (actif)
    
    attachInterrupt(0, correction, FALLING); //validation des corrections
    //on charge les valeurs de correction dans le tableau Correc
    correction();
  }

  void correction(){
    digitalWrite(2, LOW);//bascule sur le multiplex correction
    for(int i=0;i<5;i++){
      digitalWrite(15, i & 0x04);  // bit de poids fort, entrée C
      digitalWrite(16, i & 0x02);  // bit de poids moyen, entrée B
      digitalWrite(17, i & 0x01);  // bit de poids faible, entrée A
      delay(1);
      Correc[i]= analogRead(A0);
    }
    digitalWrite(2, HIGH);//on remet sur le multiplexeur température 
  }

à chaque m=0, je stocke les températures dans un tableau
les valeurs de corrections de chaque circuit sont stockées à l'initialisation ou seront actualisées par attachInterrupt(0
elles servent à adapter les températures au différents type de bâtiment, plancher chauffant, atelier, bureau ...
et une correction sur la courbe générale pour monter ou descendre tout l'ensemble
il n'y a plus qu'a additionner.

@zoroastre : j’ai regardé ton code mais ça me dépasse complètement !

Merci
Gérard