Using a USB Memory Stick for Data Logging on Opta™
Learn how to interface an Opta™ device with a USB memory stick for data logging.
Overview
In this tutorial, we will learn how to interface an Opta™ device with a USB memory stick for data logging. Data logging is an essential process in industrial environments, where it is critical to continuously monitor and record vital parameters like temperature, pressure, or flow rates. These parameters are often captured through sensors connected to the input ports of a device like Opta™.
Through this guide, we will show you how to record readings from four analog input ports of an Opta™ device and store the data in a
.txt
file inside a USB memory stick. Additionally, we will use the onboard user button and LEDs of the Opta™ device to start, stop, and indicate the status of the data logging process to the user.Goals
- Connect an Opta™ device to a USB memory stick for data logging.
- Read data from four analog input ports of an Opta™ device and write it to a
file on a USB memory stick..txt
- Use the onboard user button of an Opta™ device to start and stop the data logging process.
- Use the onboard user LEDs of an Opta™ device to indicate the different states of the data logging process to the user.
Hardware and Software Requirements
Hardware Requirements
- Opta™ (x1)
- USB-A to USB-C® cable (x1)
- +12-24 VDC power supply (x1)
- Compatible USB-C® memory stick (x1)
Software Requirements
- Arduino IDE 1.8.10+, Arduino IDE 2.0+, or Arduino Web Editor
- Arduino_UnifiedStorage library
- Arduino_POSIXStorage library
- Arduino_USBHostMbed5 library
- ArduinoRS485 library
Compatible USB Memory Sticks
Any USB-C® memory stick should work with Opta® devices and the
Arduino_UnifiedStorage
library. Additionally, the following USB-C® memory sticks have been officially tested by the Arduino Team and are known to be fully compatible with Opta® devices and the Arduino_UnifiedStorage
library:- Kingston® DataTraveler® 80 M USB-C 256 GB Flash Drive
- SanDisk® Ultra® Dual Drive USB Type-C 64 GB Flash Drive
- SanDisk® Ultra® Dual Drive Go USB Type-C 64 GB Flash Drive
All USB memory sticks were formatted with the
file system before they were used with an Opta® device and the FAT32
library. It is recommended to use USB memory sticks with a storage capacity of 256 GB or less. If a memory stick has a storage capacity greater than 256 GB, it is advised to partition it, limiting the accessible storage to 256 GB or less.Arduino_UnifiedStorage
USB Memory Sticks and Data Logging
USB memory sticks and Flash drives are essential for data logging purposes in industrial environments. These small, rewritable storage devices equipped with integrated Flash memory and a USB interface are ideal for storing data such as temperature, pressure, and machine performance over time.
Data logging, particularly in industrial environments, is essential for predictive maintenance, process optimization, and quality control. It involves collecting large amounts of data over time, which can be analyzed to identify trends, predict equipment failures and improve operational efficiency.
To manage the communication between a USB memory stick and Opta™, you will use the
library. This library is excellent for working with different types of storage, including the FAT file systems that USB memory sticks often use. The main benefit of this library is that it makes dealing with various storage devices and file systems more straightforward. This is especially important in industrial data logging, where you need reliable and accurate data recording.Arduino_UnifiedStorage
The
library simplifies how to read and write data to external storage devices, ensuring precise and consistent data logging. You can learn more about this library in the following blog post.Arduino_UnifiedStorage
Instructions
Setting Up the Arduino IDE
This tutorial requires the latest version of the Arduino IDE that you can download here. In the Arduino IDE, you need to install the core for Opta™ devices, which can be done by navigating to Tools > Board > Boards Manager or clicking the Boards Manager icon in the left tab of the IDE.
In the Boards Manager tab, search for
opta
and install the latest Arduino Mbed OS Opta Boards
release.You can start now compiling and uploading Arduino sketches to an Opta™ device using the Arduino IDE.
Installing the Required Libraries
This tutorial also requires the latest version of the
Arduino_UnifiedStorage
library installed on the Arduino IDE. This can be done by navigating to Tools > Manage Libraries or clicking the Library Manager icon in the left tab of the IDE. In the Library Manager tab, search for Arduino_UnifiedStorage
and install the latest version.The
library needs some dependencies: the Arduino_UnifiedStorage
, the Arduino_POSIXStorage
and the Arduino_USBHostMbed5
libraries. The IDE will ask you if you want to install them. Ensure all the mentioned libraries are installed correctly and updated to their latest version.ArduinoRS485
Note: In case you want to receive and show the debug messages on your computer, you can use a USB to RS-485 converter, such as the converter used by the Arduino Pro Content Team. You can use the Arduino IDE's Serial Monitor to display the messages received in the converter or another serial terminal such as CoolTerm, a simple and cross-platform (Windows, Mac, and Linux) serial port terminal application (no terminal emulation) that is geared towards hobbyists and professionals.
Setting Up the Hardware
Connect a +12-24 VDC power supply to your Opta™ device.
To receive debug messages, which is optional, connect a USB to RS-485 converter to the RS-485 interface of your Opta™ device.
The example sketch logs data from the analog inputs ports
,I1
,I2
, andI3
of an Opta™ device; connect an analog signal source to these input ports to see real values logs on those pins.I4
For programming your Opta™ device, connect it to your computer using a USB-A to USB-C® cable.
Writing Data to a USB Memory Stick
Open the Arduino IDE and paste and save the following code:
1/**2 Opta USB data logging example sketch3 Name: usb_data_logging_opta.ino4 Purpose: This sketch logs data from four analog inputs of an Opta device5 into a single line in a file on a USB memory stick. The data logging process starts6 when the user button is pressed for 3 seconds and stops when the button is7 pressed again for 3 seconds. A Knight Rider LED pattern is used to indicate8 the status of USB connection. Once the data logging is done, all the user9 LEDs blink 10 times.10
11 @author Arduino PRO Content Team12 @version 1.1 10/11/2313*/14
15#include "Arduino_UnifiedStorage.h"16
17// Constants for analog input pins and LED pins18const int analog_pins[] = { A0, A1, A2, A3 };19const int led_pins[] = { LED_D0, LED_D1, LED_D2, LED_D3 };20
21// Define constants for voltage, resolution, and divider.22const float VOLTAGE_MAX = 3.0; // Maximum voltage that can be read23const float RESOLUTION = 4095.0; // 12-bit resolution24const float DIVIDER = 0.3; // Voltage divider25
26// Timing control variables27unsigned long previousMillis = 0;28const long interval = 1000;29
30// Knight Rider LED pattern variables31int ledDirection = 1;32int currentLed = 0;33
34// USB storage and folder instances35USBStorage usbStorage;36Folder backupFolder = Folder();37bool usbIntialized = false;38volatile bool usbAvailable = false;39
40/**41 Function to handle USB connection callback.42 Sets the USB available flag and removes the connection callback.43
44 @param none45 @return none46*/47void connectionCallback() {48 usbAvailable = true;49 Arduino_UnifiedStorage::debugPrint("- USB device connected!");50 usbStorage.removeOnConnectCallback();51}52
53/**54 Function to handle USB disconnection callback.55 Resets the USB available flag and reinstalls the connection callback.56
57 @param none58 @return none59*/60void disconnectionCallback() {61 usbAvailable = false;62 Arduino_UnifiedStorage::debugPrint("- USB device disconnected!");63 usbStorage.onConnect(connectionCallback);64}65
66/**67 Function to handle Knight Rider LED pattern.68 Displays a LED sequence on Opta's user LEDs to indicate waiting for USB connection.69
70 @param none71 @return none72*/73void knightRiderPattern() {74 for (int i = 0; i < 4; i++) {75 digitalWrite(led_pins[i], LOW);76 }77
78 digitalWrite(led_pins[currentLed], HIGH);79 delay(100);80 currentLed += ledDirection;81
82 if (currentLed == 3) {83 ledDirection = -1;84 } else if (currentLed == 0) {85 ledDirection = 1;86 }87}88
89/**90 Function to check for a 3-second button press.91 Used to start or stop the data logging process.92
93 @param none94 @return true if button is pressed for 3 seconds, false otherwise95*/96bool checkButtonPress() {97 if (digitalRead(BTN_USER) == LOW) {98 unsigned long buttonPressTime = millis();99 while (digitalRead(BTN_USER) == LOW) {}100 if (millis() - buttonPressTime >= 3000) {101 Arduino_UnifiedStorage::debugPrint("- Button pressed for 3 seconds!");102 return true;103 }104 }105 return false;106}107
108/**109 Function to blink all user LEDs a specified number of times.110 Indicates the start or end of a process like data logging.111
112 @param times Number of times to blink the LEDs113 @return none114*/115void blinkAllLeds(int times) {116 for (int i = 0; i < times; i++) {117 for (int j = 0; j < 4; j++) {118 digitalWrite(led_pins[j], HIGH);119 }120 delay(500);121 for (int j = 0; j < 4; j++) {122 digitalWrite(led_pins[j], LOW);123 }124 delay(500);125 }126}127
128/**129 Function to handle the writing of data to USB storage.130 Manages USB initialization, mounting, and writing of sensor data to file.131
132 @param none133 @return none134*/135void writeToUSB() {136 if (usbAvailable && !usbIntialized) {137 usbStorage.begin();138 Folder usbRoot = usbStorage.getRootFolder();139 String folderName = "backup_data";140 backupFolder = usbRoot.createSubfolder(folderName);141 Arduino_UnifiedStorage::debugPrint("- Backup folder created: " + backupFolder.getPathAsString());142 usbStorage.unmount();143 usbIntialized = true;144 } else if (usbAvailable && usbIntialized) {145 if (!usbStorage.isMounted()) {146 if (usbStorage.begin()) {147 performUpdate();148 }149 } else if (usbStorage.isMounted()) {150 performUpdate();151 }152 }153}154
155/**156 Function to perform data update on USB storage.157 Writes analog sensor data in a formatted string to a text file.158
159 @param none160 @return none161*/162void performUpdate() {163 UFile backupFile = backupFolder.createFile("analog_inputs_data.txt", FileMode::APPEND);164 unsigned long currentMillis = millis();165 if (currentMillis - previousMillis >= interval) {166 previousMillis = currentMillis;167
168 String buffer = "";169 for (int i = 0; i < 4; i++) {170 int value = analogRead(analog_pins[i]);171
172 // Convert the terminal value to its corresponding voltage. 173 float voltage = value * (VOLTAGE_MAX / RESOLUTION) / DIVIDER;174 if (i > 0) {175 buffer += "; ";176 }177 buffer += "A" + String(i) + ": " + String(voltage);178 }179 buffer += "\n";180 backupFile.write(buffer);181 Arduino_UnifiedStorage::debugPrint("- Data written to file: " + buffer);182 }183 backupFile.close();184 usbStorage.unmount();185 Arduino_UnifiedStorage::debugPrint("- File closed and USB storage unmounted!");186}187
188// Board initialization 189void setup() {190 Serial.begin(115200); 191 Arduino_UnifiedStorage::debuggingModeEnabled = false;192 analogReadResolution(12);193
194 usbStorage = USBStorage();195 usbStorage.onConnect(connectionCallback);196 usbStorage.onDisconnect(disconnectionCallback);197
198 for (int i = 0; i < 4; i++) {199 pinMode(led_pins[i], OUTPUT);200 digitalWrite(led_pins[i], LOW);201 }202
203 pinMode(BTN_USER, INPUT_PULLUP);204 Arduino_UnifiedStorage::debugPrint("- Setup complete!");205}206
207// Main loop208void loop() {209 static bool dataLoggingStarted = false;210
211 if (usbAvailable && !dataLoggingStarted) {212 knightRiderPattern();213
214 if (checkButtonPress()) {215 dataLoggingStarted = true;216
217 // Turn off all the user LEDs218 for (int i = 0; i < 4; i++) {219 pinMode(led_pins[i], OUTPUT);220 digitalWrite(led_pins[i], LOW);221 }222
223 // Turn on LED_D0 for data logging indication224 digitalWrite(led_pins[0], HIGH); 225 Arduino_UnifiedStorage::debugPrint("- Data logging started!");226 }227 } else if (dataLoggingStarted) {228 writeToUSB();229
230 // Toggle LED_D0231 digitalWrite(led_pins[0], digitalRead(led_pins[0]) == LOW); 232
233 if (checkButtonPress()) {234 dataLoggingStarted = false;235 Arduino_UnifiedStorage::debugPrint("- Data logging stopped!");236 237 // Blink all LEDs 10 times to indicate end of data logging238 blinkAllLeds(10); 239 }240 }241}
To upload the example sketch, click the Verify button to compile and check for errors; then click the Upload button to program the device with the sketch.
After uploading the example sketch, you can test it by connecting a compatible USB-C® memory stick. The example sketch logs data from the analog inputs ports
I1
, I2
, I3
, and I4
. Connect an analog signal source to these input ports to test this functionality.The example code from above shows how to interface an Opta™ device with a USB memory stick for storing data from four analog inputs into a single line in a file on a USB memory stick. Here's a brief overview of the example sketch functionality:
Connecting the USB memory stick: Once a USB memory stick is connected to an Opta™ device, the device enters into "waiting mode" indicated by a dynamic "Knight Rider" LED pattern with the onboard user LEDs.
Starting the process: The data logging process begins by pressing and holding the user button on an Opta™ device for three seconds and then releasing it. This action automatically starts logging data. Data from four analog inputs of the Opta™ device are recorded in a structured format onto the USB memory stick. During this process,
blinks to indicate active data logging.LED_D0
Stopping data logging: The process stops by pressing and holding the user button for another three seconds and then releasing it. The device stops recording data and signals completion by flashing all user LEDs ten times.
Here is a step-by-step breakdown of the code tested:
Import libraries:
- The sketch starts by importing the
library, which is essential for managing the USB memory stick and file system.Arduino_UnifiedStorage
Variables and instances definition:
- The sketch establishes instances for handling the USB memory stick and the file system. Arrays are defined to store the analog input pin numbers (
) and the onboard user LED numbers (analog_pins
).led_pins
- Variables for managing time (
andpreviousMillis
) are used to track data logging intervals without relying on the built-ininterval
function.delay()
- The "Knight Rider" LED pattern is controlled by
andledDirection
variables, sequentially illuminating the user LEDs on the Opta™ device.currentLed
The
setup()
function:- The sketch initializes the Opta™ device, setting the analog-to-digital converter resolution and preparing the onboard user LEDs.
- The sketch also establishes connection handlers for the USB memory stick using the
andconnectionCallback()
functions.disconnectionCallback()
The main
loop()
function:- The sketch monitors the onboard user button for a three-second pressing, holding, and then releasing it to initiate or stop the data logging process.
- When data logging is started,
is illuminated as an indication of the process. The "Knight Rider" LED pattern is displayed while the device waits for a USB memory stick connection.LED_D0
- The
function manages the data writing process to the USB memory stick, including initialization and updating data to the USB memory stick through thewriteToUSB()
function.performUpdate()
- Analog input data is formatted and written to a file named
on the USB memory stick.analog_inputs_data.txt
- When the data logging is completed (indicated by pressing the user button for three seconds again), the sketch stops writing data to the USB memory stick.
- The sketch shows the end of the data logging process by blinking all the onboard user LEDs ten times.
Optional: Debugging with
debugPrint
statements via Opta's RS-485 interface.- The
functions provide essential feedback throughout the sketch, aiding in monitoring and troubleshooting. The function can be turned on or off by setting thedebugPrint
function toArduino_UnifiedStorage::debuggingModeEnabled()
ortrue
.false
- These statements output important information via your Opta™ device's onboard RS-485 serial interface, including status updates during USB memory stick connection and file operation results.
Conclusion
In this tutorial, you have learned how to interface an Opta™ device with a USB memory stick, read analog input data, and store it on the USB memory stick. Additionally, you have understood how to use the onboard user LEDs to display status information to the user. With these skills, you can explore more complex projects, such as implementing advanced data logging and analysis for various sensors with Opta™ devices.
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.