[Из песочницы] Мобильная метеостанция на Arduino
#include
#include
#include
#include
#include
#include
#include
//84x48
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);
// Create a DS1302 object.
DS1302 rtc(12, 11, 10);// Chip Enable, Input/Output, Serial Clock
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[] = {0,0,12,22,03,16};
byte today[6];
//-------------
//long previousMillis = 0, previousMillis2 = 0; // храним время последней команды
//long interval = 1800000; // интервал между командами
//long interval = 3600000; // интервал между командами
//long interval2 = 1000; // интервал между командами
byte prevSecond = 99, prevHour = 99;
//-------------
BMP085 dps = BMP085();
long Temperature = 0, Pressure = 0;
float t_f = 0;
//-------------buttons--------------------
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
//-------------moon----------------------
//0.0 New Moon 0.99 - Almost new
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
};
//Waxing Crescent
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
};
//0.25 First Quarter
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
};
//Waxing Gibbous
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
};
//0.5 Full Moon
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
};
//Waning Gibbous
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
};
//0.75 Third Quarter (Last Quarter)
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
};
//Waning Crescent
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);
}; //0.000 New moon
if (phase > 0.0625 && phase <= 0.1875) {
drawMoon(moon_x, moon_y, 1);
}; //0,125
if (phase > 0.1875 && phase <= 0.3125 ) {
drawMoon(moon_x, moon_y, 2);
}; //0.250 First Quarter
if (phase > 0.3125 && phase <= 0.4375) {
drawMoon(moon_x, moon_y, 3);
}; //0,375
if (phase > 0.4375 && phase <= 0.5625) {
drawMoon(moon_x, moon_y, 4);
}; //0.500 Full
if (phase > 0.5625 && phase <= 0.6875) {
drawMoon(moon_x, moon_y, 5);
}; //0,625
if (phase > 0.6875 && phase <= 0.8125) {
drawMoon(moon_x, moon_y, 6);
}; //0.750 Last Quarter
if (phase > 0.8125 && phase <= 0.9375) {
drawMoon(moon_x, moon_y, 7);
}; //0.875
if (phase > 0.9375 && phase <= 1) {
drawMoon(moon_x, moon_y, 0);
}; //0.990 Almost new
}
//=====================================================================================
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);
// 3, 44 4, 2 0, 76 0, 152
//4,200 full 4
//4,048 3
//3,896 2
//3,744 1
//3,592 0
//3,440 zero -
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);
//display.fillRect(0+x, 0+y, 30, 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)) // if the sun will rise today (it might not, in the [ant]arctic)
{
display.setCursor(x, y);
display.print((int) today[tl_hour]);
display.print(":");
display.println((int) today[tl_minute]);
}
if (tardis.SunSet(today)) // if the sun will set today (it might not, in the [ant]arctic)
{
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(ceil(Pressure / 133.3), 0);
display.println(Pressure / 133.3, 1);
}
//=====================================================================================
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#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); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
//scale_constant = internal1.1Ref * 1023 * 1000
//где
//internal1.1Ref = 1.1 * Vcc1 (показания_вольтметра) / Vcc2 (показания_функции_readVcc())
//4.967/4600-------1215079.369565217
// result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*100000
result = 1132060 / result;
return result; // Vcc in millivolts
//http://blog.unlimite.net/?p=25
}
//===========================================================================================
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);
//-----------------------------------------------------------------------------
//rtc.writeProtect(false);
//rtc.halt(false);
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;
//EEPROM.write(0, 9);
// for (int i=0; i <= 83; i++){
// EEPROM.write(i, random(1, 23));
// pressure_drawLine(i,EEPROM.read(i));
// Serial.println(EEPROM.read(i));
// }
}
//=====================================================================================
void loop()
{
unsigned long currentMillis = millis();
unsigned long currentMillis2 = millis();
byte temp;
//timer---------------------- 1 hour
// if (currentMillis - previousMillis > interval) {
// previousMillis = currentMillis;
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();
}
//timer---------------------- 1 sec
// if (currentMillis2 - previousMillis2 > interval2) {
// previousMillis2 = currentMillis2;
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);
// drawVcc(0, 16, readVcc());
display.display();
}
//timer----------------------
buttonState = digitalRead(8);
// Serial.println(buttonState);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPushCounter++;
}
}
lastButtonState = buttonState;
if (buttonPushCounter % 2 == 0) {
digitalWrite(2, HIGH);
} else {
digitalWrite(2, LOW);
}
}
//=====================================================================================