fbpixel
Détection d’objets Raspberry Pi et TensorFlow Lite

Détection d’objets Raspberry Pi et TensorFlow Lite

Pour améliorer les performances sur Raspberry Pi vous pouvez utiliser le langage C++ ainsi que des librairies optimisées afin d’accélérer la vitesse de calcul des modèles de détection d’objets. C’est ce que propose TensorFlow Lite.

Une bonne référence pour commencer sur le sujet est le site QEngineering.

Matériel

  • Raspberry Pi 4
  • Écran+souris+clavier
  • Carte SD avec OS Raspbian 64bits

Configuration

Pour de meilleures performances, il vous faudra installer la version 64bits de Raspberry Pi OS. Cette version est disponible dans le logiciel Raspberry Pi Imager dans le menu Raspberry Pi OS (others)

Installation de Code::Blocks

Code blocks IDE est un logiciel comme Thonny ou Geany qui vous permettra de compiler et de lancer des codes écrits en C/C++

sudo apt-get install codeblocks

Installation d’OpenCV pour Cpp

Pour installer la version Cpp d’OpenCV nous passons par l’outil apt-get

sudo apt-get install libopencv-dev

Installation de TensorFlow Lite sur Raspberry Pi OS 64bits

Pour de meilleures performances sur Raspberry Pi, une solution est d’utiliser la version Lite de TensorFlow. Veuillez suivre la procédure décrite sur le site QEngineering pour installer TensorFlow Lite sur Raspberry Pi OS 64bits

N.B.: n’oubliez pas de redémarrer le Raspberry Pi après l’installation de tensorflow

Code pour la détection d’objet

Vous pouvez récupérer le code et projet sur le Github de QEngineering

On construit le modèle à partir du fichier tflite. Dans ce projet, nous utilisons MobileNet V1

    std::unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile("detect.tflite");

Puis on ouvre un flux vidéo (où un fichier vidéo ou une image)

    VideoCapture cap(0);

On exécute ensuite le modèle sur chaque image

    interpreter->Invoke();

Enfin nous traçons les résultats de la détections sur l’image et l’affichons

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/highgui.hpp>
#include <fstream>
#include <iostream>
#include <opencv2/core/ocl.hpp>
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/string_util.h"
#include "tensorflow/lite/model.h"
#include <cmath>

using namespace cv;
using namespace std;

const size_t width = 300;
const size_t height = 300;

std::vector<std::string> Labels;
std::unique_ptr<tflite::Interpreter> interpreter;

static bool getFileContent(std::string fileName)
{

	// Open the File
	std::ifstream in(fileName.c_str());
	// Check if object is valid
	if(!in.is_open()) return false;

	std::string str;
	// Read the next line from File untill it reaches the end.
	while (std::getline(in, str))
	{
		// Line contains string of length > 0 then save it in vector
		if(str.size()>0) Labels.push_back(str);
	}
	// Close The File
	in.close();
	return true;
}

void detect_from_video(Mat &src)
{
    Mat image;
    int cam_width =src.cols;
    int cam_height=src.rows;

    // copy image to input as input tensor
    cv::resize(src, image, Size(300,300));
    memcpy(interpreter->typed_input_tensor<uchar>(0), image.data, image.total() * image.elemSize());

    interpreter->SetAllowFp16PrecisionForFp32(true);
    interpreter->SetNumThreads(4);      //quad core

//        cout << "tensors size: " << interpreter->tensors_size() << "\n";
//        cout << "nodes size: " << interpreter->nodes_size() << "\n";
//        cout << "inputs: " << interpreter->inputs().size() << "\n";
//        cout << "input(0) name: " << interpreter->GetInputName(0) << "\n";
//        cout << "outputs: " << interpreter->outputs().size() << "\n";

    interpreter->Invoke();      // run your model

    const float* detection_locations = interpreter->tensor(interpreter->outputs()[0])->data.f;
    const float* detection_classes=interpreter->tensor(interpreter->outputs()[1])->data.f;
    const float* detection_scores = interpreter->tensor(interpreter->outputs()[2])->data.f;
    const int    num_detections = *interpreter->tensor(interpreter->outputs()[3])->data.f;

    //there are ALWAYS 10 detections no matter how many objects are detectable
//        cout << "number of detections: " << num_detections << "\n";

    const float confidence_threshold = 0.5;
    for(int i = 0; i < num_detections; i++){
        if(detection_scores[i] > confidence_threshold){
            int  det_index = (int)detection_classes[i]+1;
            float y1=detection_locations[4*i  ]*cam_height;
            float x1=detection_locations[4*i+1]*cam_width;
            float y2=detection_locations[4*i+2]*cam_height;
            float x2=detection_locations[4*i+3]*cam_width;

            Rect rec((int)x1, (int)y1, (int)(x2 - x1), (int)(y2 - y1));
            rectangle(src,rec, Scalar(0, 0, 255), 1, 8, 0);
            putText(src, format("%s", Labels[det_index].c_str()), Point(x1, y1-5) ,FONT_HERSHEY_SIMPLEX,0.5, Scalar(0, 0, 255), 1, 8, 0);
        }
    }
}

