Forum Électro-Bidouilleur

Merci de vous connecter ou de vous inscrire.

Connexion avec identifiant, mot de passe et durée de la session
Recherche avancée  

Nouvelles:

Bienvenue au Forum de discussion Électro-Bidouilleur! Inscrivez-vous pour participer aux discussions!: 
https://forum.bidouilleur.ca/index.php?action=register Les demandes d'inscription sont révisées quotidiennement.

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.

Sujets - sylvainmahe

Pages: 1 [2] 3
16
De nouveau bonjour,

Schéma :


J'aimerais que la sortie passe dans un circuit (aop certainement) afin de changer l'échelle qui est actuellement de 1V à  3.4V pour être 0V à  5V.

Pensez-vous qu'il existe un montage simple qui permet de recentrer et changer d'échelle un signal ?

J'ai fait des essais avec des aop mais je pense que le simulateur est buggé car ça ne donne rien de bien.

Merci d'avance.

17
Trucs et Astuces d'Électronique / PWM duty cycle 0% 100% sans NE555
« le: Novembre 15, 2023, 09:05:07 pm »
Bonjour à  vous, je poste ce montage oscillateur PWM ici si besoin. Montage que j'ai trouvé en réponse d'un autre post sur un autre forum.



Pour avoir un duty cycle réellement 0% 100% il faut que les résistances que je vais nommer R1 R3 (8.2k) du double pont diviseur disons R1 R2 R3 formé par les 8.2k 10k 8.2k soient légèrement inférieures à  R2 (10k). Graphiquement ça veut dire que l'amplitude de l'onde triangulaire rouge est inférieure à  la tension verte moins la tension jaune.

Inversement si elles sont supérieures, votre plage de duty cycle sera d'autant réduite. Graphiquement ça veut dire que l'amplitude de l'onde triangulaire rouge est supérieure à  la tension verte moins la tension jaune.


18
Bonjour :)

Connaissez-vous un compteur décade qui n'aurait pas besoin d'horloge externe ? Quelqu'un m'a dit que ça existe mais je ne trouve pas...

Merci d'avance.

19
Bonjour à  vous bidouilleurs,

Document 2N3904 : https://www.onsemi.com/pdf/datasheet/2n3903-d.pdf

Un ami m'a déjà  demandé ce que signifie les dB indiqués pour la "noise figure". Je n'ai pas réussi à  répondre vraiment.

Ce serait la dégradation du signal sur bruit ? Le signal serait notre signal sur "l'entrée", base émetteur ?

Merci d'avance.

20
Bonjour à  vous,



Je me demande si dans certains cas pour déterminer la résistance en série avec la base d'un transistor bipolaire, il est logique de tenir compte de ce que je pense être la capacité parasite du transistor ? Comme un RC autrement-dit déterminer le temps de charge de cette capacité à  travers la résistance qu'on aura choisi.

Par exemple le 2n3904 a :
Cobo = 4pF
Cibo = 8pF

J'aimerais bien vos conseils de pro :)

Merci d'avance.

21
Bonjour à  vous,

Schéma :


Je mettrais bien une diode zener 4.3V (BZX85C4V3) entre l'émetteur et la base du MJE15032 afin de le protéger car sa VBE absolue est de 5V.

Selon ce que j'ai compris cette différence de potentiel n'est jamais atteinte car immédiatement que la tension augmente entre l'émetteur et la masse au delà  de +5V + tolérance (sortie regulée), via le pont diviseur de tension le TL431 pilote son npn interne via son aop interne, et donc la VBE chute immédiatement.

Qu'en pensez-vous ?

MJE15032 : https://www.onsemi.com/download/data-sheet/pdf/mje15032-d.pdf
TL431 : https://www.ti.com/lit/gpn/TL431

Merci d'avance.

22
Bonjour à  la communauté,

Les calculs en régime alternatif demandent des nombres complexes.

Questions :
Lorsqu'en régime continu nous déterminons une valeur de résistance en série avec une DEL pour quelle brille en fonctionnement normal (ni sous alimentée ni sur-alimentée) ou lorsque nous estimons la valeur d'une résistance à  la base d'un transitor pour être certain qu'il soit dans sa plage saturation désaturation, est-ce que les calculs valent si un signal PWM est envoyé à  la place du continu ?

Autrement-dit est-ce que les valeurs de résistance sont toujours correctes ?

Merci à  vous si vous avez des réponses à  apporter.

23
Bonjour à  vous, je vous soumets les schémas suivants :



Mes interrogations résultent la phrase suivante : plus je réfléchis à  ces schémas et moins je comprends ce qui normalement doit être simple.

Je m'explique :
La DEL 2V 15mA transforme un courant (ou une partie du courant ?) qui la traverse en lumière. Nous avons donc des électrons qui se transforment en photons dans le visible et une partie en infrarouge, la DEL chauffe.

La résistance limite le courant dans la DEL. Dans ma simulation j'ai été obligé de rajouter en série une résistance parasite de 15 ohms pour que la différence de potentiel électrique de ce couple DEL + résistance parasite soit bien de 2V (simulateur : proto).

En haut l'ampèremètre indique environ 14,96mA. Sans la résistance parasite il indique 16,07mA et la tension aux bornes de la DEL passe de 2V à  1,8V.

