Using the Fiddle


The Fiddle is a small add-on board providing some basic UI (User Interface).
It features the exact same footprint as the ioNode, and therefore can easily be added to anything that relies on the ioNode (or even just the ioNode itself).

The Fiddle module features a 128x32 I2C OLED display, a 5-way tactile switch (mini-joystick) as well as 2 buttons.
A library is provided to simplify development of applications using this add-on.

This page will present some usage examples for this module.

Using the library

In order to use the fiddle library, it needs to be added to the list of dependencies in dfe.conf:

# Firmware Element Configuration
# ...
  - fiddle


Before anything, we need to initialize the library. Assuming we're using the eloop library (instructions here), we can place this in our init method:

#include <fiddle/fiddle.h>

// Init
void init()
    // Initialize Fiddle module

Drawing to the display

The display included in the Fiddle is a classic I2C OLED display. Another tutorial explains how to use it: Using an I2C OLED display.

Reading input

Once the library is initialized, we can read user input from it. The fiddle_input_read method (from fiddle/input.h) will return a byte (uint8_t) representing the state of all buttons (5-way tactile switch + buttons):

uint8_t fiddle_input_read()
Returns a byte (uint8_t) representing the state of all buttons

Macros are also provided to check the bits of the return value:
  • FIDDLE_INPUT_UP(i) -> Joystick up
  • FIDDLE_INPUT_DOWN(i) -> Joystick down
  • FIDDLE_INPUT_LEFT(i) -> Joystick left
  • FIDDLE_INPUT_RIGHT(i) -> Joystick right
  • FIDDLE_INPUT_CENTER(i) -> Joystick center (press down)
  • FIDDLE_INPUT_BTN1(i) -> Button 1
  • FIDDLE_INPUT_BTN2(i) -> Button 2

This means we can check the state of each button as follows (for simplicity, we're using the eloop library):

#include <fiddle/fiddle.h>
#include <fiddle/input.h>
#include <ssd1306/ssd1306.h>
#include <ssd1306/fb.h>
#include <ssd1306/txt.h>

// Init
void init()
    // Initialize Fiddle

// Loop
void loop()
    uint8_t i;

    // Clear display

    // Read Input
    i = fiddle_input_read();

    // Display some info
    if(FIDDLE_INPUT_UP(i))      { ssd1306_txt("UP pressed!", 0, 0); }
    if(FIDDLE_INPUT_DOWN(i))    { ssd1306_txt("DOWN pressed!", 0, 0); }
    if(FIDDLE_INPUT_LEFT(i))    { ssd1306_txt("LEFT pressed!", 0, 0); }
    if(FIDDLE_INPUT_RIGHT(i))   { ssd1306_txt("RIGHT pressed!", 0, 0); }

    // Update display

Simplified UI API

The Fiddle library provides a UI abstraction layer. This is just a header file that can be included into a project to provide some syntactic sugar.

If the Fiddle is the main UI for your project, using the ui.h header is recommended.
This will help keep your code simple to read and understand.

Rewriting the previous example using this abstraction layer looks like the following:

#include <fiddle/fiddle.h>
#include <fiddle/ui.h>

// Init
void init()
    // Initialize Fiddle

// Loop
void loop()
    uint8_t i;

    // Clear display

    // Read Input
    i = input();

    // Display some info
    if(is_down_pressed(i))      { draw_text("UP pressed!", 0, 0); }
    if(is_up_pressed(i))        { draw_text("DOWN pressed!", 0, 0); }
    if(is_left_pressed(i))      { draw_text("LEFT pressed!", 0, 0); }
    if(is_right_pressed(i))     { draw_text("RIGHT pressed!", 0, 0); }

    // Update display

Available abstractions

Below is a list of all abstractions provided by the UI layer:

Display API
  • void clear_display()
  • void update_display()
Draw API
  • void draw_pixel(uint8_t x, uint8_t y, uint8_t v)
  • void draw_line(int from_x, int from_y, int to_x, int to_y, uint8_t v)
  • void draw_rect(int x, int y, int w, int h, uint8_t v)
  • void draw_ngon(uint8_t v, uint8_t n, ...)
  • void draw_circle(int x, int y, uint8_t r, uint8_t v)
  • void draw_text(void *s, int x, int y)
  • void draw_text_n(void *s, uint8_t l, int x, int y)
  • void draw_text_c(uint8_t c, int x, int y)
  • void draw_text_f(int x, int y, void *fmt, ...)
  • void draw_img(uint8_t *img, int x, int y)
  • void draw_pbar(uint8_t pct, uint8_t w, int x, int y)
Terminal API
  • void term_init()
  • void term_write(void *x, uint8_t s)
  • void term_print(void *x)
  • void term_printf(void *fmt, ...)
Input API
  • uint8_t input()
  • uint8_t is_up_pressed(uint8_t i)
  • uint8_t is_down_pressed(uint8_t i)
  • uint8_t is_left_pressed(uint8_t i)
  • uint8_t is_right_pressed(uint8_t i)
  • uint8_t is_center_pressed(uint8_t i)
  • uint8_t is_btn1_pressed(uint8_t i)
  • uint8_t is_btn2_pressed(uint8_t i)