Copier/Coller et projets Wokwi

27 juillet 2021

A – Les copier/coller

B – Les projets sur Wokwi


A- Les copier/coller

A.1 – Arduino – Stub de départ

#include <Arduino.h>

/*
  Commentaires d'entête
*/

void setup() {
} // setup()

void loop() {
} // loop()

// Sous Arduino IDE, la fonction main() est abstraite.
// Son implémentation ressemble à :
void main() {
  init();
  setup();
  for(;;){
    loop();
  }
}


A.2 – Configuration d’un ‘snippet’ C++ dans VS-Code pour le ‘stub’ Arduino de départ: (fichier cpp.json) F1-> snippet …

{
"Arduino code de départ" : {
		"prefix" : "stub",
		"body" : [
			"/*",
			"   Projet:  $TM_DIRECTORY",
			"   Fichier: $TM_FILENAME",
			"   Auteur:  ",
			"   Date:    $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE $CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND",
			"-----------------------------------------------",
			"   Description:",
			"",
			"-----------------------------------------------",
			"   M-A-J:",
			"*/",
			"",
			"#include <Arduino.h>",
			"#define VITESSE_UART 9600",
			"",
			"void setup() {",
			" Serial.begin(VITESSE_UART);",
			" Serial.println(F(\"Début du programme ...\"));",
			"} // setup()",
			"",
			"void loop() {",
			"} // loop()",
			"",
			"// FIN DU FICHIER"
		]
	},
"Arduino main.h" : {
		"prefix" : "main_h",
		"body" : [	
			"#ifndef main_h",
			"#define main_h",
			"",
			"#endif"
		]
	}		
}

Référence: Snippets in Visual Studio Code


A.3 – Lier une librairie Installée, à un projet dans PatformIO:


1 – Afficher dans la console série

void setup() {
  // Note: Sous PlatformIO, la vitesse du terminal est de 9600 Baud.
  // Il est possible de la changer, dans le fichier platformio.ini,  avec la propriété monitor_speed = 115200. 
  Serial.begin(9600);
  Serial.print("Bonjour le ");
  Serial.println("monde!");
}

2 – Afficher un nombre en binaire et hexadécimal:

void setup() {
  unsigned int unNombre = 99;
  Serial.begin(9600);
  Serial.print("unNombre affiché en binaire: ");
  Serial.println(unNombre, BIN);
  Serial.print("unNombre affiché en hexadécimal: ");
  Serial.println(unNombre, HEX);
}

3 – Augmenter la valeur d’une variable de 5

uneVariable+=5;

4 – Diminuer la valeur d’une variable de 47

uneVariable-=47;

5 – Renseigner une broche digitale en mode de sortie (OUTPUT) et y appliquer un signal ‘ALLUMER’ (HIGH)

pinMode(noBroche, OUTPUT);
digitalWrite(noBroche, HIGH);  // Allume la DEL connectée à la broche noBroche

6 – Renseigner une broche digitale en mode d’entrée/lecture (INPUT) et lire son état

pinMode(pinPushButton, INPUT);
etatPushButton = digitalRead(pinPushButton, HIGH);  // Placer l'état du pushButton dans etatPushButton

7 – Attendre que le pushButton soit relâché avant de continuer

 if (digitalRead(BROCHE_BOUTON))        // Si bouton appuyé alors
  {
    // ... traitement ...
    while(digitalRead(BROCHE_BOUTON));  // Attendre le relâchement du bouton
    delay(50);                          // Éliminer le bruit du bouton.  
  }     

7.1 – Bouton, compteur et relai

/*
    Nos premiers pas avec un bouton interrupteur
    Lorsqu'appuyé, le bouton vaut 1 sinon, il vaut 0.
*/

#include <Arduino.h>
#include <Streaming.h>
#define LED             4
#define BOUTON          3
#define RELAI           2
#define VITESSE_SERIAL  9600

void setup() {
    Serial.begin(VITESSE_SERIAL);
    Serial << F("Début du programme ...\n");
    pinMode(LED, OUTPUT);
    pinMode(RELAI, OUTPUT);
    pinMode(BOUTON, INPUT);
    digitalWrite(LED,HIGH);
} // setup()

void loop() {
    static unsigned long i = 0;
    if (digitalRead(BOUTON)) {
      Serial << "Bouton appuyé " << ++i << " fois" << endl; 
      digitalWrite(RELAI, HIGH);
      while(digitalRead(BOUTON)); // tant que BOUTON appuyé
      delay(50);  // Debounce
      digitalWrite(RELAI, LOW);
    } // if
} // loop()

8 – Utilisation de la mémoire: char[] vs String vs F()

/*
    Projet:  
    Auteur: Alain Boudreault
    Date:   2025.01.22
    --------------------------------------------------------------
    Description:

    Démonstration de l'utilisation de la mémoire RAM/Flash 
    entre une déclaration de type char[] et String
    RAM : 218, Flash: 1546  -> char[]
    RAM : 234, Flash: 2878  -> String

    Utilisation de la Macro F() -> Chaine en Mem Flash
    RAM : 188, Flash: 1560  -> char[]
    --------------------------------------------------------------
    Advanced Memory Usage is available via 
    "PlatformIO Home > Project Inspect"
    RAM:   [=         ]   9.2% (used 188 bytes from 2048 bytes)
    Flash: [          ]   4.8% (used 1560 bytes from 32256 bytes)
*/