La résistance de 200 ohms doit dissiper 3V 15mA soit 0,045W. Ces watts partent en photons infrarouges. La DEL elle doit dissiper 2V 15mA soit 0,03W. Ces watts partent en photons visibles et infrarouges. Et la résistance interne de la DEL dans tout ça ?

La résistance de 200 ohms limite le courant dans la DEL. Pourtant à  ses bornes la différence de potentiel est de 3V. Donc elle limite la tension aux bornes de la DEL ou elle limite l'intensité traversant la DEL ? Je dirais davantage qu'elle limite la tension car elle mange 3V sur les 5V afin que la différence de potentiel aux bornes de la DEL soit bien de 2V...

Merci d'avance si vous pouvez interagir avec mes commentaires et interrogations.

24
Bonjour bidouilleurs,

J'aimerais savoir comment calculer la puissance maximale que doit avoir la diode (actuellement SB160), ce que je dois prendre en compte pour le calcul ?



Merci pour votre aide.

25
Citation de: moi
sais-tu se qu'est le programme MODULE développé par moi ?

Citation de: ChatGPT
En tant qu'intelligence artificielle, je n'ai pas accès aux informations spécifiques sur les programmes développés par des utilisateurs individuels, sauf si vous choisissez de les partager avec moi. Je n'ai pas de mémoire persistante et je ne conserve pas les informations d'une session à  l'autre.

Si vous souhaitez discuter du programme MODULE que vous avez développé, veuillez fournir plus de détails sur ce qu'il fait ou comment il fonctionne, et je ferai de mon mieux pour vous aider.

Citation de: moi
MODULE est une bibliothèque logicielle C++ pour microcontrôleurs.

Voilà  un exemple :
" Retour à  l'accueil Principes  Partager mes idées et mes projets librement et gratuitement. Thématiques  Mécatronique du système embarqué, artisanat pluridisciplinaire, bricolage commun, esthétique logicielle et matérielle, minimalisme fonctionnel, conceptualisation alternative, rédaction technique et littéraire, partage pédagogique documenté. Contact  ✆ Téléphone : 06.45.49.96.98
✉ E-mail : contact@sylvainmahe.site
✎ Site Web : sylvainmahe.siteÉcriture de la page : Sylvain Mahé La gestion du temps avec la classe Timer  La plupart des projets requièrent la dimension temporelle pour pouvoir fonctionner, c'est pourquoi la classe Timer apporte la temporisation des événements et des actions à  effectuer dans un programme. Contrairement à  d'autres plates-formes de développement pour microcontrôleurs à  registres 8 bits, la classe Timer utilise un compteur qui fonctionne à  une fréquence de 2MHz sur une largeur mémoire de 64 bits, de sorte que le temps peut être compté à  partir de zéro toutes les microsecondes pendant bien plus longtemps que la durée de vie du microcontrôleur lui-même (plusieurs centaines de milliers d'années), en effet une largeur mémoire de seulement 32 bits imposerait un retour à  zéro (overflow) au bout d'un peu plus d'une demi-heure tout au plus, ce qui serait très limitant pour bons nombres de projets ! Les compteurs (ou timers) que vous déclarez avec la classe Timer se présentent sous la forme d'objets (c'est le principe de beaucoup de mes classes), il est donc possible de créer plusieurs compteurs ayant tous des fonctions indépendantes dans votre programme. Exemple d'utilisation de la classe Timer : #include <Timer.h>

int main()
{
   Timer myTimer = Timer();
   
   myTimer.start (0);
   
   while (true)
   {
      myTimer.state();
      
      //myTimer.s est le temps écoulé en secondes
      //myTimer.ms est le temps écoulé en millisecondes
      //myTimer.us est le temps écoulé en microsecondes
   }
   
   return 0;
} Dans cet exemple, un objet myTimer de type Timer est déclaré, puis via cet objet, la fonction start est appelée prenant en paramètre 0, le temps de départ indiqué en millisecondes : Dans la plupart des cas nous souhaitons qu'un compteur démarre à  0 (comme l'exemple) lorsque la fonction start est appelée, mais si vous le souhaitez vous pouvez le faire partir à  une autre valeur. Plus loin cet objet myTimer appelle la fonction state (état) dans une boucle ce qui permet de mettre à  jour les variables s (secondes), ms (millisecondes), et us (microsecondes) que vous pourrez utiliser dans vos conditions logiques et divers calculs. La fonction pause :  Malgré que l'utilisation première de la classe Timer permet la création d'objets instanciés indépendants, il est néanmoins parfois utile de pouvoir bénéficier de pauses bloquantes appelées de façon statique sans objet, directement à  partir de la classe concernée. La fonction pause remplie cette fonctionnalité. Exemple de clignotement d'une del avec la classe Timer : #include <GpioWrite.h>
#include <Timer.h>

int main()
{
   GpioWrite myLed = GpioWrite (1);
   
   while (true)
   {
      myLed.toggle();
      Timer::pause (1000);
   }
   
   return 0;
} Contrairement au premier exemple et l'utilisation d'un objet, ici la fonction statique pause est directement appelée à  partir de la classe Timer. Cette fonction prend en paramètre 1000, la durée de la pause en millisecondes. Dans l'exemple ci-dessus, si une del était branchée sur le port GPIO 1 de l'automate programmable, elle clignoterait toutes les secondes (1000 millisecondes), mais dans ces conditions le programme ne pourrait pas faire autre chose que gérer la commutation du port GPIO numéro 1, la pause est dite bloquante car rien d'autre ne peut être effectué en parallèle. L'exemple suivant résout ce problème. Exemple de clignotement d'une del sans pause bloquante avec la classe Timer : #include <GpioWrite.h>
#include <Timer.h>

int main()
{
   GpioWrite myLed = GpioWrite (1);
   Timer myTimer = Timer();
   
   myTimer.start (0);
   
   while (true)
   {
      myTimer.state();
      
      //tâche à  effectuer toutes les 1000ms :
      if (myTimer.ms >= 1000)
      {
         myLed.toggle();
         myTimer.start (0);
      }
      
      //autres tâches à  effectuer en parallèle...
   }
   
   return 0;
} L'exemple ci-dessus montre bien que lors d'un tour de boucle, si à  partir du démarrage du compteur le temps écoulé est supérieur ou égal à  1000 millisecondes, l'exécution rentre dans la condition logique, effectue la commutation de la del, redémarre le compteur à  zéro, et à  la suite exécute toutes les autres tâches du programme sans passer par un état bloquant comme c'était le cas précédemment. Dans une problématique comme celle-ci, plusieurs solutions sont souvent possibles, c'est ce que montre l'exemple suivant avec l'utilisation d'une variable qui est incrémentée pour suivre l'avancée du temps imposé par le compteur (ce qui évite un cumul d'erreurs dans le temps), ainsi ce dernier n'a pas besoin d'être redémarré à  zéro à  chaque fois. Autre exemple de clignotement d'une del sans pause bloquante avec la classe Timer : #include <GpioWrite.h>
#include <Timer.h>

