Getting started#

Examples#

The best way for you to quickly learn about xpcc's APIs is to look at and experiment with our examples, especially if you have a development board that xpcc supports out-of-the-box. Make sure you have the toolchain installed.

Here are our favorite examples for our supported development boards:

Here are some additional examples of displays and sensors we like:

Have a look at the build system commands to see how to compile and program your targets.

Your own project#

Start your own project by cloning our getting-started project from GitHub:

git clone --recursive https://github.com/roboterclubaachen/getting-started-with-xpcc.git
cd getting-started-with-xpcc
tree
.
├── LICENSE
├── README.md
├── hello-world
│   ├── SConstruct
│   ├── main.cpp
│   └── project.cfg
└── xpcc (git submodule)

The example contains the xpcc framework as a git submodule, a SConstruct file for our build system, a project configuration file and of course the source code:

#include <xpcc/architecture/platform.hpp>

int main()
{
    Board::initialize();
    Board::Leds::setOutput();

    while (1)
    {
        Board::Leds::toggle();
        xpcc::delayMilliseconds(Board::Button::read() ? 250 : 500);
#ifdef XPCC_BOARD_HAS_LOGGER
        static uint32_t counter(0);
        XPCC_LOG_INFO << "Loop counter: " << (counter++) << xpcc::endl;
#endif
    }
    return 0;
}

You can change the development board for which you want to compile the example for in the project.cfg file:

[build]
board = stm32f4_discovery
#board = arduino_uno
#board = nucleo_f103rb
#board = stm32f072_discovery
#board = stm32f1_discovery
#board = stm32f3_discovery
#board = stm32f429_discovery
#board = stm32f469_discovery
#board = stm32f7_discovery

When you create you own project, you need to adapt the xpccpath inside the SConstruct to point to the location of the xpcc framework. Note that this allows you to use different versions of the xpcc frameworks (your own fork?) for your projects.

# path to the xpcc root directory (modify as needed!)
xpccpath = '../xpcc'
# execute the common SConstruct file
execfile(xpccpath + '/scons/SConstruct')

Show me the basics#

All of this code works the same on all platforms, however, the pin and module names may need to be adapted.

GPIO#

using Led = GpioOutputB0;
Led::setOutput();
Led::set();    // 1 instruction on AVR
Led::reset();  // 3 instructions on Cortex-M
Led::toggle();

using Button = GpioInputB0;
Button::setInput(Gpio::InputType::PullUp);
bool state = Button::read();

Buffered UART#

using Uart = Uart0;
// configure and initialize UART to 115.2kBaud
GpioOutputD1::connect(Uart::Tx);
GpioInputD0::connect(Uart::Rx);
Uart::initialize<systemClock, 115200>();

Uart::write('H');  // Ohai there
Uart::write('i');

uint8_t buffer;
while(1) {
    // create a simple loopback
    if (Uart::read(buffer)) {
        Uart::write(buffer);
    }
}

IOStream#

using Uart = Uart0;
// Create a IODevice with the Uart
xpcc::IODeviceWrapper<Uart> device;
xpcc::IOStream stream(device);

GpioOutputD1::connect(Uart::Tx);
Uart::initialize<systemClock, 115200>();

stream << 42 << " is a nice number!" << xpcc::endl;

Software Timers#

using Led = GpioOutputB0;
xpcc::Timeout timeout(10000);   // 10s timeout
xpcc::PeriodicTimer timer(250); // 250ms period

Led::setOutput(xpcc::Gpio::High);

while(1) {
    if (timeout.execute()) {
        timer.stop();
        Led::reset();
    }
    if (timer.execute()) {
        Led::toggle();
    }
}

Have a look at the xpcc/examples/ folder for more advanced use cases.