int main(int argc,char ** argv)
{
    float f;
    float FPS[16];
    int i, Fcnt=0;
    Mat frame;
    chrono::steady_clock::time_point Tbegin, Tend;

    for(i=0;i<16;i++) FPS[i]=0.0;

    // Load model
    std::unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile("detect.tflite");

    // Build the interpreter
    tflite::ops::builtin::BuiltinOpResolver resolver;
    tflite::InterpreterBuilder(*model.get(), resolver)(&interpreter);

    interpreter->AllocateTensors();

	// Get the names
	bool result = getFileContent("COCO_labels.txt");
	if(!result)
	{
        cout << "loading labels failed";
        exit(-1);
	}

    VideoCapture cap("James.mp4");
    if (!cap.isOpened()) {
        cerr << "ERROR: Unable to open the camera" << endl;
        return 0;
    }

    cout << "Start grabbing, press ESC on Live window to terminate" << endl;
	while(1){
//        frame=imread("Traffic.jpg");  //need to refresh frame before dnn class detection
        cap >> frame;
        if (frame.empty()) {
            cerr << "ERROR: Unable to grab from the camera" << endl;
            break;
        }

        Tbegin = chrono::steady_clock::now();

        detect_from_video(frame);

        Tend = chrono::steady_clock::now();
        //calculate frame rate
        f = chrono::duration_cast <chrono::milliseconds> (Tend - Tbegin).count();
        if(f>0.0) FPS[((Fcnt++)&0x0F)]=1000.0/f;
        for(f=0.0, i=0;i<16;i++){ f+=FPS[i]; }
        putText(frame, format("FPS %0.2f", f/16),Point(10,20),FONT_HERSHEY_SIMPLEX,0.6, Scalar(0, 0, 255));

        //show output
//        cout << "FPS" << f/16 << endl;
        imshow("RPi 4 - 1,9 GHz - 2 Mb RAM", frame);

        char esc = waitKey(5);
        if(esc == 27) break;
    }

  cout << "Closing the camera" << endl;
  destroyAllWindows();
  cout << "Bye!" << endl;

  return 0;
}

Les résultats de ce code montre une détection d’objet à une vitesse entre 10 et 20 FPS mais avec une faible précision sur cet exemple.

Une étude avec d’autres exemples et modèles doit être mené mais ce projet montre l’intérêt de C++ et Tensorflow Lite pour la détection d’objet sur Raspberry Pi

Sources

Installer et configurer GRBL pour Ramps 1.4 (MPCNC)

Installer et configurer GRBL pour Ramps 1.4 (MPCNC)

Nous allons voir dans ce tutoriel comment configurer le firmware GRBL 0.9 pour Ramps 1.4 avec Arduino Mega 2560 et s’interfacer avec LaserGRBL. Pour contrôler votre CNC ou MPCNC avec LaserGRBL, vous avez besoin d’installer et de configurer un Firmware sur votre carte Arduino, pour qu’elle puisse interpréter correctement les ordres et commandes de votre software de gravure/découpe Laser, qu’on appelle un émetteur G-code ( G-code étant le langage de programmation pour les machines CNC ). Dans ce tutoriel nous aborderons LaserGRBL

