Skip to content

Commit 6d7f36c

Browse files
committed
Merge branch 'main' into aliphys/exampleRevision
2 parents 26a7cd1 + f8717bc commit 6d7f36c

File tree

14 files changed

+285
-134
lines changed

14 files changed

+285
-134
lines changed

examples/logger/logger.ino

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
This example demonstrates the usage of the "Arduino_UnifiedStorage" library for logging and backing up data to USB storage in case a USB Mass Storage device is inserted.
3+
4+
The code defines two main functions: "logData" and "performUpdate".
5+
The "logData" function logs sensor data by reading an analog sensor and writing the data to the log file.
6+
7+
The "performUpdate" function performs the update process by:
8+
* reading the last update size from a file (number of bytes)
9+
* copying the new data from the log file to a backup file
10+
* and updating the last update size.
11+
12+
INSTRUCTIONS
13+
* Make sure the QSPI storage of your board is properly partitioned.
14+
* You can do that by flashing the QSPIFormat example that can be found in the STM32H747_System folder
15+
* Open the serial monitor and select answer with "Y" when this appears "Do you want to use partition scheme 1? Y/[n]"
16+
* Reboot the board
17+
* Connect a RS485-enabled device to see the debugging output.
18+
* This sketch will log data, and check if there is any USB MSD Device connected to the USB Port of the Opta.
19+
The USB device is mounted and unmounted after every update operation. The first status LED is on when the USB drive is mounted.
20+
So as long as the status LED is off you can safely remove the drive.
21+
The skecth will log to internal storage in the meantime, and wait for the USB drive to be inserted again.
22+
*/
23+
24+
#include "Arduino_UnifiedStorage.h"
25+
#include <vector>
26+
27+
28+
constexpr auto baudrate { 115200 };
29+
30+
#if defined(ARDUINO_PORTENTA_H7_M7)
31+
#define USB_MOUNTED_LED LED_BLUE
32+
#elif defined(ARDUINO_PORTENTA_C33)
33+
#define USB_MOUNTED_LED LEDB
34+
#endif
35+
36+
37+
InternalStorage internalStorage = InternalStorage();
38+
USBStorage usbStorage = USBStorage();
39+
std::vector<String> sensorDataBuffer;
40+
41+
unsigned long bytesWritten = 0;
42+
unsigned long lastLog = 0;
43+
unsigned long lastMove = 0;
44+
unsigned long lastBackup = 0;
45+
46+
47+
bool backingUP = false;
48+
49+
50+
// Function to run a given method periodically
51+
void runPeriodically(void (*method)(), unsigned long interval, unsigned long* variable) {
52+
unsigned long currentMillis = millis();
53+
54+
if (currentMillis - *variable >= interval) {
55+
*variable = currentMillis;
56+
method(); // Call the provided method
57+
}
58+
}
59+
60+
// Function to log sensor data
61+
void logDataToRAM() {
62+
int timeStamp = millis();
63+
int sensorReading = analogRead(A0);
64+
String line = String(timeStamp) + "," + String(sensorReading) + "\n";
65+
sensorDataBuffer.push_back(line);
66+
}
67+
68+
void moveDataToQSPI() {
69+
if(!backingUP){
70+
UFile _logFile = internalStorage.getRootFolder().createFile("log.txt", FileMode::APPEND);
71+
for (const auto& line : sensorDataBuffer) {
72+
bytesWritten += _logFile.write(line); // Write the log line to the file
73+
}
74+
_logFile.close();
75+
sensorDataBuffer.clear();
76+
}
77+
}
78+
79+
80+
void performUpdate() {
81+
Folder usbRoot = usbStorage.getRootFolder(); // Get the root folder of the USB storage
82+
UFile logFile = internalStorage.getRootFolder().createFile("log.txt", FileMode::READ);
83+
UFile backupFile = usbRoot.createFile("backup_file.txt", FileMode::APPEND); // Create or open the backup file
84+
UFile lastUpdateFile = usbRoot.createFile("diff.txt", FileMode::READ); // Create or open the last update file
85+
86+
backingUP = true;
87+
int lastUpdateBytes = lastUpdateFile.readAsString().toInt(); // Read the last update size from the file
88+
89+
Serial.print("Last update bytes: "); Serial.println(lastUpdateBytes);
90+
91+
if (lastUpdateBytes >= bytesWritten) {
92+
Serial.println("No new data to copy.");
93+
backupFile.close();
94+
lastUpdateFile.close();
95+
backingUP = false;
96+
return;
97+
}
98+
99+
logFile.seek(lastUpdateBytes); // Move the file pointer to the last update position
100+
unsigned long totalBytesToMove = bytesWritten - lastUpdateBytes;
101+
Serial.print("New update bytes: "); Serial.println(totalBytesToMove);
102+
103+
uint8_t buffer[totalBytesToMove];
104+
size_t bytesRead = logFile.read(buffer, totalBytesToMove);
105+
size_t bytesMoved = backupFile.write(buffer, bytesRead); // Only write the bytes that haven't been backed up yet
106+
107+
Serial.println("Successfully copied " + String(bytesMoved) + " new bytes.");
108+
109+
lastUpdateFile.changeMode(FileMode::WRITE); // Open the last update file in write mode
110+
lastUpdateFile.write(String(lastUpdateBytes + bytesMoved)); // Update the last update size
111+
112+
backupFile.close();
113+
logFile.close();
114+
lastUpdateFile.close();
115+
116+
Serial.println();
117+
usbStorage.unmount(); // Unmount the USB storage
118+
119+
digitalWrite(USB_MOUNTED_LED, HIGH);
120+
backingUP = false;
121+
}
122+
123+
124+
void disconnect(){
125+
126+
}
127+
// Function to backup data to USB storage
128+
void backupToUSB() {
129+
if (usbStorage.isAvailable()) {
130+
Serial.println("USB Mass storage is available");
131+
delay(100);
132+
if (!usbStorage.isConnected()) {
133+
134+
Serial.println("Mounting USB Mass Storage");
135+
digitalWrite(USB_MOUNTED_LED, LOW);
136+
if(usbStorage.begin()){
137+
performUpdate();
138+
}
139+
140+
141+
142+
} else if (usbStorage.isConnected()) {
143+
Serial.println("USB Mass storage is connected, performing update");
144+
performUpdate();
145+
146+
}
147+
} else {
148+
Serial.println("USB Mass storage is not available");
149+
}
150+
151+
152+
}
153+
154+
155+
void setup() {
156+
Serial.begin(115200);
157+
while (!Serial);
158+
pinMode(USB_MOUNTED_LED, OUTPUT);
159+
Serial.println("Formatting internal storage...");
160+
int formatted = internalStorage.format();
161+
Serial.print("QSPI Format status: "); Serial.println(formatted);
162+
163+
//configureRS485(baudrate);
164+
//Serial.println("RS485 goes brrr...");
165+
166+
if (!internalStorage.begin() == 0) {
167+
Serial.println("Failed to initialize internal storage");
168+
return;
169+
} else {
170+
Serial.println("Initialized storage");
171+
}
172+
173+
}
174+
175+
void loop() {
176+
#if defined(ARDUINO_PORTENTA_H7_M7)
177+
usbStorage.checkConnection();
178+
#endif
179+
runPeriodically(logDataToRAM, 100, &lastLog);
180+
runPeriodically(moveDataToQSPI, 1000, &lastMove);
181+
runPeriodically(backupToUSB, 10000, &lastBackup);
182+
}

