0

I am new to arduino programming (Arduino Pro Mini 3.3v version), i have some code like below. I am connecting 9DOF, OLED screen and a BLE breakout to arduino pro mini.

I already went through some of the memory optimization tips, but i still have some issue. Even with the following code, i only have 9 bytes left for dynamic memory. If i enable BTLEserial.begin();, it will kill the memory. Please any suggestions will be appreciated.

#include <Wire.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>
#include "Adafruit_BLE_UART.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);



LSM9DS1 imu;


#define LSM9DS1_M  0x1E // Would be 0x1C if SDO_M is LOW
#define LSM9DS1_AG  0x6B // Would be 0x6A if SDO_AG is LOW

#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2
#define ADAFRUITBLE_RST 9

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);



void setup(void) {

  Serial.begin(9600);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)

  display.display();
  delay(2000);


  display.clearDisplay();


  display.drawPixel(10, 10, WHITE);

  display.display();
  delay(2000);
  display.clearDisplay();

  imu.settings.device.commInterface = IMU_MODE_I2C;
  imu.settings.device.mAddress = LSM9DS1_M;
  imu.settings.device.agAddress = LSM9DS1_AG;
  if (!imu.begin())
  {
    while (1)
      ;
  }


 // BTLEserial.begin(); - if i uncomment this code, i will get a not enough memory error.

}


aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

void loop() {

  displayAllDOF();

}

void displayAllDOF(){
  display.setTextSize(1);
  display.setTextColor(WHITE);

  imu.readGyro();
  display.setCursor(0,0);
  display.print("G:");
  display.print(imu.calcGyro(imu.gx));
  display.print(", ");
  display.print(imu.calcGyro(imu.gy));
  display.print(", ");
  display.print(imu.calcGyro(imu.gz));
  display.println(" ");

  imu.readAccel();
  display.print("A:");
  display.print(imu.calcAccel(imu.ax));
  display.print(", ");
  display.print(imu.calcAccel(imu.ay));
  display.print(", ");
  display.print(imu.calcAccel(imu.az));
  display.println(" ");

  imu.readMag();
  display.print("M:");
  display.print(imu.calcMag(imu.mx));
  display.print(", ");
  display.print(imu.calcMag(imu.my));
  display.print(", ");
  display.print(imu.calcMag(imu.mz));
  display.println(" ");

  display.display();
  display.clearDisplay();

}

1 Answer 1

1

To start, you'll need to figure out where your RAM is going - How much does each library take? Do you really need to run them all at the same time? You know that you can run the display library, and the IMU code in your current setup - Can you implement something that only enables the IMU code, pulls data, then disables it? And the same with the display and BTLE code? That way each library is only consuming RAM when it's needed, and frees it once it's operation is finished

Update 1

An example of what I mentioned above. I do not know if all the libraries implement the .end() function. They may have a similar method you can use.

// Simple data storage for the .gx and .gy values
typedef struct {
    float x, y;
} GyroData_t; 

GyroData_t getImuData() {
    GyroData_t data; 
    // Create the IMU class, gather data from it, and then destroy it
    LSM9DS1 *imu = new LSM9DS1();
    imu->begin();
    imu->readGyro();
    data.x = imu.gx;
    data.y = imu.gy;
    imu->end();
    // This will reclaim the RAM that was used by the IMU - We no longer need it
    delete imu;
    return data;
}

void displayAllDOF() {
    // Gather the IMU data
    GyroData_t data = getImuData();
    // Create the display object, and print the data we received
    Adafruit_SSD1306 *display = new Adafruit_SSD1306(OLED_RESET);
    display->print(...);
    ....
    display->end();
    // Reclaim the display RAM used
    delete display;

    // Do any bluetooth operations now
    doBluetoothStuff();
}

void doBluetoothStuff() { 
   Adafruit_BLE_UART *BTLEserial = new Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
   BTLESerial->begin();
   ...
   BTLESerial->end();
   delete BTLESerial;
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is what i am missing, I am a mobile developer, and just started the low level programming. I got the idea now. Thanks a lot Daniel.
Hi Daniel, same question again, if i do need to run BTLE, IMU, OLED display all together, do you have any suggestion? Thanks
I dont think you will be able to - Your compiler clearly states you can't have all of the classes running simultaneously, you simply do not have enough RAM to do it. However, I am fairly certain you don't need to run them all at the same time, just long enough to do what you need to do. Separate each process into it's own function, and handle one at a time. I've updated my answer with some semi-pseudocode that hopefully shows this better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.