Ce tutoriel fait suite à celui-ci : Installation et câblage d’une carte Ramps 1.4 pour une MPCNC.

Matériel

  • Arduino MEGA 2560
  • Carte RAMPS 1.4
  • 1 Laser 20W : LD4070HA
  • 5 Moteurs pas à pas : 17HS15-1504S-X1
  • 3 Pilotes de moteurs pas à pas : DRV8825

Softwares

Nettoyer l’EEPROM

Avant de de télécharger et téléverser GRBL sur votre carte, il faut s’assurer que toutes les valeurs stockées sont nettoyées, et pour cela on a besoin du code suivant pour remettre les paramètres par défaut de votre carte :

/*
 * EEPROM Clear
 *
 * Sets all of the bytes of the EEPROM to 0.
 * Please see eeprom_iteration for a more in depth
 * look at how to traverse the EEPROM.
 *
 * This example code is in the public domain.
 */

#include <EEPROM.h>

void setup() {
  // initialize the LED pin as an output.
  pinMode(13, OUTPUT);
  
  /***
    Iterate through each byte of the EEPROM storage.
    Larger AVR processors have larger EEPROM sizes, E.g:
    - Arduino Duemilanove: 512 B EEPROM storage.
    - Arduino Uno:         1 kB EEPROM storage.
    - Arduino Mega:        4 kB EEPROM storage.
    Rather than hard-coding the length, you should use the pre-provided length function.
    This will make your code portable to all AVR processors.
  ***/

  for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }

  // turn the LED on when we're done
  digitalWrite(13, HIGH);
}

void loop() {
  /** Empty loop. **/
}

Brancher votre carte Arduino en liaison série avec son câble USB, copier et coller ce code dans votre Arduino IDE et puis uploader pour nettoyer l’EEPROM.

Modification de GRBL pour Ramps

Vous pouvez télécharger GRBL for Ramps sur ce Repository Github. Si vous ne savez pas utiliser Git, vous pouvez suivre ce tutoriel pour avoir les bases de cet outil.

Le Firmware GRBL a été modifié à certains endroits pour qu’il soit adapté à notre MPCNC. Avant d’uploader le Firmware avec Arduino IDE, voici les paramètres à vérifier par rapport à votre installation :

// Enables variable spindle output voltage for different RPM values. On the Arduino Uno, the spindle
// enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled.
// NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch!
// The hardware PWM output on pin D11 is required for variable spindle output voltages.
#define VARIABLE_SPINDLE // Default disabled. Uncomment to enable.<----------------------------------- Uncommented for Ramps 1.4 

Ici, on décommente la ligne #define VARIABLE_SPINDLE dans le fichier config.h pour avoir le contrôle en PWM sur le laser.

/*-----------------------------------------------------------suite du code---------------------------------------------------*/
// Define spindle enable and spindle direction output pins.
#define SPINDLE_ENABLE_DDR   DDRH
#define SPINDLE_ENABLE_PORT  PORTH
#define SPINDLE_ENABLE_BIT   6  // MEGA2560 Digital Pin 9 <---------- Modified for Ramps 1.4. Orignal was BIT 3 for Digital Pin 6
#define SPINDLE_DIRECTION_DDR   DDRE
#define SPINDLE_DIRECTION_PORT  PORTE
#define SPINDLE_DIRECTION_BIT   3 // MEGA2560 Digital Pin 5

// Define flood and mist coolant enable output pins.
// NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
// a later date if flash and memory space allows.
#define COOLANT_FLOOD_DDR   DDRH
#define COOLANT_FLOOD_PORT  PORTH
#define COOLANT_FLOOD_BIT   5 // MEGA2560 Digital Pin 8
#ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable.
#define COOLANT_MIST_DDR   DDRH
#define COOLANT_MIST_PORT  PORTH
#define COOLANT_MIST_BIT   3 // MEGA2560 Digital Pin 6 <---------- Modified for Ramps 1.4. Orignal was BIT 6 for Digital pin 9
/*-----------------------------------------------------------suite du code--------------------------------------------------*/