#include <Arduino.h>
#define MESSAGE "abcdef"

#define TESTER_F
//#define STRING

#ifndef TESTER_F
  #ifdef STRING
    String msg = MESSAGE;
  #else
    char msg[] = MESSAGE;
  #endif
#endif

int i = 50;

void setup() {
   Serial.begin(115200);
#ifndef TESTER_F
   Serial.println("Début du programme...");
   Serial.println(msg);
#else   
   Serial.println(F("Début du programme..."));
   Serial.println(F(MESSAGE));
#endif   
}

void loop() {
}

9 – Conversion d’un ‘float’ en chaine de caractères

float fPI = PI;  // sous Arduino, float == double.
char
    szStr[30],
    szF[6]; // Prévoir de la place pour le point, le signe (-) et le car de fin \0.
    
void setup( void )
{
    Serial.begin(115200);
    // dtostrf(float_value, min_largeur, nombres_apres_decimale, tableau_de_car)
    dtostrf( fPI, 4, 2, szF );
    sprintf( szStr, "PI est égal à %s", szF ); // Voir la fn snprintf()
    Serial.println( szStr );
    
}//setup

10.1 – Utilisation d’une MACRO pour l’affichage au terminal

#ifdef DEBUG
#define AFFICHER(x) Serial.print(x)
#else
#define AFFICHER
#endif

// Utilisation:
AFFICHER("Un message ...\n");

10.2 – Exemple d’une MACRO avec un nombre variable de paramètres:

#define AFFICHER(...)  Serial.print(__VA_ARGS__)

// Utilisation:
AFFICHER(255, HEX);
AFFICHER("Test");

11 – Exemple de contenu du fichier platformio.ini

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:uno]
platform      = atmelavr
board         = uno
framework     = arduino
monitor_speed = 115200
debug_tool    = avr-stub

build_flags   =  -felide-constructors -std=c++0x

;debug_port = SERIAL_PORT
;debug_port = /dev/cu.usbmodem834201

; platform_packages = 
;	toolchain-atmelavr@~3.70300.220127
; GDB stub implementation
;lib_deps =
;    jdolinay/avr-debugger @ ~1.5

12 – lcd_rgb – Variation de RED

/*
  Projet:  C:\Users\alin_\Documents\PlatformIO\Projects\Projet02\src
  Fichier: main.cpp
  Auteur:  
  Date:    2025-01-28 17:06:27
-----------------------------------------------
  Description:

-----------------------------------------------
  M-A-J:
*/

#include "main.h"

rgb_lcd ecran;

void setup() {
  Serial.begin(VITESSE_UART);
  Serial.println(F("Début du programme ..."));
  ecran.begin(16,2);
} // setup()

void loop() {
  ecran.clear();
  ecran.print("Variation de RED");
  for (int i = 255; i > 0; i-=10)
    { 
      ecran.setRGB(i,0,0);
      ecran.setCursor(0,1);
      ecran.print("i = ");
      ecran.setCursor(4,1);
      ecran.print("   ");
      ecran.setCursor(4,1);
      ecran.print(i);
      AFFICHER(i);AFFICHER("\n");
      delay(UN_COURT_MOMENT);
    }
} // loop()

// FIN DU FICHIER
// main.h
#ifndef main_h
    #define main_h
    #define DEBUG
    #include <Arduino.h>
    #define VITESSE_UART 9600
    #include "rgb_lcd.h"
    #define UN_COURT_MOMENT  100

    #ifdef DEBUG
        #define AFFICHER(...)  Serial.print(__VA_ARGS__)
    #else 
        #define AFFICHER
    #endif
#endif

13 – lcd_rgb : Défilement de caractères:

#include <Arduino.h>
#include "rgb_lcd.h"

rgb_lcd ecran;  // Déclaration de l'objet de contrôle du LCD 

void uneFonctionAmusante();
void setup() {
  ecran.begin(16,2);
  ecran.print("Coucou");
}

void loop() {
  static long unsigned int i = 1;
  ecran.clear();
  ecran.print("i = ");
  ecran.print(i++);
  delay(500);
  uneFonctionAmusante();
}

void uneFonctionAmusante(){
    
    ecran.setCursor(0, 0);  // Curseur à la position (0,0)

    // Afficher 0 à 9:
    for (int thisChar = 0; thisChar < 10; thisChar++) {
        ecran.print(thisChar);
        delay(50);
    } // for

    ecran.setCursor(16, 1); // Curseur à la position (16,1):
    ecran.autoscroll();     // Activer le défilement
    // Afficher 0 à 9:
    for (int thisChar = 0; thisChar < 10; thisChar++) {
        ecran.print(thisChar);
        delay(50);
    }
    ecran.noAutoscroll();   // Desactiver le défilement
    ecran.clear();          // Effacer l'écran:
} // uneFonctionAmusante

