Using Arduino and Orange Pi for Datalogging

10/18/18

Last modified on 10/18/18

Categories: Microcontrollers Single Board Computers Tags: Orange Pi Arduino

I wanted to log data from a series of sensors I’m experimenting with. I was already powering the Arduino via OrangePi PC2 USB so I decided to transfer the data serially between the two devices using Python. First, plug in the Arduino and locate the device name.

ls /dev/tty*

Mine is ttyUSB0. Next, install PySerial, not to be confused with serial which is a different library. A lot of people have issues importing the module, this StackOverflow thread highlights some the main issues. Make sure you install the correct library and don’t name your file serial.py. (Sounds like a given, but I messed up on both counts.)

sudo python -m pip install pyserial

Since the data is tranferred per byte it is useful to know exactly how many bytes you’ll be sending. The data I want to transfer from my Arduino is soil moisture readings. These readings will always be within the range 0 to 1023, so I account for a 4-digit integer for each reading. After collecting the readings I use the below function to add leading zeros where needed and concatenate them all with commas inbetween.

// sends a string of results via serial to opi, which logs the data
void sendData(){
  char list[26];
  snprintf(list, 26, "%04d,%04d,%04d,%04d,%04d", varA, varB, varC, varE, varF);
  Serial.write(list);
}

On the OPi I have a Python script that checks for incoming data, and when 24 bytes are recieved it adds the data to the next row in a cvs file. The OPi provides the datestamp. Otherwise, the Arduino would need a real time clock module to be able to reliably provide a datestamp.

import serial
from time import strftime, time
import csv

csv_file = "/home/USER/logs/soil_tests.csv"
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.flushInput()

def log_data(data_string):
    with open(csv_file, "a") as output:
        output.write("{0},{1}\n".format(strftime("%Y-%m-%d %H:%M:%S"),data_string) )

while True:
    if ser.inWaiting()>0:
        inputValue = ser.read(24)
        print(inputValue)
        log_data(inputValue)

SD card modules can be purchased quite cheaply but bear in mind if you also need an accurate timestamp you’ll need an RTC module. There are datalogging modules that specifically include both.