Reduino transpiles Python scripts into efficient Arduino C++ and uploads automatically. A simple, intuitive way to control sensors, LEDs, and actuators without touching C++.
Project description
Table of contents
- Overview
- Quick start
- The
target()function (Required) - API reference
- Supported Python features
- License
Overview
Reduino lets you write high-level Python that compiles into clean Arduino C++, then optionally uploads it to your board via PlatformIO.
Quick start
pip install Reduino
pip install platformio # required for automatic uploads
[!NOTE] PlatformIO is only required for automatic build & upload. You can still transpile without it.
The target() function (Required)
Place target() at the very top of your script, immediately after imports. This is the entry point that tells Reduino to parse your entire file, transpile it to Arduino C++, and (optionally) upload it.
| Parameter | Type | Default | Description |
|---|---|---|---|
port |
str |
— | Serial port, e.g. "COM3" or "/dev/ttyACM0". |
upload |
bool |
True |
If True, compile & upload via PlatformIO. If False, only transpile. |
platform |
str |
"atmelavr" |
PlatformIO platform ID. Reduino currently supports atmelavr and atmelmegaavr. |
board |
str |
"uno" |
PlatformIO board ID. Must be compatible with platform. |
Returns: str of the generated Arduino C++ source.
Minimal example (top-of-file target)
from Reduino import target
target("COM3") # upload=True by default
# Your Reduino code below...
Example: Reduino structure explained
Reduino automatically splits your Python code into Arduino sections.
from Reduino import target
target("COM3")
from Reduino.Actuators import Led
led = Led(13)
while True:
led.toggle() # repeated code -> goes into void loop()
Generated Arduino structure (conceptually):
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, !digitalRead(13));
delay(500);
}
Everything before while True: (declarations, prints, sensor setup, etc.) is placed inside setup(), and everything inside the while True loop is placed in loop().
Transpile only (no upload)
from Reduino import target
cpp = target("COM3", upload=False)
print(cpp)
# Your Reduino code below...
Targeting different platforms & boards
Reduino validates that the requested PlatformIO platform/board pair is supported. At the moment two PlatformIO platforms are available:
atmelavr– classic AVR-based boards (Uno, Nano, Leonardo, etc.).atmelmegaavr– newer megaAVR devices (Nano Every, Uno WiFi Rev2, Curiosity Nano kits, ...).
Every board listed in the PlatformIO board registry for all platforms can be targeted. If you choose an unsupported board, or one that does not belong to the selected platform, target() raises a ValueError with a helpful message.
from Reduino import target
# Build for an Arduino Nano Every without uploading automatically.
target(
"COM9",
upload=False,
platform="atmelmegaavr",
board="nano_every",
)
# Build for a classic Arduino Uno and upload immediately.
target("/dev/ttyUSB0", platform="atmelavr", board="uno")
[!IMPORTANT]
target()reads the whole file text and generates code for everything below it. Ifupload=True, it also builds and flashes using a temporary PlatformIO project.
API reference
Actuators
LED
| Method | Description |
|---|---|
Led(pin=13) |
Bind an LED to a digital/PWM pin. |
on() / off() |
Turn fully on/off. |
toggle() |
Flip state. |
get_state() |
True if on. |
get_brightness() / set_brightness(v) |
PWM 0–255. |
blink(duration_ms, times=1) |
Blink helper. |
fade_in(step=5, delay_ms=10) / fade_out(step=5, delay_ms=10) |
Smooth ramp. |
flash_pattern(pattern, delay_ms=200) |
Run pattern of 0 & 1s eg: [1,0,0,1,1,1]. |
Example
from Reduino import target
target("COM3")
from Reduino.Actuators import Led
from Reduino.Utils import sleep
led = Led(9)
led.set_brightness(128)
led.blink(200, times=3)
sleep(500)
led.off()
RGB LED
| Method | Description |
|---|---|
RGBLed(r_pin, g_pin, b_pin) |
Bind RGB to three PWM pins. |
set_color(r,g,b) |
Set color (0–255 each). |
on(r=255,g=255,b=255) / off() |
White / off. |
fade(r,g,b,duration_ms=1000,steps=50) |
Transition to target color. |
blink(r,g,b,times=1,delay_ms=200) |
Blink with color. |
Example
from Reduino import target
target("COM3")
from Reduino.Actuators import RGBLed
from Reduino.Utils import sleep
rgb = RGBLed(9, 10, 11)
rgb.set_color(0, 128, 255)
rgb.fade(255, 0, 0, duration_ms=1500)
sleep(300)
rgb.off()
Buzzer
| Method | Description |
|---|---|
Buzzer(pin=8, default_frequency=440.0) |
Create buzzer. |
play_tone(frequency, duration_ms=None) |
Play tone. |
stop() |
Stop sound. |
beep(frequency=None, on_ms=100, off_ms=100, times=1) |
Repeated tone. |
sweep(start_hz, end_hz, duration_ms, steps=10) |
Sweep frequencies. |
melody(name, tempo=None) |
Play built-in melody. |
Built-in melodies: success, error, startup, notify, alarm, scale_c, siren
Example
from Reduino import target
target("COM3")
from Reduino.Actuators import Buzzer
from Reduino.Utils import sleep
bz = Buzzer(8)
bz.melody("startup")
sleep(500)
bz.beep(frequency=880, on_ms=100, off_ms=100, times=3)
bz.stop()
Servo
| Method | Description |
|---|---|
Servo(pin=9, min_angle=0, max_angle=180, min_pulse_us=544, max_pulse_us=2400) |
Create servo. |
write(angle) |
Move to degrees (clamped). |
write_us(pulse) |
Move by pulse width (clamped). |
Example
from Reduino import target
target("COM3")
from Reduino.Actuators import Servo
from Reduino.Utils import sleep
s = Servo(9)
s.write(90)
sleep(500)
s.write(0)
DC Motor
| Method | Description |
|---|---|
DCMotor(in1, in2, enable) |
Control a motor driver with two direction pins and a PWM enable. |
set_speed(value) |
Drive with normalized speed -1.0 (full reverse) to 1.0 (full forward). |
backward(speed=1.0) |
Convenience helper for negative speeds. |
stop() / coast() |
Active brake the motor or let it spin freely. |
invert() |
Toggle the wiring direction without rewiring. |
ramp(target_speed, duration_ms) |
Linearly change speed over a duration. |
run_for(duration_ms, speed) |
Drive at speed for duration_ms then stop. |
get_speed() / get_applied_speed() / is_inverted() / get_mode() |
Inspect the requested speed, final direction, wiring inversion and current drive mode ("drive", "coast", "brake"). |
Example
from Reduino import target
target("COM3")
from Reduino.Actuators import DCMotor
from Reduino.Utils import sleep
motor = DCMotor(4, 5, 6)
motor.set_speed(0.4)
motor.run_for(1500, speed=1.0)
motor.ramp(-1.0, duration_ms=800)
sleep(250)
motor.stop()
PWM Driver
| Method | Description |
|---|---|
PWMDriver(i2c_addr=0x40, frequency_hz=50.0, channels=16, resolution=4095) |
Create an I²C PWM expander abstraction (PCA9685-style defaults). |
set_frequency(frequency_hz) / get_frequency() |
Set/read the shared PWM update frequency (applies to all channels). |
set_duty(channel, value) / get_duty(channel) |
Write/read raw duty counts in the 0..resolution range. |
set_level(channel, value) / get_level(channel) |
Write/read normalized duty in the 0.0..1.0 range. |
off(channel) / all_off() |
Turn a channel off, or all channels off. |
Example
from Reduino import target
target("COM3")
from Reduino.Actuators import PWMDriver
from Reduino.Utils import sleep
driver = PWMDriver() # defaults: 0x40, 50Hz, 16 channels, 12-bit (4095)
driver.set_frequency(60)
driver.set_duty(0, 2048) # ~50% raw duty
driver.set_level(1, 0.25) # 25% normalized duty
duty = driver.get_duty(0)
level = driver.get_level(1)
freq = driver.get_frequency()
sleep(200)
driver.all_off()
[!NOTE] During transpilation, Reduino injects
WireandAdafruit_PWMServoDriverincludes automatically whenPWMDriveris used.
Displays
LCD
| Method | Description |
|---|---|
LCD(rs, en, d4, d5, d6, d7, cols=16, rows=2, rw=None, backlight_pin=None) |
4-bit parallel wiring with optional RW and PWM backlight pin. Constructor automatically calls begin() and clears the display. |
LCD(i2c_addr, cols=16, rows=2) |
PCF8574-style I²C backpack wiring. Constructor calls init()/backlight() for you. |
write(col, row, text, clear_row=True, align="left") |
Position text anywhere; optional row clearing and alignment ("left", "center", "right"). |
line(row, text, align="left", clear_row=True) |
Replace an entire row with aligned text. |
message(top=None, bottom=None, top_align="left", bottom_align="left", clear_rows=True) |
Convenience helper for two-line messages. |
clear() / display(on) / backlight(on) |
Clear the screen and toggle the LCD/backlight power. |
brightness(level) |
Set PWM backlight brightness (parallel mode with backlight_pin). |
glyph(slot, bitmap) |
Upload a custom 5×8 glyph (bitmap = 8 integers). |
progress(row, value, max_value=100, width=None, label=None, style="block") |
Render a progress bar (style = "block", "hash", "pipe", or "dot"). |
animate(style, row, text, speed_ms=200, loop=False) |
Start a non-blocking animation (style = "scroll", "blink", "typewriter", or "bounce"); the transpiler injects the required loop tick(). |
[!NOTE]
brightness()is available only when a parallel display is created withbacklight_pin. All alignment parameters accept"left","center", or"right"(case-insensitive).
Available animation styles:
scroll– marquee-style horizontal scrolling.blink– toggles the text on and off without blocking.typewriter– reveals the message one character at a time.bounce– slides the text from edge to edge before reversing.
Parallel wiring example (PWM backlight + progress bar)
from Reduino import target
target("COM3")
from Reduino.Displays import LCD
lcd = LCD(rs=12, en=11, d4=5, d5=4, d6=3, d7=2, backlight_pin=9)
lcd.message("Setup complete", bottom="Waiting…", top_align="center")
lcd.progress(1, 30, max_value=100, width=12, label="Load")
lcd.brightness(200)
I²C backpack example (custom glyph + marquee animation)
from Reduino.Displays import LCD
panel = LCD(i2c_addr=0x27, cols=20, rows=4)
panel.glyph(0, [0, 2, 5, 8, 8, 5, 2, 0])
panel.line(0, "Ready to scroll", align="center")
panel.animate("scroll", 2, "This text scrolls without blocking!", speed_ms=150, loop=True)
Sensors
Button
| Method | Description |
|---|---|
Button(pin, on_click=None, state_provider=None) |
Digital input w/ optional callback/provider. |
is_pressed() |
1 if pressed else 0. |
Example
from Reduino import target
from Reduino.Actuators import Led
from Reduino.Sensors import Button
target("COM3")
led = Led(6)
btn = Button(7)
if btn.is_pressed():
led.toggle()
Potentiometer
| Method | Description |
|---|---|
Potentiometer(pin="A0", value_provider=None) |
Analog helper. |
read() |
0–1023 integer. |
Example
from Reduino import target
from Reduino.Communication import SerialMonitor
target("COM3")
from Reduino.Sensors import Potentiometer
mon = SerialMonitor(9600 , "COM3")
pot = Potentiometer("A0")
while True:
value = pot.read()
mon.write(value)
InfraredDigital
| Method | Description |
|---|---|
InfraredDigital(pin, state_provider=None, default_state=False) |
Digital infrared obstacle/proximity helper with strict argument validation. |
read() |
Returns 1 when detected, else 0. |
Example
from Reduino import target
target("COM3")
from Reduino.Sensors import InfraredDigital
ir = InfraredDigital(pin=7)
while True:
detected = ir.read()
[!NOTE]
InfraredDigitalis intentionally a structured runtime placeholder. The actual hardware-oriented behavior is generated by the Reduino DSL transpiler (digitalRead(pin)+pinMode(pin, INPUT)in emitted Arduino C++).
Ultrasonic
| Method | Description |
|---|---|
Ultrasonic(trig, echo, sensor="HC-SR04", distance_provider=None, default_distance=0.0) |
HC-SR04 factory. |
measure_distance() |
Distance in cm (handles timeouts/backoff). |
Example
from Reduino import target
target("COM3")
from Reduino.Sensors import Ultrasonic
from Reduino.Utils import sleep
u = Ultrasonic(trig=9, echo=10)
d = u.measure_distance()
print(d)
sleep(60)
Communication
SerialMonitor
| Method | Description |
|---|---|
SerialMonitor(baud_rate=9600, port=None, timeout=1.0) |
Host-side serial console. |
connect(port) |
Open serial (requires pyserial). |
close() |
Close port. |
write(value) |
Send text. |
read() |
Read text. |
Example (host-side)
from Reduino import target
target("COM3")
from Reduino.Communication import SerialMonitor
mon = SerialMonitor(baud_rate=115200, port="COM4")
while True:
mon.write("hello")
mon.read()
mon.close()
[!NOTE]
pyserialis optional; only needed if you callconnect().
Utilities
sleep
from Reduino import target
target("COM3")
from Reduino.Utils import sleep
sleep(250) # ms
map
from Reduino import target
target("COM3")
from Reduino.Utils import map
mapped = map(512, 0, 1023, 0.0, 5.0) # 2.5-ish
print(mapped)
Core
The Core module exposes low-level helpers that map directly to the Arduino API. Use these when you need to configure a pin or interact with a sensor that doesn't yet have a dedicated Reduino abstraction.
| Helper | Description |
|---|---|
pin_mode(pin, mode) |
Configure a pin for INPUT, INPUT_PULLUP, or OUTPUT. |
digital_write(pin, value) |
Write HIGH/LOW to a digital pin. |
analog_write(pin, value) |
Output a PWM value (0–255). |
digital_read(pin) |
Read a digital pin (returns 0 or 1). |
analog_read(pin) |
Read an analogue value (0–1023 on most boards). |
Constants INPUT, OUTPUT, INPUT_PULLUP, HIGH, and LOW mirror the
Arduino macros so your code matches what you would write in C++.
from Reduino import target
target("COM3")
from Reduino.Core import pin_mode, digital_write, digital_read, OUTPUT, HIGH, LOW
pin_mode(7, OUTPUT)
digital_write(7, HIGH)
if digital_read(2) == HIGH:
digital_write(7, LOW)
Supported Python features
Reduino implements a pragmatic subset of Python that cleanly lowers to Arduino C++.
Control flow
while True:➜ Arduinoloop()for x in range(...), includingrange(start, stop, step)if / elif / else,break,continue,try/except(mapped to C++ try/catch where used)
Variables & assignment
-
Standard assignment and pythonic swap:
a, b = b, a
-
Multiple assignment & tuple unpacking
-
Augmented ops (
+=,-=,*=, etc.)
Collections
-
Lists (
[]), tuples (()), and membership checks (x in items) -
List comprehensions:
squares = [i for i in range(10)]
-
len()on strings, lists, and internal list type
Built-ins
len(),abs(),max(),min()print()maps to serial printing in emitted code when serial is configured
[!TIP] Many constant expressions are folded at transpile time for smaller, faster C++.
License
Reduino is distributed under the GNU General Public License v3.0 (GPLv3).
You are free to use, modify, and distribute this software for personal or educational purposes,
as long as derivative works remain open-source and licensed under the same terms.
For commercial usage, redistribution, or integration into closed-source systems,
please contact me at arnavbajaj9@gmail.com for alternative licensing options.
See LICENSE for full details.
Star History
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reduino-1.3.0.tar.gz.
File metadata
- Download URL: reduino-1.3.0.tar.gz
- Upload date:
- Size: 109.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fd26875770c0c86f7c13b8733b862cf2ba1d6905cca3f09362fe1f93e444e7d
|
|
| MD5 |
72f527142e3bdc53a0323e97d1d9b50b
|
|
| BLAKE2b-256 |
f1f40078cec27c6202d877fa8e2a85095aaa7d34469eab2e04d35f82ec75bfe0
|
File details
Details for the file reduino-1.3.0-py3-none-any.whl.
File metadata
- Download URL: reduino-1.3.0-py3-none-any.whl
- Upload date:
- Size: 96.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef879d563bb8d9ecb48f1f3dfbc492de767bac99d656a38fc2f61f52ec45d6c2
|
|
| MD5 |
a9411dd26e071f3a6f7d72af24cda903
|
|
| BLAKE2b-256 |
4bb47118587422db98ab9745d546510880839eb8e8cf1db2693cea036ac56740
|