Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

Building the XMP‑1: A Low‑Cost XMOS‑Raspberry Pi Mobile Platform

Introduction

The XMOS startKIT, available through Farnell (or Newark) for just £12 (VAT included), offers a compact, credit‑card‑sized platform that pairs seamlessly with a Raspberry Pi. With minimal soldering—only a screwdriver, wire cutters, and pliers—developers can assemble a functional robotics prototype that leverages XMOS’s multi‑core, low‑jitter parallel processing.

In this article we walk through the construction of the XMP‑1 (XMOS Mobile Platform), a simple mobile platform that demonstrates high‑speed, bidirectional communication between the Raspberry Pi and an XMOS startKIT via a Serial Peripheral Interface (SPI). The XMP‑1 also showcases how to control hobby servos through PWM generated directly from the XMOS board, and how to expose a web‑based user interface that drives the robot in real time.

Video demonstrations are included in the original post; the first shows the XMP‑1 learning a route, while the second captures the robot’s attempts to replay the route using continuous‑rotation servos. These videos illustrate both the potential and the limitations of the current hardware and firmware.

A Bit More Detail

This post is the second in a series of XMOS startKIT experiments. Part 1 provided an introduction to XMOS terminology, architecture, and a quick start guide with sample programs. If you are new to XMOS, reviewing Part 1 will help you grasp the concepts discussed here. Part 3 (titled “XMOS startKIT: XMOS and Raspberry Pi Oscilloscope XAE 1000”) revisits the SPI framework and introduces ADC usage and real‑time browser graphics.

For those focused solely on building and operating the XMP‑1, you can skip the extended discussion and jump straight to the code sections at the bottom of this article. The firmware can be compiled and flashed onto the startKIT as described in Part 1, and the Raspberry Pi code runs on Node.js.

Solution Overview – Hardware and Software

Figure 1 (not shown) depicts the completed XMP‑1, powered via a 5 V regulator and driven by two continuous‑rotation hobby servos. The Raspberry Pi handles all networking, running a lightweight web server that serves index.html and interprets user commands into motor speed/direction messages.

The communication flow is illustrated in Figure 2 (not shown). The Pi generates a PWM signal for the servos by sending an SPI packet to the XMOS startKIT. The startKIT, acting as an SPI slave, decodes the packet and drives the servos with the appropriate PWM pulses.

Serial Peripheral Interface (SPI)

SPI relies on four wires: SS, SCLK, MOSI, and MISO. In this setup, the Raspberry Pi is the master, providing the clock and transmitting data on MOSI. The XMOS board receives the data on MOSI and returns status or acknowledgment on MISO. The SS line is active low; the Pi’s CE1 pin is used to select the startKIT.

An oscilloscope trace (captured with a Tektronix MSO2024B) confirms the integrity of the SPI transfer. Three bytes of data—0x02, 0x00, and 0x10—were transmitted from the Pi to the startKIT, with optional zero‑length response.

Controlling Hobby Servo Motors

Hobby servos convert a 1‑to‑2 msec PWM pulse width into a 0–180° mechanical rotation, with a 1.5 msec pulse centering the shaft. Continuous‑rotation servos, a variation that removes the potentiometer and end‑stops, interpret pulse widths as speed commands: 1.5 ms for neutral, 1 ms for full reverse, and 2 ms for full forward.

Each wheel on the XMP‑1 is driven by a continuous‑rotation servo. While this setup simplifies wiring—no external H‑bridge is required—it limits precise speed control compared to DC motors.

Starting Development – Connecting up the Boards

For firmware development, the Raspberry Pi and startKIT are linked via a 26‑pin ribbon cable with IDC connectors. A spare IDC connector can serve as a debugging interface for probing signals with a multimeter or oscilloscope.

Implementing SPI (spi_process) on the XMOS startKIT

Using the xTIMEcomposer IDE, the built‑in SPI slave library is imported and the source files are placed in the spi‑test/src directory. The following initialization routine configures the clock source, MOSI/MISO ports, and the SPI slave interface:

void spi_slave_init(spi_slave_interface &spi_if)
{
    int clk_start;
    set_clock_on(spi_if.blk);
    configure_clock_src(spi_if.blk, spi_if.sclk);
    configure_in_port(spi_if.mosi, spi_if.blk);
    configure_out_port(spi_if.miso, spi_if.blk, 0);
    start_clock(spi_if.blk);
    return;
}

The spi_slave_interface structure maps the SPI pins to the XMOS ports:

