Comment pourrais-je procéder à la programmation d'un commutateur (basé sur un relais à semi-conducteurs ou un triac) qui se déclenche sur une puissance de passage à zéro?
Pour ceux qui ne connaissent pas le sujet: Mettez le 230V sous tension, lorsque l'onde sinusoïdale de la ligne électrique passe à zéro - le résultat est de minimiser les perturbations électromagnétiques résultant d'un pic rapide de courant.
Plus précisément, je préférerais passer autant de logiciels que possible. Le circuit de détection composé d'un petit transformateur, d'une diode et de quelques résistances pour contrôler les niveaux et les courants fournit "1" lorsque la puissance d'entrée CA est dans la moitié positive, "0" dans le négatif, attaché à une broche GPIO d'entrée. La sortie se compose de quelques relais statiques et de l'essentiel pour les faire fonctionner (pull-ups, etc.), attachés aux broches de sortie GPIO.
The problem is timing: with 50Hz AC we get 100 zero-crossings in a second, one half-cycle is 10ms. To get within reasonable distance from zero-crossing to keep said EMI low we shouldn't activate the output more than 10% past (or before) the event of zero-crossing, that means +-1ms tolerance. That doesn't mean 1ms reaction time - we can reasonably expect the next zero-crossing to occur precisely 10ms after the first one, or the fourth - 40ms. It's about granularity - if we allow 20ms for reaction, it must be between 19 and 21ms, not 18 or 22.
Comment puis-je implémenter un tel temporisateur - déclencher la sortie GPIO soit dans 1 ms car l'entrée détecte un front, soit dans un multiple fixe de 10 ms depuis - de préférence en tenant compte d'une polarisation négative (par exemple, le transformateur et le relais introduisent un retard de 1,6 ms; donc je veux que le déclencheur se déclenche 8,4+ (n * 10) ms depuis l'impulsion d'entrée, de cette façon la polarisation contrecarre le retard introduit par le circuit.) - tout bien sûr "à la demande de l'utilisateur", par exemple, l'utilisateur écrit "1 msgstr "vers un fichier / sys / class / ... et à l 'occasion (grossièrement) la plus proche, la sortie passe" on ". L'utilisateur écrit «0» et lorsque le passage à zéro arrive, le relais spécifique se désengage.
Je crois que cela nécessiterait d'écrire ou de pirater un module du noyau. Pourriez-vous m'indiquer ce qui gère les broches GPIO de Raspberry Pi dans le noyau, et quel type de minuteries pourrais-je y attacher (à moins qu'il y en ait déjà en place) pour obtenir ce type de fonctionnalité?
Réponses:
Vous n'avez pas besoin de pirater le noyau. Vous avez juste besoin de déplacer le processus hors de la file d'attente du planificateur.
Désormais, notre processus reçoit des
cat /proc/sys/kernel/sched_rt_runtime_us
millisecondes sur chaquecat /proc/sys/kernel/sched_rt_period_us
segment de temps en millisecondes, d'une exécution ininterrompue sans risque d'être anticipé pendant ce temps (en pratique, par défaut sur BerryBoot: 0,95s sur chaque seconde.) Si vous en avez besoin de plus, mess avec ces valeurs, mais je n'en ai pas besoin de plus pour mon objectif ici.J'utilise une fonction de minuterie en millisecondes (c'est à peu près la précision dont j'ai besoin) basée sur l'
clock_gettime()
horloge de mes retards.L'appel le
timer(1)
réinitialise, l'appeltimer(0)
renvoie le temps écoulé depuis la réinitialisation.Vous devez
rt
créer un lien avec la bibliothèque pour que cela se compile - ajoutez-le-lrt
à votre commande gcc.Maintenant, pour la boucle principale. J'utilise une entrée de commutateur pour la "demande d'utilisateur", mais vous pouvez utiliser le réseau, la minuterie ou autre. Tout ce dont vous avez besoin est d'obtenir la valeur booléenne
in
.la source
TRIAC_PIN
àin
, je devrais régler leTRIAC_PIN
à 1, attendre un laps de temps déterminé (proportionnellement à gradateur souhaité), puis réglez àTRIAC_PIN
nouveau sur 0. Est-ce que cela fonctionnerait?if(in==out) continue;
àif(out==0) continue;
, droite? En fait, je suis totalement nouveau dans la programmation de pi, donc ce n'est peut-être pas nécessaire - je suppose que tout se passe de manière synchrone (c'est-à-dire que nous n'avons pas à nous soucier de l'appel de la boucle principale pendant que les boucles imbriquées sont toujours en cours d'exécution)