examples/opta_logger/opta_logger.ino

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The "performUpdate" function performs the update process by:
1212
INSTRUCTIONS
1313
* Make sure the QSPI storage of your board is properly partitioned.
1414
* You can do that by flashing the QSPIFormat example that can be found in the STM32H747_System folder
15-
* Open the serial monitor and select answer with "Y" when this appears "Do you want to use partition scheme 1? Y/[n]"
15+
* Open the //Serial monitor and select answer with "Y" when this appears "Do you want to use partition scheme 1? Y/[n]"
1616
* Reboot the board
1717
* Connect a RS485-enabled device to see the debugging output.
1818
* This sketch will log data, and check if there is any USB MSD Device connected to the USB Port of the Opta.
@@ -24,13 +24,10 @@ INSTRUCTIONS
2424
#include "Arduino_UnifiedStorage.h"
2525
#include <vector>
2626

27-
#define USB_MOUNTED_LED LED_BLUE
2827

2928
constexpr auto baudrate { 115200 };
3029

3130

32-
33-
3431
InternalStorage internalStorage = InternalStorage();
3532
USBStorage usbStorage = USBStorage();
3633
std::vector<String> sensorDataBuffer;
@@ -74,112 +71,96 @@ void moveDataToQSPI() {
7471
}
7572

7673