Ici, dans le fichier intitulé cpu_map.h, il faut bien faire attention aux pins de sortie pour le “Spindle” qui va ici correspondre à la pin pour activer ou désactiver le Laser.

#define SPINDLE_PWM_DDR		DDRB // <------------------------------ Modified for Ramps 1.4. Orignal was DDRH
#define SPINDLE_PWM_PORT    PORTB // <--------------------------- Modified for Ramps 1.4. Orignal was PORTH
#define SPINDLE_PWM_BIT		5 // MEGA2560 Digital Pin 11 <--------- Modified for Ramps 1.4. Orignal was BIT 6 for Digital Pin 9
#endif // End of VARIABLE_SPINDLE

Configuration du pinout de la carte

Toujours dans le même fichier, cpu_map.h, On modifie la pin de contrôle de la puissance du laser en PWM pour correspondre à notre câblage.

Pour comprendre un peu comment ces modifications, il faut qu’on se penche sur les schémas structurels de la carte Ramps 1.4 et de l’Arduino MEGA 2560 :

On peut remarquer que les pins digitals qui nous servent à alimenter le laser (Pin Digital 9) et celle qui sert à le contrôler (Pin Digital 11) sont définis à travers leur PORT, d’où la nécessité de les définir par leurs numéros de Port, respectivement 6 sur le PORTH et 5 sur le PORTE (PH6 et PE5 sur le schéma).
La modification PH3 pour la pin digital 6 sert juste à libérer la pin digital 9 qui utilisé de base pour un système de refroidissement qui n’est pas dans notre configuration.

Maintenant que vous avez compris les modifications apportés au Firmware, vous pouvez l’uploader sur votre carte Arduino. Attention, la compilation peut prendre plusieurs minutes, c’est normal, soyez patient.

Menu de configuration GRBL

Une fois LaserGRBL installé, ouvrez l’application puis connectez vous en liaison série USB à votre carte Arduino Mega / votre CNC :

Ensuite, cliquez sur Grbl Configuration, qui correspond aux paramètres propres à la CNC qui est connectée. Vous ne pouvez que modifier et réécrire les valeurs lorsque LaserGRBL est connecté à votre CNC.

Vous aurez accès aux paramètres de votre CNC , valeurs qui seront enregistrés sur votre carte Arduino.

N.B.: si vous utilisez plusieurs machines ou plusieurs ordinateurs, vous pouvez exporter et importer vos paramètres de configuration

Désactivation des limites de position

Tout d’abord, commencez par désactiver les Soft Limits en mettant à 0 la valeur de la ligne Soft limits enable (&20 et $21). Cela rendra les premiers tests plus simples sans que LaserGRBL pense que votre machine se trouve en dehors de ses dimensions.

Configuration des paramètres

Les paramètres importants ici tous ceux qui concernent les axes X, Y et Z.
Pour régler la valeur de travel resolution, aussi dit la résolution de déplacement de chaque axe, il faut se référer à l’équation :
Résolution de déplacement = (Pas par tour * Réduction mécanique) / Micro-pas

  • Pas par tour (Step per Revolution) : C’est le nombre de pas effectués par le moteur pour effectuer une rotation complète.(ici 200 pas par tour)
  • Réduction mécanique (Gear Reduction) : Si votre système utilise des engrenages ou des poulies pour réduire ou augmenter le couple, vous devez prendre en compte le rapport de réduction mécanique. Cela affectera la résolution de déplacement effective de l’axe. Nous utilisons des courroies qui ont pour valeur 40 : 1 de réduction mécanique.
  • Micro-pas (Microstepping) : Certains contrôleurs de moteur pas à pas prennent en charge le micro-pas, qui permet de diviser chaque pas électrique. Cela permet une meilleure résolution. Les valeurs possibles sont 1/2, 1/4, 1/8, 1/16, etc. (Ici on a 1/32).

