Asservissement de ventilateurs PWM 25khz avec sonde CPU/GPU

Bonjour,

J'aimerais remplacer par un Arduino un boitier NZXT Grid+ V3 qui permet de commander 6 ventilateurs PWM en fonction de la température du CPU ou du GPU

Pourquoi le remplacer ? Ce boitier fait son travail mais est commandé par un logiciel qui s'appelle CAM, qui n'existe que vous windows, qui ne fonctionne complètement que s'il est logué à un compte NZXT et qui utilise de temps en temps jusqu'à 1mb/s (allez savoir ce qu'il envoie)

Pour remplacer ce boitier j'ai donc besoin :

  1. de sortir plusieurs signaux PWM 25khz (autant que possible)
  2. de récupérer une ou plusieurs valeur depuis l'USB du PC qui correspondrais à la température

Pour sortir du 25khz j'ai trouvé plusieurs pistes mais ça dépend à chaque fois de l'arduino lui même et pas forcement sur plusieurs sortie en même temps.

Je sais que le sujet a déjà été abordé sur le forum anglais mais c'est tout de même plus simple pour moi ici.

Vous avez des solutions que vous avez essayé / réalisé ?

Pour le moment j'ai un petit 32u4 mais je peux très bien prendre un 2560 si c'est recommandé

Merci
Cordialement
Sébastien

Snootlab-Essai-de-l-Arduino-i2C-Power-proto-shield-ventilateurs-pwm-ds1820-fanduino

Il ne devrait pas être difficile d'étendre à 6 ventilateurs.

La gestion de la température est faite avec deux DS18B20, mais il n'est pas être très complexe de lui envoyer les températures par la ligne série.
Sous LINUX je ferais ça avec un petit daemon script + lm-sensors.

Ce boitier fait son travail mais est commandé par un logiciel qui s'appelle CAM, qui n'existe que vous windows

Il ne reste plus qu'à nous dire quel OS tu utilises vraiment.

Bonjour et merci pour ton intérêt.

J'utilise Windows (jeux) ET Xubuntu (travail), il y aura donc deux versions du soft. (python semble pas mal...pour ça)

Récupérer la température depuis une librairie ne devrait pas me poser de problème, il faudra juste que j'envoie en USB le % à appliquer aux ventilos.

Merci pour l'adresse je vais regarder

J'avais trouvé ceci il y a quelques temps : GitHub - AL-FC/AL-FanControl: An application-level fan control for desktop PCs using Linux, Python, Arduino and PWM fans.

Il fait tourner 8 ventilateurs en PWM, mais détournant d'autre sortie pour "générer" des signaux, dommage il ne précise pas la fréquence.

J'ai regardé le lien, en fait son ventilateur n'est pas un PWM, c'est pour ça qu'il utilise un Power shiled et des mosfet.

Mes ventilo son des PWM 4pin Bequiet Silent Wings 3 donc il ne devrais pas y avoir besoin de tout ça, juste une sortie PWM de 25khz (en plus de l'alim bien entendu)

Apres, je n'ai pas besoin d'avoir 6 commandes séparé, 3 serait déjà par mal il suffis que je les met en parallèle

Sur le ATmega 32u4 semblerait qu'on puisse utiliser le TIMER 1 (pins 9, 10,11) et TIMER 4 (pins 6, 13) (edit : la 13 est pas dispo, oui désolé je n'ai pas de version officiel pour le moment, mais pour la version final ça sera un original, il faut jusque que je sache le quel)

mais est ce possible en même temps à 25K ?

merci pour votre aide (c'est mon premier projet arduino, je me suis arrêté au 68HC11F1 en 2000 :slight_smile: )

Bonjour

J'ai trouvé une application concrète en utilisant la pin 6 et timer 4 d'un mega 32u4

C'est dommage il n'utilise qu'un timer

Par rapport à ce lien : Snootlab-Essai-de-l-Arduino-i2C-Power-proto-shield-ventilateurs-pwm-ds1820-fanduino

Ne suffit-il d'alimenter le ventilateur en 12V et appliquer le PWM directement sur la bonne pin en supprimant les MOSFETs de puissance ?
L'information RPM dans le cadre d'un asservissement en température n'est pas vraiment utile, à part pour l'afficher, bof.

Mes ventilo son des PWM 4pin Bequiet Silent Wings 3

Je suis fan :slight_smile: de BeQuiet depuis 2012 :
Alimentation Straight Power E9-500W 80PLUS Gold
Ventirad BeQuiet! Shadow Rock PRO SR1

Je crois que tu confonds la pin sensor RPM avec la PWM, effectivement le retour RPM ne servira à rien, ça ne sera peut être même pas câblé.

Par contre le PWM c'est la commande pour faire varier le ventilo.

Oui il suffis d'alimenter les ventilateurs en 12V et de connecter un ou plusieurs ventilateurs sur la "bonne" pin, mais ce soit être un signal PWM de 25kHz environ

Mais j’aimerais bien en avoir plusieurs de ces pins

Je suis fan aussi de BeQuiet :slight_smile:

En fait le pc est un Bi Xeon donc j'ai deux Dark Rock 3 et 5 Silent Wings 3

Donc ce dont j'ai besoin pour le moment est de savoir si avec un mega 32u4 on peu utiliser le TIMER 4 (pin 6) à env 25K + un autre timer à la même fréquence qui donnerait accès à une ou deux autres pin

ou alors il faut que parte sur autre chose

Oui : RPM. C'est corrigé.

Oui il suffis d'alimenter les ventilateurs en 12V et de connecter un ou plusieurs ventilateurs sur la "bonne" pin, mais ce soit être un signal PWM de 25kHz environ

Apparemment l'auteur utilise une fréquence de 31KHz. L'écart par rapport à 25Khz est-il dérangeant ?

Et puis il existe des librairies PWM permettant de régler la fréquence PWM.

Donc ce dont j'ai besoin pour le moment est de savoir si on peu utiliser le TIMER 4 (pin 6) à env 25K + un autre timer à la même fréquence

Les timers sont normalement indépendants.

Je ne sais pas ce qu'il utilise comme arduino sur ton lien, effectivement 31khz.

Le support BeQuiet recommande entre 21KHz et 28KHz

Comme intel et Noctua :

Je crois que je me suis fais avoir avec le 32u4, le timer 1 n'a pas la même plage de fréquence que le 4 :frowning:

// Frequency modes for TIMER1
#define PWM62k 1 //62500 Hz
#define PWM8k 2 // 7812 Hz

Donc il n'y a que le pin 6 et 13 avec Timer 4 ...

Il y a peut être des librairies pour gérer la fréquence mais je ne pense pas qu'elles fasse plus que ce qu'on peu faire à la main, ou alors je n'ai pas compris le principe de timer/ diviseur

Vous avez des exemples avec un MEGA 2560 ? C'est celui qui offre le plus de possibilité ?

Merci

https://playground.arduino.cc/Code/PwmFrequency/

Le choix du 31KHz découle d'un problème de choix dans les divisions.

Explorer la solution de jouer avec plusieurs timers.

Il serait possible aussi de générer le PWM de manière active (sans timer) dans la boucle principale en prenant comme base de temps micros(), jouer avec les différentes pins avec digitalWrite().

Une autre possibilité : utiliser un timer avec un tick court (1µs par exemple) qui sert de base de temps, et gérer le PWM dans l'interruption avec digitalWrite().

C'est logiciellement moins sexy mais avec un processeur à 16MHz cela me semble difficilement jouable.
25KHz cela donne 40µs de période.

Dans les deux cas, il faut un tableau de structures de données en mémoire permettant de stocker pour chaque sortie :

  • le nombre de ticks ON
  • le nombre de ticks OFF
  • un compteur de ticks

Avec un STM32 ?

effectivement il y a la solution logiciel, c'est ce qu'a fait GitHub - AL-FC/AL-FanControl: An application-level fan control for desktop PCs using Linux, Python, Arduino and PWM fans. mais est ce fiable ? (bof)

J'ai trouvé ceci :

// PWM output @ 25 kHz, only on pins 9 and 10.
// Output value should be between 0 and 320, inclusive.
void analogWrite25k(int pin, int value)
{
    switch (pin) {
        case 9:
            OCR1A = value;
            break;
        case 10:
            OCR1B = value;
            break;
        default:
            // no other pin will work
            break;
    }
}

void setup()
{
    // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;           // undo the configuration done by...
    TCCR1B = 0;           // ...the Arduino core library
    TCNT1  = 0;           // reset timer
    TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
           | _BV(COM1B1)  // same on ch; B
           | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
    TCCR1B = _BV(WGM13)   // ditto
           | _BV(CS10);   // prescaler = 1
    ICR1   = 320;         // TOP = 320

    // Set the PWM pins as output.
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
}

void loop()
{
    // Just an example:
    analogWrite25k( 9, 110);
    analogWrite25k(10, 210);
    for (;;) ;  // infinite loop
}

Il explique comment obtenir du 25Khz avec le timer 1 du UNO qui est sur 16bits

Le 32U4 a aussi le TIMER 1 sur 16bits, donc ce soit être utilisable aussi

Le mega 2560 a les timer 1, 3, 4 et 5 sur 16 bits ....

Si seulement je pouvais simuler tout ça :frowning:

Effectivement certaines librairies permettent de générer un PWM en µS avec le timer1 :

J'ai déjà utilisé celle-ci : Google Code Archive - Long-term storage for Google Code Project Hosting.

Il y a le site de Mike Gammon qui explique comment avoir plus de souplesse en utilisant deux timers.
Voir son article sur la génération de PWM à 38kHz

Modulating 38 kHz signal
This question seems to come up a few times on the Arduino forum: How to modulate a 38 kHz signal?

The code below uses Timer 1 to generate a 38 kHz pulse using fast PWM mode (mode 15). It then modulates the duty cycle from 0% to 100% based on a figure read from a potentiometer connected to A0.

Bonjour et merci à tous les deux, je vais regarder tout ça.

Je ne suis pas sur que l'info sera utile mais OC1A est un registre qui a une adresse fixe en mémoire.

Cette adresse est definie par les fichiers d'origine Atmel.
Ces fichiers se trouvent dans un sous-répertoire de l'IDE : arduino-1.8.7/hardware/tools/avr/avr/include/avr/
(pour la syntaxe du chemin je suis sous Linux.)

Pour l'atmega328p qui est le micro de la UNO le fichier se nomme : iom328p.h

Il devrait être possible de créer un tableau de pointeur, mais là je passe la main à plus qualifé, déjà pour dire si l'idée est intéressante ou idiote et si elle est inintéressante indiquer comment faire.

Merci beaucoup 68tjs, j'avais édité entre temps pour essayer de trouver par moi même avant d'en parler, justement pour vérifier si je ne disais pas des idioties.

Du coup je vais chercher ces adresses pour le 2560 ( j'en ai acheté un entre temps ), c'est tout de même plus sympa de gérer des tableaux de structure et de passer le pointeur plutôt que de faire un switch sur chaque PIN pour affecter les valeurs aux registres et autres

En attendant j'essais de comprendre et d'adapter le code que j'ai placé plus haut pour un 2560

et j'ai du mal à comprendre ce qu'il essais de faire ici :

   TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
           | _BV(COM1B1)  // same on ch; B
           | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
    TCCR1B = _BV(WGM13)   // ditto
           | _BV(CS10);   // prescaler = 1

vous pouvez m'éclairer ?

Merci

_BV c'est une macro, c'est du bitwise.
_BV(5) décale un 1 de 5 rang vers la gauche.

COM1A1 et les autres sont définis dans le fichier iomxyz.h. ces noms représentent les bit 0 à 7 du registre TCCR1A.

Les explications concernant le rôle des bits d'un registre sont dans la datasheet du microcontrôleur qu'hélas il faut lire.
Le code cité est bien commenté, les commentaires doivent être interprétés avec la datasheet ouverte à coté de soi.

Les datasheets Atmel ont ceci de remarquable que chaque chapitre est suivi d'exemple en assembleur et en C.
Le travail de compréhension est grandement facilité.
J'aurais bien aimé que STMicro en fasse autant, quant à Espressif même pas en rêve.

merci beaucoup,

J'ai trouvé aussi de la lecture :

https://www.locoduino.org/spip.php?article84

Je reviendrais vers vous quand j'aurais trouvé le temps de tout lire :slight_smile: