Sepro's docs Open documentation

Programmation C++ avec l'API mbed pour les débutants

Ce document résume l’utilisation de l’API basique de mbed pour une prise en main.

Entrées/ Sorties Numériques

DigitalOut

  • Vérifier qu’une sortie numérique est connectée
  • Ecrire une valeur (0->Eteint ou 1-> Active) sur une sortie numérique
  • Lire l’état de la sortie numérique (0->Eteint ou 1-> Active)
#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("Etat de la led : %d \n\r", led1.read());
    ThisThread::sleep_for(SLEEP_TIME);
    led1.write(0);
    printf("Etat de la led : %d \n\r", led1.read());
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

DigitalIn

  • Allumer une led en fonction de l’état du bouton
DigitalIn bt(BUTTON1);
DigitalOut led1(LED2);

int main() {
  while (true) {
    if(bt.read()== 1) {
      led1.write(1);
    }
    else{
      led1.write(0);
    }
    led1.write(bt.read()); // Solution 2
    ThisThread::sleep_for(SLEEP_TIME);
  }
}
  • Faire clignoter led1 ou led2 en fonction de l’état du bouton
DigitalIn bt(BUTTON1);
DigitalOut led1(LED1);
DigitalOut led2(LED2);

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

Entrées / Sorties analogique

PortInOut

Commander plusieurs LED simultanément

  • Réaliser le clignotement de 3 leds simultanément
// LED1 = pb.0  LED2 = pb.7 LED3 = pb.14
#define LED_MASK 0x4081
PortOut ledport(PortB, LED_MASK);

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

Le chenillard

  • Programmer un chenillard. (led1, puis led1 et led2, puis led3, puis led3 et led2, puis led1 et led 2 et led 3)
// LED1 = pb.0  LED2 = pb.7 LED3 = pb.14
#define LED_MASK 0x4081 // 0100 0000 1000 0001

#define MASK0 0x0000
#define MASK1 0x0001
#define MASK2 0x0080
#define MASK3 0x0081
#define MASK4 0x4000
#define MASK5 0x4080

PortOut ledport(PortB, LED_MASK);

int main() {
  while (true) {
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK1;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK2;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK3;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK4;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;// LED1 = pb.0  LED2 = pb.7 LED3 = pb.14
#define LED_MASK 0x4081 // 0100 0000 1000 0001

#define MASK0 0x0000
#define MASK1 0x0001
#define MASK2 0x0080
#define MASK3 0x0081
#define MASK4 0x4000
#define MASK5 0x4080

PortOut ledport(PortB, LED_MASK);

int main() {
  while (true) {
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK1;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK2;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK3;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK4;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK5;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK;
    ThisThread::sleep_for(SLEEP_TIME);
  }
}
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK & MASK5;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = 0;
    ThisThread::sleep_for(SLEEP_TIME);
    ledport = LED_MASK;
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Sorties PWM

Augmenter luminosité LED (v1)

  • ​ Créer un programme qui 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);
  }
  }
}

Augmenter luminosité LED (v2)

  • ​ Créer un programme qui utilise le signal PWM pour augmenter ou diminuer la luminosité d’une led.
    • Le programme utilisera le terminal du PC pour communiquer avec l’application.
    • Vous utiliserez la touche ‘a’ pour augmenter et ‘d’ pour diminuer la luminosité
PwmOut led1(LED1);
char a;

int main() {
  float i = 0.0f;
  while (1) {
    scanf("%c", &a);
    if (a == 'a') {
     led1.write(i += 0.001);
    }
    if (a == 'd') {
       led1.write(i -= 0.001);
     }
    printf("duty cycle  : %f \n\r", i);
  }
}

En musique

  • Utiliser un buzzer piezo pour faire de la musique.
  • Programmer l’Hymne à la joie
#define SLEEP_TIME                  500 // (msec)

PwmOut buzzer(D5);
#define SOL 392
#define LA 440
#define SI 494
#define DO 523
#define RE 587

float frequency[15]={SI, SI, DO, RE, RE, DO, SI, LA, SOL, SOL, LA, SI, SI, LA, LA };
float beat[15]= {1000, 1000,  1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1500, 500, 2}; 

int main() {
    while(1) {  
       for (int i = 0; i < 15 ; i++)   {
            buzzer.period(1/frequency[i]);
            buzzer.write(0.5);
            printf("Frequency %f \r\n", frequency[i]);
            ThisThread::sleep_for(0.5*beat[i]);
        }
    }
}

Entrées analogiques

Lecture potentiomètre

  • Écrire un programme lisant cette entrée 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);
  }
}

Potentiomètre et LED (v1)

  • Écrire un programme qui utilise le potentiomètre comme entrée et les 3 leds comme sorties (les Led sont allumées successivement)
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