77-
78-
79-
// Function to perform the update process
8074
void performUpdate() {
8175
Folder usbRoot = usbStorage.getRootFolder(); // Get the root folder of the USB storage
8276
UFile logFile = internalStorage.getRootFolder().createFile("log.txt", FileMode::READ);
8377
UFile backupFile = usbRoot.createFile("backup_file.txt", FileMode::APPEND); // Create or open the backup file
8478
UFile lastUpdateFile = usbRoot.createFile("diff.txt", FileMode::READ); // Create or open the last update file
8579

8680
backingUP = true;
87-
Serial.println("Opening diff file");
8881
int lastUpdateBytes = lastUpdateFile.readAsString().toInt(); // Read the last update size from the file
8982

90-
Serial.println(lastUpdateBytes);
91-
83+
//Serial.print("Last update bytes: "); //Serial.println(lastUpdateBytes);
9284

93-
if (lastUpdateBytes > bytesWritten) {
94-
Serial.println("everytime");
95-
lastUpdateFile.changeMode(FileMode::WRITE); // Open the log file in write mode
96-
lastUpdateFile.write(String(0)); // Reset the log file by writing 0 as the last update size
97-
lastUpdateBytes = 0;
85+
if (lastUpdateBytes >= bytesWritten) {
86+
//Serial.println("No new data to copy.");
87+
backupFile.close();
88+
lastUpdateFile.close();
89+
backingUP = false;
90+
return;
9891
}
9992

10093
logFile.seek(lastUpdateBytes); // Move the file pointer to the last update position
101-
unsigned long bytesMoved = 0;
10294
unsigned long totalBytesToMove = bytesWritten - lastUpdateBytes;
103-
Serial.println(totalBytesToMove);
104-
Serial.println("Ready to copy data");
95+
//Serial.print("New update bytes: "); //Serial.println(totalBytesToMove);
10596

106-
while (logFile.available()) {
107-
int data = logFile.read(); // Read a byte from the log file
97+
uint8_t buffer[totalBytesToMove];
98+
size_t bytesRead = logFile.read(buffer, totalBytesToMove);
99+
size_t bytesMoved = backupFile.write(buffer, bytesRead); // Only write the bytes that haven't been backed up yet
108100

109-
if (data != -1) {
110-
backupFile.write(data); // Write the byte to the backup file
111-
bytesMoved++;
112-
}
113-
}
114-
Serial.println("Succesfully copied data");
115-
116-
// Close the backup file
101+
//Serial.println("Successfully copied " + String(bytesMoved) + " new bytes.");
117102

118103
lastUpdateFile.changeMode(FileMode::WRITE); // Open the last update file in write mode
119-
lastUpdateFile.write(String(bytesMoved)); // Write the updated last update size to the file
104+
lastUpdateFile.write(String(lastUpdateBytes + bytesMoved)); // Update the last update size
120105

121-
backupFile.close();
106+
backupFile.close();
122107
logFile.close();
123108
lastUpdateFile.close();
124-
delay(100);
125109

126-
Serial.println("Succesfully updated diff file");
110+
//Serial.println();
127111
usbStorage.unmount(); // Unmount the USB storage
128112

129-
digitalWrite(USB_MOUNTED_LED, HIGH);
113+
digitalWrite(LED_D0, HIGH);
130114
backingUP = false;
131115
}
132116

117+
133118
void disconnect(){
134119

135120
}
136121
// Function to backup data to USB storage
137122
void backupToUSB() {
138123
if (usbStorage.isAvailable()) {
139-
Serial.println("USB Mass storage is available");
124+
//Serial.println("USB Mass storage is available");
140125
delay(100);
141126
if (!usbStorage.isConnected()) {
142127

143-
Serial.println("Mounting USB Mass Storage");
144-
digitalWrite(USB_MOUNTED_LED, LOW);
128+
//Serial.println("Mounting USB Mass Storage");
129+
digitalWrite(LED_D0, LOW);
145130
if(usbStorage.begin()){
146131
performUpdate();
147132
}
148133

149134

150135

151136
} else if (usbStorage.isConnected()) {
152-
Serial.println("USB Mass storage is connected, performing update");
137+
//Serial.println("USB Mass storage is connected, performing update");
153138
performUpdate();
154139

155140
}
156141
} else {
157-
Serial.println("USB Mass storage is not available");
142+
//Serial.println("USB Mass storage is not available");
158143
}
159144

160-
if(usbStorage.isConnected() && !usbStorage.isAvailable()){
161-
Serial.println("we should never get here");
162-
}
163145

164146
}
165147

166148

167149
void setup() {
168-
Serial.begin(115200);
169-
while (!Serial);
170-
pinMode(USB_MOUNTED_LED, OUTPUT);
171-
Serial.println("Formatting internal storage...");
150+
//Serial.begin(115200);
151+
pinMode(LED_D0, OUTPUT);
152+
//Serial.println("Formatting internal storage...");
172153
int formatted = internalStorage.format();
173-
Serial.print("QSPI Format status: "); Serial.println(formatted);
154+
//Serial.print("QSPI Format status: "); //Serial.println(formatted);
174155

175156
//configureRS485(baudrate);
176-
//Serial.println("RS485 goes brrr...");
157+
////Serial.println("RS485 goes brrr...");
177158

178159
if (!internalStorage.begin() == 0) {
179-
Serial.println("Failed to initialize internal storage");
160+
//Serial.println("Failed to initialize internal storage");
180161
return;
181162
} else {
182-
Serial.println("Initialized storage");
163+
//Serial.println("Initialized storage");
183164
}
184165

185166
}
@@ -189,5 +170,4 @@ void loop() {
189170
runPeriodically(logDataToRAM, 100, &lastLog);
190171
runPeriodically(moveDataToQSPI, 1000, &lastMove);
191172
runPeriodically(backupToUSB, 10000, &lastBackup);
192-
193173
}

src/Arduino_UnifiedStorage.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717

1818

19-
2019
#if defined(ARDUINO_PORTENTA_C33)
2120
#include "QSPIFlashBlockDevice.h"
2221
#include <BlockDevice.h>
@@ -50,7 +49,6 @@ class Arduino_UnifiedStorage {
5049
#endif
5150

5251

53-
extern Arduino_UnifiedStorage UnifiedStorage;
5452

5553
#endif
5654

0 commit comments

Comments
 (0)