Program will compile and upload but will not run if second array added

Hi, I have been struggling with this for a couple of weeks so I would really appreciate some help.

I have a program that uses a DHT11 and an OLED 126x64 display to monitor temperature and humidity, track minimum and maximum values and display the last 24hours temperature as a graph. All works well but when I implement a second array to tack humidity the program will compile and uploads but does not run. I can run it with the humidity array added and being updated, but as soon as I try and use the values to display it does not run.

The code below has the humidity array code commented out so this is the version that runs with no issue. Interestingly, if I change the temperature array from int to float, it will also not execute.

Any help would be much appreciated.

/*   Paul Brace April 2021
     Temperature and humidity monitor with minimum and maximum monitoring
       and graph
     Board - Arduino Pro Mini/Nano or Uno r3 tested
     Display - OLED 128x64 IC2
     A screen save kicks in after the period set in keepDisplayFor
     Screen save is a snooze icon that is respositioned after the period set in moveEvery
     The mode button is used to activate the diplsya and show the readings
        and to switch between the temperature, graph and humidity displays.
     The reset button is used to reset the minimum and maximum values.
*/

// Include drivers
#include <DHT.h>            // This is the DHT sensor library by Adafruit
// DHT_sensor_library
// required for the OLED display
#include <SPI.h>            // Synchronous serial data protocol library
#include <Wire.h>           // IC2 communications library
#include <Adafruit_GFX.h>   // Adafruit Graphics Core Library
#include <Adafruit_SSD1306.h>  // SSD1306 library for Monochrome 128x64 and 128x32 OLEDs 
#include <Fonts/FreeMonoBold9pt7b.h>  // Include fonts to be used
#include <Fonts/FreeSans9pt7b.h>


#define DATA_PIN 4                    // Pin used to collect data from the DHT
#define DHTTYPE DHT11                 // DHT Type  
//#define DHTTYPE DHT22               // If you have a DHT22 comment the DHT11 and
// uncomment DHT22
// Create the sensor object and assign pin
DHT dht(DATA_PIN, DHTTYPE);


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// The pins for I2C are defined by the Wire-library.
// On an arduino UNO/Nano and Pro Mini: A4(SDA), A5(SCL)
// On an arduino MEGA 2560:             20(SDA), 21(SCL)
// On an arduino LEONARDO:              2(SDA),  3(SCL), ...
#define OLED_RESET   -1 // Reset pin # (or -1 if no reset on display)
#define SCREEN_ADDRESS 0x3C // See datasheet for Address (Yours could be 0x3D)

// Creat eobject for the SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define MODE_BUTTON 2             // Activate display and switched between temperature, graph and humidity
#define RESET_BUTTON 3            // If pressed when data displayed resets min and max settings

float temp;       //Current temperature
float humid;      //Current humidity
float minTemp;    //The minimum temperature recorded
float maxTemp;    //The maximum temperature recorded
float minHumid;   //The minimum humidity recorded
float maxHumid;   //The maximum humidity recorded
unsigned long lastReadingUpdate;  // Time readings last updated

int tempHistory[96];       // Array to hold 24 hours data at 15 minute interval
//int humidHistory[96];       // Array to hold 24 hours data at 15 minute interval
// if I include an array for the humidity and just keep the code to update the array
// then the program runs without issue.
// As soon as I try and use the array by passing it to ShowGraph the program will
//   compile, upload but will not run
// I also had to make the tempHistory array an int as if I make it float
//   again the program will compile, upload but will not run
int histPointer;           // Last array element updated (-1 means no history yet stored)
unsigned long histUpdated; // time last updated
unsigned long interval =  900000ul; //(15 * 60 * 1000); 15 minutes in milliseconds


enum mode {
  dispTemp,        // Temperature currently displayed
  dispTempGraph,   // Temperature history graph displayed
  dispHumid,       // Humidity currently displayed
  //dispHumidGraph   // Humidity history graph displayed
};

mode currentMode;   // Current display setting

bool displaying;                   // True if currently displaying data
unsigned long timeDisplay;         // Time started to display, or last button pressed
unsigned long keepDisplayFor = 15000;    // Number of milliseconds before enter screen save mode

unsigned long lastMoved;           // Time last moved screen save bitmap
unsigned long moveEvery = 10000;  // Number of seconds between moves