14 – Des exemples de la directive #pragma

#pragma once // Directive de garde

#pragma message "Ce message va apparaitre à la compilation!"

#pragma message "Compilation du fichier " __FILE__ " ..."

//
#define DO_PRAGMA(x) _Pragma (#x)
#define TODO(x) DO_PRAGMA(message ("TODO - " #x))
...
TODO(Penser à corriger ceci...)

// Traiter un fichier d'entête comme un fichier système:
#ifndef MA_LIBRAIRIE_H
#define MA_LIBRAIRIE_H
#pragma GCC system_header
void uneFonction();
#endif

// Ce qui va permettre d'utiliser la syntaxe suivant:
#include <ma_librairie.h>  // au lieu de "ma_librairie.h"
// Note, sous GCC, les deux syntaxes sont interchangeables.

La directive #pragma est la méthode spécifiée par la norme C pour fournir des informations supplémentaires au compilateur, au-delà de ce qui est exprimé dans le langage lui-même. Les formes de cette directive (couramment appelées pragmas) spécifiées par la norme C commencent par le préfixe STDC (macro qui vaut 1). Un compilateur C est libre d’attribuer n’importe quelle signification aux autres pragmas. La plupart des pragmas définis et supportés par GNU ont un préfixe GCC.

C99 a introduit l’opérateur _Pragma. Cette fonctionnalité résout un problème majeur avec #pragma : étant une directive, elle ne peut pas être générée par l’expansion d’une macro. _Pragma est un opérateur, similaire à sizeof ou defined, et peut être intégré dans une macro.

Référence et ici

NOTE: GNU ne recommande pas l’utilisation de Pragma.


15 – Utilisation de sizeof()

    char buffer[8];
    Serial << "Size of char       : " << sizeof(char) << " octet(s)" << endl;
    Serial << "Size of int        : " << sizeof(int) << " octet(s)" << endl;
    Serial << "Size of long int   : " << sizeof(long int) << " octet(s)" << endl;
    Serial << "Size of float      : " << sizeof(float) << " octet(s)" << endl;
    Serial << "Size of double     : " << sizeof(double) << " octet(s)" << endl;
    Serial << "Size of pointer    : " << sizeof(void *) << " octet(s)" << endl;
    Serial << "Size of buffer[8]  : " << sizeof(buffer) << " octet(s)" << endl;

// Ces instructions, roulant sur un Arduino Uno (MCU 8 bits), vont afficher :

Size of char       : 1 octet(s)
Size of int        : 2 octet(s)
Size of long int   : 4 octet(s)
Size of float      : 4 octet(s)
Size of double     : 4 octet(s)
Size of pointer    : 2 octet(s)
Size of buffer[8]  : 8 octet(s)

20 – Transmetteur via UART ou broches digitales

/*
 Code du transmetteur - sur le MEGA
 Note: Relier deux Arduino via le port D6
*/

#include <SoftwareSerial.h>
#include "rgb_lcd.h"
#include "Streaming.h"

#define UART_RX             6
#define UART_TX             7
#define UART_VITESSE        9600
#define MAX_NB_ALEATOIRE    99
#define UNE_SECONDE         1000
#define LCD_DEUXIEME_LIGNE  1
#define LCD_NB_LIGNE        2
#define LCD_NB_COL          16

#define UART_MEGA
#ifdef UART_MEGA
   #define portSerieTransmetteur Serial3
#else
  SoftwareSerial portSerieTransmetteur(UART_RX, UART_TX); // RX, TX
#endif

rgb_lcd lcd;  // Déclaration de l'objet de contrôle du LCD 

void setup() {
  Serial.begin(UART_VITESSE); // port natif utilisé pour le débogage
  Serial.println("Démarrage du transmetteur...");
  lcd.begin(LCD_NB_COL,LCD_NB_LIGNE);
  lcd.print("Transmetteur");
  // Initialiser le port serie 'SoftwareSerial'
  portSerieTransmetteur.begin(UART_VITESSE);
} // setup()

void loop() {
   // Transmettre un code à chaque seconde  
   // générer un nombre entre 0 et MAX_NB_ALEATOIRE - 1
   byte unCode = random(MAX_NB_ALEATOIRE); 
   portSerieTransmetteur.write(unCode);
   Serial << "Envoi du code suivant: " << unCode << endl;
   lcd.setCursor(0, LCD_DEUXIEME_LIGNE);
   lcd << "Envoi de: " << unCode;
   delay(UNE_SECONDE);
} // loop()


B – Les projets sur Wokwi

1 – Serial.println()


2 – Clignoter une DEL (broche 13)


3 – Clignoter trois DELs – Lumières de circulation


4 – Conversion de base (10,2,8,16) sur un écran LCD


5 – Lecture de l’état d’un pushButton


6 – Attendre qu’un pushButton soit relâché avant que le programme reprenne


7 – Solution DOC11.3.5 – Afficher valeur POT sur LCD


8 – Solution DOC11.3.6 – LCD + Temps qui passe + compteur bouton