int main()
{
   GpioWrite myLed = GpioWrite (1);
   Timer myTimer = Timer();
   unsigned long long timePrevious = 0;
   
   myTimer.start (0);
   
   while (true)
   {
      myTimer.state();
      
      //tâche à  effectuer toutes les 1000ms :
      if (myTimer.ms - timePrevious >= 1000)
      {
         myLed.toggle();
         timePrevious += 1000;
      }
      
      //autres tâches à  effectuer en parallèle...
   }
   
   return 0;
} Cet exemple-ci est plus précis que les trois précédents car il met en jeu la variable timePrevious qui au passage dans la condition logique n'est pas initialisée sur le temps écoulé du compteur comme on pourrait être tenté de le programmer, mais plutôt bêtement incrémentée de 1000, ce qui compense et ne tient pas compte du temps d'exécution de la condition logique elle-même, de la commutation de la del, et du reste du programme. Pour parfaire l'utilisation de la classe Timer, une fonction stop existe et permet d'arrêter l'écoulement du temps, dans cette situation les variables s (secondes), ms (millisecondes), et us (microsecondes) resteront à  leurs dernières valeurs mises à  jour lors de l'appel de la fonction state, ceci avant l'appel à  la fonction stop. Références :  Récapitulatif des fonctions et variables de cette classe : unsigned long long s = 0;
unsigned long long ms = 0;
unsigned long long us = 0;
Timer();
void start (const unsigned long long TIME_START);
void state();
void stop();
static void pause (const unsigned long long DURATION); Programmation et graphismes de la page : Sylvain Mahé"

Citation de: ChatGPT
Le programme MODULE que vous avez développé est une bibliothèque logicielle en langage C++ destinée aux microcontrôleurs. La bibliothèque semble proposer des fonctionnalités liées à  la gestion du temps avec la classe Timer, permettant de créer des compteurs et d'effectuer des temporisations dans un programme. Elle utilise un compteur fonctionnant à  une fréquence de 2MHz sur une largeur mémoire de 64 bits, ce qui permet de compter le temps avec une précision élevée.

L'exemple que vous avez fourni montre comment utiliser la classe Timer pour démarrer un compteur, mettre à  jour les variables de temps (secondes, millisecondes, microsecondes) dans une boucle et effectuer différentes tâches en parallèle. Il présente également la fonction pause pour réaliser des pauses bloquantes et la manière d'utiliser la classe Timer pour clignoter une LED avec ou sans pause bloquante.

En résumé, MODULE semble être une bibliothèque conçue pour faciliter la gestion du temps et les temporisations dans le développement de logiciels pour microcontrôleurs en utilisant le langage C++.

Citation de: moi
ok. Écris un programme C++ qui utilise uniquement cette bibliothèque MODULE.

Citation de: ChatGPT
Voici un exemple de programme en langage C++ qui utilise la bibliothèque MODULE avec la classe Timer pour réaliser une temporisation et clignoter une LED :

#include <Timer.h>
#include <GpioWrite.h>

