I'm new to Arduino and am encountering an issue with my Arduino Portenta H7. I've written a sketch to sample analog signals from three sensors at a 25kHz sampling rate, using external SDRAM for data storage. The sketch manages dynamic memory allocation to store the sensor data in arrays until a specified data point count (data_len) is reached, and checks for allocation errors, stopping the program if any occur.
My problem arises when executing the free_memory function, where the program crashes, indicated by a red light blinking in a pattern of 4 long and 4 short blinks.
I've tried freeing each buffer individually, but the issue persists. Here's my code:
#include "Arduino_PortentaBreakout.h"
#include "SDRAM.h"
REDIRECT_STDOUT_TO(Serial);
// Constants for ADC warm-up and sampling interval
const int ADC_WARMUP_READS = 1000; // Number of reads to stabilize ADC readings
const long interval = 40; // Sampling interval in microseconds (40 microseconds for 25kHz sampling rate)
// Reference voltage
const float VREF = 3.10; // Reference voltage in volts
// Definitions of analog pins used
const breakoutPin PHASE_1 = ANALOG_A0;
const breakoutPin PHASE_2 = ANALOG_A1;
const breakoutPin CURRENT = ANALOG_A3;
// Array containing the analog pins for easy access
const breakoutPin PIN_Array[] = { PHASE_1, PHASE_2, CURRENT };
const char* PIN_Names[] = { "PHASE_1", "PHASE_2", "CURRENT" };
// Number of data points to sample
const long data_len = 250000;
// Buffers to store sampled values
uint16_t* data_PHASE_1;
uint16_t* data_PHASE_2;
uint16_t* data_CURRENT;
// Function to fill data arrays
void fillArrays() {
// ADC warm-up to stabilize the sensor signal
for (int i = 0; i < ADC_WARMUP_READS; i++) {
Breakout.analogRead(PHASE_1);
Breakout.analogRead(PHASE_2);
Breakout.analogRead(CURRENT);
}
// Time preparation to measure buffer fill duration
unsigned long timeStart = micros();
long i = 0;
unsigned long previousMicros = 0;
while (i < data_len) {
unsigned long currentMicros = micros();
if (currentMicros - previousMicros >= interval) {
previousMicros = currentMicros;
data_PHASE_1[i] = Breakout.analogRead(PHASE_1);
data_PHASE_2[i] = Breakout.analogRead(PHASE_2);
data_CURRENT[i] = Breakout.analogRead(CURRENT);
i++;
}
}
unsigned long timeEnd = micros();
Serial.print("Total loops completed: ");
Serial.println(i);
}
void free_memory() {
SDRAM.free(data_PHASE_1); data_PHASE_1 = NULL;
SDRAM.free(data_PHASE_2); data_PHASE_2 = NULL;
SDRAM.free(data_CURRENT); data_CURRENT = NULL;
}
void setup() {
Serial.begin(115200);
while (!Serial); // Wait for the serial connection to be established
analogReadResolution(16);
SDRAM.begin();
data_PHASE_1 = (uint16_t*)SDRAM.malloc(data_len * sizeof(uint16_t));
data_PHASE_2 = (uint16_t*)SDRAM.malloc(data_len * sizeof(uint16_t));
data_CURRENT = (uint16_t*)SDRAM.malloc(data_len * sizeof(uint16_t));
if (data_PHASE_1 == NULL || data_PHASE_2 == NULL || data_CURRENT == NULL) {
Serial.println("Error: Failed to allocate memory, halting execution.");
while (1); // Halt further execution
}
if (SDRAM.test()) {
Serial.println("SDRAM is completely functional");
}
}
void loop() {
fillArrays();
for (int i = 0; i < 3; ++i) {
delay(2000);
const char* PIN_NAME = PIN_Names[i];
uint16_t* data = (i == 0) ? data_PHASE_1 : (i == 1) ? data_PHASE_2 : data_CURRENT;
Serial.print("Transmitting data for ");
Serial.println(PIN_NAME);
for (long j = 0; j < data_len; j++) {
Serial.println(data[j]);
}
Serial.print("End of data transmission for ");
Serial.println(PIN_NAME);
}
free_memory();
Serial.println("Click on reset to restart.");
while (1); // Pause
}