table des matières
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
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
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
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);
}
}