Lost + Found PMW3901 optical flow sensor driver library for Raspberry Pi Pico C SDK
  • C 86.3%
  • Python 8.7%
  • CMake 5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-02 10:08:26 -07:00
include Initial commit of reusable lf-pmw3901 firmware package 2026-08-02 10:07:24 -07:00
src Initial commit of reusable lf-pmw3901 firmware package 2026-08-02 10:07:24 -07:00
CMakeLists.txt Initial commit of reusable lf-pmw3901 firmware package 2026-08-02 10:07:24 -07:00
conanfile.py Initial commit of reusable lf-pmw3901 firmware package 2026-08-02 10:07:24 -07:00
README.md Update README with lens handling instructions 2026-08-02 10:08:26 -07:00

lf-pmw3901

Reusable PMW3901 optical flow sensor driver library for the Raspberry Pi Pico C SDK, packaged as a Conan package. This driver is designed for the PMW3901 optical flow sensor breakout boards using the SPI interface.

This is part of the Lost + Found suite of projects.

🛠️ Usage with CMake

Copy the driver directory into your project as a subdirectory:

add_subdirectory(lib/lf-pmw3901)

target_link_libraries(your_project PRIVATE
    lf-pmw3901
)

And in your C/C++ code:

#include "lf_pmw3901.h"

🔌 Hardware Setup

Connect the PMW3901 breakout SPI pins to your Raspberry Pi Pico (using default SPI0 on GP16-GP19, or custom SPI settings):

PMW3901 Pin Function Pico 2 Physical Pin Pico 2 GP Pin Connection Description
VCC (VIN) Power Input (3.3V) Pin 36 3V3 (OUT) 3.3V Power Supply
GND Ground Pin 23 GND Common Ground (0V)
MISO (SDO/RX) SPI Microcontroller In Pin 21 GP16 SPI MISO (Serial Data Out from Sensor)
CS (CSN/SS) SPI Chip Select Pin 22 GP17 SPI CSn (Active Low, Software Controlled)
SCK (CLK) SPI Clock Pin 24 GP18 SPI Clock
MOSI (SDI/TX) SPI Microcontroller Out Pin 25 GP19 SPI MOSI (Serial Data In to Sensor)

Important

Lens Assembly Handling:

  • Don't forget to peel off the protective yellow Kapton tape over the optical sensor cavity. If left on, the sensor will be completely blind.
  • If the lens is provided separately, it might need to be secured to the optical sensor with a small dab of hot glue on the rim after removing the Kapton tape. Do not use super glue (cyanoacrylate), as its curing fumes will permanently cloud/fog the optics.

💡 Example

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "lf_pmw3901.h"

// Define custom SPI pins
#define SPI_PORT spi0
#define PIN_MISO 16
#define PIN_CSN  17
#define PIN_SCK  18
#define PIN_MOSI 19

int main() {
    stdio_init_all();
    sleep_ms(2000);

    // 1. Initialize SPI interface (SPI0 at 2 MHz)
    spi_init(SPI_PORT, 2000000);
    
    // 2. Map SPI pins to physical GP functions
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    // 3. Create and initialize device context
    lf_pmw3901_t pmw;
    if (!lf_pmw3901_init(&pmw, SPI_PORT, PIN_CSN)) {
        printf("[ERROR] Failed to initialize PMW3901 driver context or verify communication!\n");
        return -1;
    }
    printf("[SUCCESS] PMW3901 detected and initialized successfully.\n");

    // Optional: Turn on the onboard LEDs to assist tracking
    lf_pmw3901_set_led(&pmw, true);

    int16_t delta_x = 0;
    int16_t delta_y = 0;
    int32_t cum_x = 0;
    int32_t cum_y = 0;

    // Read motion in a loop
    while (true) {
        lf_pmw3901_read_motion(&pmw, &delta_x, &delta_y);
        if (delta_x != 0 || delta_y != 0) {
            cum_x += delta_x;
            cum_y += delta_y;
            printf("[MOTION] Delta X: %d | Delta Y: %d | Cum X: %d | Cum Y: %d\n",
                   delta_x, delta_y, cum_x, cum_y);
        } else {
            printf("[IDLE]   Cum X: %d | Cum Y: %d\n", cum_x, cum_y);
        }
        sleep_ms(100);
    }

    return 0;
}

⚙️ Prerequisites: Setting up Conan with uv

To install the Conan CLI package manager securely and in an isolated environment on your system, it is recommended to use uv:

# Install Conan globally as an isolated tool
uv tool install conan

This makes the conan executable available on your PATH immediately and keeps your system's Python packages clean.


📦 Consumption via Forgejo Conan Registry

The package is hosted and distributed through the Forgejo Conan Package Registry at git.clowderlabs.com.

1. Add the Remote Registry

Add the remote repository to your local Conan configuration:

conan remote add clowder https://git.clowderlabs.com/api/packages/blong/conan

2. Authenticate

Log in using your personal access token:

conan remote login -p <your_token> clowder <username>

3. Add to your Project

Add the dependency to your conanfile.txt (or conanfile.py):

[requires]
lf-pmw3901/0.0.1

Then install the dependencies:

conan install . --output-folder=build --build=missing

🛠️ Local Testing

To test building and exporting this Conan package locally without uploading, run:

conan export .

This will register lf-pmw3901/0.0.1 in your local Conan cache for offline testing.