Hi,
I am working on alarm clock that will turn the light on. Setup is NANO + RTC 1307 + OLED 0,96".
To keep the code clean I have moved OLED, RTC and light control functions to classes. LED strips cause no problem, so I'll leave them out for time being.
I pass DateTime variable from instance of RTC-encapsulating class to instance of OLED-encapsulating class to display current date and time + information on alarm. All displays fine upon call of clockrun() routine. However, when I uncomment another routine responsible for displaying data related to setting up time and date - clocksetup() - NANO resets continously.
The code is work in progress, so it is not complete.
I tried overloading (unified DisplayData as name instead of specific names) but with no success.
If anyone has bumped into this problem or knows the solution I'll be grateful for hints on how to solve the issue.
main code:
#include "Arduino.h"
//LED strip related declarations
#include "LedLight.h"
const byte yellowPin = 11;
const byte whiteC1Pin = 10;
const byte whiteW1Pin = 9;
const byte whiteW2Pin = 6;
const byte whiteC2Pin = 5;
const byte redPin = 3;
LedLight ledLight(redPin, yellowPin, whiteC1Pin, whiteC2Pin, whiteW1Pin, whiteW2Pin);
//---
//OLED related declarations
#include "OledDisplay.h"
OledDisplay oledDisplay; // declaration of OledDisplay instance
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//---
//clock section declatations
#include "ZegarRTC.h"
const byte modePin = 12;
const byte addPin = 8;
const byte delPin = 7;
const byte okPin = 4;
ZegarRTC zegarRTC;
DateTime dt;
byte wuHour = 24;
byte wuMins = 0;
bool isAlarmActive = true;
unsigned long milisAtLastUpdate = 0;
unsigned long sec2disp = 0;
//---
enum workMode
{
CLOCKRUN=1, CLOCKSETUP=2, ALARMSETUP=3, LAMP=4, SUNRISE=5, SUNSET=6
};
workMode currWorkMode;
void setup()
{
Serial.begin(9600);
//control pins
pinMode(modePin, INPUT_PULLUP);
pinMode(addPin, INPUT_PULLUP);
pinMode(delPin, INPUT_PULLUP);
pinMode(okPin, INPUT_PULLUP);
//led output pins
pinMode(yellowPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(whiteC1Pin, OUTPUT);
pinMode(whiteC2Pin, OUTPUT);
pinMode(whiteW1Pin, OUTPUT);
pinMode(whiteW2Pin, OUTPUT);
oledDisplay.begin(display);
oledDisplay.DisplayText("SUN CLOCK", 2, 10, 25, true); //uncommenting second call to OledDisplay methods (any) causes reset and displaying SUN CLOCK
delay(2000);
if (!zegarRTC.begin()) currWorkMode = CLOCKSETUP;
else currWorkMode = CLOCKRUN;
}
void loop()
{
dt = zegarRTC.GetTimeDateToDisplay();
if (digitalRead(modePin)==LOW){
currWorkMode = currWorkMode + 1;
if (currWorkMode > 6)
currWorkMode = 1;
delay(200);
}
//Serial.print("workMode: "); // using Serial.print(ln) causes hickups
//Serial.println(currWorkMode);
switch (currWorkMode) {
case CLOCKRUN:
clockrun();
break;
case CLOCKSETUP:
//clocksetup(); // uncommenting this call causes NANO to reset
break;
case ALARMSETUP:
clockrun();
break;
case LAMP:
clockrun();
break;
case SUNRISE:
clockrun();
sunrise();
break;
case SUNSET:
clockrun();
break;
}
}
void clockrun()
{
oledDisplay.ClearDisplay();
oledDisplay.DisplayData(dt, currWorkMode+20, wuMins); //second param. only to display work mode as Serial.println hickups NANO completely
}
void clocksetup()
{
oledDisplay.ClearDisplay();
oledDisplay.DisplayData(dt, "CLOCK SETUP");
}
void sunrise()
{
if (millis()-milisAtLastUpdate > 100)
{
ledLight.SimulateSunRise(sec2disp);
milisAtLastUpdate = millis();
sec2disp++;
}
}
OledDisplay.h
#include "RTClib.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
class OledDisplay
{
public:
int begin(Adafruit_SSD1306 display);
void DisplayText(String txt, byte txtSize, byte posX, byte posY, bool clearDisplay);
void DisplayData(DateTime dt, byte wuHour, byte wuMins);
void DisplayData(DateTime dt, String info);
void ClearDisplay();
private:
Adafruit_SSD1306 disp;
void DisplayWakeUpTime(byte hour, byte mins);
};
OledDisplay.cpp
//#include "Arduino.h"
#include "OledDisplay.h"
#define SCREEN_ADDRESS 0x3C
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 disp;//(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
OledDisplay::begin(Adafruit_SSD1306 display)
{//oled display init
disp = display;
if(!disp.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
disp.clearDisplay();
}
void OledDisplay::ClearDisplay()
{
disp.clearDisplay();
}
void OledDisplay::DisplayText(String txt, byte txtSize, byte posX, byte posY, bool clearDisplay)
{
if (clearDisplay) disp.clearDisplay();
disp.setTextSize(txtSize);
disp.setTextColor(WHITE);
disp.setCursor(posX, posY);
disp.println((txt));
disp.display();
}
void OledDisplay::DisplayData(DateTime dtClock, byte wuHour, byte wuMins)
{
if (wuHour < 255) DisplayWakeUpTime (wuHour, wuMins);
byte hour = dtClock.hour();
byte mins = dtClock.minute();
byte sec = dtClock.second();
int year = dtClock.year();
byte month = dtClock.month();
byte day = dtClock.day();
//hh:mm section
disp.setTextSize(3);
disp.setTextColor(WHITE);
if (hour < 10) disp.setCursor(23, 30);
else disp.setCursor(5, 30);
disp.print(hour);
if (mins < 10)
{
disp.print(":0");
disp.print(mins);
}
else
{
disp.print(":");
disp.print(mins);
}
//ss section
disp.setTextSize(2);
disp.setCursor(100, 37);
if (wuMins < 255)
{
if (sec < 10)
{
disp.print("0");
disp.println(sec);
}
else disp.println(sec);
}
//date section
disp.setTextSize(1);
disp.setCursor(35, 57);
disp.print(year);
disp.print("-");
disp.print(month);
disp.print("-");
if (day<10)
{
disp.print("0");
disp.print(day);
} else disp.print(day);
disp.display();
}
void OledDisplay::DisplayWakeUpTime(byte hour, byte mins)
{
//hh:mm section
disp.setTextSize(1);
disp.setTextColor(WHITE);
if (hour < 10) disp.setCursor(13, 5);
else disp.setCursor(7, 5);
disp.print("Wake up at ");
disp.print(hour);
if (mins < 10) disp.print(":0");
else disp.print(":");
disp.println(mins);
if (hour-1 < 10) disp.setCursor(13, 15);
else disp.setCursor(7, 15);
disp.print("Sunrise at ");
disp.print(hour-1);
if (mins < 10) disp.print(":0");
else disp.print(":");
disp.println(mins);
}
void OledDisplay::DisplayData(DateTime dt, String info)
{
DisplayText(info, 2, 5, 25, true);
DisplayData(dt, 255, 255);
}