Pour l’accélération, veuillez vous référer à la valeur donner sur la datasheet du moteur.

Notes sur le calcul des paramètres

  • Résolution

Pour un système poulie (20dents) courroie (pas 2mm) avec micro-pas (1/32), le rapport de réduction est donné par:

( 200 * 32 ) / (20*2) = 160 step/mm

Pour un système à vis sans fin avec un ratio de 8mm par revolution et micro-pas (1/32), on a

( 200 * 32 ) / 8 = 800 step/mm.

  • vitesse maximale

Pour la vitesse maximale, soit le Maximum Rate vous pouvez utiliser l’équation suivante :

Vitesse maximale = (Pas par tour * Fréquence maximale d’impulsions de pas) / (Micro-pas * 60)

Dans notre cas
Vitesse maximale = ( 200*36 000) / ( 40*60 ) = 3000 mm/min.

  • zone de travail

La taille maximale de déplacement(maximum travel) dépend de la surface réelle de travail de votre CNC. Pour la mesurer :

  • Configurez tout d’abord les paramètres précédents
  • Avec les flèches de l’interface utilisateur de LaserGRBL, déplacez la tête de votre CNC jusqu’au coin bas gauche.
  • Allumez le laser avec le bouton Focus et marquez l’endroit où il pointe, en allumant le laser avec une forte puissance par exemple.
  • répéter l’opération dans tous les coins.
  • mesurez la surface de travail avec une règle ou un mètre.

Modification et ajout de bouton sur LaserGRBL

Pour modifier un bouton, il suffit de clique-droit dessus et choisissez “Editer le bouton”

Vous pouvez modifier GCode envoyer par le bouton ainsi. Pour que le Laser Focus ainsi que Blink marche à 3% de sa puissance, vous pouvez mettre ces GCodes suivant.

; pour GCode
M3 S30
G1 F1000
; pour GCode2
M5 S0
G0

Pour créer votre propre bouton, vous pouvez faire clique-droit sur une zone vide de l’interface utilisateur où il n’y a pas de bouton et choisissez “Ajouter un bouton personnalisé”. Cela peut être utile par exemple pour ajouter de quoi manipuler l’axe Z si vous voulez changer la hauteur de l’outil de votre CNC :

  • Entrer : permet de choisir si c’est un bouton qui s’active en cliquant une fois dessus, en maintenant appuyé, qui s’enclenche et se déclenche en cliquant dessus, etc..
  • Caption : ce sera le nom afficher de votre bouton
  • Info-bulle : permet de décrire ce que fait votre bouton
  • Activé : permet de savoir quand est-ce que le bouton sera débloqué, ici Idle signifie qu’il sera actif seulement si la CNC est connecté et déverrouillé.
  • GCode : c’est là où on met les lignes de commandes qu’enverra votre bouton à votre CNC.
    Voici différents GCode pour 6 boutons pour déplacer l’axe Z avec une précision différente :
G91 Z-10 ; Monter l'axe Z de 10mm
G91 Z10 ; Descendre l'axe Z de 10mm
G91 Z-5 ; Monter l'axe Z de 5mm
G91 Z5 ; Descendre l'axe Z de 5mm
G91 Z-1 ; Monter l'axe Z de 1mm
G91 Z1 ; Descendre l'axe Z de 1mm

Sources

  • https://planet-cnc.com/how-to-setup-cnc/
  • https://blog.orientalmotor.com/motor-sizing-basics-part-3-acceleration-torque-and-rms-torque
  • https://lasergrbl.com/configuration/
  • https://docs.v1e.com/learn/gcode/
  • https://www.youtube.com/watch?v=erXw09OcdeU
Installer PlatformIO IDE sur Visual Studio Code

Installer PlatformIO IDE sur Visual Studio Code

Dans ce tutoriel nous allons configurer Visual Studio Code pour pouvoir lancer des scripts C/C++ avec PlatformIO IDE, qui est très utile pour programmer des microcontrôleurs tels que Arduino ou ESP32.

Matériel

  • Ordinateur
  • Carte Arduino UNO ou autre
  • Câble USB pour connecter la carte Arduino au PC

