Piduino par l’exemple

Comme piduino utilise la même API que Arduino, il vous suffit de vous rendre sur la référence Arduino, ou sur n’importe quel site expliquant les fonctions du langage Arduino pour en avoir une documentation.

Premier exemple, Blink !

Le dossier exemples contient des exemples du monde Arduino qui peuvent être utilisés directement avec piduino. La seule chose à ajouter par rapport à l’exemple correspondant Arduino est la ligne :

#include <Piduino.h>

Voici le code source de l’exemple Blink qui fait clignoter une led :

#include <Piduino.h> // all the magic is here ;-)

const int ledPin = 0; // Header Pin 11: GPIO17 for RPi, GPIOA0 for NanoPi

void setup() {
  // initialize digital pin ledPin as an output.
  pinMode (ledPin, OUTPUT);
}

void loop () {
  // Press Ctrl+C to abort ...
  digitalWrite (ledPin, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay (1000);                 // wait for a second
  digitalWrite (ledPin, LOW);   // turn the LED off by making the voltage LOW
  delay (1000);                 // wait for a second
}

Évidement, vous devez connaître le numéro de broche où vous avez connecté la led ! Ce nombre dépend de votre modèle de carte Pi, pour le savoir rapidement, vous pouvez taper la commande pido readall 1, qui nous donne, par exemple, l’affichage suivant sur un Raspberry Pi B:

                                    P1 (#1)
+-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
| sOc | iNo |   Name   | Mode | V | Ph || Ph | V | Mode |   Name   | iNo | sOc |
+-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
|     |     |     3.3V |      |   |  1 || 2  |   |      | 5V       |     |     |
|   2 |   8 |    GPIO2 |   IN | 1 |  3 || 4  |   |      | 5V       |     |     |
|   3 |   9 |    GPIO3 |   IN | 1 |  5 || 6  |   |      | GND      |     |     |
|   4 |   7 |    GPIO4 |   IN | 1 |  7 || 8  | 1 | ALT0 | TXD0     | 15  | 14  |
|     |     |      GND |      |   |  9 || 10 | 1 | ALT0 | RXD0     | 16  | 15  |
|  17 |   0 |   GPIO17 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO18   | 1   | 18  |
|  27 |   2 |   GPIO27 |   IN | 0 | 13 || 14 |   |      | GND      |     |     |
|  22 |   3 |   GPIO22 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO23   | 4   | 23  |
|     |     |     3.3V |      |   | 17 || 18 | 0 | IN   | GPIO24   | 5   | 24  |
|  10 |  12 |   GPIO10 |   IN | 0 | 19 || 20 |   |      | GND      |     |     |
|   9 |  13 |    GPIO9 |   IN | 0 | 21 || 22 | 0 | IN   | GPIO25   | 6   | 25  |
|  11 |  14 |   GPIO11 |   IN | 0 | 23 || 24 | 1 | IN   | GPIO8    | 10  | 8   |
|     |     |      GND |      |   | 25 || 26 | 1 | IN   | GPIO7    | 11  | 7   |
+-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
| sOc | iNo |   Name   | Mode | V | Ph || Ph | V | Mode |   Name   | iNo | sOc |
+-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+

La colonne iNo correspond au numéro ‘Arduino’, le numéro 0 pin correspond donc à la broche 11 du connecteur GPIO (GPIO17).

Pour compiler le programme blink sur la ligne de commande, vous devez taper le commander:

$ g++ -o blink blink.cpp $(pkg-config --cflags --libs piduino)

La dernière partie de la commande utilise pkg-config pour ajouter les options de construction à g ++ afin de compiler le programme correctement.

Vous pouvez ensuite exécuter le programme:

 $ sudo ./blink

sudo est nécessaire pour accéder à la zone de mémoire du GPIO. Vous pouvez activer le bit setuid pour éviter sudo à l’avenir:

$ sudo chmod u+s blink
$ ./blink

Pour disposer d’un environnement de développement plus convivial, il est conseillé d’utiliser Codelite, l’installation de piduino ajoute un modèle de programme pour piduino. Pour créer un nouveau programme piduino dans Codelite, il faut, une fois votre workspace créé, utiliser le menu Workspace/New Project et sélectionner le modèle Simple Executable (C++ piduino) :

Modèle de projet Codelite pour piduino

Dans Codelite, on peut non seulement compiler, mais aussi éditer et surtout déboguer le programme :

Débogage avec Codelite

Deuxième exemple

le deuxième exemple rtc_bq32k, utilise la bibliothèque Wire pour lire l’heure dans un circuit BQ32000 RTC.

Cela permet de découvrir 2 différences importantes entre une carte Arduino et une carte Pi :

  1. Tout d’abord, sur une carte Pi, l’interface homme-machine (écran et clavier) est fait sur la ligne de commande (la console !). Sur Arduino, le port série est utilisé.
  2. Sur une carte Pi, un programme peut se terminer pour donner la main à l’utilisateur. Sur Arduino, le programme ne s’arrête jamais (en fait, sur un système Linux, le programme du noyau ne s’arrête jamais non plus …)

Pour résoudre le premier problème, piduino définit un objet Console dont le l’utilisation est identique à l’objet Serial (c’est une classe dérivée de Stream).

Afin de permettre la compilation sur les deux plates-formes sans modifier le code source, nous pouvons ajouter au début du programme un bloc qui teste si la plate-forme cible est un système Unix/Linux (piduino), si c’est le cas, on inclut le fichier Piduino.h, sinon on définit un alias de Console qui correspond à Serial, c’est-à-dire que l’interface homme-machine est sur le port série.

#ifdef __unix__
#include <Piduino.h>  // All the magic is here ;-)
#else
// Defines the serial port as the console on the Arduino platform
#define Console Serial
#endif

#include <Wire.h>

void printBcdDigit (byte val, bool end = false) {
  val = (val / 16 * 10) + (val % 16); // BCD to DEC

  if (val < 10) {
    Console.write ('0'); // leading zero
  }
  if (end) {

    Console.println (val);
  }
  else {

    Console.print (val);
    Console.write (':');
  }
}

void setup() {

  Console.begin (115200);
  Wire.begin(); // Starting the i2c master
}

void loop() {

  Wire.beginTransmission (0x68); // start of the frame for the RTC at slave address 0x68
  Wire.write (0); // write the address of the register in the RTC, 0 first register
  Wire.endTransmission (false); // restart condition
  Wire.requestFrom (0x68, 3); // 3-byte read request

  if (Wire.available() == 3) { // if the 3 bytes have been read
    byte sec = Wire.read();
    byte min = Wire.read();
    byte hour = Wire.read() & 0x3F; // remove CENT_EN and CENT LSB bits

    // time display
    printBcdDigit (hour);
    printBcdDigit (min);
    printBcdDigit (sec, true);
  }
  exit (0); // exit the loop() function without ever coming back.
  // On Arduino, exit() performs an infinite loop as explained on
  // https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html
  // on a Pi board, exit () stops the program by returning the supplied value.
}

Pour résoudre le second problème, il est possible d’utiliser sur les 2 les plates-formes, la fonction exit() (définie dans le bibliothèque standard). Cette fonction, compatible avec les deux plates-formes, permet d’arrêter l’exécution la fonction loop().

Sur un système Unix/Linux, cela arrête le programme et revient à la ligne de commande, sur Arduino, cela effectue une boucle infinie (après avoir appelé le destructeur d’objets C++).