2016-07-01 6 views
1

Я использую клон Arduino UNO, Dccduino, и у меня проблема с памятью. Sketch использует 25,114 байт (77%) пространства для хранения программ. Максимум 32 256 байтов. Глобальные переменные используют 1,968 байт (96%) динамической памяти, оставляя 80 байтов для локальных переменных. Максимум составляет 2048 байт. Доступна низкая память, могут возникнуть проблемы со стабильностью. Есть ли способ уменьшить объем памяти около 20%, если я не думаю, что я должен купить Arduino MegaКак уменьшить использование памяти на Arduino Uno

Вот код:

#include <OneWire.h> 
#include <DallasTemperature.h> 
#include <SPI.h> 
#include <SD.h> 
#include <Wire.h> 
#include "RTClib.h" 
#include <GPRS_Shield_Arduino.h> 
#include <SoftwareSerial.h> 

// Data wire is plugged into port 3 and 2 on the Arduino 
#define ONE_WIRE_BUS_1 3 // Many sensors on pin 3 
#define ONE_WIRE_BUS_2 2 // Many sensors on pin 2 
#define TEMPERATURE_PRECISION 9 // Lower resolution 
#define PIN_TX 7 
#define PIN_RX 8 
#define BAUDRATE 9600 
#define PHONE_NUMBER "xxxxxxxxxxxxx" 

GPRS gprsTest(PIN_TX, PIN_RX, BAUDRATE); //RX,TX,PWR,BaudRate 

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 
OneWire oneWire1(ONE_WIRE_BUS_1); 
OneWire oneWire2(ONE_WIRE_BUS_2); 

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors1(&oneWire1); 
DallasTemperature sensors2(&oneWire2); 
int numberOfDevices1; // Number of temperature devices found on pin 3 
int numberOfDevices2; // Number of temperature devices found on pin 2 
DeviceAddress tempDeviceAddress1; // We'll use this variable to store a found device address for bus 3 
DeviceAddress tempDeviceAddress2; // We'll use this variable to store a found device address for bus 2 

File myFile; 

RTC_DS3231 rtc; // Create a RealTimeClock object 


void setup(void) 
{ 

    // start serial port 
#ifndef ESP8266 
    while (!Serial); // for Leonardo/Micro/Zero 
#endif 
    Serial.begin(9600); 
    delay(3000); 
    Serial.println(F("Dallas Temperature IC Control Library Demo")); 


    Serial.print(F("Initializing SD card...")); 

    if (!SD.begin(4)) { 
    Serial.println(F("\ninitialization failed!")); 
    return; 
    } 
    Serial.println(F("initialization done.")); 

    if (! rtc.begin()) { 
    Serial.println("Couldn't find RTC"); 
    while (1); 
    } 


    if (rtc.lostPower()) { 
    Serial.println("RTC lost power, lets set the time!"); 
    // following line sets the RTC to the date & time this sketch was compiled 
    //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 
    // This line sets the RTC with an explicit date & time, for example to set 
    // January 21, 2014 at 3am you would call: 
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); 
    } 

    /* while(!gprsTest.init()) { //gprs init 
     delay(1000); 
     Serial.print(F("init error\r\n")); 
     Serial.println(F("gprs init success"));*/ It takes 20% of dynamic memory so i cant use it 
    } 
    Serial.println(F("start to call ..."));// Call when device will start 
    gprsTest.callUp(PHONE_NUMBER); 
    Serial.println("start to send message ..."); 
    gprsTest.sendSMS(PHONE_NUMBER, "Hi device is ON"); //define phone number and text 


    // Start up the library 
    sensors1.begin(); 
    sensors2.begin(); 

    // Grab a count of devices on the wire 
    numberOfDevices1 = sensors1.getDeviceCount(); 
    numberOfDevices2 = sensors2.getDeviceCount(); 

    // locate devices on the bus 
    Serial.print(F("Locating devices...")); 

    Serial.print(F("Found ")); 
    Serial.print(numberOfDevices1, DEC); 
    Serial.print(F("+")); 
    Serial.print(numberOfDevices2, DEC); 
    Serial.println(F(" devices.")); 

    // report parasite power requirements 
    Serial.print("Parasite power is: "); 
    if (sensors1.isParasitePowerMode()) Serial.println(F("Sensors 1 ON")); 
    else Serial.println(F("\nSensors 1 OFF")); 
    if (sensors2.isParasitePowerMode()) Serial.println(F("Sensors 2 ON")); 
    else Serial.println(F("Sensors 2 OFF")); 


    // Loop through each device, print out address for pin 3 
    for (int i = 0; i < numberOfDevices1; i++) 
    { 
    // Search the wire for address 
    if (sensors1.getAddress(tempDeviceAddress1, i)) 
    { 
     Serial.print(F("Found device ")); 
     Serial.print(i, DEC); 
     Serial.print(F(" with address: ")); 
     printAddress(tempDeviceAddress1); 
     Serial.println(); 
     Serial.println(F("\n")); 
     // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions) 
     sensors1.setResolution(tempDeviceAddress1, TEMPERATURE_PRECISION); 


    } else { 
     Serial.print(F("Found ghost device for pin 3 at ")); 
     Serial.print(i, DEC); 
     Serial.print(F(" but could not detect address. Check power and cabling")); 
    } 
    } 


    // Loop through each device, print out address for pin 2 
    for (int i = 0; i < numberOfDevices2; i++) 
    { 
    // Search the wire for address 
    if (sensors2.getAddress(tempDeviceAddress2, i)) 
    { 
     Serial.print(F("Found device ")); 
     Serial.print(i + numberOfDevices1, DEC); 
     Serial.print(F(" with address: ")); 
     printAddress(tempDeviceAddress2); 
     Serial.println(); 
     Serial.println(F("\n")); 
     // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions) 
     sensors2.setResolution(tempDeviceAddress2, TEMPERATURE_PRECISION); 

    } else { 
     Serial.print(F("Found ghost device for pin 2 at ")); 
     Serial.print(i, DEC); 
     Serial.print(F(" but could not detect address. Check power and cabling")); 
    } 
    } 

} 