Installation de Visual Studio Code et de PlatformIO IDE

Suivez les étapes d’installation en téléchargeant .Net 6.0

Ouvrez ensuite Visual Studio Code.

Cherchez PlatformIO IDE dans l’onglet “Extensions” sur la colonne à gauche de Visual Studio Code et cliquez sur “installer”.

Une fois installé, fermez puis relancez Visual Studio Code pour que le logiciel soit bien paramétré avec PlatformIO IDE. Vous devriez alors arrivez sur la page d’accueil de l’IDE.

Démarrer votre premier Project en C avec PlatformIO IDE

Pour cela, cliquez sur ” + New Project ” et remplissez la fenêtre qui apparaît.

Ici, en terme d’exemple, j’ai choisi une carte Arduino Uno et le cadre sera aussi de type Arduino, c’est à dire que l’on va retrouver les fonctions setup() et loop() dans le fichier principal main. La création de projet peut prendre un peu de temps.

On peut remarquer à gauche dans l’espace de travail notre projet qu’on retrouve différent sous dossier. C’est le dossier ” src ” qu’on va retrouver les scriptes sources du projet, dont le fichier principal “main.cpp ” dans lequel on a va écrire notre scripte pour programmer notre carte Arduino Uno. Dans ce cadre préconstruit Arduino, on peut remarquer que dans l’entête dans du programme la ligne de commande ” #include “. Cette ligne de commande est très importante car elle permet à votre projet d’utiliser toutes les librairies et les fonctions principales que l’ont peut retrouver dans Arduino IDE.

Débuter avec un programme en C sur PlatformIO IDE

Pour tester votre premier projet en C sur PlatformIO IDE, vous allez téléverser un petit programme pour faire clignoter une LED sur la carte Arduino Uno et avoir un retour via liaison série sur l’état de la Led sur le terminal de Visual Studio Code.

// Ici dans l'entête du programme, on inclut les librairies et prototypes de fonctions nécessaires
#include <Arduino.h>

// Ici on met nos initialisations
void setup() 
{ 
    Serial.begin(9600); //ouverture pour communiquer via le port série
    pinMode(13, OUTPUT); //On initialise le pin 13 qui est associé à la LED en sortie pour pouvoir l'allumer et l'éteindre
} //Fin de la fonction setup()

// Ici dans la fonction loop on vient placer le script qui se répètera en boucle dans l'Arduino
void loop() 
{
  digitalWrite(13,HIGH); //Place le pin digital 13 à l'état HAUT (5V) -> Led allumée
  Serial.println("Led allumée");//Nous renvoie par la liaison série l'état de la Led Allumé
  delay(500); //Met en pause le programme pendant la valeur de 500 en ms

  digitalWrite(13,LOW); //Place le pin digital 13 à l'état BAS (0V) -> Led éteinte
   Serial.println("Led éteinte");//Nous renvoie par la liaison série l'état de la Led éteinte
  delay(500); //Met en pause le programme pendant la valeur de 500 en ms
} // Fin de la fonction

Une fois votre programme copier collé, vous pouvez le téléverser. Assurez vous que l’Arduino soit bien branché à un des ports USB de votre ordinateur.
Pour téléverser le programme, il existe des raccourcis qu’on peut activer en cliquant dessus tout en bas de Studio Visual Code :

  1. compiler le programme ;
  2. compiler, nettoyer et de téléverser le programme dans la carte Arduino ( la détection du PORT USB utilisé se fait automatiquement ) ;
  3. nettoyer le Terminal ainsi que la carte microcontrôleur branché ( de supprimer le script enregistré dessus ) ;
  4. tester le programme ;
  5. ouvrir un moniteur pour la Liaison Série et recevoir des envoies de la carte ( ou d’en envoyer ). Lorsque ce moniteur appelé “Serial Monitor” est ouvert, le téléversement d’un programme est impossible. Alors avant de téléverser un nouveau programme, il faut fermer le moniteur en cliquant une fois sur le terminal, puis en appuyant sur les touches Ctrl + C ;
  6. Permet d’ouvrir un Terminal.

