M5Stack Fire SPI SRAM memory test fail

I am running the following script on an M5Stack Fire with a Servo stack module and an Ultrasonic module connected to the portB (pin 36 as input and 26 as output):

#include <M5Stack.h>
#include <Adafruit_NeoPixel.h>
#include <Arduino.h>


#define M5STACK_FIRE_NEO_NUM_LEDS 10
#define M5STACK_FIRE_NEO_DATA_PIN 15
#define Echo_EingangsPin 36 // Echo Eingangs-Pin
#define Trigger_AusgangsPin 26 // Trigger Ausgangs-Pin


// Variables for Ultrasonic
int maximumRange = 300;
int minimumRange = 2;
long Abstand;
long Dauer;


Adafruit_NeoPixel pixels = Adafruit_NeoPixel(M5STACK_FIRE_NEO_NUM_LEDS, M5STACK_FIRE_NEO_DATA_PIN, NEO_GRB + NEO_KHZ800);


int angle = 90;


#define SERVO_ADDR 0x53


void setup() {


  Serial.begin (115200);
  pixels.begin();
  setLEDout();
  M5.begin();
  M5.Power.begin();
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("Ready!");
  //M5.Lcd.drawJpgFile(SD, "/bird.jpg", 120, 80);
  delay(2000); // To be able to connect Serial monitor after reset or power up and before first printout;




  pinMode(Trigger_AusgangsPin, OUTPUT);
  pinMode(Echo_EingangsPin, INPUT);


}


int8_t getBatteryLevel() {
  Wire.beginTransmission(0x75);
  Wire.write(0x78);
  M5.Lcd.print("Batt Level = ");
  if (Wire.endTransmission(false) == 0 && Wire.requestFrom(0x75, 1)) {
    switch (Wire.read() & 0xF0) {
      case 0xE0: M5.Lcd.println("25%");
      case 0xC0: M5.Lcd.println("50%");
      case 0x80: M5.Lcd.println("75%");
      case 0x00: M5.Lcd.println("100%");
        // default: Serial.print("0%");
    }
  }
}


// addr 0x11 mean control the number 1 servo by angle
void Servo_write_angle(uint8_t number, uint8_t angle) {
  Wire.beginTransmission(SERVO_ADDR);
  Wire.write(0x10 | number);
  Wire.write(angle);
  Wire.endTransmission();
}
void setLEDout() {
  for (int iLED = 0; iLED < 10; iLED++) {
    Serial.print(iLED);
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(iLED, pixels.Color(0, 0, 0)); //  NO colour.
    delay(100);
    pixels.show(); // This sends the updated pixel color to the hardware.
  }
  delay(100);
  M5.Lcd.fillScreen(BLACK);


}
void setLEDred() {
  for (int iLED = 0; iLED < 10; iLED++) {
    Serial.print(iLED);
    pixels.setPixelColor(iLED, pixels.Color(10, 0, 0)); //  RED colour.
    delay(100);//Needed to stop leds random colors
    pixels.show(); // This sends the updated pixel color to the hardware.
  }
}
void setLEDgreen() {
  for (int iLED = 0; iLED < 10; iLED++) {
    Serial.print(iLED);
    pixels.setPixelColor(iLED, pixels.Color(0, 10, 0)); //  Green colour.
    delay(100);
    pixels.show(); // This sends the updated pixel color to the hardware.
  }
}
void setLEDblue() {
  for (int iLED = 0; iLED < 10; iLED++) {
    Serial.print(iLED);
    pixels.setPixelColor(iLED, pixels.Color(0, 0, 10)); //  Blue colour.
    delay(100);
    pixels.show(); // This sends the updated pixel color to the hardware.
  }
}
void setLEDyellow() {
  for (int iLED = 0; iLED < 10; iLED++) {
    Serial.print(iLED);
    pixels.setPixelColor(iLED, pixels.Color(20, 20, 0)); //  Yellow colour.
    delay(100);
    pixels.show(); // This sends the updated pixel color to the hardware.
  }
}
void Forward() {
  M5.Lcd.clear(BLACK);
  angle = angle + 5;
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("Anticlockwise");
  M5.Lcd.print("Speed = ");
  M5.Lcd.println(angle);
  Servo_write_angle(0, 107);
  Servo_write_angle(1, 75);
}
void Reverse() {
  M5.Lcd.clear(BLACK);
  angle = angle + 5;
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("Anticlockwise");
  M5.Lcd.print("Speed = ");
  M5.Lcd.println(angle);
  Servo_write_angle(0, 75);
  Servo_write_angle(1, 105);
}
void Stop() {
  M5.Lcd.clear(BLACK);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.print("Stop");
  angle = 90;
  Servo_write_angle(0, angle);
  Servo_write_angle(1, angle);
}
void Right() {
  M5.Lcd.clear(BLACK);
  angle = angle + 5;
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("Anticlockwise");
  M5.Lcd.print("Speed = ");
  M5.Lcd.println(angle);
  Servo_write_angle(0, 105);
  Servo_write_angle(1, 90);
}
void Left() {
  M5.Lcd.clear(BLACK);
  angle = angle + 5;
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("Anticlockwise");
  M5.Lcd.print("Speed = ");
  M5.Lcd.println(angle);
  Servo_write_angle(0, 90);
  Servo_write_angle(1, 75);
}
void loop() {
  M5.update();
  if (M5.BtnA.wasPressed()) {
    Forward();
  }
  if (M5.BtnB.wasPressed()) {
    Stop();
  }
  M5.Lcd.setTextColor(RED);
  M5.Lcd.setTextSize(6);
  //M5.Lcd.println("Hello");
  // Abstandsmessung wird mittels des 10us langen Triggersignals gestartet
  digitalWrite(Trigger_AusgangsPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trigger_AusgangsPin, LOW);


  // Nun wird am Echo-Eingang gewartet, bis das Signal aktiviert wurde
  // und danach die Zeit gemessen, wie lang es aktiviert bleibt
  Dauer = pulseIn(Echo_EingangsPin, HIGH);


  // Nun wird der Abstand mittels der aufgenommenen Zeit berechnet
  Abstand = Dauer / 58.2;


  // Überprüfung ob gemessener Wert innerhalb der zulässingen Entfernung liegt
  if (Abstand >= maximumRange || Abstand <= minimumRange)
  {
    // Falls nicht wird eine Fehlermeldung ausgegeben.
    M5.Lcd.println("Clear");
  }


  else
  {
    // Der berechnete Abstand wird in der seriellen Ausgabe ausgegeben
    M5.Lcd.clear(BLACK);
    M5.Lcd.setCursor(90, 90);
    M5.Lcd.print(Abstand);
    M5.Lcd.println("cm");
    if(Abstand <= 7) {
      setLEDred();
      Reverse();
      delay(1000);
      Left();
      delay(1000);
      Forward();
    }
  }
  // Pause zwischen den einzelnen Messungen
  delay(100);

}