// Icon displayed when system is asleep
static const unsigned char PROGMEM snooze[] =
{ B00000000, B00001110,
  B00000000, B00000100,
  B00000000, B00001110,
  B00000011, B11000000,
  B00000011, B11000000,
  B00000000, B10000000,
  B00000001, B00000000,
  B00000011, B11000000,
  B00000011, B11000000,
  B11111000, B00000000,
  B11111000, B00000000,
  B00010000, B00000000,
  B00100000, B00000000,
  B01000000, B00000000,
  B11111000, B00000000,
  B11111000, B00000000,
};

// Arrows used to indicate maximum and minimum
static const unsigned char PROGMEM upArrow[] {
  B00000000,
  B00011000,
  B00111100,
  B01111110,
  B11111111,
  B00011000,
  B00011000,
  B00011000
};

static const unsigned char PROGMEM downArrow[] {
  B00011000,
  B00011000,
  B00011000,
  B11111111,
  B01111110,
  B00111100,
  B00011000,
  B00000000
};

void setup() {
  minTemp = 99;    //Set to a figure that is going to be too high
  maxTemp = -9;    //Set to a figure that is going to be too low
  minHumid = 99;   //Set to a figure that is going to be too high
  maxHumid = -9;   //Set to a figure that is going to be too low
  pinMode(MODE_BUTTON, INPUT_PULLUP);  // Use INPUT_PULLUP - will go LOW when pressed
  pinMode(RESET_BUTTON, INPUT_PULLUP);
  // Start sensor
  dht.begin();
  // Initialise display
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.setTextColor(WHITE);
  currentMode = dispTemp;
  displaying = true;
  timeDisplay = millis();   // Set so initially displays for set period
  histUpdated = millis(); // First update will be interval after startup
  lastMoved = millis();     // Time bitmap last moved
}

void loop() {
  if ((millis() - timeDisplay) > keepDisplayFor) {
    displaying = false;
    if ((millis() - lastMoved) > moveEvery) {
      // Update time last moved
      lastMoved = millis();
      // Dislpay bitmap in random position
      display.clearDisplay();
      display.drawBitmap(random(10, 110), random(10, 48), snooze, 16, 16, WHITE);
      display.display();

    }
  }
  // Update the readings every 2 seconds
  if ((millis() - lastReadingUpdate) > 2000ul) {
    // Get readings, update minimum and maximum values
    lastReadingUpdate = millis();
    humid = dht.readHumidity();                   // read humidity
    temp = dht.readTemperature();                 // read temperature
    if (temp < minTemp)
      minTemp = temp;
    if (temp > maxTemp)
      maxTemp = temp;
    if (humid < minHumid)
      minHumid = humid;
    if (humid > maxHumid)
      maxHumid = humid;
    if (displaying) {
      // Update display
      switch (currentMode) {
        case dispTemp:
          ShowTemperature();
          break;
        case dispTempGraph:
          ShowGraph(tempHistory);
          break;
        case dispHumid:
          ShowHumidity();
          break;
          //case dispHumidGraph:
          //  ShowTempGraph(humidHistory);
          //  break;
      }
    }
  }
  CheckButtons();
  if ((millis() - histUpdated) > interval)
    UpdateHistory();
  delay(150);           // Short pause before continuing
}

void UpdateHistory() {
  histUpdated += interval;
  // Use a circular list
  // Increment to next element and circulate back to 0 if end
  // of array reached
  histPointer++;
  if (histPointer > 95)
    histPointer = 0;
  tempHistory[histPointer] = temp;
  //humidHistory[histPointer] = humid;
}


// Routine to ensure numbers are displayed align
void dispNumber(int y, float value, bool tDisp) {
  if (value < 10.0 && value > 0.0)
    display.setCursor(72, y);
  else
    display.setCursor(60, y);
  display.print(value);
  if (tDisp)
    display.print("c");
  else
    display.print("%");
}

