arduino编程:没有足够的内存消息

时间:2016-04-13 15:38:56

标签: memory arduino

我是arduino编程的新手(Arduino Pro Mini 3.3v版),我有一些代码如下。我正在将9DOF,OLED屏幕和BLE突破连接到arduino pro mini。

我已经完成了一些内存优化提示,但我仍有一些问题。即使使用以下代码,我只剩下9个字节用于动态内存。如果我启用BTLEserial.begin();,它将终止内存。请提出任何建议。

#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 个答案:

答案 0 :(得分:1)

首先,您需要确定RAM的位置 - 每个库占用多少?你真的需要同时运行它们吗?您知道可以在当前设置中运行显示库和IMU代码 - 您是否可以实现启用IMU代码,提取数据然后禁用它的内容?显示和BTLE代码一样吗?这样每个库只在需要时消耗RAM,并在操作完成后释放它

更新1

我上面提到的一个例子。我不知道所有库是否都实现了.end()函数。他们可能会使用类似的方法。

// 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;
}