int main()
{
    GpioWrite myLed = GpioWrite(1); // Initialise la LED connectée au port GPIO 1
    Timer myTimer = Timer(); // Initialise l'objet Timer

    myTimer.start(0); // Démarre le compteur de temps à  partir de zéro

    while (true)
    {
        myTimer.state(); // Met à  jour les variables de temps (s, ms, us)

        // Tâche à  effectuer toutes les 1000 ms :
        if (myTimer.ms >= 1000)
        {
            myLed.toggle(); // Inverse l'état de la LED (allume/éteint)
            myTimer.start(0); // Redémarre le compteur à  zéro
        }

        // Autres tâches à  effectuer en parallèle...

    }

    return 0;
}

Dans cet exemple, le programme utilise la classe Timer de la bibliothèque MODULE pour créer un compteur de temps. La LED est représentée par l'objet `myLed` de la classe GpioWrite, également fournie par la bibliothèque MODULE. La temporisation est réalisée en vérifiant si le temps écoulé en millisecondes (`myTimer.ms`) est supérieur ou égal à  1000 ms. Si c'est le cas, la LED change d'état (allumée ou éteinte) à  l'aide de la méthode `toggle()` de l'objet `myLed`, et le compteur de temps est redémarré à  zéro.

Notez que cet exemple suppose que vous avez correctement installé et configuré la bibliothèque MODULE et que vous avez les fichiers d'en-tête nécessaires (`Timer.h` et `GpioWrite.h`) ainsi que les fichiers binaires de la bibliothèque (`Timer.cpp` et `GpioWrite.cpp`) inclus dans votre environnement de développement. Assurez-vous d'adapter le code en fonction de votre configuration matérielle et de vos besoins spécifiques.

Citation de: moi
ok. Ajoute une autre led qui sera violette et qui va clignoter.

Citation de: ChatGPT
Voici une version modifiée du programme précédent, ajoutant une deuxième LED violette qui clignote en utilisant la bibliothèque MODULE et la classe Timer :

#include <Timer.h>
#include <GpioWrite.h>

int main()
{
    GpioWrite redLed = GpioWrite(1); // LED rouge sur le port GPIO 1
    GpioWrite purpleLed = GpioWrite(2); // LED violette sur le port GPIO 2
    Timer myTimer = Timer();

    myTimer.start(0);

    while (true)
    {
        myTimer.state();

        // Tâche pour la LED rouge toutes les 1000 ms :
        if (myTimer.ms >= 1000)
        {
            redLed.toggle();
            myTimer.start(0);
        }

        // Tâche pour la LED violette toutes les 500 ms :
        if (myTimer.ms >= 500)
        {
            purpleLed.toggle();
        }

        // Autres tâches à  effectuer en parallèle...

    }

    return 0;
}

Dans cet exemple, j'ai ajouté une deuxième LED violette connectée au port GPIO 2. La tâche pour la LED violette est déclenchée toutes les 500 ms en vérifiant si le temps écoulé en millisecondes (`myTimer.ms`) est supérieur ou égal à  500 ms. Lorsque cette condition est remplie, la méthode `toggle()` est utilisée pour inverser l'état de la LED violette.

Assurez-vous de configurer correctement les ports GPIO pour vos LED rouge et violette en fonction de votre configuration matérielle.

Citation de: moi
ok. Ajoutes un deuxième compteur.

Citation de: ChatGPT
Voici une version mise à  jour du programme avec l'ajout d'un deuxième compteur en utilisant la bibliothèque MODULE et la classe Timer :

#include <Timer.h>
#include <GpioWrite.h>

int main()
{
    GpioWrite redLed = GpioWrite(1); // LED rouge sur le port GPIO 1
    GpioWrite purpleLed = GpioWrite(2); // LED violette sur le port GPIO 2
    Timer timer1 = Timer();
    Timer timer2 = Timer();

    timer1.start(0);
    timer2.start(0);

    while (true)
    {
        timer1.state();
        timer2.state();

        // Tâche pour la LED rouge toutes les 1000 ms :
        if (timer1.ms >= 1000)
        {
            redLed.toggle();
            timer1.start(0);
        }

        // Tâche pour la LED violette toutes les 500 ms :
        if (timer2.ms >= 500)
        {
            purpleLed.toggle();
            timer2.start(0);
        }

        // Autres tâches à  effectuer en parallèle...

    }

    return 0;
}

Dans cette version modifiée, j'ai ajouté un deuxième objet Timer nommé `timer2`. La tâche pour la LED violette est maintenant déclenchée toutes les 500 ms en utilisant le compteur `timer2` au lieu du compteur `timer1`. Lorsque la condition est remplie, la méthode `toggle()` est utilisée pour inverser l'état de la LED violette, et `timer2` est redémarré à  zéro.

Assurez-vous de bien configurer les ports GPIO pour vos LED rouge et violette, ainsi que d'adapter le code en fonction de votre configuration matérielle spécifique.

