<div align="center">
<img src="https://raw.githubusercontent.com/Jackhammer9/Reduino/refs/heads/main/.github/workflows/Reduino.png" alt="Reduino" width="360" />
<h1>Reduino</h1>
<p><em>Write friendly Python. Get Arduino-ready C++. Upload Easily to MCUs.</em></p>
<a href="https://www.buymeacoffee.com/Jackhammer">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="45" />
</a> <br> <br>
<a href="https://www.gnu.org/licenses/gpl-3.0">
<img alt="License" src="https://img.shields.io/badge/License-GPLv3-blueviolet" />
</a>
<a href="https://github.com/Jackhammer9/Reduino/stargazers">
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/Jackhammer9/Reduino?logo=Github" />
</a>
<a href="https://github.com/Jackhammer9/Reduino/network/members">
<img alt="GitHub forks" src="https://img.shields.io/github/forks/Jackhammer9/Reduino?color=red&logo=Github&style=flat-square" />
</a>
<a href="https://github.com/Jackhammer9/Reduino/watchers">
<img alt="GitHub watchers" src="https://img.shields.io/github/watchers/Jackhammer9/Reduino?logo=Github" />
</a>
<a href="https://github.com/Jackhammer9">
<img alt="GitHub followers" src="https://img.shields.io/github/followers/Jackhammer9?logo=Github" />
</a>
<a href="https://github.com/Jackhammer9/Reduino/pulls?q=is%3Apr+is%3Aclosed">
<img alt="Closed PRs" src="https://img.shields.io/github/issues-pr-closed/Jackhammer9/Reduino?logo=Github" />
</a>
<a href="https://github.com/Jackhammer9/Reduino/issues?q=is%3Aissue+is%3Aclosed">
<img alt="Closed issues" src="https://img.shields.io/github/issues-closed/Jackhammer9/Reduino?logo=Github" />
</a>
<a href="https://github.com/Jackhammer9/Reduino">
<img alt="Repo size" src="https://img.shields.io/github/repo-size/Jackhammer9/Reduino?logo=Github" />
</a>
<a href="https://github.com/Jackhammer9/Reduino/releases/latest">
<img alt="Latest release" src="https://img.shields.io/github/v/release/Jackhammer9/Reduino?display_name=tag&logo=Github" />
</a>
<a href="https://pypi.org/project/Reduino/">
<img alt="PyPI version" src="https://img.shields.io/pypi/v/Reduino?logo=pypi" />
</a>
<a href="https://pypistats.org/packages/reduino">
<img alt="PyPI downloads" src="https://img.shields.io/pypi/dm/Reduino?label=PyPI%20downloads&logo=pypi" />
</a>
<img alt="Python Lines Of Code" src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Jackhammer9/221805154809373180108ca1d24ddccd/raw/python-loc.json" />
</div>
---
## Table of contents
* [Overview](#overview)
* [Quick start](#quick-start)
* [The `target()` function (Required)](#the-target-function-required)
* [API reference](#api-reference)
* [Actuators](#actuators)
* [LED](#led)
* [RGB LED](#rgb-led)
* [Buzzer](#buzzer)
* [Servo](#servo)
* [DC Motor](#dc-motor)
* [Displays](#displays)
* [LCD](#lcd)
* [Sensors](#sensors)
* [Button](#button)
* [Potentiometer](#potentiometer)
* [Ultrasonic](#ultrasonic)
* [Communication](#communication)
* [SerialMonitor](#serialmonitor)
* [Utilities](#utilities)
* [sleep](#sleep)
* [map](#map)
* [Core](#core)
* [Supported Python features](#supported-python-features)
* [License](#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
```bash
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`)**
```python
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.
```python
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):
```cpp
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)**
```python
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](https://docs.platformio.org/en/latest/boards/index.html) 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.
```python
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.
> If `upload=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**
```python
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**
```python
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**
```python
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**
```python
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**
```python
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()
```
---
### 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 with `backlight_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)**
```python
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)**
```python
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**
```python
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**
```python
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)
```
---
#### 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**
```python
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)**
```python
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]
> `pyserial` is optional; only needed if you call `connect()`.
---
### Utilities
#### sleep
```python
from Reduino import target
target("COM3")
from Reduino.Utils import sleep
sleep(250) # ms
```
#### map
```python
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++.
```python
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:` ➜ Arduino `loop()`
* `for x in range(...)`, including `range(start, stop, step)`
* `if / elif / else`, `break`, `continue`, `try/except` (mapped to C++ try/catch where used)
### Variables & assignment
* Standard assignment and **pythonic swap**:
```python
a, b = b, a
```
* Multiple assignment & tuple unpacking
* Augmented ops (`+=`, `-=`, `*=`, etc.)
### Collections
* **Lists** (`[]`), tuples (`()`), and membership checks (`x in items`)
* **List comprehensions**:
```python
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](https://www.gnu.org/licenses/gpl-3.0) for full details.
<h1> Star History </h1>
<br>
<div align = "center">
[](https://star-history.com/#Jackhammer9/Reduino&Date)
</div>
Raw data
{
"_id": null,
"home_page": null,
"name": "Reduino",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "arduino, embedded, transpiler, robotics, avr, cpp",
"author": null,
"author_email": "Arnav Bajaj <arnavbajaj9@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/c4/df/231648244711ed15f494ae97b0e62a1256d99d23aa3be506a87ef8a6b7ff/reduino-1.2.0.tar.gz",
"platform": null,
"description": "<div align=\"center\">\r\n <img src=\"https://raw.githubusercontent.com/Jackhammer9/Reduino/refs/heads/main/.github/workflows/Reduino.png\" alt=\"Reduino\" width=\"360\" />\r\n\r\n <h1>Reduino</h1>\r\n <p><em>Write friendly Python. Get Arduino-ready C++. Upload Easily to MCUs.</em></p>\r\n\r\n<a href=\"https://www.buymeacoffee.com/Jackhammer\">\r\n <img src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" height=\"45\" />\r\n</a> <br> <br>\r\n <a href=\"https://www.gnu.org/licenses/gpl-3.0\">\r\n <img alt=\"License\" src=\"https://img.shields.io/badge/License-GPLv3-blueviolet\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino/stargazers\">\r\n <img alt=\"GitHub Repo stars\" src=\"https://img.shields.io/github/stars/Jackhammer9/Reduino?logo=Github\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino/network/members\">\r\n <img alt=\"GitHub forks\" src=\"https://img.shields.io/github/forks/Jackhammer9/Reduino?color=red&logo=Github&style=flat-square\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino/watchers\">\r\n <img alt=\"GitHub watchers\" src=\"https://img.shields.io/github/watchers/Jackhammer9/Reduino?logo=Github\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9\">\r\n <img alt=\"GitHub followers\" src=\"https://img.shields.io/github/followers/Jackhammer9?logo=Github\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino/pulls?q=is%3Apr+is%3Aclosed\">\r\n <img alt=\"Closed PRs\" src=\"https://img.shields.io/github/issues-pr-closed/Jackhammer9/Reduino?logo=Github\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino/issues?q=is%3Aissue+is%3Aclosed\">\r\n <img alt=\"Closed issues\" src=\"https://img.shields.io/github/issues-closed/Jackhammer9/Reduino?logo=Github\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino\">\r\n <img alt=\"Repo size\" src=\"https://img.shields.io/github/repo-size/Jackhammer9/Reduino?logo=Github\" />\r\n </a>\r\n <a href=\"https://github.com/Jackhammer9/Reduino/releases/latest\">\r\n <img alt=\"Latest release\" src=\"https://img.shields.io/github/v/release/Jackhammer9/Reduino?display_name=tag&logo=Github\" />\r\n </a>\r\n <a href=\"https://pypi.org/project/Reduino/\">\r\n <img alt=\"PyPI version\" src=\"https://img.shields.io/pypi/v/Reduino?logo=pypi\" />\r\n </a>\r\n <a href=\"https://pypistats.org/packages/reduino\">\r\n <img alt=\"PyPI downloads\" src=\"https://img.shields.io/pypi/dm/Reduino?label=PyPI%20downloads&logo=pypi\" />\r\n </a>\r\n \r\n <img alt=\"Python Lines Of Code\" src=\"https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Jackhammer9/221805154809373180108ca1d24ddccd/raw/python-loc.json\" />\r\n</div>\r\n\r\n---\r\n\r\n## Table of contents\r\n\r\n* [Overview](#overview)\r\n* [Quick start](#quick-start)\r\n* [The `target()` function (Required)](#the-target-function-required)\r\n* [API reference](#api-reference)\r\n * [Actuators](#actuators)\r\n * [LED](#led)\r\n * [RGB LED](#rgb-led)\r\n * [Buzzer](#buzzer)\r\n * [Servo](#servo)\r\n * [DC Motor](#dc-motor)\r\n * [Displays](#displays)\r\n * [LCD](#lcd)\r\n * [Sensors](#sensors)\r\n * [Button](#button)\r\n * [Potentiometer](#potentiometer)\r\n * [Ultrasonic](#ultrasonic)\r\n * [Communication](#communication)\r\n * [SerialMonitor](#serialmonitor)\r\n * [Utilities](#utilities)\r\n * [sleep](#sleep)\r\n * [map](#map)\r\n * [Core](#core)\r\n* [Supported Python features](#supported-python-features)\r\n* [License](#license)\r\n\r\n---\r\n\r\n## Overview\r\n\r\n**Reduino** lets you write high-level Python that compiles into clean Arduino C++, then optionally uploads it to your board via PlatformIO.\r\n\r\n---\r\n\r\n## Quick start\r\n\r\n```bash\r\npip install Reduino\r\npip install platformio # required for automatic uploads\r\n```\r\n\r\n> [!NOTE]\r\n> PlatformIO is only required for **automatic** build & upload. You can still transpile without it.\r\n\r\n---\r\n\r\n## The `target()` function (Required)\r\n\r\nPlace `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.\r\n\r\n| Parameter | Type | Default | Description |\r\n| ---------: | :----: | :----------: | --------------------------------------------------------------------------- |\r\n| `port` | `str` | \u2014 | Serial port, e.g. `\"COM3\"` or `\"/dev/ttyACM0\"`. |\r\n| `upload` | `bool` | `True` | If `True`, compile & upload via PlatformIO. If `False`, only transpile. |\r\n| `platform` | `str` | `\"atmelavr\"` | PlatformIO platform ID. Reduino currently supports `atmelavr` and `atmelmegaavr`. |\r\n| `board` | `str` | `\"uno\"` | PlatformIO board ID. Must be compatible with `platform`. |\r\n\r\n**Returns:** `str` of the generated Arduino C++ source.\r\n\r\n**Minimal example (top-of-file `target`)**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\") # upload=True by default\r\n\r\n# Your Reduino code below...\r\n```\r\n\r\n### Example: Reduino structure explained\r\n\r\nReduino automatically splits your Python code into Arduino sections.\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Actuators import Led\r\nled = Led(13)\r\n\r\nwhile True:\r\n led.toggle() # repeated code -> goes into void loop()\r\n```\r\nGenerated Arduino structure (conceptually):\r\n\r\n```cpp\r\nvoid setup() {\r\n pinMode(13, OUTPUT);\r\n}\r\n\r\nvoid loop() {\r\n digitalWrite(13, !digitalRead(13));\r\n delay(500);\r\n}\r\n```\r\nEverything before while True: (declarations, prints, sensor setup, etc.)\r\nis placed inside setup(), and everything inside the while True loop is placed in loop().\r\n\r\n**Transpile only (no upload)**\r\n\r\n```python\r\nfrom Reduino import target\r\ncpp = target(\"COM3\", upload=False)\r\nprint(cpp)\r\n\r\n# Your Reduino code below...\r\n```\r\n\r\n### Targeting different platforms & boards\r\n\r\nReduino validates that the requested PlatformIO platform/board pair is supported.\r\nAt the moment two PlatformIO platforms are available:\r\n\r\n* `atmelavr` \u2013 classic AVR-based boards (Uno, Nano, Leonardo, etc.).\r\n* `atmelmegaavr` \u2013 newer megaAVR devices (Nano Every, Uno WiFi Rev2, Curiosity Nano kits, ...).\r\n\r\nEvery board listed in the [PlatformIO board registry for all platforms](https://docs.platformio.org/en/latest/boards/index.html) 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.\r\n\r\n```python\r\nfrom Reduino import target\r\n\r\n# Build for an Arduino Nano Every without uploading automatically.\r\ntarget(\r\n \"COM9\",\r\n upload=False,\r\n platform=\"atmelmegaavr\",\r\n board=\"nano_every\",\r\n)\r\n\r\n# Build for a classic Arduino Uno and upload immediately.\r\ntarget(\"/dev/ttyUSB0\", platform=\"atmelavr\", board=\"uno\")\r\n```\r\n\r\n> [!IMPORTANT]\r\n> `target()` reads the whole file text and generates code for everything below it.\r\n> If `upload=True`, it also builds and flashes using a temporary PlatformIO project.\r\n\r\n---\r\n\r\n## API reference\r\n\r\n### Actuators\r\n\r\n#### LED\r\n\r\n| Method | Description |\r\n| ---------------------------------------------------------------- | --------------------------------- |\r\n| `Led(pin=13)` | Bind an LED to a digital/PWM pin. |\r\n| `on()` / `off()` | Turn fully on/off. |\r\n| `toggle()` | Flip state. |\r\n| `get_state()` | `True` if on. |\r\n| `get_brightness()` / `set_brightness(v)` | PWM 0\u2013255. |\r\n| `blink(duration_ms, times=1)` | Blink helper. |\r\n| `fade_in(step=5, delay_ms=10)` / `fade_out(step=5, delay_ms=10)` | Smooth ramp. |\r\n| `flash_pattern(pattern, delay_ms=200)` | Run pattern of 0 & 1s eg: `[1,0,0,1,1,1]`. |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Actuators import Led\r\nfrom Reduino.Utils import sleep\r\n\r\nled = Led(9)\r\nled.set_brightness(128)\r\nled.blink(200, times=3)\r\nsleep(500)\r\nled.off()\r\n```\r\n\r\n---\r\n\r\n#### RGB LED\r\n\r\n| Method | Description |\r\n| --------------------------------------- | --------------------------- |\r\n| `RGBLed(r_pin, g_pin, b_pin)` | Bind RGB to three PWM pins. |\r\n| `set_color(r,g,b)` | Set color (0\u2013255 each). |\r\n| `on(r=255,g=255,b=255)` / `off()` | White / off. |\r\n| `fade(r,g,b,duration_ms=1000,steps=50)` | Transition to target color. |\r\n| `blink(r,g,b,times=1,delay_ms=200)` | Blink with color. |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Actuators import RGBLed\r\nfrom Reduino.Utils import sleep\r\n\r\nrgb = RGBLed(9, 10, 11)\r\nrgb.set_color(0, 128, 255)\r\nrgb.fade(255, 0, 0, duration_ms=1500)\r\nsleep(300)\r\nrgb.off()\r\n```\r\n\r\n---\r\n\r\n#### Buzzer\r\n\r\n| Method | Description |\r\n| ------------------------------------------------------ | --------------------- |\r\n| `Buzzer(pin=8, default_frequency=440.0)` | Create buzzer. |\r\n| `play_tone(frequency, duration_ms=None)` | Play tone. |\r\n| `stop()` | Stop sound. |\r\n| `beep(frequency=None, on_ms=100, off_ms=100, times=1)` | Repeated tone. |\r\n| `sweep(start_hz, end_hz, duration_ms, steps=10)` | Sweep frequencies. |\r\n| `melody(name, tempo=None)` | Play built-in melody. |\r\n\r\n**Built-in melodies**: `success`, `error`, `startup`, `notify`, `alarm`, `scale_c`, `siren`\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Actuators import Buzzer\r\nfrom Reduino.Utils import sleep\r\n\r\nbz = Buzzer(8)\r\nbz.melody(\"startup\")\r\nsleep(500)\r\nbz.beep(frequency=880, on_ms=100, off_ms=100, times=3)\r\nbz.stop()\r\n```\r\n\r\n---\r\n\r\n#### Servo\r\n\r\n| Method | Description |\r\n| ------------------------------------------------------------------------------- | ------------------------------ |\r\n| `Servo(pin=9, min_angle=0, max_angle=180, min_pulse_us=544, max_pulse_us=2400)` | Create servo. |\r\n| `write(angle)` | Move to degrees (clamped). |\r\n| `write_us(pulse)` | Move by pulse width (clamped). |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Actuators import Servo\r\nfrom Reduino.Utils import sleep\r\n\r\ns = Servo(9)\r\ns.write(90)\r\nsleep(500)\r\ns.write(0)\r\n```\r\n\r\n---\r\n\r\n#### DC Motor\r\n\r\n| Method | Description |\r\n| ------------------------------------------------------------- | --------------------------------------------- |\r\n| `DCMotor(in1, in2, enable)` | Control a motor driver with two direction pins and a PWM enable. |\r\n| `set_speed(value)` | Drive with normalized speed ``-1.0`` (full reverse) to ``1.0`` (full forward). |\r\n| `backward(speed=1.0)` | Convenience helper for negative speeds. |\r\n| `stop()` / `coast()` | Active brake the motor or let it spin freely. |\r\n| `invert()` | Toggle the wiring direction without rewiring. |\r\n| `ramp(target_speed, duration_ms)` | Linearly change speed over a duration. |\r\n| `run_for(duration_ms, speed)` | Drive at ``speed`` for ``duration_ms`` then stop. |\r\n| `get_speed()` / `get_applied_speed()` / `is_inverted()` / `get_mode()` | Inspect the requested speed, final direction, wiring inversion and current drive mode (`\"drive\"`, `\"coast\"`, `\"brake\"`). |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Actuators import DCMotor\r\nfrom Reduino.Utils import sleep\r\n\r\nmotor = DCMotor(4, 5, 6)\r\nmotor.set_speed(0.4)\r\nmotor.run_for(1500, speed=1.0)\r\nmotor.ramp(-1.0, duration_ms=800)\r\nsleep(250)\r\nmotor.stop()\r\n```\r\n\r\n---\r\n\r\n### Displays\r\n\r\n#### LCD\r\n\r\n| Method | Description |\r\n| ------ | ----------- |\r\n| `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. |\r\n| `LCD(i2c_addr, cols=16, rows=2)` | PCF8574-style I\u00b2C backpack wiring. Constructor calls `init()`/`backlight()` for you. |\r\n| `write(col, row, text, clear_row=True, align=\"left\")` | Position text anywhere; optional row clearing and alignment (`\"left\"`, `\"center\"`, `\"right\"`). |\r\n| `line(row, text, align=\"left\", clear_row=True)` | Replace an entire row with aligned text. |\r\n| `message(top=None, bottom=None, top_align=\"left\", bottom_align=\"left\", clear_rows=True)` | Convenience helper for two-line messages. |\r\n| `clear()` / `display(on)` / `backlight(on)` | Clear the screen and toggle the LCD/backlight power. |\r\n| `brightness(level)` | Set PWM backlight brightness (parallel mode with `backlight_pin`). |\r\n| `glyph(slot, bitmap)` | Upload a custom 5\u00d78 glyph (`bitmap` = 8 integers). |\r\n| `progress(row, value, max_value=100, width=None, label=None, style=\"block\")` | Render a progress bar (`style` = `\"block\"`, `\"hash\"`, `\"pipe\"`, or `\"dot\"`). |\r\n| `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()`. |\r\n\r\n> [!NOTE]\r\n> `brightness()` is available only when a parallel display is created with `backlight_pin`. All alignment parameters accept `\"left\"`, `\"center\"`, or `\"right\"` (case-insensitive).\r\n\r\nAvailable animation styles:\r\n\r\n* `scroll` \u2013 marquee-style horizontal scrolling.\r\n* `blink` \u2013 toggles the text on and off without blocking.\r\n* `typewriter` \u2013 reveals the message one character at a time.\r\n* `bounce` \u2013 slides the text from edge to edge before reversing.\r\n\r\n**Parallel wiring example (PWM backlight + progress bar)**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Displays import LCD\r\n\r\nlcd = LCD(rs=12, en=11, d4=5, d5=4, d6=3, d7=2, backlight_pin=9)\r\nlcd.message(\"Setup complete\", bottom=\"Waiting\u2026\", top_align=\"center\")\r\nlcd.progress(1, 30, max_value=100, width=12, label=\"Load\")\r\nlcd.brightness(200)\r\n```\r\n\r\n**I\u00b2C backpack example (custom glyph + marquee animation)**\r\n\r\n```python\r\nfrom Reduino.Displays import LCD\r\n\r\npanel = LCD(i2c_addr=0x27, cols=20, rows=4)\r\npanel.glyph(0, [0, 2, 5, 8, 8, 5, 2, 0])\r\npanel.line(0, \"Ready to scroll\", align=\"center\")\r\npanel.animate(\"scroll\", 2, \"This text scrolls without blocking!\", speed_ms=150, loop=True)\r\n```\r\n\r\n---\r\n\r\n### Sensors\r\n\r\n#### Button\r\n\r\n| Method | Description |\r\n| ------------------------------------------------- | -------------------------------------------- |\r\n| `Button(pin, on_click=None, state_provider=None)` | Digital input w/ optional callback/provider. |\r\n| `is_pressed()` | `1` if pressed else `0`. |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\nfrom Reduino.Actuators import Led\r\nfrom Reduino.Sensors import Button\r\n\r\ntarget(\"COM3\")\r\n\r\nled = Led(6)\r\nbtn = Button(7)\r\nif btn.is_pressed():\r\n led.toggle()\r\n```\r\n\r\n---\r\n\r\n#### Potentiometer\r\n\r\n| Method | Description |\r\n| ---------------------------------------------- | --------------- |\r\n| `Potentiometer(pin=\"A0\", value_provider=None)` | Analog helper. |\r\n| `read()` | 0\u20131023 integer. |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\nfrom Reduino.Communication import SerialMonitor\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Sensors import Potentiometer\r\n\r\nmon = SerialMonitor(9600 , \"COM3\")\r\npot = Potentiometer(\"A0\")\r\n\r\nwhile True:\r\n value = pot.read()\r\n mon.write(value)\r\n```\r\n\r\n---\r\n\r\n#### Ultrasonic\r\n\r\n| Method | Description |\r\n| ---------------------------------------------------------------------------------------- | ------------------------------------------ |\r\n| `Ultrasonic(trig, echo, sensor=\"HC-SR04\", distance_provider=None, default_distance=0.0)` | HC-SR04 factory. |\r\n| `measure_distance()` | Distance in cm (handles timeouts/backoff). |\r\n\r\n**Example**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Sensors import Ultrasonic\r\nfrom Reduino.Utils import sleep\r\n\r\nu = Ultrasonic(trig=9, echo=10)\r\nd = u.measure_distance()\r\nprint(d)\r\nsleep(60)\r\n```\r\n\r\n---\r\n\r\n### Communication\r\n\r\n#### SerialMonitor\r\n\r\n| Method | Description |\r\n| ------------------------------------------------------- | ---------------------------------- |\r\n| `SerialMonitor(baud_rate=9600, port=None, timeout=1.0)` | Host-side serial console. |\r\n| `connect(port)` | Open serial (requires `pyserial`). |\r\n| `close()` | Close port. |\r\n| `write(value)` | Send text. |\r\n| `read()` | Read text. |\r\n\r\n**Example (host-side)**\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Communication import SerialMonitor\r\n\r\nmon = SerialMonitor(baud_rate=115200, port=\"COM4\")\r\n\r\nwhile True:\r\n mon.write(\"hello\")\r\n mon.read()\r\n mon.close()\r\n```\r\n\r\n> [!NOTE]\r\n> `pyserial` is optional; only needed if you call `connect()`.\r\n\r\n---\r\n\r\n### Utilities\r\n\r\n#### sleep\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Utils import sleep\r\nsleep(250) # ms\r\n```\r\n\r\n#### map\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Utils import map\r\nmapped = map(512, 0, 1023, 0.0, 5.0) # 2.5-ish\r\nprint(mapped)\r\n```\r\n\r\n### Core\r\n\r\nThe **Core** module exposes low-level helpers that map directly to the Arduino\r\nAPI. Use these when you need to configure a pin or interact with a sensor that\r\ndoesn't yet have a dedicated Reduino abstraction.\r\n\r\n| Helper | Description |\r\n| ------ | ----------- |\r\n| `pin_mode(pin, mode)` | Configure a pin for `INPUT`, `INPUT_PULLUP`, or `OUTPUT`. |\r\n| `digital_write(pin, value)` | Write `HIGH`/`LOW` to a digital pin. |\r\n| `analog_write(pin, value)` | Output a PWM value (0\u2013255). |\r\n| `digital_read(pin)` | Read a digital pin (returns `0` or `1`). |\r\n| `analog_read(pin)` | Read an analogue value (0\u20131023 on most boards). |\r\n\r\nConstants `INPUT`, `OUTPUT`, `INPUT_PULLUP`, `HIGH`, and `LOW` mirror the\r\nArduino macros so your code matches what you would write in C++.\r\n\r\n```python\r\nfrom Reduino import target\r\ntarget(\"COM3\")\r\n\r\nfrom Reduino.Core import pin_mode, digital_write, digital_read, OUTPUT, HIGH, LOW\r\n\r\npin_mode(7, OUTPUT)\r\ndigital_write(7, HIGH)\r\n\r\nif digital_read(2) == HIGH:\r\n digital_write(7, LOW)\r\n```\r\n\r\n---\r\n\r\n## Supported Python features\r\n\r\nReduino implements a pragmatic subset of Python that cleanly lowers to Arduino C++.\r\n\r\n### Control flow\r\n\r\n* `while True:` \u279c Arduino `loop()`\r\n* `for x in range(...)`, including `range(start, stop, step)`\r\n* `if / elif / else`, `break`, `continue`, `try/except` (mapped to C++ try/catch where used)\r\n\r\n### Variables & assignment\r\n\r\n* Standard assignment and **pythonic swap**:\r\n\r\n ```python\r\n a, b = b, a\r\n ```\r\n* Multiple assignment & tuple unpacking\r\n* Augmented ops (`+=`, `-=`, `*=`, etc.)\r\n\r\n### Collections\r\n\r\n* **Lists** (`[]`), tuples (`()`), and membership checks (`x in items`)\r\n* **List comprehensions**:\r\n\r\n ```python\r\n squares = [i for i in range(10)]\r\n ```\r\n* `len()` on strings, lists, and internal list type\r\n\r\n### Built-ins\r\n\r\n* `len()`, `abs()`, `max()`, `min()`\r\n* `print()` maps to serial printing in emitted code when serial is configured\r\n\r\n> [!TIP]\r\n> Many constant expressions are folded at transpile time for smaller, faster C++.\r\n\r\n---\r\n\r\n## License\r\n\r\nReduino is distributed under the **GNU General Public License v3.0 (GPLv3)**. \r\nYou are free to use, modify, and distribute this software for personal or educational purposes, \r\nas long as derivative works remain open-source and licensed under the same terms.\r\n\r\nFor commercial usage, redistribution, or integration into closed-source systems, \r\nplease contact me at arnavbajaj9@gmail.com for alternative licensing options.\r\n\r\nSee [LICENSE](https://www.gnu.org/licenses/gpl-3.0) for full details.\r\n\r\n<h1> Star History </h1>\r\n<br>\r\n<div align = \"center\">\r\n\r\n[](https://star-history.com/#Jackhammer9/Reduino&Date)\r\n\r\n</div>\r\n",
"bugtrack_url": null,
"license": null,
"summary": "Reduino transpiles Python scripts into efficient Arduino C++ and uploads automatically. A simple, intuitive way to control sensors, LEDs, and actuators without touching C++.",
"version": "1.2.0",
"project_urls": {
"Homepage": "https://github.com/Jackhammer9/Reduino",
"Issues": "https://github.com/Jackhammer9/Reduino/issues"
},
"split_keywords": [
"arduino",
" embedded",
" transpiler",
" robotics",
" avr",
" cpp"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f6a3c25486f60a9400a64a173980c66f18c2e2bc7c90fce9c186a006134f4bba",
"md5": "17f8e6c2d89d85418c1a1cc93beddbb1",
"sha256": "8a78b9ac8b15610ccb4a166acab6a7d5f59b27bfe28cf9c9c792b203cdca1906"
},
"downloads": -1,
"filename": "reduino-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "17f8e6c2d89d85418c1a1cc93beddbb1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 91284,
"upload_time": "2025-11-16T09:08:06",
"upload_time_iso_8601": "2025-11-16T09:08:06.868933Z",
"url": "https://files.pythonhosted.org/packages/f6/a3/c25486f60a9400a64a173980c66f18c2e2bc7c90fce9c186a006134f4bba/reduino-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c4df231648244711ed15f494ae97b0e62a1256d99d23aa3be506a87ef8a6b7ff",
"md5": "fd4f53a31f67469fe7847c5431dc4e0b",
"sha256": "0da2a6de58be06dc8e37f6e9eea606f016819ed0739cdfbb8fc0f46b8bffb0a4"
},
"downloads": -1,
"filename": "reduino-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "fd4f53a31f67469fe7847c5431dc4e0b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 103432,
"upload_time": "2025-11-16T09:08:08",
"upload_time_iso_8601": "2025-11-16T09:08:08.267190Z",
"url": "https://files.pythonhosted.org/packages/c4/df/231648244711ed15f494ae97b0e62a1256d99d23aa3be506a87ef8a6b7ff/reduino-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-16 09:08:08",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Jackhammer9",
"github_project": "Reduino",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "platformio",
"specs": []
},
{
"name": "pyserial",
"specs": []
},
{
"name": "pytest",
"specs": []
}
],
"lcname": "reduino"
}