Hi,
This is my first time posting, so I apologise if I miss any details. I also have very basic computing knowledge and am fairly new to Arduino in general.
I'm building a Voltmeter/Power Meter/Data-Logger device, and have finished all of the code for it. It uses a micro SD card breakout board, an I2C 0.96 OLED display and an INA219 breakout, as well as some buttons and resistors.
Throughout making it I have continually tested it, and everything works separately. As soon as they are combined I run out of space and the code does indeed upload, but nothing appears to work. If I remove some functionality (e.g: the data logging), the screen comes to life and the code seems to work.
I believe this is because I've run out of memory, as this is the message I receive after compiling:
Sketch uses 26066 bytes (84%) of program storage space. Maximum is 30720 bytes.
Global variables use 1936 bytes (94%) of dynamic memory, leaving 112 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.
I've tried to optimise the code by removing everything that seems unnecessary, but I don't think I can remove anything else without losing functionality. I'm aware that the libraries take up a lot of space, as well as all of the code that involves writing to the screen.
Here is the code I am using:
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_INA219.h>
const int pinCS = 3;
File myFile;
int voltInput = A0;
float Vout = 0.0;
float Vin = 0.0;
float R1 = 100000.0;
float R2 = 10000.0;
int value = 0;
int resInput = A1;
int raw = 0;
int Rin = 5;
float Rout = 0;
float X1 = 1000;
float X2 = 0;
float buffer1 = 0;
const int numReadings2 = 10;
int readings2[numReadings2];
int readIndex2 = 0;
int total2 = 0;
int average2 = 0;
int resistance;
const int numReadings1 = 10;
int readings1[numReadings1];
int readIndex1 = 0;
int total1 = 0;
int average1 = 0;
int voltage;
int mode = 0;
int dataWrite = 0;
unsigned int fileNumber = 0;
int buttonState1;
int buttonState2;
int buttonState3;
int lastButtonState1;
int lastButtonState2;
int lastButtonState3;
int reading1;
int reading2;
int reading3;
unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long debounceDelay = 50;
float shuntVoltage = 0;
float busVoltage = 0;
float current_mA = 0;
float loadVoltage = 0;
float power_mW = 0;
unsigned long Time = 0;
unsigned long previousTime = 0;
unsigned long currentTime = 0;
unsigned long previousMillis = 0;
const long interval = 1000;
unsigned long currentMillis = 0;
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_INA219 ina219;
void setup(){
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
ina219.begin();
pinMode(pinCS, OUTPUT);
for (int thisReading1 = 0; thisReading1 < numReadings1; thisReading1++) {
readings1[thisReading1] = 0;
}
for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++) {
readings2[thisReading2] = 0;
}
if (!SD.begin(pinCS)){
return;
}
delay(100);
}
void loop(){
reading1 = digitalRead(6);
if (reading1 != lastButtonState1){
lastDebounceTime1 = millis();
}
if ((millis() - lastDebounceTime1) > debounceDelay) {
if (reading1 != buttonState1) {
buttonState1 = reading1;
if (buttonState1 == HIGH) {
mode++;
if (mode > 2){
mode = 0;
}}}}
lastButtonState1 = reading1;
reading2 = digitalRead(5);
if (reading2 != lastButtonState2){
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay) {
if (reading2 != buttonState2){
buttonState2 = reading2;
if (buttonState2 == HIGH) {
dataWrite = !dataWrite;
}}}
lastButtonState2 = reading2;
reading3 = digitalRead(7);
if (reading3 != lastButtonState3){
lastDebounceTime3 = millis();
}
if ((millis() - lastDebounceTime3) > debounceDelay) {
if (reading3 != buttonState3){
buttonState3 = reading3;
if (buttonState3 == HIGH) {
fileNumber = ++fileNumber;
}}}
lastButtonState3 = reading3;
switch (mode) {
case 0:
power();
break;
case 1:
volt();
break;
case 2:
ohm();
break;
}
shuntVoltage = ina219.getShuntVoltage_mV();
busVoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadVoltage = busVoltage + (shuntVoltage / 1000);
String filename = String();
filename = "Exp_";
filename += fileNumber;
filename += ".txt";
char charFileName[filename.length() + 1];
filename.toCharArray(charFileName, sizeof(charFileName));
if (dataWrite == HIGH){
currentMillis = millis();
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
Time++;
myFile = SD.open(charFileName, FILE_WRITE);
if (myFile){
myFile.print(shuntVoltage);
myFile.print(" , ");
myFile.print(busVoltage);
myFile.print(" , ");
myFile.print(current_mA);
myFile.print(" , ");
myFile.print(power_mW);
myFile.print(" , ");
myFile.print(loadVoltage);
myFile.print(" , ");
myFile.println(Time);
myFile.close();
}}} else {
Time = 0;
}
}
void volt(){
display.clearDisplay();
total1 = total1 - readings1[readIndex1];
readings1[readIndex1] = analogRead(voltInput);
total1 = total1 + readings1[readIndex1];
readIndex1 = readIndex1 + 1;
if (readIndex1 >= numReadings1) {
readIndex1 = 0;
}
value = total1 / numReadings1;
Vout = (value * 5) / 1024.0;
Vin = Vout / (R2/(R1+R2));
if (Vin < 0.09) {
Vin = 0.0;
}
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(36,0);
display.print("VOLTMETER");
display.setTextSize(2);
display.setCursor(38,15);
display.print(Vin);
display.display();
}
void ohm(){
display.clearDisplay();
total2 = total2 - readings2[readIndex2];
readings2[readIndex2] = analogRead(resInput);
total2 = total2 + readings2[readIndex2];
readIndex2 = readIndex2 + 1;
if (readIndex2 >= numReadings2) {
readIndex2 = 0;
raw = total2 / numReadings2;
buffer1 = raw * Rin;
Rout = (buffer1)/1024;
buffer1 = (Rin/Rout) - 1;
X2 = X1 * buffer1;
if (X2 > 1000000){
X2 = 0;
}
}
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(36,0);
display.print("OHM-METER");
display.setTextSize(2);
display.setCursor(38,15);
display.print(X2);
display.display();
}
void power(){
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.print("V: ");
display.setCursor(20,0);
display.print(loadVoltage);
display.setCursor(60,0);
display.print(" V");
display.setCursor(0,12);
display.print("I: ");
display.setCursor(20,12);
display.print(current_mA);
display.setCursor(60,12);
display.print("mA");
display.setCursor(0,24);
display.print("P: ");
display.setCursor(20,24);
display.print(power_mW);
display.setCursor(60,24);
display.print("mW");
display.display();
}
Any tips or advice on how to free up some space and get the code working would be greatly appreciated. Thank you!