Citation de: moi
ok. Voilà  un autre exemple de comment fonctionne MODULE :
"Sylvain MahéLe site Web Retour à  l'accueil Principes  Partager mes idées et mes projets librement et gratuitement. Thématiques  Mécatronique du système embarqué, artisanat pluridisciplinaire, bricolage commun, esthétique logicielle et matérielle, minimalisme fonctionnel, conceptualisation alternative, rédaction technique et littéraire, partage pédagogique documenté. Contact  ✆ Téléphone : 06.45.49.96.98
✉ E-mail : contact@sylvainmahe.site
✎ Site Web : sylvainmahe.siteÉcriture de la page : Sylvain Mahé Générer des nombres aléatoires avec la classe Random  Par définition, l'électronique numérique dans sa conception même est un environnement complètement déterministe, ce qui exclut le hasard. Éventuellement, une suite de nombres dits pseudo-aléatoires (appelés ainsi de part leurs caractères difficilement prédictibles) peuvent être générés via des calculs plus ou moins élaborés, mais ils n'en restent pas moins entièrement déterminés. Pour effectuer de l'aléatoire avec un microcontrôleur déterministe, il convient donc d'y introduire une variable extérieure dont l'évolution est imprévisible et incalculable. Une bonne solution consiste à  laisser en l'air une broche, soit physiquement connectée à  rien en externe, mais reliée en interne au convertisseur analogique/numérique du microcontrôleur, ceci dans le but de capter le bruit électromagnétique provenant de l'extérieur (et du composant lui même finalement), pour ainsi générer des véritables nombres aléatoires. La classe Random propose l'option d'utiliser un port de l'automate programmable relié au convertisseur analogique/numérique du microcontrôleur comme source d'approvisionnement en bruit analogique, mais également dispose d'un générateur de bruit artificiel (pseudo aléatoire) lorsqu'un port inapproprié est utilisé, ou lorsque le bruit analogique est identique sur plusieurs mesures consécutives (et par conséquent rejeté de l'équation), ce qui en fait un algorithme très robuste. Exemple d'utilisation de la classe Random : #include <Random.h>

int main()
{
   Random::seed (25);
   Random::integer (1, 6);
   
   return 0;
} Dans cet exemple la fonction statique seed est appelée prenant en seul paramètre l'utilisation du port GPIO numéro 25 de l'automate programmable relié en interne au convertisseur analogique/numérique (l'ADC) du microcontrôleur. Ce port doit être physiquement laissé libre (en l'air) car il sert au système de génération de nombres aléatoires qui lorsqu'un port approprié est sélectionné, utilise du bruit analogique pour générer de l'aléatoire. Si vous ne souhaitez pas utiliser de bruit analogique pour le système de génération de nombres aléatoires, indiquez 0 en paramètre, dans ce cas seul le générateur de bruit artificiel (pseudo aléatoire) sera utilisé. Le bruit analogique extérieur permet au système de génération de nombres aléatoires de la classe Random d'obtenir la probabilité la plus linéaire et naturelle possible. Afin de conserver cette qualité opérationnelle, il est vivement conseillé de sélectionner un port approprié (voir la liste ci-dessous). Ports des automates programmables concernés par l'ADC : Automate programmable MODULABLE 20 :
- Port GPIO 15 (PC0) = ADC0 (analog to digital converter 0)
- Port GPIO 16 (PC1) = ADC1 (analog to digital converter 1)
- Port GPIO 17 (PC2) = ADC2 (analog to digital converter 2)
- Port GPIO 18 (PC3) = ADC3 (analog to digital converter 3)
- Port GPIO 19 (PC4) = ADC4 (analog to digital converter 4)
- Port GPIO 20 (PC5) = ADC5 (analog to digital converter 5)

Automate programmable MODULABLE 32 :
- Port GPIO 25 (PA7) = ADC7 (analog to digital converter 7)
- Port GPIO 26 (PA6) = ADC6 (analog to digital converter 6)
- Port GPIO 27 (PA5) = ADC5 (analog to digital converter 5)
- Port GPIO 28 (PA4) = ADC4 (analog to digital converter 4)
- Port GPIO 29 (PA3) = ADC3 (analog to digital converter 3)
- Port GPIO 30 (PA2) = ADC2 (analog to digital converter 2)
- Port GPIO 31 (PA1) = ADC1 (analog to digital converter 1)
- Port GPIO 32 (PA0) = ADC0 (analog to digital converter 0) Puis la fonction statique integer est appelée prenant en paramètres l'intervalle de nombres aléatoires souhaitée (de 1 à  6 dans l'exemple), ceux-ci peuvent être indifféremment plus petits ou plus grands l'un par rapport à  l'autre (de 6 à  1). Après calculs, cette fonction retourne un nombre entier aléatoire que vous pouvez utiliser dans votre programme. À noter que ce sont chaque bit du nombre aléatoire généré dans l'intervalle de nombres demandé qui fera l'objet d'un calcul et d'un traitement distinct via le bruit analogique récupéré et le générateur de bruit artificiel, ce qui garanti une probabilité la plus linéaire et naturelle possible. Une autre fonction existe : Une fonction statique boolean permet de générer et retourner un état binaire false (faux) ou true (vrai) aléatoire. Références :  Récapitulatif des fonctions de cette classe : static void seed (const unsigned char PIN_ANALOG);
static bool boolean();
static signed long integer (const signed long MIN, const signed long MAX); Programmation et graphismes de la page : Sylvain Mahé"

Ajoutes de l'aléatoire pour que les leds clignotent au hasard.

Citation de: ChatGPT
Pour ajouter de l'aléatoire au clignotement des LED, nous pouvons utiliser la classe Random de la bibliothèque MODULE pour générer des délais aléatoires entre les changements d'état des LED. Voici une version mise à  jour du programme avec des délais aléatoires pour les LED rouge et violette :