void loop(void) 
{ 
    // call sensors1.requestTemperatures() to issue a global temperature 
    // request to all devices on the bus 
    Serial.print(F("Requesting temperatures to pin 3...")); 
    sensors1.requestTemperatures(); // Send the command to get temperatures for pin 3 
    Serial.println(F("DONE")); 

    myFile = SD.open("test1.txt", FILE_WRITE); //open file 

    // Loop through each device , print out temperature data for pin 3 
    for (int i = 0; i < numberOfDevices1; i++) 
    { 
    // Search the wire for address 
    if (sensors1.getAddress(tempDeviceAddress1, i)) 
    { 
     // Output the device ID 
     Serial.print(F("Temperature for device: ")); 
     Serial.println(i, DEC); 

     // It responds almost immediately. Let's print out the data 

     printTemperature1(tempDeviceAddress1);// Use a simple function to print out the data 

     Serial.print(F("\n")); 
    } 
    delay(4000); 
    //else ghost device! Check your power requirements and cabling 
    }// End forloop for pin 3 
    if (numberOfDevices2 != 0) { 
    Serial.print(F("Requesting temperatures to pin 2...")); 
    sensors2.requestTemperatures(); // Send the command to get temperatures for pin 2 
    Serial.println(F("DONE")); 
    } 


    // Loop through each device for pin 2, print out temperature data 
    for (int i = 0; i < numberOfDevices2; i++) 
    { 
    // Search the wire for address 
    if (sensors2.getAddress(tempDeviceAddress2, i)) 
    { 
     // Output the device ID 
     Serial.print(F("Temperature for device: ")); 
     Serial.println(i + numberOfDevices1, DEC); 
     // It responds almost immediately. Let's print out the data 
     printTemperature2(tempDeviceAddress2);// Use a simple function to print out the data 
     Serial.print(F("\n")); 
    } 
    else Serial.print(F("ghost device! Check your power requirements and cabling")); 
    delay(4000); 
    } //End forloop for pin 3 

    myFile.close(); // Should I close it? 

}// End loop() 






void printAddress(DeviceAddress deviceAddress) // function to print a device address 
{ 
    for (uint8_t i = 0; i < 8; i++) 
    { 
    if (deviceAddress[i] < 16) Serial.print(F("0")); 
    Serial.print(deviceAddress[i], HEX); 
    } 
} 






void printTemperature1(DeviceAddress deviceAddress1) // function to print the temperature for a device (pin 3) 
{ 
    float tempC = sensors1.getTempC(deviceAddress1); 
    Serial.print("Temp C: "); 
    Serial.print(tempC); 
    if (myFile) 
    { 
    Serial.println(F("\nWriting to test.txt...")); 
    myFile.print(F("C: ")); 
    myFile.print(tempC); 
    print_time(); // Call print_time() function to print time on file 
    myFile.print(F("\n")); 
    Serial.print(F("Done!")); 
    } 
    else Serial.print(F("Error opening file 1")); 
    Serial.println("\n"); 
} 



