{"id":1609,"date":"2021-11-11T10:26:45","date_gmt":"2021-11-11T15:26:45","guid":{"rendered":"http:\/\/ve2cuy.com\/420-1c4\/?page_id=1609"},"modified":"2024-03-18T09:41:38","modified_gmt":"2024-03-18T14:41:38","slug":"solutionnaire-examen-2021","status":"publish","type":"page","link":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/solutionnaire-examen-2021\/","title":{"rendered":"Solutionnaire &#8211; Examen 2021"},"content":{"rendered":"\n<h2 class=\"has-vivid-red-color has-text-color wp-block-heading\">Version 1.0 de l&rsquo;application<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"128\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/*\n    Projet:       Solution de l'examen 2021.11.10\n    R\u00e9f\u00e9rence:    http:\/\/ve2cuy.com\/420-1c4\/index.php\/ex01-2021-11-10-_9abc\/\n    Auteur:       Alain Boudreault, aka VE2CUY\n    Date:         2021.11.10\n    Version:      1.0\n    -------------------------------------------------------------------------\n    Description:  Varier la couleur des pixels en fonction de la temp\u00e9rature, \n                  d'une temp\u00e9rature de r\u00e9f\u00e9rence variable \n                  et d'une valeur de palier variable.\n\n    NOTE:         J'ai utilis\u00e9 une technique qui n'a pas \u00e9t\u00e9 pr\u00e9sent\u00e9e\n                  en classe pour l'affichage des traces dans la console.\n\n                  Au lieu d'utiliser un delai dans la fonction loop() et\n                  de ralentir l'application, j'ai plut\u00f4t utilis\u00e9 un des\n                  'timer' du Atmega328 pour ex\u00e9cuter une fonction d'affichage\n                  des traces \u00e0 toutes les 3 secondes.\n\n    ATTENTION:    La vitesse de console s\u00e9rie est fix\u00e9e \u00e0 115200                           \n    -------------------------------------------------------------------------\n    Mise \u00e0 jour:\n\n      2021.11.11 - A.B. Ajout d'une fonction TIMER pour le d\u00e9bogage.\n      2021.11.11 - A.B. Am\u00e9lioration de la documentation du code.\n      2021.11.12 - A.B. Gestion du bouton et lecture du potentiom\u00e8tre.\n      2021.11.12 - A.B. Affichage des donn\u00e9es sur l'\u00e9cran LCD.\n      2021.11.12 - A.B. Publication de la version 1.0 de l'application             \n\n*\/\n\n\/\/ *************************************\n\/\/ D\u00e9finition des fichiers d'ent\u00eate\n\/\/ *************************************\n#include &lt;Wire.h>                         \/\/ Inclure la librairie pour I2C (le capteur SHT31 est de type I2C)\n#include \"SHT31.h\"                        \/\/ Inclure la librairie pour le capteur de temp\u00e9rature et d'humidit\u00e9 SHT31\n#include &lt;Adafruit_NeoPixel.h>            \/\/ Inclure la librairie pour la barre de pixels\n#include \"rgb_lcd.h\"                      \/\/ Inclure la librairie pour le LCD\n#include \"Streaming.h\"                    \/\/ Au besoin, pour les traces sur la console s\u00e9rie:\n\n\/\/ *************************************\n\/\/ D\u00e9finition des MACROS\n\/\/ *************************************\n#define DEBUG\n\/\/#define ARDUINO_PROF\n\n#define SERIAL_BAUD_RATE      115200\n#define PIN_BOUTON            2             \/\/ GPIO de connexion du bouton\n#define PIN_NEOPIXEL          4             \/\/ GPIO de connexion de la barre de pixels\n\n#ifdef  ARDUINO_PROF\n#define PIN_POT               A2            \/\/ GPIO de connexion du potentiom\u00e8tre pour l'Arduino du prof\n#else\n#define PIN_POT               A3            \/\/ GPIO de connexion du potentiom\u00e8tre pour l'examen\n#endif\n\n#define NUMPIXELS               10          \/\/ NB de pixels sur la barre\n#define PIXEL_ROUGE             200,22,33   \/\/ La combinaison RGB de la couleur rouge\n#define PIXEL_BLEU              25,50,150   \/\/ La combinaison RGB de la couleur bleue\n#define TEMP_REF_DEPART         22          \/\/ D\u00e9termine la valeur de d\u00e9part de la temp\u00e9rature de r\u00e9f\u00e9rence\n#define TEMP_REF_MINIMUM        19          \/\/ D\u00e9termine la valeur minimum de la temp\u00e9rature de r\u00e9f\u00e9rence\n#define TEMP_REF_MAXIMUM        33          \/\/ D\u00e9termine la valeur maximum de la temp\u00e9rature de r\u00e9f\u00e9rence\n#define PALIER_MINIMUM          1           \/\/ D\u00e9termine la valeur minimum * 10, des paliers de la temp\u00e9rature\n#define PALIER_MAXIMUM          10          \/\/ D\u00e9termine la valeur maximum * 10, des paliers de la temp\u00e9rature\n\n#define NB_CARACTERES_ECRAN_LCD 16\n#define NB_LIGNES_ECRAN_LCD     2\n\/\/ Ce qui suit sert au d\u00e9bogage du programme\n#ifdef  DEBUG\n#include &lt;avr\/io.h>\n#include &lt;avr\/interrupt.h>\n#define TIMER_TICK_PAR_SECONDE  15624\n#define DELAI_TIMER             TIMER_TICK_PAR_SECONDE * 3\n#endif\n\n\/\/ *************************************\n\/\/ D\u00e9finition des variables globales\n\/\/ *************************************\nunsigned int        valeurDuPotentiometre  = 0;\nint                 temperatureDeReference = TEMP_REF_DEPART;\nfloat               temperatureDePalier    = 0.5;                               \/\/ Fixer la valeur de d\u00e9part du palier au centre du MIN\/MAX\nint                 nbPixelsRouges         = 0;                                 \/\/ Le nom de la variable dit tout ;-)\nfloat               temperature            = 0.0;                               \/\/ Sert \u00e0 stocker la temp\u00e9rature du capteur\nunsigned long int   accumulateurClicBouton = 0;                                 \/\/ Cumule les utilisations du bouton poussoir\n                                                                                \/\/ Servira \u00e0 d\u00e9terminer si le pot ajuste la tempDeref ou le palier  \nchar                lcdLigne1[NB_CARACTERES_ECRAN_LCD + 1];                     \/\/ Servira \u00e0 construire la chaine \u00e0 afficher sur la ligne 1 du LCD\nchar                lcdLigne2[NB_CARACTERES_ECRAN_LCD + 1];                     \/\/ +1 -> la fonction sprintf ajoute un 0 \u00e0 la fin de la chaine\nSHT31               capteurTemperature;                                         \/\/ Cr\u00e9ation d'un objet pour le contr\u00f4le du capteur de temp\u00e9rature\/humidit\u00e9\nrgb_lcd             ecran;                                                      \/\/ Cr\u00e9ation d'un objet pour le contr\u00f4le de l'\u00e9cran LCD\nAdafruit_NeoPixel   pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);      \/\/ Cr\u00e9ation d'un objet pour le contr\u00f4le de la barre de pixels.\n\n\/* --------------------------- D\u00e9but du code ----------------------------- *\/\n\n\/\/ ******************************************************\n\/\/ Initialisation des objets et des param\u00e8tres de d\u00e9part.\n\/\/ ******************************************************\nvoid setup() {\n  Serial.begin(SERIAL_BAUD_RATE);         \/\/ Pour le d\u00e9bogage\n  pinMode(PIN_BOUTON, INPUT);             \/\/ Programmer la broche de connexion du bouton en mode lecture\n  capteurTemperature.begin();             \/\/ Me semble que c'est clair ;)\n  ecran.begin(NB_CARACTERES_ECRAN_LCD,\n              NB_LIGNES_ECRAN_LCD);       \/\/ Initialiser l'\u00e9cran LCD\n\n  #ifdef DEBUG\n  init_timer();                           \/\/ Initialise un Timer pour l'ex\u00e9cution automatique d'une fonction \u00e0 toutes les DELAI_TIMER\n  enteteDepart();                         \/\/ Afficher les informations de d\u00e9part\n  #endif\n\n  pixels.begin();                         \/\/ Me semble que c'est clair ;)\n  pixels.clear();                         \/\/ Effacer tous les PIXELS\n  pixels.setBrightness(50);               \/\/ Pour ne pas faire sauter le port USB sur mon pr\u00e9cieux MACBOOK PRO\n  \n  for(int i=0; i&lt;NUMPIXELS; i++) {        \/\/ Au d\u00e9part, allumer tous les pixels en bleu, parce que c'est beau ;)-\n    pixels.setPixelColor(i, \n      pixels.Color(PIXEL_BLEU));\n  } \/\/ for\n  pixels.show();                          \/\/ Actualiser l'affichage sur le module NOEPIXEL sinon, NO SHOW!\n} \/\/ setup\n\n\/\/ ******************************************************\n\/\/ Fonction principale de l'application\n\/\/ ******************************************************\nvoid loop() {\n  uint32_t couleur;                                           \/\/ Servira \u00e0 renseigner la couleur du pixel [r|b]\n  temperature     = capteurTemperature.getTemperature();      \/\/ Lire la temp\u00e9rature actuelle\n  nbPixelsRouges  = determinerLeNombreDePixelsRouges(\n    temperature, \n    temperatureDeReference, \n    temperatureDePalier);\n  \n  \/\/ ***************************************************************************\n  \/\/ Renseigner la couleur des pixels en fonction des paliers de la temp\u00e9rature\n  \/\/ ***************************************************************************\n  for (int pixelCourant = NUMPIXELS; pixelCourant >= 0; pixelCourant--) {\n    \/\/ Oui je sais, un peu complexe mais pas trop ...\n    \/\/ D\u00e9terminer s'il faut renseigner un pixel rouge ou un pixel bleu en v\u00e9rifiant si nous avons \u00e9puis\u00e9 tous les pixels bleus.\n    couleur = pixelCourant &lt; (NUMPIXELS - nbPixelsRouges) ? pixels.Color(PIXEL_BLEU) : pixels.Color(PIXEL_ROUGE);\n    pixels.setPixelColor(pixelCourant, couleur);              \/\/ Wow, rouge ou bleu, c'est selon ....\n  } \/\/ for pixelCourant\n  pixels.show();   \/\/ Actualiser l'affichage\n\n  \/\/ ********************************************************************\n  \/\/ Traiter la lecture du potentiom\u00e8tre en fonction de l'\u00e9tat du bouton\n  \/\/ ********************************************************************\n  valeurDuPotentiometre = analogRead(PIN_POT);\n  if ( accumulateurClicBouton % 2 ) {                         \/\/ Ajustement de la temp\u00e9rature de r\u00e9f\u00e9rence \n    temperatureDeReference  = map(valeurDuPotentiometre, 1023, 0, TEMP_REF_MINIMUM, TEMP_REF_MAXIMUM);\n  } else {                                                    \/\/ Ajustement de la valeur du palier\n    temperatureDePalier     = map(valeurDuPotentiometre, 1023, 0, PALIER_MINIMUM, PALIER_MAXIMUM) \/ 10.0;\n  } \/\/ if accumulateurClicBouton % 2\n\n  \/\/ ******************\n  \/\/ Gestion du bouton\n  \/\/ ******************\n  if (digitalRead(PIN_BOUTON)) {\n    accumulateurClicBouton++;                                 \/\/ Le bouton f\u00fbt appuy\u00e9 alors, incr\u00e9menter son accumulateur\n    while (digitalRead(PIN_BOUTON));                          \/\/ Attendre que le bouton soit relach\u00e9\n  }\n\n  \/\/ *************************************\n  \/\/ Afficher les valeurs sur l'\u00e9cran LCD\n  \/\/ *************************************\n  int intTemperature = round(temperature);                   \/\/ Convertir la valeur de la temp\u00e9rature en valeur enti\u00e8re\n  int intPalier      = temperatureDePalier * 10;             \/\/ Convertir la valeur de palier en valeur enti\u00e8re entre 1 et 10\n  \/\/ Note: J'ai ajout\u00e9 la car '*' apr\u00e8s la valeur de palier ou de r\u00e9f\u00e9rence en fonction de l'\u00e9tat du potentiom\u00e8tre.\n  sprintf(lcdLigne1, \"R:%02d%c P:%02d%c T:%02d\", \n      temperatureDeReference, \n      accumulateurClicBouton % 2 ? '*' : ' ',               \/\/ Afficher un '*' apr\u00e8s la valeur de r\u00e9f\u00e9rence si le pot est en mode 'tempR\u00e9f\u00e9rence'\n      intPalier, \n      accumulateurClicBouton % 2 ? ' ' : '*',               \/\/ Afficher un '*' apr\u00e8s la valeur de palier si le pot est en mode 'palier'\n      intTemperature);\n  sprintf(lcdLigne2, \"BL : %02d  RG : %02d\",NUMPIXELS - nbPixelsRouges,  nbPixelsRouges);\n  ecran.setCursor(0,0); ecran.print(lcdLigne1);\n  ecran.setCursor(0,1); ecran.print(lcdLigne2);\n\n} \/\/ loop\n\n\n\/* *********************************************************\n  Cette fonction programme une int\u00e9rruption mat\u00e9rielle sur\n  le minuteur (timer) num\u00e9ro 2 de la puce Atmega328.\n\n  Cela permet d'\u00e9x\u00e9cuter une fonction automatiquement \u00e0\n  chaque temps imparti du minuteur.\n\n  Ici, j'ai fix\u00e9 le minuteur \u00e0 3 sec.\n\n  Au bout du d\u00e9lai, la fonction ISR(TIMER1_COMPA_vect) sera\n  ex\u00e9cut\u00e9e puis le minuteur sera redemarr\u00e9 \u00e0 nouveau.\n\n  C'est technique permet de ne pas avoir \u00e0 ins\u00e9rer des \n  d\u00e9lais inutiles dans notre boucle principale.\n\n*********************************************************** *\/\nvoid init_timer() {\n  \/\/ INITIALIZE TIMER INTERRUPTS\n  cli();                      \/\/ disable global interrupts\n  TCCR1A = 0;                 \/\/ set entire TCCR1A register to 0\n  TCCR1B = 0;                 \/\/ same for TCCR1B\n  OCR1A = DELAI_TIMER;        \/\/ set compare match register to desired timer count. 16 MHz with 1024 prescaler = 15624 counts\/s\n  TCCR1B |= (1 &lt;&lt; WGM12);     \/\/ turn on CTC mode. clear timer on compare match\n  TCCR1B |= (1 &lt;&lt; CS10);      \/\/ Set CS10 and CS12 bits for 1024 prescaler\n  TCCR1B |= (1 &lt;&lt; CS12);\n  TIMSK1 |= (1 &lt;&lt; OCIE1A);    \/\/ enable timer compare interrupt\n  sei();                      \/\/ enable global interrupts\n} \/\/ init_timer()\n\n\/\/ ********************************************************************\n\/\/ Vecteur du TIMER, cette fonction sera ex\u00e9cut\u00e9e \u00e0 chaque DELAI_TIMER.\n\/\/ ********************************************************************\nISR(TIMER1_COMPA_vect)\n{\n  static unsigned long int nbTrace = 1;\n  Serial &lt;&lt; \"\\n\\n================================================================================\\n\";\n  Serial &lt;&lt; \"Trace numero ----> \" &lt;&lt; ++nbTrace &lt;&lt; endl;\n  Serial &lt;&lt; \"Le potentiom\u00e8tre renseigne \" &lt;&lt; ( accumulateurClicBouton % 2 ? \"la temperature de reference\" : \"la valeur du palier\") \n         &lt;&lt; \", valeur du POT: \" &lt;&lt; valeurDuPotentiometre &lt;&lt; endl;\n  Serial &lt;&lt; \"La temperature est \" &lt;&lt; ((temperature &lt; temperatureDeReference) ? \"inferieure\": \"superieure\") &lt;&lt; \" a la temperature de reference\" &lt;&lt; endl;\n  Serial &lt;&lt; \"Temperature: \" &lt;&lt; temperature &lt;&lt; \", reference: \" &lt;&lt; temperatureDeReference &lt;&lt; \", tempPaliers: \" &lt;&lt; temperatureDePalier &lt;&lt; endl;\n  Serial &lt;&lt; \"Delta de temperature: \" &lt;&lt; abs(temperature - temperatureDeReference) &lt;&lt; endl;\n  Serial &lt;&lt; \"Calcul du nombre de paliers: \\n\";\n  Serial &lt;&lt; \"   (temperature - temperatureDeReference) \/ temperatureDePalier = \" &lt;&lt; abs(temperature - temperatureDeReference)  \/ temperatureDePalier &lt;&lt; endl;  \n  Serial &lt;&lt; \"NB pixels rouges = \" &lt;&lt; (nbPixelsRouges) &lt;&lt; endl;\n  Serial &lt;&lt; \"--------------------------------------------------------------------------------\\n\";\n  Serial &lt;&lt; \"Trace du contenu LCD:\\n\";\n  Serial &lt;&lt; \"  Ligne 1: '\" &lt;&lt; lcdLigne1 &lt;&lt;\"'\\n\";\n  Serial &lt;&lt; \"  Ligne 2: '\" &lt;&lt; lcdLigne2 &lt;&lt;\"'\\n\";\n  Serial &lt;&lt; \"================================================================================\\n\";\n} \/\/ ISR(TIMER1_COMPA_vect)\n\n\/\/ ************************************************************************\n\/\/ Affiche dans la console de d\u00e9bogage le texte de d\u00e9part de l'application\n\/\/ ************************************************************************\nvoid enteteDepart() {\n  Serial &lt;&lt; \"Solution de l'examen d'objets connect\u00e9s version 2021.11.12\\n\";\n  Serial &lt;&lt; \"Application par Alain Boudreault\\nVersion 1.0\\n\";\n  Serial &lt;&lt; \"----------------------------------------------------------\\n\";\n  Serial &lt;&lt; \"Temperature de depart: \" &lt;&lt; capteurTemperature.getTemperature() &lt;&lt; endl;\n  Serial &lt;&lt; \"----------------------------------------------------------\\n\\n\";  \n} \/\/ enteteDepart()\n\n\/\/ *******************************************************************************************************\n\/\/ Calculer le nombre de paliers de temp\u00e9rature sup\u00e9rieure \u00e0 la temp\u00e9rature de base.\n\/\/ Le nombre de paliers d\u00e9termine le nombre de pixels rouges \u00e0 allumer.\n\/\/ Note: \u00c9limination des valeurs n\u00e9gatives avec abs() et arrondir le r\u00e9sultat de la division avec round() \n\/\/       Si la temp\u00e9rature est > temperatureDeReference alors calculer les paliers sinon, retourner 0.\n\/\/ *******************************************************************************************************\nint determinerLeNombreDePixelsRouges(float _temperature, int _temperatureDeReference, float _temperatureDePalier) {\n  int nbPixelsRed = _temperature > _temperatureDeReference ? round(abs(_temperatureDeReference - _temperature) \/ _temperatureDePalier) : 0;\n  \/\/ Des fois que nbPixelsRouges > NUMPIXELS\n  nbPixelsRed = nbPixelsRed > NUMPIXELS ? NUMPIXELS : nbPixelsRed;\n  return nbPixelsRed; \n} \/\/ determinerLeNombreDePixelsRouges\n\n\/\/ ############################ FIN DU FICHIER ###############################\n<\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Version 1.0 de l&rsquo;application<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"ub_ctt_via":"","footnotes":""},"class_list":["post-1609","page","type-page","status-publish","hentry"],"featured_image_src":null,"_links":{"self":[{"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/pages\/1609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/comments?post=1609"}],"version-history":[{"count":14,"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/pages\/1609\/revisions"}],"predecessor-version":[{"id":1625,"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/pages\/1609\/revisions\/1625"}],"wp:attachment":[{"href":"https:\/\/ve2cuy.com\/420-1c4\/index.php\/wp-json\/wp\/v2\/media?parent=1609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}