#include <Timer.h>
#include <GpioWrite.h>
#include <Random.h>

int main()
{
    GpioWrite redLed = GpioWrite(1); // LED rouge sur le port GPIO 1
    GpioWrite purpleLed = GpioWrite(2); // LED violette sur le port GPIO 2
    Timer timer1 = Timer();
    Timer timer2 = Timer();

    timer1.start(0);
    timer2.start(0);

    Random::seed(25); // Utilise le port GPIO 25 pour générer des nombres aléatoires

    while (true)
    {
        timer1.state();
        timer2.state();

        // Tâche pour la LED rouge avec délai aléatoire :
        if (timer1.ms >= Random::integer(500, 2000)) // Délai aléatoire entre 500 et 2000 ms
        {
            redLed.toggle();
            timer1.start(0);
        }

        // Tâche pour la LED violette avec délai aléatoire :
        if (timer2.ms >= Random::integer(500, 1500)) // Délai aléatoire entre 500 et 1500 ms
        {
            purpleLed.toggle();
            timer2.start(0);
        }

        // Autres tâches à  effectuer en parallèle...

    }

    return 0;
}

Dans cette version mise à  jour, j'ai ajouté l'inclusion de la bibliothèque `Random.h` et appelé la fonction `Random::seed(25)` pour initialiser la génération de nombres aléatoires en utilisant le port GPIO 25. Ensuite, j'ai utilisé la fonction `Random::integer(min, max)` pour générer des délais aléatoires entre les changements d'état des LED. Les délais aléatoires sont compris entre 500 et 2000 ms pour la LED rouge et entre 500 et 1500 ms pour la LED violette.

N'oubliez pas d'ajuster les numéros des ports GPIO en fonction de votre configuration matérielle spécifique.

Globalement c'est correct (même si il y a des fautes) pour ça et d'autres choses, comme la littérature assez simple, ou la capacité d'amalgamer tout un "bordel" textuel sans le comprendre, ce que font naturellement nos hommes politiques.

26
Discussion Générale d'Électronique / Schéma YouTube bizarre
« le: Mai 25, 2023, 05:45:19 pm »
Bonjour à  vous, j'aimerais votre pensée sur ce schéma qu'on trouve depuis quelques temps, qui permettrait des miracles selon leur auteur afin de faire fonctionner un moteur triphasé synchrone sans balais sans capteurs de position du rotor :



Sachant qu'il manque au moins dans cette vue le point milieu du stator auquel le positif de l'alimentation est branché.

27
Bonjour à  vous,

Voir photos (schémas à  venir) :














Voir la vidéo en fonctionnement : https://youtu.be/BBTFnXLWgNg

28
Bonjour à  vous,

Je partage avec vous ma première fabrication qui m'a aidée à  comprendre ce que je commençais tout juste à  programmer : l'unité arithmétique et logique des microcontrôleurs.

La machine à  calculer 8 bits est comme son nom ne l'indique pas, compacte et légère, vous pouvez l'emmener partout dès que vous avez un problème pour additionner des nombres de 0 à  255 dont la somme (résultat) ne dépasse pas 255 !




Pour s'en servir c'est assez simple, il suffit de comprendre et lire le binaire avec un petit peu de pratique de la logique combinatoire...

Cette machine dispose de 8 bascules (registre), qui représentent à  l'état repos 8 zéros, c'est-à -dire 1 octet de poids faible (00000000). Quand vous souhaitez additionner 2 nombres, il vous faut insérer les bits (ou billes) par le dessus, de droite à  gauche (logique de la programmation). Les bascules selon leurs états (0 ou 1) changent d'état quand un bit est inséré dans le mécanisme. Ceci est le premier nombre à  additionner avec un second.

Le second nombre s'insère dans la machine de la même manière. Le résultat du calcul étant la position finale des bascules.




Exemple :
- J'insère l'octet 00001010 dans la machine (10 en décimal).
- J'insère un nouvel octet 00000111 dans la machine (7 en décimal).
- Le registre indique en binaire 00010001, soit 17 en décimal, c'est le résultat du calcul.

Citer
Quand le résultat du calcul est supérieur à  255, la machine se trouve dans une situation de dépassement de la taille du registre. Un bit (une bille) est alors éjecté à  gauche dans la 9ème case disponible, si il existait plusieurs machines en cascade, ce bit viendrait alors changer l'état d'un 9ème transistor (bascule) d'un second registre de 8 bits.

29
Bonjour à  vous,

J'ai souhaité écrire cette aide au fil de l'écoute des conversations dans les laboratoires de fabrication notamment, en effet il me semble important d'apporter des éléments de compréhension et de calculs à  chacun pour les cartes Arduino UNO afin de programmer le microcontrôleur ATmega328P en restant dans les spécifications constructeur.

Cette aide peut ouvrir des portes d'entrées et de sorties de ou vers d'autres paradigmes de comment penser la machine que nous programmons. Mais ceci est une démarche qui doit être entreprise volontairement. Je ne peux que montrer un des chemins possibles.

