DEV Community

Ertugrul
Ertugrul

Posted on

πŸ–₯️ Building a Mini SCADA Console on Raspberry Pi Pico (C++)

Industrial control systems often rely on SCADA (Supervisory Control and Data Acquisition) to monitor and control field devices. In this project, I recreated a miniature SCADA-like console on the Raspberry Pi Pico, entirely in C++, with no external sensors required. The Pico appears as a USB serial device, accepts commands, and responds with telemetryβ€”just like a field unit in an industrial network.


🎯 Project Goal

  • Simulate a SCADA field device with minimal hardware.
  • Build an interactive command console over USB-CDC.
  • Show telemetry (internal temperature sensor), device control (LED), and logging.
  • Learn how to integrate command parsing, ADC reads, and serial communication on bare-metal Pico.

✨ Features Implemented

  • USB-CDC console (appears as COM port on Windows, /dev/ttyACM0 on Linux).
  • Commands:

    • help β€” list available commands
    • id β€” show device identifier
    • status β€” print current status (temperature, LED state, logging period)
    • temp β€” one-shot temperature read
    • led on|off|toggle β€” control onboard LED
    • rate <ms> β€” set periodic status reporting interval
    • log on|off β€” enable/disable periodic logging
  • Periodic logging of temperature and LED state.

  • Built-in LED feedback for visibility.


πŸ”§ Technical Breakdown

1. USB-CDC Communication

The Pico is configured to use USB-CDC (serial over USB) as its standard I/O channel. With:

pico_enable_stdio_usb(scada_console 1)
pico_enable_stdio_uart(scada_console 0)
Enter fullscreen mode Exit fullscreen mode

all printf and getchar calls redirect to USB. On Windows, the board enumerates as USB Serial Device (COMx).

I used PuTTY to connect at 115200 baud, with Flow Control = None. This gave me a direct SCADA-like console experience.

2. Command Parser

Instead of building a full protocol stack, I implemented a lightweight line-based command parser in C++. Every command line is read from getchar_timeout_us(), buffered, and passed to a handler function that maps text commands to actions.

This approach makes it easy to extend with new commands (e.g., alarm, reset, profile save).

3. Telemetry (Temperature via ADC)

The RP2040 has a built-in temperature sensor accessible on ADC4. Using hardware/adc.h, I read raw ADC values, converted them to volts, and applied the datasheet formula:

float read_internal_temp_c() {
    uint16_t raw = adc_read();
    float volts = raw * (3.3f / 4095.0f);
    return 27.0f - (volts - 0.706f) / 0.001721f;
}
Enter fullscreen mode Exit fullscreen mode

This gives a rough internal temperature (not highly accurate, but perfect for telemetry demo).

4. Status Logging

I implemented periodic logging using absolute_time_t and make_timeout_time_ms(). When log on is enabled, the Pico automatically prints status every rate <ms> milliseconds.

This simulates how industrial field devices send periodic reports to SCADA masters.

5. Project Structure

mini-scada-pico/
 β”œβ”€ main.cpp                # Application entry point
 β”œβ”€ utils.hpp / utils.cpp   # Command parser + helpers
 β”œβ”€ CMakeLists.txt
 β”œβ”€ pico_sdk_import.cmake
 └─ assets/demo.gif
Enter fullscreen mode Exit fullscreen mode

πŸ–₯️ Example Session

== Mini SCADA Console ==
Device: PICO-FIELD-01
Commands:
  help
  id
  status
  log on|off
  rate <ms>
  led on|off|toggle
  temp

> id
PICO-FIELD-01
> status
id=PICO-FIELD-01 temp=28.75C led=OFF period=1000ms
> led on
OK
> temp
28.70
> log on
OK log on
[STATUS] id=PICO-FIELD-01 temp=28.77C led=ON period=1000ms
Enter fullscreen mode Exit fullscreen mode

πŸ“š What I Learned

  • How to use USB-CDC on Pico as the main I/O channel.
  • Building a command console on bare-metal hardware is simpler than it looks when using C++ and Pico SDK.
  • The internal temperature sensor (ADC4) is a handy built-in telemetry source.
  • Industrial-style periodic logging can be simulated with absolute_time_t timers.
  • Debugging USB-CDC on Windows sometimes requires driver fixes (usbser/Zadig) and patience.

πŸ“œ Source Code

The full code is available on GitHub:
πŸ‘‰ Mini SCADA Console Repository

Top comments (0)