Skip to content

SERIAL_TIMESERIES

Download Flojoy Studio to try this app
Extract simple, time-dependent 1D data from an Arduino or a similar serial device. Params: num_readings : int Number of points to record. record_period : float Length between two recordings in seconds. baudrate : int Baud rate for the serial device. comport : string COM port of the serial device. num_readings * record_period : Is roughly the run length in seconds. Returns: out : OrderedPair
Python Code
from datetime import datetime
from time import sleep
from typing import Optional

import numpy as np
import serial
from flojoy import OrderedPair, flojoy


@flojoy(deps={"pyserial": "3.5"})
def SERIAL_TIMESERIES(
    default: Optional[OrderedPair] = None,
    comport: str = "/dev/ttyUSB0",
    baudrate: int = 9600,
    num_readings: int = 100,
    record_period: int = 1,
) -> OrderedPair:
    """Extract simple, time-dependent 1D data from an Arduino or a similar serial device.

    Parameters
    ----------
    num_readings : int
        Number of points to record.
    record_period : float
        Length between two recordings in seconds.
    baudrate : int
        Baud rate for the serial device.
    comport : string
        COM port of the serial device.

    num_readings * record_period :
        Is roughly the run length in seconds.

    Returns
    -------
    OrderedPair
    """

    set = serial.Serial(comport, timeout=1, baudrate=baudrate)
    readings = []
    times = []
    # The first reading is commonly empty.
    s = set.readline().decode()

    for i in range(num_readings):
        ts = datetime.now()
        s = set.readline().decode()
        # Some readings may be empty.
        if s != "":
            reading = s[:-2].split(",")
            if len(reading) == 1:
                reading = reading[0]
            readings.append(reading)

            ts = datetime.now()
            seconds = float(
                ts.hour * 3600 + ts.minute * 60 + ts.second + ts.microsecond / 10**6
            )

            times.append(seconds)

            if len(times) > 0:
                time1 = seconds - times[i]
            else:
                # Estimate execution time.
                time1 = 0.1

            if time1 < record_period:
                sleep(record_period - time1)

    times = np.array(times)
    try:
        times -= times[0]
    except IndexError:
        raise IndexError("No data detected from the Arduino")

    readings = np.array(readings)
    readings = readings.astype("float64")

    return OrderedPair(x=times, y=readings)

Find this Flojoy Block on GitHub

Videos

Arduino Temperature Sensor

Example App

Having problems with this example app? Join our Discord community and we will help you out!
React Flow mini map

In this example, we use the SERIAL_TIMESERIES node to extract some time-dependent measurements received from an Arduino microcontroller, and visualize the output.

First, you need to connect the Arduino to your computer. Then, you’ll need to upload an Arduino script to your board to define its behavior (with the Arduino IDE software). When your Arduino sends data to the serial monitor of the Arduino IDE, you can start using the SERIAL_TIMESERIES node. After placing the node on Flojoy, you must specify the communication port to which the Arduino is connected. This port is found in the Arduino IDE software under Tools/Port.

The SERIAL_TIMESERIES node receives data through serial communication with the Arduino, and stores the measured values in a table named readings. The Arduino prints new values on the serial console for each loop. The SERIAL_TIMESERIES node then extracts a single measurement (for this node, each time dependant measurement must contain only one value).

The TABLE node displays all values stored in the timeseries measurement.

Remarks about the Arduino code:

In order to use this node properly, you need to print one value per line using the command (i.e. println()).

For example:

println(reading)