Skip to main content

High-Level Embedded Python Library for declarative hardware programming

Project description

BitBound – High-Level Embedded Python Library

Hardware abstraction for MicroPython that makes embedded development as simple as working with modern web APIs.

License: MIT Python 3.7+ MicroPython

🎯 Vision

MicroPython is excellent, but complex hardware interactions often require deep knowledge of bus protocols and register configurations. BitBound abstracts hardware components (sensors, motors, displays) with a modern, declarative API—similar to how web frameworks abstract HTTP.

from bitbound import Hardware

# Create hardware manager
hardware = Hardware()

# Attach devices with simple, declarative syntax
sensor = hardware.attach("I2C", type="BME280")
fan = hardware.attach("GPIO", type="Relay", pin=5)

# Use threshold-based events instead of polling loops
sensor.on_threshold("temperature > 25°C", lambda e: fan.on())
sensor.on_threshold("temperature < 23°C", lambda e: fan.off())

# Read values naturally
print(f"Temperature: {sensor.temperature}°C")
print(f"Humidity: {sensor.humidity}%")
print(f"Pressure: {sensor.pressure} hPa")

# Run the event loop
hardware.run()

✨ Features

  • Declarative Hardware Attachment: No more manual register configuration
  • Natural Unit Expressions: "temperature > 25°C", "pressure < 1000hPa"
  • Event-Driven Programming: Threshold callbacks, change detection, interval events
  • Simulation Mode: Develop and test without physical hardware
  • Wide Device Support: Sensors, actuators, displays
  • Cross-Platform: Works on MicroPython, CircuitPython, and standard Python

📦 Installation

Standard Python (for development/simulation)

pip install bitbound

MicroPython

Copy the bitbound folder to your device's filesystem:

mpremote cp -r bitbound :

🚀 Quick Start

Basic Sensor Reading

from bitbound import Hardware

hw = Hardware()

# BME280 temperature/humidity/pressure sensor
sensor = hw.attach("I2C", type="BME280")

# Read all values
data = sensor.read_all()
print(f"Temperature: {data['temperature']}°C")
print(f"Humidity: {data['humidity']}%")
print(f"Pressure: {data['pressure']} hPa")
print(f"Altitude: {data['altitude']} m")

LED Control

from bitbound import Hardware

hw = Hardware()

# Simple LED
led = hw.attach("GPIO", type="LED", pin=2)
led.on()
led.off()
led.blink(times=5)

# RGB LED
rgb = hw.attach("GPIO", type="RGB", pins={"r": 12, "g": 13, "b": 14})
rgb.color = (255, 0, 0)      # Red
rgb.color = "#00FF00"        # Green (hex)
rgb.color = "blue"           # Named color

Motor Control

from bitbound import Hardware

hw = Hardware()

# DC Motor with H-Bridge
motor = hw.attach("GPIO", type="DCMotor",
                  enable_pin=5, in1_pin=6, in2_pin=7)
motor.forward(speed=75)   # 75% speed
motor.backward(speed=50)
motor.stop()

# Servo Motor
servo = hw.attach("GPIO", type="Servo", pin=15)
servo.angle = 90  # Move to 90 degrees
servo.sweep(0, 180)  # Sweep from 0 to 180

Display Output

from bitbound import Hardware

hw = Hardware()

# Character LCD
lcd = hw.attach("I2C", type="LCD1602")
lcd.write("Hello World!")
lcd.write("Line 2", y=1)

# OLED Display
oled = hw.attach("I2C", type="SSD1306")
oled.text("BitBound", 0, 0)
oled.line(0, 10, 127, 10)
oled.show()

Event-Driven Programming

from bitbound import Hardware

hw = Hardware()

sensor = hw.attach("I2C", type="BME280")
fan = hw.attach("GPIO", type="Relay", pin=5)
led = hw.attach("GPIO", type="LED", pin=2)
buzzer = hw.attach("GPIO", type="Buzzer", pin=15)

# Temperature thresholds
sensor.on_threshold("temperature > 30°C", lambda e: (
    fan.on(),
    buzzer.beep()
))

sensor.on_threshold("temperature < 25°C", lambda e: fan.off())

# Humidity alert
sensor.on_threshold("humidity > 80%", lambda e: led.blink(3))

# Value change detection
sensor.on_change("temperature", lambda e: 
    print(f"Temp changed: {e.old_value} -> {e.new_value}")
)

# Run event loop
hw.run()

Complex Expressions

# Compound conditions
sensor.on_threshold(
    "temperature > 25°C AND humidity < 40%",
    lambda e: humidifier.on()
)

# Range check
sensor.on_threshold(
    "temperature BETWEEN 20°C AND 25°C",
    lambda e: print("Optimal temperature!")
)

# Pressure monitoring
sensor.on_threshold(
    "pressure < 1000hPa OR pressure > 1030hPa",
    lambda e: alert()
)

