This repository helps you quickly set up and develop your serial port communication project. Built with ElectronJS and a modern Ionic/Angular front-end, it uses an NX monorepo structure for efficient project management.
The repository provides:
- Core functionality of Arduino's Serial Monitor, enhanced with tools to configure, monitor, and communicate with serial devices
- Core functionality of Arduino's Serial Plotter, enhanced with tools to select, zoom, export and visualize data
- Cross-platform desktop application (
windows
,linux
andmacOS
) - Hot-reloading to accelerate development and testing cycles
- Enforced code linting and formatting
- Enforced conventional commits
- Streamlined workspace management and remote caching with NX
- CI/CD workflows
- Angular's signals and RxJS for reactivity and state management
- Unit testing examples
- E2E testing examples
- Automatic updates on new github releases (see limitations for more details)
- Modern tech stack:
Package version nodejs 22.x.x angular 19.x.x ionic 8.x.x electron 33.3.x nx 20.2.2 typescript 5.5.x
For a demo, check the sample binaries.
Firstly, ensure the following are installed:
- Node.js (preferably using
nvm
for version management) - NX CLI (
npm install -g nx
, or you can usenpx nx ...
if you prefer)
- Clone the repository:
git clone https://github.com/robsonos/spie
cd spie
- Install dependencies:
npm i
- Run the application:
nx run-many -t serve
If you want a minimalistic two way serial example, use the following:
#include <Arduino.h>
int period = 1000;
unsigned long time_now = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
if (Serial.available() > 0)
Serial.write(Serial.read());
if (millis() > time_now + period) {
time_now = millis();
Serial.print("Hello World ");
Serial.println(millis());
}
}
For a example used on the plotter images, check out spie-firmware.
The Plotter expects a line feed LF (\n
) to separate records. Ensure that there is a linebreak character after the last variable in each record.
You can use different delimiters to separate variables within a record: space (
), tab (\t
), or comma (,
).
For labeled data, the plotter can interpret variables in the format <label>:<value>
.
The Plotter supports parsing single and multiple variables in each record, handles duplicates for the same
variable label, and correctly groups the data under their respective labels.
Examples:
Single variable: 1\n
, 2\n
Multiple variables: 1,2\n
, 3,4\n
Multiple labeled variables: temp1:1,temp2:2\n
, temp1:3,temp2:4\n
Learn more about NX in this Angular Monorepo tutorial. Here are the most commonly used NX tasks:
- Serve the applications:
nx run-many -t serve
[NOTE] If you see a blank screen, that will be because
spie
finished building beforespie-ui
. You can reload the web application with eitherCTRL+R
on thedevelop tool window
or typingr
followed byENTER
on the terminal window. Alternatively, you can runnx run spie-ui:serve
first and thennx run spie:serve
.
- Lint the code:
nx run-many -t lint
- Run unit tests:
nx run-many -t test
- Run e2e tests:
nx run-many -t e2e
- Build the applications (development):
nx run-many -t build
- Build the applications (production):
nx run-many -t build --prod
- Build and generate unpacked executables:
Warning
Build the applications first
nx run spie:package
Output files are located in dist\packages
- Build and generate the executables:
Warning
Build the applications first
nx run spie:make
Output files are located in dist\executables
There are many ways CD/CI workflow can be implemented. I chose the most convenient one and here is how it is meant to work:
dev
: holds the development code. Pushes to this branch will trigger theCI workflow
, which will test the code that changes since the last release, and display a summary of the the next release.main
: holds the code for the latest release. Pushes to this branch will trigger theCD workflow
, which will create a new github release, a tag. New releases will then trigger theBinaries workflow
to build and upload binaries the release.- If you need to maintain more release channels, form instance
main
is atv3.x.x
and you need to supportv1.x.x
, I would recommend using a similar approach:main
forv3.x.x
main/v1
forv1.x.x
dev
forv3.x.x
developmentdev/v1
forv1.x.x
development
- I may look into exemplifying the above and
pre-releases
in the feature
You can use act to test workflows locally. Read more about act
here. Also, check out .actrc
- CI
act push -W .github/workflows/ci.yml
- CD
act push -W .github/workflows/cd.yml
- Release
act release -W .github/workflows/release.yml -e event.json
Sample event.json
{
"action": "created",
"release": {
"name": "v1.0.0",
"tag_name": "1.0.0"
}
}
- Serial data may be delivered in more than one
.on('data')
event. This means data received by the serialport library might arrive in multiple packets. For details, see node-serialport/issues/659. This is not a problem in most cases, but unexpected behavior may occur if you are trying to monitor data at a fast rate. A good way to demonstrate the issues is to send data every5ms
,115200
baud rate and withshow timestamps
. You will notice that every so often there is a "broken" message. If your data is terminated with a new line (\n
) you can useuse readline parser
to alleviate that. If you are developing your own application, I would recommend using one of the parsers available. - Depending on your operating system, the serial port ingestion may take a while, which could make the
plotter
look off when usingtimestamp
instead ofsample count
. macOS
application must be signed in order for auto updating to work. See electron-builder Auto Update for more details.