Nouvelles:

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

Menu principal

Exemple ChatGPT3.5 qui apprend à  programmer avec une bibliothèque

Démarré par sylvainmahe, Juin 05, 2023, 12:21:53 PM

« précédent - suivant »

sylvainmahe

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

Citation de: ChatGPTEn 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: moiMODULE 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: ChatGPTLe 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: moiok. Écris un programme C++ qui utilise uniquement cette bibliothèque MODULE.

Citation de: ChatGPTVoici 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: moiok. Ajoute une autre led qui sera violette et qui va clignoter.

Citation de: ChatGPTVoici 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: moiok. Ajoutes un deuxième compteur.

Citation de: ChatGPTVoici 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: moiok. 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: ChatGPTPour 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.