AnalogIn potm(A0);

float poten = 0.0f;

int main() {
  float Vpotm=0.0;
    while(1){
        Vpotm=potm.read();
        printf("Vpotm = %f \n \r",Vpotm); 
        ThisThread::sleep_for(SLEEP_TIME);
        if (Vpotm<=0.2){
            led1.write(0);
            led2.write(0);
            led3.write(1);
            printf ("cas1\n\r");
        }
        else if ((Vpotm>0.2) && (Vpotm<=0.4)){
            led1.write(0);
            led2.write(1);
            led3.write(0);
            printf ("cas2\n\r");
        }
        else if ((Vpotm>0.4) && (Vpotm<=0.7)){
            led1.write(1);
            led2.write(1);
            led3.write(0);
            printf ("cas3\n\r");
        }
        else if ((Vpotm>0.7) && (Vpotm<=1.0)){
            led1.write(1);
            led2.write(1);
            led3.write(1);
            printf ("cas4\n\r");
        }
    }   
}

Potentiomètre et LED (v2)

  • Écrire un programme qui contrôle l’intensité d’une led en PWM en fonction de la valeur analogique lu au potentiomètre.
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

Capteur environnement BME 280

  • Écrire le programme permettant :
    • L’initialisation du capteur,
    • La lecture de la température, de la pression et de l’humidité de ce capteur en continue
    • L’affichage des valeurs dans le terminal série

Remarque : La librairie BME280 doit être importée avant tout

#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);
  }
}

Ecran LCD Grove-LCD RGB BackLight

  • Écrire le programme permettant :
    • D’afficher « Hello World » sur la première ligne.
    • D’afficher « Ceci est un test » sur la deuxième ligne
    • De permuter la couleur de l’afficheur (en rouge, puis en vert, puis en bleu) pendant 500ms.
#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("CECI EST UN TEST");
  ThisThread::sleep_for(SLEEP_TIME * 10);
  while (true) {
    rgbLCD.setRGB(0xff, 0x00, 0x00);
    ThisThread::sleep_for(SLEEP_TIME);
    rgbLCD.setRGB(0x00, 0xff, 0x00);
    ThisThread::sleep_for(SLEEP_TIME);
    rgbLCD.setRGB(0x00, 0x00, 0xff);
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Affichage de la témpérature sur l’écran LCD

  • Écrire le programme permettant :
    • de lire la température depuis le BME280
    • d’afficher cette température sur l’écran LCD
BME280 sensor(I2C_SDA, I2C_SCL);
Grove_LCD_RGB_Backlight rgbLCD(I2C_SDA, I2C_SCL);

char str[20];
float temperature;

int main() {
  printf("\r\nTarget started.\r\n");
  rgbLCD.setRGB(0xff, 0xff, 0xff);
  rgbLCD.print("TEST");
  while (1) {
    temperature = sensor.getTemperature();
    printf("\r\n %2.2f degC, %04.2f hPa, %2.2f %%\r\n", temperature,
           sensor.getPressure(), sensor.getHumidity());
    rgbLCD.clear();
    rgbLCD.locate(0, 0);
    sprintf(str, "TEMP=%2.2f °", temperature);
    rgbLCD.print(str);
    ThisThread::sleep_for(SLEEP_TIME);
  }
}

Interruptions et Watchdog

Toggle LED again

  • En utilisant une interruption
    • Faire clignoter la led 2.
    • Faire changer d’état la led 1 lors de l’appui sur le USER_BUTTON (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(USER_BUTTON);

void flip() { led1 = !led1; }

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

Watchdog

D’après la doc Mbed

  • Ecrire un programme qui reboot automatiquement la carte toutes les 5s, sauf si l’utilisateur appuie sur le bouton poussoir
#include "mbed.h"

const uint32_t TIMEOUT_MS = 5000;
InterruptIn button(USER_BUTTON);
volatile int countdown = 9;

void trigger()
{
    Watchdog::get_instance().kick();
    countdown = 9;
}

int main()
{
    printf("\r\nTarget started.\r\n");

    Watchdog &watchdog = Watchdog::get_instance();
    watchdog.start(TIMEOUT_MS);
    button.rise(&trigger);

    uint32_t watchdog_timeout = watchdog.get_timeout();
    printf("Watchdog initialized to %lu ms.\r\n", watchdog_timeout);
    printf("Press BUTTON1 at least once every %lu ms to kick the "
           "watchdog and prevent system reset.\r\n", watchdog_timeout);

    while (1) {
        printf("\r%3i", countdown--);
        fflush(stdout);
        ThisThread::sleep_for(TIMEOUT_MS / 10);
    }
}