Manar ANEJAE
Manar ANEJAE

Reputation: 11

Problem with SDRAM on Portenta H7, red light blinks 4 long 4 short

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 
}

Upvotes: 1

Views: 137

Answers (1)

Andy S
Andy S

Reputation: 1

I have this exact issue. I've not investigated it too thoroughly yet. I've double checked the address allocated is the same as the address passed to free, definitely something going on.

Upvotes: 0

Related Questions