📖 Supported Devices

Sensors

Device Bus Properties
BME280/BMP280 I2C temperature, humidity, pressure, altitude
DHT11/DHT22 GPIO temperature, humidity
DS18B20 OneWire temperature
BH1750 I2C lux
MPU6050 I2C acceleration, gyroscope, temperature
PIR GPIO motion
Analog ADC value, voltage, percent

Actuators

Device Bus Methods
Relay GPIO on(), off(), toggle()
LED GPIO on(), off(), blink()
RGB LED GPIO color property
NeoPixel GPIO fill(), pixel[], rainbow()
DC Motor GPIO forward(), backward(), stop()
Servo GPIO angle property, sweep()
Stepper GPIO step(), rotate()
Buzzer GPIO beep(), tone(), melody()

Displays

Device Bus Methods
LCD1602/LCD2004 I2C write(), clear(), backlight
SSD1306 OLED I2C text(), line(), rect(), pixel()
7-Segment GPIO digit(), number()

🔧 Configuration

Custom Pin Configuration

hw = Hardware()

# I2C with custom pins
sensor = hw.attach("I2C", type="BME280", scl=22, sda=21, freq=400000)

# SPI with all pins specified
device = hw.attach("SPI", type="...", sck=18, mosi=23, miso=19, cs=5)

# UART with custom settings
gps = hw.attach("UART", type="...", tx=17, rx=16, baudrate=9600)

Device Discovery

hw = Hardware()

# Scan I2C bus
addresses = hw.scan("I2C")
print(f"Found devices at: {[hex(a) for a in addresses]}")

# Auto-discover devices
discovered = hw.discover()
for category, devices in discovered.items():
    print(f"{category}: {devices}")

🧪 Simulation Mode

BitBound automatically runs in simulation mode when no hardware is detected. This allows development and testing on any computer:

from bitbound import Hardware

# Simulation mode is automatic on desktop
hw = Hardware()

# All devices work in simulation
sensor = hw.attach("I2C", type="BME280")
print(sensor.temperature)  # Returns simulated value: 23.5

led = hw.attach("GPIO", type="LED", pin=2)
led.on()  # Works without hardware

🔌 Unit System

BitBound understands physical units:

from bitbound.units import parse_value, convert

# Parse values with units
value, unit = parse_value("25°C")
print(unit.to_si())  # 298.15 (Kelvin)

# Convert between units
celsius = convert(77, "°F", "°C")  # 25.0

Supported units:

  • Temperature: °C, °F, K
  • Pressure: Pa, hPa, kPa, bar, mbar, psi, atm
  • Humidity: %, RH, %RH
  • Length: mm, cm, m, km, in, ft
  • Time: ms, s, min, h
  • Electrical: V, mV, A, mA, µA, W, Ω, kΩ, MΩ
  • Light: lux, lx
  • Frequency: Hz, kHz, MHz

📁 Project Structure

bitbound/
├── __init__.py          # Main exports
├── hardware.py          # Hardware manager
├── device.py            # Device base classes
├── event.py             # Event system
├── expression.py        # Expression parser
├── units.py             # Unit handling
├── buses/
│   ├── base.py          # Bus abstraction
│   ├── i2c.py           # I2C implementation
│   ├── spi.py           # SPI implementation
│   ├── gpio.py          # GPIO implementation
│   ├── uart.py          # UART implementation
│   └── onewire.py       # OneWire implementation
└── devices/
    ├── sensors/         # Sensor implementations
    ├── actuators/       # Actuator implementations
    └── displays/        # Display implementations

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

MIT License - see LICENSE for details.

🙏 Acknowledgments

  • Inspired by modern web frameworks and their declarative approaches
  • Built on top of the excellent MicroPython/CircuitPython ecosystems
  • Thanks to all the open-source hardware driver contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bitbound-0.1.0.tar.gz (52.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bitbound-0.1.0-py3-none-any.whl (59.2 kB view details)

Uploaded Python 3

File details

Details for the file bitbound-0.1.0.tar.gz.

File metadata

  • Download URL: bitbound-0.1.0.tar.gz
  • Upload date:
  • Size: 52.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for bitbound-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b85daab67412b4ad0497e105fac570e13d3216e89fc4838b00e6f191e315a503
MD5 913e885b9a193aba3f2db1f0e1db67a8
BLAKE2b-256 5a71d66b3e8ef1e163e0c76e375eb7bf671773e5b4d95d1a99ff6d0b466204ad

See more details on using hashes here.

File details

Details for the file bitbound-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: bitbound-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 59.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for bitbound-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ca1a92271da5b93b1a1661874a19a9ec996bf276524af7e1ff1b798ded1bd63c
MD5 8b97f001273dc6bb004edb22edbcf3bd
BLAKE2b-256 1bcff0ca9704b961b37b332657f1bca4f674d947e34e935b7d2e3b72cedd07d4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page