table des matières
  1. Entrées/ Sorties Numériques
    1. DigitalOut
    2. DigitalIn
    3. PortOut
    4. Sorties PWM
      1. PWM et Led
      2. PWM et buzzer
    5. Entrées analogiques
      1. Lecture potentiomètre
      2. Potentiomètre et LED (v2)
  2. Liaison série I2C et bibliothèques de composant
    1. Capteur environnement BME 280
    2. Écran LCD Grove-LCD RGB BackLight
  3. Interruptions
    1. Toggle LED again

Cette page résume la mise en oeuvre basique des composants matériels et logiciels avec Mbed-os La version de mbed utilisée est la dernière stable, soit la 6.15.0 au moment de la rédaction de la page.

Entrées/ Sorties Numériques

DigitalOut

Bdd-DigitalOut

DigitalOut est une sortie numérique qui peut être piloté en tout ou rien. On peut également vérifier que la broche est connecté et lire l’état de la sortie.

Le programme ci-après fait clignoter la led1 en boucle.

#include "mbed.h"

#define SLEEP_TIME 1000ms // (msec)
DigitalOut led1(LED1);

int main() {
  if(led1.is_connected())  {
    printf("led1 OK. Debut prog ! \n\r");
  }
  while (true) {
    //led1 = !led1;
    led1.write(1);
    printf("État de la led : %d \n\r", led1.read());
    ThisThread::sleep_for(SLEEP_TIME);
    led1.write(0);
    printf("État de la led : %d \n\r", led1.read());
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Information : On peut visualiser la sortie écran avec mbed sterm

mbed sterm --port /dev/ttyACM0

DigitalIn

Bdd-DigitalIn

DigitalIn est une entrée numérique tout en rien. On peut lire cette entrée et effectuer une action en fonction de l’état de l’entrée

Ce programme allume la led1 lorsque le bouton est enfoncé.

DigitalIn bt(BUTTON1);
DigitalOut led1(LED1);

int main() {
  while (true) {
    if(bt.read()== 1) {
      led1.write(1);
    }
    else{
      led1.write(0);
    }
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Information : Selon la valeur de SLEEP_TIME, il y a un temps de réaction plus ou moins long. Nous verrons une autre (et meilleure) solution plus tard avec les interruptions.

PortOut

On peut aussi commander les broches d’un port simultanément. Ici, les LED2 et LED3

// LED1 = pb.0  LED2 = pb.7 LED3 = pb.14
#define LED_MASK 0x4080
PortOut ledport(PortB, LED_MASK);

int main() {
  while (true) {
    ledport = 0x4080;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0x0000;
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Sorties PWM

Le PWM (Pulse Width Modulation) permet de commander une sortie numérique plus finement.

Attention
Toutes les sorties de la carte ne peuvent pas être commandées en PWM. Il faut se référer à la documentation de la carte pour savoir si la broche choisie supporte le PWM.

On peut s’en servir pour

  • Faire varier l’intensité d’une LED en jouant sur la tension moyenne
  • Commander un servomoteur

PWM et Led

Ce programme augmente la luminosité d’une LED en faisant passer progressivement le duty cycle de 0 à 0.1 par pas de 0.001. (La période du signal sera de 40 millisecondes)

PwmOut led1(LED1);

int main() {
  led1.period_ms(40);
  
  while (true) {
    for (float i = 0.0f; i < 0.1f; i += 0.001) {
    led1.write(i);
    ThisThread::sleep_for(10ms);
  }
  }
}

PWM et buzzer

Un buzzer se commande en PWM en réglant la fréquence de fonctionnement.

#define SLEEP_TIME                  500 // (msec)

PwmOut buzzer(D5);
#define DO 523

int main() {
  float periodPWM = 1.0/DO ;
  while(1) {  
    buzzer.period(periodPWM);
    buzzer.write(0.5);
    ThisThread::sleep_for(SLEEP_TIME);
    buzzer.write(0.0);
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Entrées analogiques

Les entrées analogiques sont directement connectées à un ADC pour conversion analogique/numérique. Il faut connaître la tension de référence et la résolution du convertisseur pour pouvoir l’utiliser correctement.

Lecture potentiomètre

Ce programme lit une entrée analogique et affiche sa valeur (brute et en volt)

AnalogIn potentiometre(A0);
float poten = 0.0f;

int main() {
  while (1) {
    poten = potentiometre.read();
    float poten2 = poten * 3.3;
    printf("Potentiomètre : %f\r\n", poten);
    printf("Valeur en Volt : %0.2f Volts\r\n", poten2);
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Attention
Par défaut, mbed n’affiche pas la valeur des réels. Pour que le programme ci-dessus fonctionne, il faut préciser que les réels doivent s’afficher lors d’un printf() dans le fichier mbed_app.json

{
    "target_overrides": {
 	"*": {
            "target.printf_lib": "minimal-printf",
            "platform.minimal-printf-enable-floating-point": true,
            "platform.minimal-printf-set-floating-point-max-decimals": 6,
            "platform.minimal-printf-enable-64-bit": false
        },
        "K64F": {
            "platform.stdio-baud-rate": 9600
        }
    }
}

Potentiomètre et LED (v2)

Ce programme combine lecture analogique et sortie PWM.

PwmOut led(D5);
AnalogIn potm(A0);

float poten = 0.0f;

int main() {
    while(1){
        led = potm.read();
    }   
}

Liaison série I2C et bibliothèques de composant

I2C

La liaison série I2C est très utilisé dans le mode de l’informatique embarqué.

Les bibliothèques de composants sont très utiles pour utiliser des fonctionnalités plus évoluées.

Capteur environnement BME 280

LE BME280 est un capteur environnemental (température, pression, humidité). Avant de l’utiliser dans un programme, il faut importer la librairie du capteur.

mbed add http://os.mbed.com/users/MACRUM/code/BME280/

Ce programme affiche sur le terminal série les valeurs de température, pression et humidité.

#include "BME280.h"
BME280 sensor(I2C_SDA, I2C_SCL);

float temperature = 0.0f;

int main() {
  printf("\r\n Target Started \r\n");
  while (1) {
    temperature = sensor.getTemperature();
        printf("\r\n %2.2f °, %04.2f hPa, %2.2f %%\r\n", temperature,
           sensor.getPressure(), sensor.getHumidity());
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Écran LCD Grove-LCD RGB BackLight

Cet écran LCD se commande grâce à une liaison série I2C.

Avant de l’utiliser, il faut ajouter la bibliothèque de composant de l’écran

mbed add http://os.mbed.com/users/sepro/code/Grove_LCD_RGB_BacklightvMbed6/

Le programme suivant :

  • Affiche « Hello World » sur la première ligne.
  • Affiche « Écran LCD » sur la deuxième ligne
#include "Grove_LCD_RGB_Backlight.h"

#define SLEEP_TIME 1000ms

Grove_LCD_RGB_Backlight rgbLCD(I2C_SDA, I2C_SCL);

int main() {
  printf("\r\nTarget started.\r\n");
  rgbLCD.setRGB(0xff, 0xff, 0xff);
  rgbLCD.print("HELLO WORLD");
  rgbLCD.locate(0, 1);
  rgbLCD.print("Ecran LCD");
}

Interruptions

Certaines des broches peuvent détecter une interruption matérielle. Lors de la détection de celle-ci, une callback d’interruption est appelée.

Toggle LED again

Le programme ci-dessous utilise une interruption

Faire clignoter la led 2. Faire changer d’état la led 1 lors de l’appui sur le BUTTON1 (si la led est allumée, elle s’éteint et inversement)

#include "mbed.h"

#define SLEEP_TIME 200ms

DigitalOut led1(LED1);
DigitalOut led2(LED2);

InterruptIn bt(BUTTON1);

void flip() { led1 = !led1; }

int main() {
  printf("\r\nTarget started.\r\n");
  bt.rise(&flip);
  while (true) {
    led2 = !led2;
    ThisThread::sleep_for(SLEEP_TIME);
  }
}