This works fine with the Abstand variable below 8 but if the Abstand variable is set to 8 or above the sketch doesn't load and I get the error:

E (1881) spiram: SPI SRAM memory test fail. 391/131072 writes failed, first @ 3F800000

I would be grateful for any help in solving this. Please be aware the sketch is a work in progress and is by no means finished.

When I use PSRAM with an ESP32, Arduino does not have PSRAM, I initialize the ram before use.

I do not know about the m5stack thingy but I do not see any code that you posted that shows PSRAM initialization.

#include "sdkconfig.h"  //
#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "esp32-hal-psram.h"
#include "esp_himem.h"
// #include "esp_spiram.h"
// #include "rom/cache.h"
extern "C"
{
//#include <esp_himem.h>
#include <esp_spiram.h>
}
//extern "C"
//{
//#include <esp_himem.h>
//}

////
const int SerialDataBits = 115200;
////
struct stuTime
{
  int iSeconds = 0;
  int iMinutes = 0;
  int iHours = 0;
};
////
void setup()
{

//  Serial.begin(115200);
//
//  Serial.println("========================================");
//  Serial.printf("PSRAM total size     : %u \n", esp_spiram_get_size());
//  Serial.println("----------------------------------------");
//  Serial.printf("PSRAM first 4MB size : %u \n", ESP.getPsramSize());
//  Serial.printf("PSRAM first 4MB free : %u \n", ESP.getMaxAllocPsram());
//  Serial.printf("PSRAM HI-MEM    size : %u \n", esp_himem_get_phys_size());
//  Serial.printf("PSRAM HI-MEM    free : %u \n", esp_himem_get_free_size());
//  Serial.println("========================================");
//  Serial.printf("Internal RAM  size   : %u \n", ESP.getHeapSize()); 
//  Serial.printf("Internal RAM  free   : %u \n", ESP.getFreeHeap()); 
//  Serial.println("========================================");
//
//  Serial.println("Testing the free memory of PSRAM HI-MEM ...");
//  test_region(esp_himem_get_free_size(), 0xaaaa);
//  Serial.println("Done!");

  ////////////////////////////////////////////////////////////////////////////////
  esp_spiram_init();
  vTaskDelay(1);
//  esp_himem_handle_t mh; //Handle for the address space we're using
//    esp_himem_rangehandle_t rh; //Handle for the actual RAM.
//    esp_himem_alloc( 1024, &mh);
  // Serial.begin( SerialDataBits );
  // psramInit();
  // vTaskDelay(3);
  // esp_spiram_init();
  // vTaskDelay(1);
  //   log_i("Total heap: %u", ESP.getHeapSize());
  //   log_i("Free heap: %u", ESP.getFreeHeap());
  // log_i("Total PSRAM: %u", ESP.getPsramSize());
  // log_i("Free PSRAM: %d", ESP.getFreePsram());
  // log_i("spiram size %u", esp_spiram_get_size());
//  log_i("himem free %u", esp_himem_get_free_size());
//  log_i("himem phys %u", esp_himem_get_phys_size());
//  log_i("himem reserved %u", esp_himem_reserved_area_size());
  //
  //   int *ptr, *ptr1;
  //   int n, n1, i, sum = 0;
  //   float *ptrFloat;
  //   // Get the number of elements for the array
  //   n = 10;
  //   n1 = 20;
  //   log_i("Number of elements ptr: %d", n);
  //   log_i("Number of elements ptr1: %d", n1);
  //   log_i("Number of elements ptr1: %d\n", n1);
  //   // Dynamically allocate memory using malloc()
  //   // ptr = (int*)ps_malloc(n * sizeof(int)); //works
  //   ptr = (int*)ps_calloc( n, sizeof(int) ); // works
  //   log_i("Free PSRAM: %d", ESP.getFreePsram());
  //   ptr1 = (int*)ps_calloc( n1, sizeof(int) ); // works
  //   log_i("Free PSRAM: %d", ESP.getFreePsram());
  //    // Check if the memory has been successfully
  //    // allocated in ps_ram
  //    ptrFloat = (float*)ps_calloc( n, sizeof(float) ); // works
  //    if (ptr == NULL) {
  //      log_i(" ptr memory not allocated.\n");
  //      exit(0);
  //    }
  //    if (ptr1 == NULL)
  //    {
  //      log_i("ptr1 memory not allocated.\n");
  //      exit(0);
  //    }
  //    else
  //    {
  //       // Memory has been successfully allocated
  //      // log_i("ps_ram memory successfully allocated using ps_calloc.");
  //      // put elements into ps_ram array
  //      for (i = 0; i < n; ++i)
  //      {
  //        ptr[i] = i + 1;
  //      }
  //      for (i = 0; i < n1; ++i)
  //      {
  //        ptr1[i] = i + 2;
  //      }
  //      for (i = 0; i < n; ++i)
  //      {
  //        ptrFloat[i] = (float)i + 1.06555f;
  //      }
  //      // Print the elements of the array
  //      log_i("The elements of the ptr array are: ");
  //      for (i = 0; i < n; ++i) {
  //        log_i("%d, ", ptr[i]);
  //      }
  //      log_i("The elements of the ptr1 array are: ");
  //      for (i = 0; i < n1; ++i) {
  //        log_i("%d, ", ptr1[i]);
  //      }
  //      log_i("The elements of the ptrFloat array are: ");
  //      for (i = 0; i < n1; ++i) {
  //        log_i("%f, ", ptrFloat[i]);
  //      }
  //    }
  //    //
  //    // put a structure into psram. Works.
  //    struct stuTime *ptrStuTime;
  //    log_i("size of structure: %d", sizeof(struct stuTime) );
  //     //
  //    ptrStuTime = (struct stuTime *)ps_malloc(sizeof(struct stuTime));
  //    log_i("Free PSRAM after structure: %d", ESP.getFreePsram());
  //    ptrStuTime->iSeconds = 10;
  //    ptrStuTime->iMinutes = 60;
  //    ptrStuTime->iHours = 100;
  //    log_i("Seconds: %d Minutes: %d Hours: %d", ptrStuTime->iSeconds, ptrStuTime->iMinutes, ptrStuTime->iHours );
  //    free(ptr);
  // free(ptr1);
  //    free(ptrStuTime);
  //    // works
  //    log_i("Free PSRAM before String: %d", ESP.getFreePsram());
  //    char *str;
  //    char OneChar = 'a';
  //    char TwoChar = 'b';
  //    char ThreeChar = 'c';
  //    str = (char *)ps_calloc(300, sizeof(char) );
  //    log_i("Free PSRAM after String: %d", ESP.getFreePsram());
  //    // concantenate one char variable to end of char array to the str
  //    strncat( str, &OneChar, 1 ); //works
  //    strncat( str, &TwoChar, 1 );
  //    strncat( str, &ThreeChar, 1 );
  //    //
  //    //*(str+0) = 'G';  // works
  //    //*(str+1) = 'f';
  //    //*(str+2) = 'G';
  //    //*(str+3) = '\0';
  //    log_i("%s", str );
  //    free(str);

  ///////
  //size_t memfree=esp_himem_get_free_size();
  //log_i( "himemFree %d", memfree );
  //  int memcnt=esp_himem_get_phys_size();
  // int memfree=esp_himem_get_free_size();
  //  log_i( "SpiRamPhysSize %d", memcnt );
  //  log_i( "SpiRamFree %d", memfree );
  // esp_himem_get_phys_size(void)
  // esp_himem_handle_t mh; //Handle for the address space we're using
  // esp_himem_rangehandle_t rh; //Handle for the actual RAM.
  // esp_err_t intError = esp_himem_alloc( 4095, &mh);
  // log_i( "%s", esp_err_to_name( intError) );
  // log_i("spiram size %u", esp_spiram_get_size());
  // log_i( "Handle %d", mh );


} // setup()
////

Some ways I have been able to configures and access PSRAM.


You mean you have issues when this

 // Nun wird der Abstand mittels der aufgenommenen Zeit berechnet
  Abstand = Dauer / 58.2;

is set to 8>=?

I noticed Adstand is declared as an int and you do float things to the variable, is that by intent?

No, what I meant was that if the line

if(Abstand <= 7 {.....

is set to 7 or less the sketch works but if it is set above 8 I get the SPI error. The code for setting the Abstand variable was from the ultrasonic example sketch.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.