Getting Started

Learn how to install and use the PoKeys Core Library in your Rust projects

Installation

Add PoKeys Core Library to your Cargo.toml:

[dependencies]
pokeys-lib = "0.21.8"

💡 Tip: You can also install from git for the latest features:

pokeys-lib = { git = "https://github.com/pokeys-toolkit/core" }

System Requirements

Software

  • • Rust 1.88 or later
  • • Cargo package manager
  • • USB drivers (for USB devices)

Supported Platforms

  • • Windows 10/11
  • • macOS 10.15+
  • • Linux (Ubuntu, Debian, etc.)

Your First Program

Let's create a simple program that connects to a PoKeys device and controls a digital output pin.

Step 1: Create a new Rust project

cargo new pokeys-example
cd pokeys-example

Step 2: Add the dependency

Edit your Cargo.toml:

[dependencies]
pokeys-lib = "0.21.8"

Step 3: Write your first program

Replace the contents of src/main.rs:

use pokeys_lib::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("🚀 Starting PoKeys example...");

    // Enumerate USB devices
    let device_count = enumerate_usb_devices()?;
    println!("📱 Found {} PoKeys devices", device_count);

    if device_count == 0 {
        println!("❌ No PoKeys devices found. Please connect a device.");
        return Ok(());
    }

    // Connect to the first device
    let mut device = connect_to_device(0)?;
    println!("✅ Connected to device: {}", device.get_device_name()?);

    // Configure pin 1 as digital output
    device.set_pin_function(1, PinFunction::DigitalOutput)?;
    println!("🔧 Configured pin 1 as digital output");

    // Blink the LED 5 times
    for i in 1..=5 {
        println!("💡 Blink {} - Turning pin 1 ON", i);
        device.set_digital_output(1, true)?;
        std::thread::sleep(std::time::Duration::from_millis(500));

        println!("💡 Blink {} - Turning pin 1 OFF", i);
        device.set_digital_output(1, false)?;
        std::thread::sleep(std::time::Duration::from_millis(500));
    }

    println!("🎉 Example completed successfully!");
    Ok(())
}

Step 4: Run your program

cargo run

You should see output like:

🚀 Starting PoKeys example...
📱 Found 1 PoKeys devices
✅ Connected to device: PoKeys56U
🔧 Configured pin 1 as digital output
💡 Blink 1 - Turning pin 1 ON
💡 Blink 1 - Turning pin 1 OFF
...

Understanding the Code

Device Enumeration

let device_count = enumerate_usb_devices()?;

This function scans for connected PoKeys USB devices and returns the count. It's the first step in any PoKeys application.

Device Connection

let mut device = connect_to_device(0)?;

Connects to the device at index 0 (the first device found). Returns a Device object for controlling the hardware.

Pin Configuration

device.set_pin_function(1, PinFunction::DigitalOutput)?;

Configures pin 1 as a digital output. PoKeys pins are versatile and can be configured for different functions like digital I/O, analog input, PWM, etc.

Digital Output Control

device.set_digital_output(1, true)?;  // Turn ON
device.set_digital_output(1, false)?; // Turn OFF

Controls the digital output state. true sets the pin HIGH (typically 3.3V or 5V), false sets it LOW (0V).

Common Pin Functions

Digital I/O

// Digital Output
device.set_pin_function(1, PinFunction::DigitalOutput)?;
device.set_digital_output(1, true)?;

// Digital Input
device.set_pin_function(2, PinFunction::DigitalInput)?;
let state = device.get_digital_input(2)?;

Analog Input

// Configure as analog input
device.set_pin_function(3, PinFunction::AnalogInput)?;

// Read analog value (0-4095 for 12-bit ADC)
let value = device.get_analog_input(3)?;
let voltage = (value as f32 / 4095.0) * 3.3;

PWM Output

// Configure PWM
device.set_pin_function(4, PinFunction::PWMOutput)?;

// Set PWM duty cycle (0-100%)
device.set_pwm_duty_cycle(4, 50.0)?; // 50% duty cycle

Encoder Input

// Configure encoder on pins 5 & 6
let options = EncoderOptions::with_4x_sampling();
device.configure_encoder(0, 5, 6, options)?;

// Read encoder position
let position = device.get_encoder_value(0)?;

Error Handling

The PoKeys library uses Rust's Result type for error handling. Here's how to handle common errors:

use pokeys_lib::*;

fn main() {
    match run_pokeys_app() {
        Ok(()) => println!("✅ Application completed successfully"),
        Err(e) => {
            eprintln!("❌ Error: {}", e);
            std::process::exit(1);
        }
    }
}

fn run_pokeys_app() -> Result<(), Box<dyn std::error::Error>> {
    // Check if devices are available
    let device_count = enumerate_usb_devices()?;
    if device_count == 0 {
        return Err("No PoKeys devices found. Please connect a device.".into());
    }

    // Try to connect
    let mut device = match connect_to_device(0) {
        Ok(dev) => dev,
        Err(e) => {
            return Err(format!("Failed to connect to device: {}", e).into());
        }
    };

    // Validate pin capabilities
    if !device.is_pin_available(1)? {
        return Err("Pin 1 is not available on this device".into());
    }

    // Your application logic here...
    device.set_pin_function(1, PinFunction::DigitalOutput)?;
    device.set_digital_output(1, true)?;

    Ok(())
}

Next Steps