PicoLC is an Arduino library for the PicoLC controller, a compact RP2040/RP2350-based control board designed for 12 V and 24 V automation projects.
The library provides a logical, scan-based interface for:
- Four protected field inputs
- Four configurable field outputs
- Output pairing
- Status indicators and board buttons
- IEC-style timers
- RS-485 communication
- Nonvolatile user storage
- Board-level diagnostics
PicoLC uses the Earle Philhower Arduino-Pico core and is not intended to support other Arduino cores.
Status
This library is under active development.
The public API may change while the hardware and library are being validated. Storage and paired-output support are still being finalized.
Requirements
- PicoLC hardware
- Raspberry Pi Pico, Pico W, Pico 2, or Pico 2 W as supported by the PicoLC board
- Arduino IDE or Arduino CLI
- Earle Philhower Arduino-Pico core
Installation
Install the Earle Philhower Arduino-Pico core, then install this library into your Arduino libraries directory.
For local development, place or link the repository at:
Documents/Arduino/libraries/PicoLC
Restart the Arduino IDE after adding or updating the library.
Basic Usage
#include <PicoLC.h>
void setup() {
}
void loop() {
}
Main interface to PicoLC hardware and shared runtime services.
PicoLCOutput Y0
Hardware outputs Y0 through Y3.
PicoLCInput X0
Hardware inputs X0 through X3.
void update()
Advances PicoLC by one application scan.
void enableOutputs()
Enables physical output-driver operation.
void begin()
Initializes PicoLC hardware and child objects.
void outputMode(OutputMode mode)
Sets the electrical drive mode.
bool write(bool state)
Applies a logical command to the output.
Scan Model
Call plc.update() once at the beginning of each loop() iteration.
update():
- Captures one shared millisecond timestamp for the scan
- Increments the scan counter
- Samples and filters inputs and buttons
- Updates edge-detection state
- Advances output and LED pulse, blink, and PWM behavior
- Applies configured logical output behavior to the board
Timed API components use the timestamp captured by the most recent plc.update(). This keeps timers, filters, pulses, and blink patterns consistent within one application scan.
Logical and Physical States
The public API works with logical states.
bool inputActive = plc.
X0.
read();
Electrical output behavior is configured separately:
Physical output drive is globally controlled through:
void disableOutputs()
Disables all physical output-driver channels.
Disabling physical outputs preserves logical output states. Output indicator LEDs continue to display the states that would otherwise be sent to the physical outputs.
Inputs
PicoLC inputs expose filtered logical state and edge detection:
Filtering and inversion are applied before logical state changes and edge detection.
Edge results remain valid until the next plc.update().
Outputs
Each output has an electrical mode, a pattern mode, and a linear PWM duty value.
void patternMode(PatternMode mode)
Sets the timed behavior applied to the output.
uint16_t duty(uint16_t duty)
Sets the linear PWM duty.
The output duty range is:
0 = 0%
500 = 50%
1000 = 100%
Output Patterns
Applies the logical state continuously.
void pulseLength(uint32_t ms)
Sets the Pulse-mode duration.
Starts or restarts a fixed-duration pulse. Writing false stops the pulse at the next update() cycle.
void blinkOnTime(uint32_t ms)
Sets the active time within each Blink-mode cycle.
void blinkPeriod(uint32_t ms)
Sets the complete Blink-mode cycle period.
Starts a repeating blink pattern in the on phase. Writing false stops blinking at the next update() cycle.
LEDs
Board LEDs use the same steady, pulse, and blink pattern modes as outputs.
PicoLCLED StatusLED
Board indicator LEDs.
void blinkOnTime(uint32_t ms)
Sets the active time within each Blink-mode cycle.
void brightness(uint16_t brightness)
Sets the perceived LED brightness.
void blinkPeriod(uint32_t ms)
Sets the complete Blink-mode cycle period.
void patternMode(PatternMode mode)
Sets the timed behavior applied to the LED.
bool write(bool state)
Applies a logical command to the LED.
LED brightness uses a user-facing range of 0 through 100. The library converts this to a nonlinear PWM value to provide more natural perceived brightness changes.
A brightness of zero does not change the logical LED state or configured pattern.
Buttons
Board buttons expose the same filtered logical-state and edge-detection interface as field inputs:
if (plc.BootButton.
rising()) {
}
void toggle()
Toggles the LED state or active pulse.
read() returns true when the button is logically pressed.
Timers
PicoLC timers provide standard IEC-style TON, TOF, and TP behavior using the shared PicoLC scan timebase.
IEC-style timer using the shared PicoLC scan timebase.
The compact form performs write(input) followed by read():
The operations may also be called separately:
bool output = onDelay.read();
Additional timer state is available through:
onDelay.running();
onDelay.elapsed();
onDelay.remaining();
onDelay.presetMillis();
onDelay.reset();
Timers should normally be serviced once per PicoLC scan.
RS-485 Serial
plc.Serial provides an Arduino Stream-compatible interface to the PicoLC RS-485 port.
void setup() {
}
void loop() {
}
}
PicoLCSerial Serial
RS-485 serial interface.
void begin(uint32_t baud, uint16_t config=SERIAL_8N1)
Initializes the RS-485 UART and transceiver-control pins.
size_t write(uint8_t byte) override
Transmits one byte over RS-485.
int available() override
Returns the number of received bytes available to read.
int read() override
Reads the next received byte.
The current implementation is blocking. A write call returns after transmission is complete and the RS-485 transceiver has returned to receive mode.
plc.Serial is separate from the Arduino USB Serial interface.
Board Diagnostics
Output enable state
bool outputsEnabled() const
Reports whether physical outputs are globally enabled.
Output-driver fault
}
bool outputFault() const
Reports the current output-driver fault indication.
Output-driver reset
void resetOutputDriver()
Resets the hardware output driver.
Supply voltage
float supplyVoltage() const
Measures the PicoLC supply voltage.
supplyVoltage() samples the board VIN sense circuit when called and is independent of plc.update().
Examples
The library includes progressive examples covering:
- Basic input and output
- Input filtering
- Input edge detection
- Output patterns
- LED patterns
- TON timer
- TOF timer
- TP timer
- Global output enable
- Output fault monitoring
Open them through the Arduino IDE under:
Repository Layout
PicoLC/
├── examples/
├── src/
│ ├── PicoLC.h
│ ├── PicoLCClass.h
│ ├── PicoLCInput.h
│ ├── PicoLCOutput.h
│ ├── PicoLCLED.h
│ ├── PicoLCButton.h
│ ├── PicoLCTimer.h
│ ├── PicoLCSerial.h
│ └── ...
├── library.properties
├── LICENSE
└── README.md
Hardware Notes
PicoLC is designed around fixed board resources and the Earle Philhower RP2040/RP2350 Arduino core.
Some hardware resources are shared:
- Outputs Y0 and Y1 are on the same RP2 PWM slice and share a PWM frequency
- Outputs Y2 and Y3 also share a PWM frequency.
- Individual outputs retain independent PWM duty values
- Output pairs may impose additional shared configuration requirements
- Physical outputs remain disabled until explicitly enabled
License
Released under MIT license. See LICENSE file.
Project
Project website: picolc.com