OK, now that is helpful - thank you. As it happens, the setup does include an OLED display.
I have just tried removing a section of code from the sketch and the problem seems to have disappeared so, considering that it runs unaltered on a Zero, maybe RAM is the issue. Is there any way of telling how much ram is used at runtime.?
FWIW, the sketch follows. The offending statement is the first in the void loop (around line # 70).
#include <Servo.h> //Servo
#include <RTClib.h> //RT Clock
#include "DHT.h" // Temperature & Humidity sensor
#include <Adafruit_SSD1306.h> //OLED display
#include <Adafruit_GFX.h>
#include <Fonts/FreeMono12pt7b.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define DHTPIN 10 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11 type of temperature & humidity sensor
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Servo myservo; // Create servo object to control a servo
RTC_DS3231 rtc; //Initialize RTC
int lowPos = 60; //Servo position (in degrees) for low heat setting
int hiPos = 150; //for high (180 degrees is max rotation of servo)
int pos; //Current servo position - to initiate at 0 position (elec blnk controller at full off)
unsigned long currentMillis = millis(); //Set up timeout for manual increase/decrease of servo position
unsigned long previousMillis;
unsigned long timeOut = 3000; //Timeout = 3000 milliseconds
void setup() {
pinMode(3, INPUT_PULLUP); //Button push for time adjust hour or minute decrease or, decrease servo position
pinMode(4, INPUT_PULLUP); //hour or minute increase or, increase servo position
pinMode(12, INPUT_PULLUP); //Button to trigger or release hour/minute adjust (button on proto board)
pinMode(A3, INPUT); //Input for photocell (measuring ambient light level)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr
display.setTextColor(WHITE, BLACK);
dht.begin(); //Initiate sensor
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(0); //Initiate servo at 0 position (elec blnk controller at full off)
// SETUP RTC MODULE
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1)
;
}
//Manually sets the RTC with an explicit date & time.
//rtc.adjust(DateTime(2024, 2, 21, 0, 0, 0));
Serial.begin(9600);
}
void setContrast(Adafruit_SSD1306* display, uint8_t contrast) { //Code enables OLED brightness adjustment
display->ssd1306_command(SSD1306_SETCONTRAST);
display->ssd1306_command(contrast);
}
void loop() {
int tt = dht.readTemperature();
//int servoHigh = map(t, 25, 19, 0, hiPos);
//int servoLow = map(t, 25, 19, 0, lowPos);
DateTime now = rtc.now(); //Get current time
int hrs = now.hour();
int mins = now.minute();
int secs = now.second();
//Set time hours & minutes to wanted values
//Set Hours
if (digitalRead(12) == 0) { //Hour/minute adjust button pushed?
delay(500); //Wait ime for button to be released
while (digitalRead(12) == 1) { //Stay in hour adjust loop until adjust button again pressed
display.clearDisplay();
display.setCursor(0, 50);
display.print("Hr");
display.setCursor(70, 50);
display.print(hrs);
display.display();
if (digitalRead(3) == 0) { //Decrease hours?
delay(300);
if (digitalRead(3) == 0) {
hrs = hrs - 1;
if (hrs < 0) {
hrs = 24;
}
}
}
if (digitalRead(4) == 0) { //Increase hours?
delay(300);
if (digitalRead(4) == 0) {
hrs = hrs + 1;
if (hrs > 24) {
hrs = 1;
}
}
}
}
delay(500); //Wait again for adjust button to be released
//Set minutes
delay(500); //Wait ime for button to be released
while (digitalRead(12) == 1) { //Stay in hour adjust loop until adjust button again pressed
display.clearDisplay();
display.setCursor(0, 50);
display.print("Mn");
display.setCursor(70, 50);
display.print(mins);
display.display();
if (digitalRead(3) == 0) {
delay(300);
if (digitalRead(3) == 0) {
mins = mins - 1;
if (mins < 0) {
mins = 59;
}
}
}
if (digitalRead(4) == 0) {
delay(300);
if (digitalRead(4) == 0) {
mins = mins + 1;
if (mins > 59) {
mins = 0;
}
}
}
}
delay(1000); //Wait agian for finished time adjust button release
rtc.adjust(DateTime(2024, 2, 21, hrs, mins, secs)); //Finished adjustments - set clock to new time
//(only hour & minute values needed).
}
// Read temperature as Celsius and Humidity
int t = dht.readTemperature();
t = int(t * 0.88); //Emperical correction factor
int h = dht.readHumidity();
h = h * 1.01; //Humidity
//Serial.println(t);
//Serial.println(h);
//Serial.println((String) "Hours = " + hrs + " Minutes = " + mins + " Seconds = " + secs);
//Turn controller to high at specified time?
if (now.hour() == 22 && now.minute() == 30) {
pos = hiPos;
myservo.write(pos); // send servo to position in variable 'pos'
}
//Turn controller to low at specified time?
if (now.hour() == 23 && now.minute() == 0) {
pos = lowPos;
myservo.write(pos); // send servo to position in variable 'pos'
}
if (now.hour() == 23 && now.minute() == 1) { //Repeat to make sure
pos = lowPos;
myservo.write(pos); // send servo to position in variable 'pos'
}
//Turn controller to off position?
if (now.hour() == 9 && now.minute() == 0) {
myservo.write(0); // servo to 0 (full off)
}
if (now.hour() == 9 && now.minute() == 1) { //Repeat to make sure it goes to off
myservo.write(0); // servo to 0 (full off)
}
//Use 2 buttons (wired to D3 & D4) to increase or decrease servo setting
if (digitalRead(3) == 0) {
previousMillis = millis();
while (millis() - previousMillis <= timeOut) { //Timed out?
if (digitalRead(3) == 0) {
pos = pos - 2;
if (pos < 0) {
pos = 0;
}
myservo.write(pos); //Decrease setting a bit
display.clearDisplay(); //Show it briefly on screen
display.setCursor(40, 50);
display.print(pos);
display.display();
delay(200);
previousMillis = millis();
}
}
}
if (digitalRead(4) == 0) {
previousMillis = millis();
while (millis() - previousMillis <= timeOut) { //Timed out?
if (digitalRead(4) == 0) {
pos = pos + 2;
if (pos > 180) { //180 degrees is the max the servo can turn
pos = 180;
}
myservo.write(pos); //Increase setting a bit
display.clearDisplay(); //Show it briefly on screen
display.setCursor(40, 50);
display.print(pos);
display.display();
delay(200);
previousMillis = millis();
}
}
}
//delay(100); //Wait so decrease/increase settings goes slowly
display.clearDisplay();
display.setFont(&FreeMono12pt7b);
//Display temperature & humidity every 10 seconds
if (secs % 10 == 0) {
display.setTextSize(1);
display.setCursor(0, 15);
display.print("Temp Hum");
display.setTextSize(2);
display.setCursor(0, 60);
display.print(t);
display.setCursor(76, 60);
display.print(h);
}
else { //Display time
display.setTextSize(2);
if (hrs > 12) { //Convert time from MST 24 hr clock to MST 12 hr clock
hrs = hrs - 12;
}
if (hrs == 0) {
hrs = 1;
}
if (hrs <= 9) { //For formatting o/p
display.setCursor(0, 50);
display.print(" ");
display.setCursor(28, 50);
} else {
display.setCursor(0, 50);
}
display.print(hrs);
if (secs % 2 == 0) {
display.print(":");
} else {
display.print(" ");
}
if (mins <= 9) { //Display a leading "0"
display.setCursor(76, 50);
display.print("0");
display.setCursor(104, 50);
} else {
display.setCursor(76, 50);
}
display.print(mins);
}
display.display();
setContrast(&display, 1); //Turn down display brighness to lowest level (too bright at night & OK during day)
}