// Routine to display graph
void ShowGraph(int history[]) {
  // Calculate scale
  int minimum = 99;
  int maximum = -9;
  float yScale;
  for (int  i = 0; i < 96; i++) {
    if (history[i] < minimum)
      minimum = history[i];
    if (history[i] > maximum)
      maximum = history[i];
  }
  if ((maximum - minimum) != 0)
    yScale = 63.0 / (maximum - minimum);
  else
    yScale = 1;
  display.clearDisplay();
  display.setFont();
  display.setTextSize(1);
  display.setCursor(0, 54);
  display.print(minimum);
  if (currentMode == dispTempGraph)
    display.print("c");
  else
    display.print("%");
  display.setCursor(0, 0);
  display.print(maximum);
  if (currentMode == dispTempGraph)
    display.print("c");
  else
    display.print("%");
  display.setCursor(0, 25);
  if (currentMode == dispTempGraph)
    display.print("Temp.");
  else
    display.print("Humid.");
  // Graph arrary from histPointer + 1 circulating to histPointer
  int el = histPointer + 1;
  int lastel;
  // Count 1 less than array as stating at point 2
  for (int i = 1; i < 96; i++) {
    el++;
    if (el > 95)
      el = 0;
    if (el > 0)
      lastel = el - 1;
    else
      lastel = 95;
    display.drawLine(32 + i - 1, 63 - (history[lastel] - minimum) * yScale,
                     32 + i, 63 - (history[el] - minimum) * yScale, SSD1306_WHITE);
  }
  display.display();
}

void ShowTemperature() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setFont(&FreeSans9pt7b);  // Font used for text
  display.setCursor(0, 15);
  display.print("Temp:");
  display.drawBitmap(20, 35 - 9, upArrow, 8, 8, WHITE);
  display.drawBitmap(20, 55 - 9, downArrow, 8, 8, WHITE);
  display.setFont(&FreeMonoBold9pt7b);  // Font used for numbers
  dispNumber(15, temp, true);
  dispNumber(35, maxTemp, true);
  dispNumber(55, minTemp, true);
  display.display();
}

void ShowHumidity() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setFont(&FreeSans9pt7b);  // Font used for text
  display.setCursor(0, 15);
  display.print("Humid:");
  display.drawBitmap(20, 35 - 9, upArrow, 8, 8, WHITE);
  display.drawBitmap(20, 55 - 9, downArrow, 8, 8, WHITE);
  display.setFont(&FreeMonoBold9pt7b);    // Font used for numbers
  dispNumber(15, humid, false);
  dispNumber(35, maxHumid, false);
  dispNumber(55, minHumid, false);
  display.display();
}

void CheckButtons() {
  // If just woken up then pause for 1/2 second to allow button to be released
  // If the mode or reset button has been pressed pin will go LOW
  // Check if mode button pressed if so switch mode between displays
  if (digitalRead(MODE_BUTTON) == LOW) {
    timeDisplay = millis();           // Reset so remains awake for set period after switching mode
    if (!displaying) {
      displaying = true;   // Set so displays data
      currentMode = dispTemp;
      ShowTemperature();
      delay(1000);
      return;
    }
    switch (currentMode) {
      case dispTemp:
        currentMode = dispTempGraph;
        ShowGraph(tempHistory);
        break;
      case dispTempGraph:
        currentMode = dispHumid;
        ShowHumidity();
        break;
      case dispHumid:
      //  currentMode = dispHumidGraph;
      //  ShowTempGraph(humidHistory);
      //  break;
      //case dispHumidGraph:
        currentMode = dispTemp;
        ShowTemperature();
        break;
    }
    delay(1000);                     // Give time to release button
  }

  // Check if reset button pressed
  // Is the system awake?
  // If so the reset min and max values
  if (displaying) {
    if (digitalRead(RESET_BUTTON) == LOW) {
      maxTemp = -9;
      minTemp = 99;
      maxHumid = -9;
      minHumid = 99;
      delay(1000);                     // Give time to release button
    }
  }
}

Please Auto format your code in the IDE, use Copy for forum in the IDE and paste it here so that it is code tags to make it easier to read and copy for examination

Sorry. I edited this as soon as I realised it was not format. :slightly_smiling_face:

Thanks for changing it. So much easier to read and copy for examination and to spot problems such as missing or extra curly brackets

I missed what controller You are using. I suspect it’s not a micro IBM 360…

Hi, No. I have tested this on the following:

Arduino Pro Mini/Nano and Uno r3 tested

Same result on all 3.

Your problem sounds like you’re running out of memory. Adding a second int array or changing the one array from int to float resulting in problems seems to indicate that.

If you have a Mega, you can try to test it on that.

Hi, Thanks for your suggestion. I do not have Mega to try but I had no thought of memory as when compiled with the second array the memory use is shown as:

Program 23,300 bytes used 72% of 32,256
Global variables 1,013 bytes used 49% of 2,048

I am not using many local variables so I thought that would be sufficient.

Maybe my next step is to try and store the history in EPROM.

Paul

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.