typedef struct spi_slave_interface
{
    clock  blk;
    in port ss;
    in buffered port:8 mosi;
    out buffered port:8 miso;
    in port sclk;
} spi_slave_interface;

Incoming SPI data is read into a buffer using the following routine, which implements a simple tag‑length‑value (TLV) protocol to allow variable‑length messages:

void spi_slave_in_buffer(spi_slave_interface &spi_if, unsigned char buffer[], int num_bytes)
{
    unsigned int data;
    unsigned int vlen=0;
    clearbuf(spi_if.miso);
    clearbuf(spi_if.mosi);
    for (int i = 0; i < num_bytes; i++)
    {
        spi_if.mosi :> data;
        data=data<<24;
        buffer[i]=bitrev(data);
        if (i==2)
        {
            vlen=((unsigned int)buffer[1])<<8 | (unsigned int)buffer[2];
            if (vlen==0)
                break;
        }
        if (i >= vlen+2)
        {
            break;
        }
    }
}

The first byte of a packet is a tag (0–255). The next two bytes encode the payload length (up to 4096 bytes). An odd tag signals that the Raspberry Pi expects a response; an even tag indicates no response is required.

Inter‑Process Communication

XMOS cores communicate via transaction‑based interfaces rather than simple channels. This approach allows multiple data types and return values within a single interface call, which is ideal for coordinating the SPI handling core, the data processing core, and the PWM generation core.

Example interface definitions:

interface program_display
{
    void backlight(int state, int color);
    void plot(int x, int y, int color);
}

Designing the IPC Architecture to Handle SPI Content

The spi_process core captures incoming SPI data into a 4099‑byte buffer and forwards a pointer to the data_handler core via a movable array transaction. After processing, data_handler may populate the buffer with a response and signal spi_process that data is ready to be transmitted back on the next SPI exchange.

interface to_rpi
{
    void code(unsigned char c);
};

interface from_rpi
{
    unsigned char* movable array_data(unsigned char* movable bufp);
};

Core logic snippets:

void spi_process(interface to_rpi server s, interface from_rpi client c)
{
    unsigned char storage[4099];
    unsigned char* movable buf=storage;
    buf=c.array_data(move(buf));
    select
    {
        case s.code(unsigned char c):
            if (c==SEND)
            {
                spi_slave_out_buffer(spi_sif, buf, 4099);
            }
            break;
    }
}
void data_handler(interface to_rpi client c, interface from_rpi server s)
{
    select
    {
        case s.array_data(unsigned char* movable vp) -> unsigned char* movable vq:
            vq[0]=0x22;  // tag
            vq[1]=0x00;  // length
            vq[2]=0x00;
            vq=move(vp);
            tosend=1;
            break;
    }
    if (tosend)
    {
        c.code(SEND);
    }
}

This architecture delivers a general‑purpose, bidirectional communication channel between the Raspberry Pi and the XMOS startKIT, which can be adapted for a wide range of robotics or IoT projects.

Implementing PWM (servo_handler) on the startKIT

The servo control routine runs on a dedicated XMOS core and manages up to eight servos. Each servo’s PWM signal is generated by toggling an output pin at the appropriate duty cycle every 20 ms, with a microsecond resolution for fine speed adjustment. The initial values are centered (or stationary for continuous‑rotation servos), and the core updates the signal on each cycle based on the latest command received via the IPC framework.

Although the current XMP‑1 uses only two continuous‑rotation servos, the firmware supports expansion to additional motors or DC‑motor control through an H‑bridge interface if needed.

For full source code and compilation instructions, see the end of this article.


Manufacturing process

  1. Build a Multi‑Sensor Temperature & Light Monitoring System with Raspberry Pi & DS18B20
  2. Mastering Raspberry Pi Sensor & Actuator Control: Accelerometer, Servo, and Data Streaming
  3. Build a Smart Robot with the Bridge Shield – Raspberry Pi & Arduino Integration
  4. Build Your Own Raspberry Pi Robot with the MonkMakes RRB2 Kit – A Detailed Guide
  5. DIY Wall‑E Inspired Raspberry Pi CD‑Box Robot
  6. Build a Robot with Raspberry Pi and Python: A Complete Guide
  7. Build an Internet‑Controlled Video‑Streaming Robot with Arduino & Raspberry Pi
  8. Integrating Microsoft Kinect with Raspberry Pi for Real‑Time Human Detection on the Sonbi Robot
  9. Autonomous Sudoku Solving Robot
  10. Build a Raspberry Pi 3 & Arduino Laptop: Step‑by‑Step Guide