Learning Mbed
To get started with Mbed I began programming a non-trivial but not complex LED library. The Pioneer PSOC6 board contains 3 user programmable LEDs: an RGB LED, an orange LED and a red LED.
The source code runs 2 threads: main() and ledThread(). main() controls the LEDs by sending messages, through an Mbeds' Queue object, to ledThread(). LEDs can operate in 3 different modes: on or off, oscillating and pulsing. The program is made of 3 files:
main.cpp
#include "mbed.h"
#include "LedThread.h"
static Thread ledThreadObject;
int main()
{
ledThreadObject.start(ledThread);
while (true)
{
printf(" O: Pulse 0.2 s \n");
ThisThread::sleep_for(5'000);
pulse(Led::o, 0.2);
printf(" R: Pulse 1.0 s \n");
ThisThread::sleep_for(5'000);
pulse(Led::r, 1.0);
printf("RGB_R: On\n");
ThisThread::sleep_for(5'000);
set(Led::rgbR, true);
printf("RGB_R: Off\n");
ThisThread::sleep_for(5'000);
set(Led::rgbR, false);
printf("RGB_G: frequency: 5.0 Hz\n");
ThisThread::sleep_for(5'000);
oscillate(Led::rgbG, 1.f / 5.f);
printf("RGB_G: frequency: 15.0 Hz\n");
ThisThread::sleep_for(5'000);
oscillate(Led::rgbG, 1.f / 15.f);
printf("RGB_G: Off\n");
ThisThread::sleep_for(5'000);
set(Led::rgbG, false);
printf("RGB_B: frequency: 2.0 Hz\n");
ThisThread::sleep_for(5'000);
oscillate(Led::rgbB, 1.f / 2.f);
printf("RGB_B: pulse: 2.0 s\n");
ThisThread::sleep_for(5'000);
pulse(Led::rgbB, 2.0);
}
}
LedThread.h
#ifndef LED_THREAD_H
#define LED_THREAD_H
// LED types
enum class Led
{
r,
o,
rgbR,
rgbG,
rgbB,
};
// LED thread
void ledThread();
// Set LED at specified state
void set(Led led, bool state);
// Generate a LED pulse at specified duration
void pulse(Led led, float duration);
// Oscillate LED at specified period (50% duty cycle)
void oscillate(Led led, float period);
#endif
LedThread.cpp
#include <cmath>
#include "mbed.h"
#include "LedThread.h"
enum class Mode
{
continuous,
pulsed,
oscillation
};
struct Properties
{
Mode mode_ = Mode::continuous;
float period_ = 0.;
float elapsed_ = 0.;
};
struct Message
{
Led led_;
Mode mode_;
float value_; // this can be on/off state (mode_ = Mode::continuous), pulse duration (mode_ = Mode::Pulsed), or period (mode_ = Mode::oscillation)
};
static Queue<Message, 16> queue;
static MemoryPool<Message, 16> pool;
static uint64_t t0 = 0;
static uint64_t t1 = 0;
static DigitalOut ledO(LED1); // Red LED
static DigitalOut ledR(LED2); // Orange LED
static DigitalOut ledRgbR(LED3); // RGB LED red
static DigitalOut ledRgbG(LED4); // RGB LED green
static DigitalOut ledRgbB(LED5); // RGB LED blue
static DigitalOut* digitalOut[5];
static Properties properties[5];
void ledThread()
{
digitalOut[static_cast<int>(Led::o)] = &ledO;
digitalOut[static_cast<int>(Led::r)] = &ledR;
digitalOut[static_cast<int>(Led::rgbR)] = &ledRgbR;
digitalOut[static_cast<int>(Led::rgbG)] = &ledRgbG;
digitalOut[static_cast<int>(Led::rgbB)] = &ledRgbB;
for (int led = 0; led < 5; led++)
*digitalOut[led] = 1;
while (true)
{
t0 = get_ms_count();
float delta = static_cast<float>(t0 - t1) / 1000.f;
t1 = t0;
for (int led = 0; led < 5; led++)
{
switch (properties[led].mode_)
{
case Mode::pulsed:
properties[led].elapsed_ += delta;
if (properties[led].elapsed_ >= properties[led].period_)
{
properties[led].mode_ = Mode::continuous;
*digitalOut[led] = 1;
}
break;
case Mode::oscillation:
properties[led].elapsed_ += delta;
if (properties[led].elapsed_ >= .5f * properties[led].period_)
{
properties[led].elapsed_ -= .5f * properties[led].period_;
*digitalOut[led] = !*digitalOut[led];
}
break;
default:
break;
}
}
osEvent event = queue.get(0);
if (event.status == osEventMessage)
{
Message* message = static_cast<Message*>(event.value.p);
int led = static_cast<int>(message->led_);
properties[led].mode_ = message->mode_;
properties[led].period_ = message->value_;
properties[led].elapsed_ = 0.f;
if (message->mode_ == Mode::continuous && !message->value_)
*digitalOut[led] = 1;
else
*digitalOut[led] = 0;
pool.free(message);
}
ThisThread::sleep_for(10);
}
}
void set(Led led, bool state)
{
Message* message = pool.alloc();
message->led_ = led;
message->mode_ = Mode::continuous;
message->value_ = static_cast<float>(state);
queue.put(message);
}
void pulse(Led led, float duration)
{
Message* message = pool.alloc();
message->led_ = led;
message->mode_ = Mode::pulsed;
message->value_ = duration;
queue.put(message);
}
void oscillate(Led led, float period)
{
Message* message = pool.alloc();
message->led_ = led;
message->mode_ = Mode::oscillation;
message->value_ = period;
queue.put(message);
}
The board looks like this when running the code:
Top Comments