void printTemperature2(DeviceAddress deviceAddress2) // function to print the temperature for a device (pin 2) 
{ 
    float tempC = sensors2.getTempC(deviceAddress2); 
    Serial.print(F("Temp C: ")); 
    Serial.print(tempC); 
    if (myFile) 
    { 
    Serial.print(F("\nWriting to test.txt...")); 
    myFile.print(F("C: ")); 
    myFile.print(tempC); 
    print_time(); // Call print_time() function to print time on file 
    myFile.print(F("\n")); 
    Serial.print(F("Done!")); 
    } else Serial.print(F("Error opening file 2")); 

    Serial.println("\n"); 
} 

void print_time() { // print time function 

    DateTime now = rtc.now(); 
    Serial.print(now.year(), DEC); 
    Serial.print('/'); 
    Serial.print(now.month(), DEC); 
    Serial.print('/'); 
    Serial.print(now.day(), DEC); 
    Serial.print(now.hour(), DEC); 
    Serial.print(':'); 
    Serial.print(now.minute(), DEC); 
    Serial.print(':'); 
    Serial.print(now.second(), DEC); 
    Serial.println(); 
    myFile.print(now.year(), DEC); 
    myFile.print('/'); 
    myFile.print(now.month(), DEC); 
    myFile.print('/'); 
    myFile.print(now.day(), DEC); 
    myFile.print(now.hour(), DEC); 
    myFile.print(':'); 
    myFile.print(now.minute(), DEC); 
    myFile.print(':'); 
    myFile.print(now.second(), DEC); 
    myFile.println(); 
} 

ответ

1

Я думаю, что я уже видел этот код, прежде чем на другом сайте , Из вашего кода Предполагаю, что вы создаете регистратор температуры, и вы хотите регистрировать данные на SD-карте. Большая часть вашего кода избыточна, если вы используете библиотеку DS1307RTC.h и библиотеку Time.h. DS1307RTC - это общая библиотека RTC. С его помощью вам не нужны OneWire, Wire или SPI и Wire. Программное обеспечение Serial также не нужно. Однако, я предлагаю вам проверить мой Arduino DATALOGGER Библиотеку Github: https://github.com/FreelanceJavaDev/DataLogger

Я довольно много увеличившихся памяти я сохранил на моей Uno до 22,680 байт (70%) пространств для хранения программ и 1237 байт (60%) SRAM (динамическая память). Он автоматически настраивает RTC и SD-карту. Это делает CSV-файл для экспорта превосходным в течение каждого месяца, когда он работает по дате.

0

В свое время я создал несколько регистраторов данных Arduino, и все из них, использующие карты SD, потерпели неудачу из-за нехватки памяти. SD сам по себе использует половину памяти, доступной на ATMega 328. Добавьте к этому пару библиотек для другого оборудования, и у вас совсем нет памяти для вашего эскиза.

Я перешел на 24LC512s. Один из них обычно достаточно, но вы можете использовать до 4 с разными адресами, если хотите. Это относительно небольшой объем памяти, но я нашел, что этого всегда достаточно. Слишком просто создать мегабайты данных, которые слишком велики для анализа. Один 24LC512 содержит более чем достаточно данных для одной электронной таблицы. Единственная нижняя сторона заключается в том, что вам нужно использовать Arduino для чтения данных через USB.

Я использую первые два байта для хранения количества записей, а следующий байт - для хранения количества байтов на запись. (Хотя в ретроспективе последнее на самом деле не обязательно.) Вы можете подумать, что первые два байта будут «изнашиваться», потому что они переписываются каждый раз, когда создается новая запись, но это еще не со мной. У меня был тот же Arduino, который постоянно работает 7 лет (без перерыва от нескольких обновлений к эскизу) и генерирует более 1000 записей в месяц, поэтому первые два байта должны быть обновлены столько раз. У меня никогда не было проблем с первыми двумя байтами, и даже если бы я это сделал, было бы достаточно дешево заменить 24LC512.

Вы даже можете уйти от «горячего подключения»: я оставляю логгер включенным и меняю чип памяти на новый, чтобы я мог читать данные, не прерывая регистратор. (Прочитайте количество записей, затем увеличьте его и напишите новый номер и данные.)