#include <BMP085.h>
#include <EEPROM.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <DS1302.h>
#include <TimeLord.h>
#include <Wire.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);
DS1302 rtc(12, 11, 10);
Time t = rtc.time();
String dayAsString(const Time::Day day) {
switch (day) {
case Time::kSunday: return "Sunday";
case Time::kMonday: return "Monday";
case Time::kTuesday: return "Tuesday";
case Time::kWednesday: return "Wednesday";
case Time::kThursday: return "Thursday";
case Time::kFriday: return "Friday";
case Time::kSaturday: return "Saturday";
}
return "(unknown day)";
}
TimeLord tardis;
float const LATITUDE = 52.70;
float const LONGITUDE = 25.40;
byte today[6];
byte prevSecond = 99, prevHour = 99;
BMP085 dps = BMP085();
long Temperature = 0, Pressure = 0;
float t_f = 0;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
const unsigned char PROGMEM moon0[] =
{ B00000111, B11100000,
B00001000, B00010000,
B00010000, B00001000,
B00100000, B00000100,
B01000000, B00000010,
B10000000, B00000001,
B10000000, B00000001,
B10000000, B00000001,
B10000000, B00000001,
B10000000, B00000001,
B01000000, B00000010,
B00100000, B00000100,
B00010000, B00001000,
B00001000, B00010000,
B00000111, B11100000
};
const unsigned char PROGMEM moon1[] =
{ B00000111, B11100000,
B00001000, B01110000,
B00010000, B00111000,
B00100000, B00011100,
B01000000, B00001110,
B10000000, B00001111,
B10000000, B00001111,
B10000000, B00001111,
B10000000, B00001111,
B10000000, B00001111,
B01000000, B00001110,
B00100000, B00011100,
B00010000, B00111000,
B00001000, B01110000,
B00000111, B11100000
};
const unsigned char PROGMEM moon2[] =
{ B00000111, B11100000,
B00001000, B11110000,
B00010000, B11111000,
B00100000, B11111100,
B01000000, B11111110,
B10000000, B11111111,
B10000000, B11111111,
B10000000, B11111111,
B10000000, B11111111,
B10000000, B11111111,
B01000000, B11111110,
B00100000, B11111100,
B00010000, B11111000,
B00001000, B11110000,
B00000111, B11100000
};
const unsigned char PROGMEM moon3[] =
{ B00000111, B11100000,
B00001011, B11110000,
B00010111, B11111000,
B00101111, B11111100,
B01001111, B11111110,
B10001111, B11111111,
B10001111, B11111111,
B10001111, B11111111,
B10001111, B11111111,
B10001111, B11111111,
B01001111, B11111110,
B00101111, B11111100,
B00010111, B11111000,
B00001011, B11110000,
B00000111, B11100000
};
const unsigned char PROGMEM moon4[] =
{ B00000111, B11100000,
B00001111, B11110000,
B00011111, B11111000,
B00111111, B11111100,
B01111111, B11111110,
B11111111, B11111111,
B11111111, B11111111,
B11111111, B11111111,
B11111111, B11111111,
B11111111, B11111111,
B01111111, B11111110,
B00111111, B11111100,
B00011111, B11111000,
B00001111, B11110000,
B00000111, B11100000
};
const unsigned char PROGMEM moon5[] =
{ B00000111, B11100000,
B00001111, B11010000,
B00011111, B11101000,
B00111111, B11110100,
B01111111, B11110010,
B11111111, B11110001,
B11111111, B11110001,
B11111111, B11110001,
B11111111, B11110001,
B11111111, B11110001,
B01111111, B11110010,
B00111111, B11110100,
B00011111, B11101000,
B00001111, B11010000,
B00000111, B11100000
};
const unsigned char PROGMEM moon6[] =
{ B00000111, B11100000,
B00001111, B00010000,
B00011111, B00001000,
B00111111, B00000100,
B01111111, B00000010,
B11111111, B00000001,
B11111111, B00000001,
B11111111, B00000001,
B11111111, B00000001,
B11111111, B00000001,
B01111111, B00000010,
B00111111, B00000100,
B00011111, B00001000,
B00001111, B00010000,
B00000111, B11100000
};
const unsigned char PROGMEM moon7[] =
{ B00000111, B11100000,
B00001110, B00010000,
B00011100, B00001000,
B00111000, B00000100,
B01110000, B00000010,
B11110000, B00000001,
B11110000, B00000001,
B11110000, B00000001,
B11110000, B00000001,
B11110000, B00000001,
B01110000, B00000010,
B00111000, B00000100,
B00011100, B00001000,
B00001110, B00010000,
B00000111, B11100000
};
void drawMoon(int moon_x, int moon_y, int phase) {
display.fillRect(moon_x, moon_y, 16, 15, WHITE);
display.drawBitmap(moon_x, moon_y, moon4, 16, 15, WHITE);
switch (phase) {
case 0:
display.drawBitmap(moon_x, moon_y, moon0, 16, 15, BLACK);
break;
case 1:
display.drawBitmap(moon_x, moon_y, moon1, 16, 15, BLACK);
break;
case 2:
display.drawBitmap(moon_x, moon_y, moon2, 16, 15, BLACK);
break;
case 3:
display.drawBitmap(moon_x, moon_y, moon3, 16, 15, BLACK);
break;
case 4:
display.drawBitmap(moon_x, moon_y, moon4, 16, 15, BLACK);
break;
case 5:
display.drawBitmap(moon_x, moon_y, moon5, 16, 15, BLACK);
break;
case 6:
display.drawBitmap(moon_x, moon_y, moon6, 16, 15, BLACK);
break;
case 7:
display.drawBitmap(moon_x, moon_y, moon7, 16, 15, BLACK);
break;
default:
display.drawBitmap(moon_x, moon_y, moon4, 16, 15, WHITE);
}
}
void drawMoonDate(int moon_x, int moon_y, uint8_t * datetoday) {
float phase;
phase = tardis.MoonPhase(datetoday);
if (phase >= 0.0 && phase <= 0.0625) {
drawMoon(moon_x, moon_y, 0);
};
if (phase > 0.0625 && phase <= 0.1875) {
drawMoon(moon_x, moon_y, 1);
};
if (phase > 0.1875 && phase <= 0.3125 ) {
drawMoon(moon_x, moon_y, 2);
};
if (phase > 0.3125 && phase <= 0.4375) {
drawMoon(moon_x, moon_y, 3);
};
if (phase > 0.4375 && phase <= 0.5625) {
drawMoon(moon_x, moon_y, 4);
};
if (phase > 0.5625 && phase <= 0.6875) {
drawMoon(moon_x, moon_y, 5);
};
if (phase > 0.6875 && phase <= 0.8125) {
drawMoon(moon_x, moon_y, 6);
};
if (phase > 0.8125 && phase <= 0.9375) {
drawMoon(moon_x, moon_y, 7);
};
if (phase > 0.9375 && phase <= 1) {
drawMoon(moon_x, moon_y, 0);
};
}
void drawSignal(float streng) {
display.fillRect(0, 0, 12, 6, WHITE);
display.drawTriangle(0, 0, 8, 0, 4, 4, BLACK);
display.drawLine(4, 0, 4, 6, BLACK);
display.drawLine(6, 5, 6, 6, BLACK);
display.drawLine(8, 4, 8, 6, BLACK);
display.drawLine(10, 2, 10, 6, BLACK);
display.drawLine(12, 0, 12, 6, BLACK);
}
void drawBatteryState(float v_bat) {
display.fillRect(68, 0, 16, 7, WHITE);
display.drawRect(83, 2, 1, 3, BLACK);
display.drawRoundRect(68, 0, 15, 7, 2, BLACK);
if (v_bat > 4500) {
display.fillRect(70, 2, 10, 3, BLACK);
}
if (v_bat > 4048) {
display.drawRect(79, 2, 2, 3, BLACK);
}
if (v_bat > 3896) {
display.drawRect(76, 2, 2, 3, BLACK);
}
if (v_bat > 3744) {
display.drawRect(73, 2, 2, 3, BLACK);
}
if (v_bat > 3592) {
display.drawRect(70, 2, 2, 3, BLACK);
}
}
void drawTime(byte x, byte y) {
display.fillRect(0 + x, 0 + y, 48, 7, WHITE);
Time t = rtc.time();
display.setTextColor(BLACK);
display.setTextSize(1);
display.setCursor(x, y);
display.print(t.hr);
display.print(":");
display.print(t.min);
display.print(":");
display.print(t.sec);
}
void updateMoonSunDate()
{
Time t = rtc.time();
today[0] = 0;
today[1] = 0;
today[2] = 12;
today[3] = t.date;
today[4] = t.mon;
today[5] = t.yr - 2000;
}
void drawSunRiseSet(byte x, byte y) {
updateMoonSunDate();
display.setTextSize(1);
display.setTextColor(BLACK);
display.fillRect(x, y, 33, y + 8, WHITE);
if (tardis.SunRise(today))
{
display.setCursor(x, y);
display.print((int) today[tl_hour]);
display.print(":");
display.println((int) today[tl_minute]);
}
if (tardis.SunSet(today))
{
display.setCursor(x, y + 8);
display.print((int) today[tl_hour]);
display.print(":");
display.println((int) today[tl_minute]);
}
}
void drawPressure(byte x, byte y) {
display.setTextSize(1);
display.setTextColor(BLACK);
display.fillRect(x, y, 33, y + 8, WHITE);
display.setCursor(x, y);
t_f = Temperature;
display.println( t_f / 10, 1);
display.setCursor(x, y + 8);
display.println(Pressure / 133.3, 1);
}
long readVcc() {
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(75);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC));
uint8_t low = ADCL;
uint8_t high = ADCH;
long result = (high << 8) | low;
result = 1132060 / result;
return result;
}
void drawVcc(byte x, byte y, word vcc) {
display.setTextSize(1);
display.setTextColor(BLACK);
display.fillRect(x, y, 33, y + 8, WHITE);
display.setCursor(x, y);
display.println(vcc);
}
void pressure_drawLine(byte x, byte h)
{
display.drawLine(x, 47 - h, x, 47, BLACK);
}
void pressure_drawGraph()
{
display.fillRect(0, 25, 83, 47, WHITE);
for (int i = 0; i <= 83; i++) {
pressure_drawLine(i, EEPROM.read(i));
}
}
void setup()
{
Serial.begin(9600);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(2, OUTPUT);
String day = dayAsString(t.day);
tardis.TimeZone(3 * 55);
tardis.Position(LATITUDE, LONGITUDE);
Wire.begin();
display.begin();
display.setContrast(55);
display.clearDisplay();
display.drawLine(0, display.height() / 2, display.width(), display.height() / 2, BLACK);
dps.init();
updateMoonSunDate();
drawMoonDate(34, 8, today);
pressure_drawGraph();
display.display();
prevHour = rtc.time().hr;
}
void loop()
{
unsigned long currentMillis = millis();
unsigned long currentMillis2 = millis();
byte temp;
if (rtc.time().hr != prevHour) {
prevHour = rtc.time().hr;
dps.getPressure(&Pressure);
dps.getTemperature(&Temperature);
for (int i = 0; i <= 82; i++) {
temp = EEPROM.read(i + 1);
EEPROM.write(i, temp);
}
EEPROM.write(83, ceil(Pressure / 133.3) - 740);
pressure_drawGraph();
display.display();
}
if (rtc.time().sec != prevSecond) {
prevSecond = rtc.time().sec;
dps.getPressure(&Pressure);
dps.getTemperature(&Temperature);
updateMoonSunDate();
drawPressure(0, 8);
drawTime(17, 0);
drawSunRiseSet(53, 8);
drawMoonDate(34, 8, today);
drawBatteryState(readVcc());
drawSignal(5);
display.display();
}
buttonState = digitalRead(8);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPushCounter++;
}
}
lastButtonState = buttonState;
if (buttonPushCounter % 2 == 0) {
digitalWrite(2, HIGH);
} else {
digitalWrite(2, LOW);
}
}