2016-04-13 357 views
0

我是arduino編程新手(Arduino Pro Mini 3.3v版本),我有一些類似下面的代碼。我將9DOF,OLED屏幕和BLE breakout連接到arduino pro mini。arduino編程:沒有足夠的內存消息

我已經通過了一些內存優化技巧,但我仍然有一些問題。即使使用下面的代碼,我只剩下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

首先,你需要弄清楚你的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; 
} 
+0

這就是我所缺少的,我是一個移動開發者,並且剛開始低級編程。我現在明白了。非常感謝Daniel。 – triston

+0

嗨丹尼爾,同樣的問題,如果我確實需要運行BTLE,IMU,OLED顯示在一起,你有什麼建議嗎?謝謝 – triston

+1

我不認爲你能夠 - 你的編譯器清楚地說明你不能同時運行所有的類,你只是沒有足夠的內存來完成它。但是,我相當肯定你不需要同時運行它們,只需足夠長時間就可以做你需要做的事情。將每個進程分成它自己的功能,並且一次處理一個進程。我用一些半僞代碼更新了我的答案,希望能更好地展示這一點 –

相關問題