Une fois que vous avez cliqué sur téléversement, vous devriez avoir un retour dans un terminal qui confirme que la compilation et le téléversement a été un succès qui ressemble à ceci :

Ensuite, cliquez sur la commande pour ouvrir un Moniteur et établir la liaison série.

Vous pouvez alors observer le retour de l’état de la Led en direct sur le moniteur.

Comment installer un librairie externe sur Visual Studio Code pour la PlatformIO IDE

Pour cela rien de plus. Télécharger d’abord votre librairie externe. Une fois que vous aurez un fichier .zipp, vous devez l’extraire ( ou copiez collez de dossier non compressé de la librairie ) dans ce dossier là ( ici la librairie qui nous servira d’exemple sera ServoLib, qui sert à faciliter la commande de servo-moteur ) :

On pourra retrouver l’accès ce dossier ” lib ” de votre projet fait pour accueillir les libraires externes via Visual Studio Code.

Une fois une librairie installé dans votre projet, vous devez l’inclure dans le programme dans l’entête tel que :

Voilà, maintenant vous avez toutes les bases pour débuter sur PlatformIO IDE pour programmer en C/C++ !

Programmer un Raspberry Pi Pico avec Arduino IDE

Programmer un Raspberry Pi Pico avec Arduino IDE

Le Raspberry Pi Pico est une carte de développement basé sur le RP2040 programmable avec l’Arduino IDE. Elle possède un grand nombre d’entrées/sorties, différents bus de communication et une bonne puissance de calcul. Nous allons voir comment utiliser l’Arduino IDE pour programmer un RPi Pico.

Installer les pilotes sur l’ordinateur

Le Raspberry Pi Pico est reconnu comme un appareil de stockage USB Fat32. Il n’y a donc pas de driver particulier à installer pour le connecter à un ordinateur. Pour passer le RPi Pico en clé USB:

  • Déconnecter le Pico de son alimentation
  • Appuyer sur le bouton BOOTSEL
  • Brancher le Pico à l’ordinateur à l’aide du câble USB
  • Relâcher le bouton BOOTSEL

Ajouter les gestionnaires JSON

Pour pouvoir programmer d’autres microcontrôleurs avec l’IDE d’Arduino, il faut installer sur l’Arduino des gestionnaires de carte contenant tous les outils nécessaires pour leur programmation. Pour récupérer les gestionnaires il faut trouver l’URL correspondant. Dans le cas du Raspberry Pi Pico, https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json.

N.B.: Si vous rencontrez des problèmes de compilation, vérifiez bien si une précédente version du Pico est installée. Si c’est le cas effacez-là manuellement (C:\Users\<USERNAME>\AppData\Local\Arduino15\packages\rp2040).

Ouvrez ensuite la fenêtre Fichier>Préférences du logiciel Arduino. En bas de la page vous trouverez une zone de texte dans laquelle entrer l’URL: “URL de gestionnaire de cartes supplémentaires”. (n’oubliez pas de séparer les URL par une virgule “,”)

Installer les gestionnaires

Sous l’onglet “Outils”, suivez le chemin “Type de carte > Gestionnaire de carte”. L’IDE va charger le catalogue de carte à partir de l’URL.

Si vous recherchez le microcontrôleur dans la barre de recherche, le paquet à installer devrait s’afficher.

Sélectionner la configuration

Une fois le paquet de gestion installé, le microcontrôleur devrait apparaître dans les types de carte disponibles.

Il vous faudra ensuite connaitre les caractéristiques de votre carte pour sélectionner les bons paramètres. Toutefois, sauf cas exceptionnel, les paramètres par défaut fonctionneront sans problème.

Code exemple

Vous pouvez copier-coller ce code exemple pour tester la compilation et le téléversement. Une liste des librairies Arduino compatible avec le microcontrôleur RP2040 est disponible ici.

//Constants
#define BRIGHTNESS 200

//Parameters
const int ledPin = 25;

//Variables
bool ledStatus = 0;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init led
  pinMode(ledPin, OUTPUT);

}

void loop() {
  testLed();
}

