I have a Arduino sketch I made and I have run out of dynamic memory on my Arduino Nano. How could I possibly reduce the amount of memory the program takes? (I'm not that good at this stuff)
P.S: The code is here:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
const int chipSelect = 4;
#define OLED_RESET 5
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
#error("Fix Height");
#endif
/********************************************/
#define CHARWIDTH 5
#define CHARHEIGHT 8
#define AXISWIDTH (2 + 1)
#define VISIBLEVALUEPIXELS (128 - AXISWIDTH)
#define NUMVALUES (2 * VISIBLEVALUEPIXELS)
#define TRIGGER_ENABLE_PIN 2
#define SCREEN_UPDATE_ENABLE_PIN 3
byte values[NUMVALUES];
int pos = 0;
int count = 0;
unsigned long readStartTime = 0;
int sampleRate = 1;
void displayln(const char* format, ...)
{
char buffer[32];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
int len = strlen(buffer);
for (uint8_t i = 0; i < len; i++) {
display.write(buffer[i]);
}
}
// Draws the graph ticks for the vertical axis
void drawAxis()
{
// graph ticks
for (int x = 0; x < 2; x++) {
display.drawPixel(x, 0, WHITE);
display.drawPixel(x, 13, WHITE);
display.drawPixel(x, 26, WHITE);
display.drawPixel(x, 38, WHITE);
display.drawPixel(x, 50, WHITE);
display.drawPixel(x, 63, WHITE);
}
}
// Draws the sampled values
void drawValues()
{
int start = 0;
if ( digitalRead(TRIGGER_ENABLE_PIN) ) {
// Find the first occurence of zero
for (int i = 0; i < NUMVALUES; i++) {
if ( values[i] == 0 ) {
// Now find the next value that is not zero
for (; i < NUMVALUES; i++) {
if ( values[i] != 0 ) {
start = i;
break;
}
}
break;
}
}
// If the trigger point is not within half of our values, we will
// not have enough sample points to show the wave correctly
if ( start >= VISIBLEVALUEPIXELS )
return;
}
for (int i = 0; i < VISIBLEVALUEPIXELS; i++) {
display.drawPixel(i + AXISWIDTH, 63 - (values[i + start]), WHITE);
}
}
// Shows the time taken to sample the values shown on screen
void drawFrameTime(unsigned long us)
{
display.setCursor(9 * CHARWIDTH, 7 * CHARHEIGHT - 2); // almost at bottom, approximately centered
displayln("%ld us", us);
}
/********************************************/
void setup() {
// Set up the display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Initialize with the I2C addr 0x3D (for the 128x64)
display.setTextColor(WHITE);
pinMode(TRIGGER_ENABLE_PIN, INPUT);
pinMode(SCREEN_UPDATE_ENABLE_PIN, INPUT);
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("init start");
if (!SD.begin(chipSelect)) {
Serial.println("fail");
// don't do anything more:
while (1);
}
Serial.println("init ok");
}
/********************************************/
void loop() {
// If a sampling run is about to start, record the start time
if ( pos == 0 )
readStartTime = micros();
// If this iteration is one we want a sample for, take the sample
if ( (++count) % sampleRate == 0 )
values[pos++] = analogRead(0) >> 4; // shifting right by 4 efficiently maps 0-1023 range to 0-63
// If we have filled the sample buffer, display the results on screen
if ( pos >= NUMVALUES ) {
// Measure how long the run took
unsigned long totalSampleTime = (micros() - readStartTime) / 2; // Divide by 2 because we are taking twice as many samples as are shown on the screen
if ( !digitalRead(SCREEN_UPDATE_ENABLE_PIN) ) {
// Display the data on screen
display.clearDisplay();
drawAxis();
drawValues();
drawFrameTime(totalSampleTime);
display.display();
}
// Reset values for the next sampling run
pos = 0;
count = 0;
}
String dataString = "";
// read three sensors and append to the string:
for (int analogPin = 0; analogPin < 3; analogPin++) {
int sensor = analogRead(analogPin);
dataString += String(sensor);
dataString += ",";
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
String
. Put your string literals in flash withF(...)
.