Reduino


NameReduino JSON
Version 1.2.0 PyPI version JSON
download
home_pageNone
SummaryReduino transpiles Python scripts into efficient Arduino C++ and uploads automatically. A simple, intuitive way to control sensors, LEDs, and actuators without touching C++.
upload_time2025-11-16 09:08:08
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
keywords arduino embedded transpiler robotics avr cpp
VCS
bugtrack_url
requirements platformio pyserial pytest
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <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">

[![Star History Chart](https://api.star-history.com/svg?repos=Jackhammer9/Reduino&type=Date)](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[![Star History Chart](https://api.star-history.com/svg?repos=Jackhammer9/Reduino&type=Date)](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"
}
        
Elapsed time: 0.89985s