void testLed( ) {
  digitalWrite(ledPin, HIGH);
  Serial.println(F("LED ON"));
  delay(500);
  digitalWrite(ledPin, LOW);
  Serial.println(F("LED OFF"));
  delay(500);
}

Si le téléversement fonctionne, ce message devrait s’afficher

Resetting COM15
Converting to uf2, output size: 105472, start address: 0x2000
Flashing E: (RPI-RP2)
Wrote 105472 bytes to E:/NEW.UF2

Résultat

Sources

Programmer un Raspberry Pi Pico en C++ avec Visual Studio Code

Programmer un Raspberry Pi Pico en C++ avec Visual Studio Code

Nous allons voir comment programmer le microcontrôleur Raspberry Pi Pico en C++ à l’aide du logiciel Visual Studio Code. La carte Raspberry Pi Pico est un microcontrôleur basé sur la puce RP2040 de chez Raspberry Pi. Elle est programmable en C++ et MicroPython et peut interagir avec tout type d’équipement.

Matériel

  • Ordinateur
  • Raspberry Pi Pico
  • Câble USB B Mâle vers USB Micro B

Brancher le Raspberry Pi Pico sur un port USB de votre Ordinateur

Installation et configuration de Visual Studio Code

Allez sur la page de téléchargement de Visual Studio Code et téléchargez la version correspondante à votre OS.

Lancez l’installateur et suivez la procédure

Dans extensions, chercher et installer PlatformIO IDE

N.B: Si l’installation de PlatformIO affiche une erreur, veuillez suivre les solutions décrites sur cette page. Pour la solution3: mettre à jour la version de platformio (i.e: get-platformio-1.1.2.py)

Création d’un projet pour Raspberry Pi Pico

Cliquez sur l’icone PlatformIO dans la barre à gauche puis sélectionnez Projects & Configuration dans le menu Quick Access. Créer un nouveau projet

Rechercher la carte Raspberry Pi Pico et sélectionnez le Framework Arduino

Dans l’onglet Explorer, vous pouvez éditer le fichier main.cpp (C:\Users\%USERPROFILE%\Documents\PlatformIO\Projects\RPiPico Debug\src). Copier puis coller le code exemple suivant

#include <Arduino.h>

//Variables 
bool ledStatus = 0; 

void testLed( ){ 
	digitalWrite(LED_BUILTIN,HIGH); 
  	Serial.println(F("LED ON")); 
	delay(500); 
	digitalWrite(LED_BUILTIN,LOW); 
  	Serial.println(F("LED OFF")); 
	delay(500); 
} 

void setup(){ 
	//Init Serial USB 
	Serial.begin(9600); 
	
	Serial.println(F("Initialize System")); 
	//Init led 
	pinMode(LED_BUILTIN,OUTPUT); 
 
} 
 
void loop(){ 
	testLed(); 
} 
 

Une fois votre code rédigé, vous pouvez compiler en appuyant sur l’icone “Build”

Une fois le projet compilé, vous pouvez retrouver le fichier binaire uf2 dans le dossier C:\Users\%USERPROFILE%\Documents\PlatformIO\Projects\RPiPico Debug.pio\build\pico

Vous pouvez ensuite copier le fichier firmware.uf2 sur le Raspberry Pi Pico qui est alors vu comme un appareil de stockage USB.

Prochains téléversements

Une fois qu’un premier code a été chargé sur le Raspberry Pi Pico, il ne sera plus disponible comme appareil de stockage USB. Pour pouvoir charger un code à nouveau, il vous faut soit:

  • Débrancher le RPi Pico et le rebrancher en gardant le bouton BOOTSEL appuyé. Vous pouvez ensuite copier le fichier uf2 compilé.
  • Utiliser la fonction Upload de PlatformIO pour programmer le Pico avec Visual Studio

N.B.: Si le bouton Upload de PlatformIO ne fonctionne pas, vous pouvez essayer d’installer libUSB avec Zadig

Résultats

Comme pour Arduino, vous pouvez observer les messages de debug dans le moniteur série de PlatformIO

Sources