Je pense que le mieux ici est de commencer par quelque chose de simple : lire une broche de la carte Arduino UNO reliée en interne au convertisseur analogique/numérique du microcontrôleur ATmega328P, ceci sans utiliser l'ide Arduino car il bride la compréhension du fonctionnement interne du microcontrôleur.

Cette idée m'est venue en entendant la phrase suivante :

Citer
"Je peux faire lire à  ma carte Arduino UNO un signal avec une impédance de 1MΩ en entrée du convertisseur analogique/numérique."

Vous allez voir que cette affirmation est importante, car qui prendra cette information pourra y croire et faire des montages qui ne fonctionneront pas, ou fonctionneront dans certaines conditions extrêmes et extrêmement spécifiques qui dérogent complètement à  la fiche technique du microcontrôleur considéré.

Exemple complet en langage C de lecture ADC avec l'ATmega328P :

La première chose à  prendre en considération lorsque nous souhaitons programmer le microcontrôleur d'une carte Arduino UNO, est la fiche technique de l'ATmega328P : https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

À l'aide de cette fiche technique nous pouvons écrire le programme suivant qui est complet (je vais expliquer les différentes lignes ci-après) :

#define _ADCSRA (*(volatile unsigned char *)(0x7a))
#define _ADMUX (*(volatile unsigned char *)(0x7c))
#define _ADCLH (*(volatile unsigned int *)(0x78))

void startAnalog()
{
      _ADCSRA = 0b10000101;
}

unsigned int readAnalog()
{
      _ADMUX = 0b01000000;
      _ADCSRA |= 0b01000000;

      while ((_ADCSRA & 0b01000000) != 0b00000000)
      {
      }

      return _ADCLH;
}

int main()
{
      startAnalog();

      while (true)
      {
            readAnalog();
      }

      return 0;
}

Cet exemple est minimaliste mais permet sans bibliothèque additionnelle et sans ide Arduino de faire fonctionner le convertisseur analogique/numérique du microcontrôleur connecté sur la broche PC0.

Dans le programme la première chose à  écrire se sont les directives préprocesseur qui permettent d’appeler les pointeurs des adresses de registres dont vous allez avoir besoin :

#define _ADCSRA (*(volatile unsigned char *)(0x7a))
#define _ADMUX (*(volatile unsigned char *)(0x7c))
#define _ADCLH (*(volatile unsigned int *)(0x78))

ADCSRA permet de démarrer le convertisseur analogique/numérique, de choisir le pré-diviseur d'horloge, et aussi de démarrer une conversion et de savoir si elle s'est terminée.

ADMUX permet d'indiquer le bon canal connecté à  la bonne broche que nous souhaitons lire, et d'indiquer si la référence de tension est interne ou externe.

ADCLH est la valeur numérique sur 10 bits de la tension mesurée sur le canal choisi.

La fonction principale :

int main()
{
      startAnalog();

      while (true)
      {
            readAnalog();
      }

      return 0;
}

Nous souhaitons démarrer le convertisseur analogique/numérique, et effectuer une lecture d'une façon périodique, c'est pourquoi nous pouvons écrire deux fonctions : startAnalog et readAnalog
Nul besoin de plus dans cette fonction principale.

La fonction startAnalog est très simple, mais renseigner un octet cohérent pour ce registre ADCSRA mérite que l'on s'y attarde plus qu'un petit peu :

void startAnalog()
{
      _ADCSRA = 0b10000101;
}

Détail de l'octet 0b10000101 :

_ADCSRA = 0b10000101;
ADC activé & pré-diviseur d'horloge = 32

La fréquence du microcontrôleur est de 16MHz. La fréquence du multiplexeur du convertisseur analogique numérique est donc égale à  :

16000000Hz à· 32 = 500000Hz = 500kHz

La fiche technique du microcontrôleur indique que la ligne du convertisseur analogique/numérique a une capacité de 14pF.

Le calcul du temps alloué à  la charge de la capacité de 14pF à  la fréquence du multiplexeur sera de :

1000000µs ෠(16000000Hz ෠32) = 2µs

Nous allons considérer un potentiomètre de résistance 10kΩ ± 5% connecté au convertisseur analogique/numérique par la broche PC0 du microcontrôleur.

La fiche technique du microcontrôleur nous indique une largeur mémoire du convertisseur analogique/numérique sur 10 bits.

La résolution du convertisseur analogique/numérique est donc de :

(2 ^ 10) - 1 = 1023

La charge et la décharge d'un condensateur est un phénomène physique exponentiel, ceci fait appel à  la constante d'Euler qui se calcule de cette façon :

(1 + 1 ෠inf) ^ inf ≈ 2,718

La charge d'un condensateur fait appel à  la constante de temps Tau. Cette constante de temps se calcule via la multiplication de la résistance par la capacité. Nous pouvons donc multiplier la résistance maximale du potentiomètre par la capacité de la ligne du convertisseur analogique/numérique :

10500 à— 0,000000000014 = 0,000000147s = 147ns

La constante de temps Tau est donc de 147ns.

Afin d'être certain que la capacité de 14pF soit assez chargée ou assez déchargée dans le temps imparti par le multiplexage du convertisseur analogique/numérique, il nous faut calculer jusqu'à  quelle valeur nous souhaitons que cette capacité ce charge. Une bonne idée consiste à  la charger assez pour tomber supérieur ou égal à  la résolution du convertisseur analogique/numérique.

Comme indiqué le phénomène physique étant exponentiel, nous pouvons utiliser la bijection réciproque de la fonction exponentiel, soit la fonction logarithme naturel, car :

e ^ ln (x) = x

Le calcul va permettre de connaître le nombre de fois que nous devons multiplier la constante de temps Tau.

Le nombre de fois la constante de temps Tau égale à  la résolution du convertisseur analogique/numérique est donc de :

ln ((2 ^ 10) - 1) ≈ 6,93

Le temps de charge de la capacité de 14pF avec la résistance de 10k ± 5% et adc 10 bits est alors de :

10500 à— 0,000000000014 à— ln ((2 ^ 10) - 1) ≈ 1,018µs

Je rappelle la période du multiplexeur du convertisseur analogique/numérique avec pré-diviseur d'horloge de 32 qui est de :

1000000 ෠(16000000 ෠32) = 2µs

Avec donc un pré-diviseur d'horloge de 32 pour le multiplexeur du convertisseur analogique/numérique, et une impédance en entrée de 10500Ω, la capacité de 14pF aura le temps de se charger à  une valeur supérieure ou égale à  la résolution du convertisseur analogique/numérique, ce qui permet d'obtenir un fonctionnement très cohérent.

Nous pouvons également calculer la résistance maximale avec adc 10 bits et période de 2µs du multiplexeur :

(1 à· (16000000 à· 32)) à· (0,000000000014 à— ln ((2 ^ 10) -1)) ≈ 20,612kΩ

Toujours dans la fiche technique du microcontrôleur, il est indiqué que le multiplexeur du convertisseur analogique numérique peut fonctionner avec une impédance en entrée de 1kΩ à  100kΩ, ceci est cohérent avec le choix du pré-diviseur d'horloge qui peut aller de 2 à  128, cela se retrouve par calcul comme précédemment :

(1 à· (16000000 à· 2)) à· (0,000000000014 à— ln ((2 ^ 10) - 1)) ≈ 1,288kΩ

(1 à· (16000000 à· 128)) à· (0,000000000014 à— ln ((2 ^ 10) - 1)) ≈ 82,451kΩ

Il est indiqué également que le convertisseur analogique/numérique est optimisé pour une impédance en entrée de 10kΩ, soit la formule du temps de charge de la capacité de 14pF avec une impédance en entrée de 10kΩ ± 0% :

10000 à— 0,000000000014 à— ln ((2 ^ 10) - 1) ≈ 970ns

Avec une impédance de 10kΩ en entrée la capacité met 970ns à  se charger à  une valeur égale à  la résolution du convertisseur analogique/numérique.

Autre importance, pour ce cas une fréquence de fonctionnement du microcontrôleur plus élevée n'est pas forcément intéressante, un exemple avec une fréquence de microcontrôleur plus basse réglée sur 8MHz :

(1 à· (8000000 à· 2)) à· (0,000000000014 à— ln ((2 ^ 10) − 1)) ≈ 2.576kΩ

(1 à· (8000000 à· 128)) à· (0,000000000014 à— ln ((2 ^ 10) − 1)) ≈ 164.902kΩ

Les calculs ci-dessus montrent que la capacité de la ligne du convertisseur analogique/numérique sera chargée davantage avec un microcontrôleur cadencé à  8MHz.


À présent vous pouvez renseigner un octet cohérent avec votre matériel pour le registre ADCSRA.
Si vous n'utilisez qu'un port ADC vous ne verrez sans doute pas de phénomène négatif au fait d'utiliser une impédance d'entrée trop élevée par rapport à  la fréquence de multiplexage choisie, car la capacité sera chargée sur plusieurs échantillons successifs, mais la malfaçon n'en reste pas moins présente et sera bien visible lorsque vous utiliserez plusieurs ports.

La suite est plus succinct, explications de la fonction readAnalog :

_ADMUX = 0b01000000;
C'est le port PC0 relié à  l'ADC0 (convertisseur analogique/numérique canal 0) & le choix de la broche AVCC pour l'alimentation du convertisseur analogique/numérique et référence de tension avec condensateur externe via la broche AREF.

_ADCSRA |= 0b01000000;
Correspond au démarrage d'une conversion analogique/numérique.

while ((_ADCSRA & 0b01000000) != 0b00000000)
{
}

Ceci boucle tant que la conversion n'est pas terminée, le bit repasse à  0 si elle est terminée.

return _ADCLH;
C'est la valeur numérique sur 10 bits de la tension mesurée sur PC0.

Il ne manque plus qu'à  compiler le programme avec avr-gcc, le compilateur gcc dédiée au microcontrôleurs d'architecture AVR, et le téléverser dans le circuit intégré avec avrdude.

N'hésitez pas si vous avez des interrogations, des idées, contributions, suggestions à  apporter.

30
Bonjour à  vous.

En rapport au titre du forum, je me permets lamentablement de proposer une définition de la bidouille, qui est celle-ci :

Citer
La bidouille est davantage ne pas comprendre ce qui fonctionne, que comprendre ce qui ne fonctionne pas.

Pages: 1 [2] 3