878 lines
19 KiB
C++
878 lines
19 KiB
C++
// ----------------------------------------------------------------------------------------------------
|
||
// Watchdog v3 - Leonardo
|
||
// EoF 2017
|
||
// ----------------------------------------------------------------------------------------------------
|
||
|
||
#include "watchdog_3.h"
|
||
|
||
GPRS modem(Serial1, MOD_PWR);
|
||
bool modemOK = false;
|
||
byte modemErrCount = 0;
|
||
DHT dht(T_PIN, DHT11);
|
||
|
||
char command[CMD_SIZE];
|
||
char message[SMS_SIZE];
|
||
char phone[PHONE_SIZE];
|
||
char datetime[DATE_SIZE];
|
||
char s_buffer[BUFFER_SIZE];
|
||
char l_buffer[LONG_BUFFER_SIZE];
|
||
|
||
bool cmdFromModem = false;
|
||
|
||
unsigned long t = 0;
|
||
int addr = 0;
|
||
|
||
byte temp = 0, hum = 0, loud = 0, power = 0, battery = 0;
|
||
|
||
byte btnCount = 0;
|
||
bool btnTrigger = false;
|
||
byte event;
|
||
|
||
const float r12_1 = 20000; // 20K
|
||
const float r12_2 = 10000; // 10K
|
||
const float r5_1 = 10000; // 20K
|
||
const float r5_2 = 10000; // 10K
|
||
const float rbat_1 = 10000; // 10K
|
||
const float rbat_2 = 10000; // 10K
|
||
const float rout_1 = 10000; // 10K
|
||
const float rout_2 = 10000; // 10K
|
||
|
||
float vcc = 0.0;
|
||
float k12, k5, kbat, kout;
|
||
float v12, v5, vbat, vout;
|
||
|
||
// эту константу (typVbg) необходимо откалибровать индивидуально
|
||
const float typVbg = 1.08; // 1.0 -- 1.2
|
||
|
||
void setup() {
|
||
Serial.begin(COM_BR);
|
||
Serial1.begin(MOD_BR);
|
||
modem.powerOn();
|
||
modemOK = modem.init();
|
||
|
||
// Конфигурируем пины
|
||
pinMode(A_PIN, INPUT);
|
||
pinMode(V5_PIN, INPUT);
|
||
pinMode(V12_PIN, INPUT);
|
||
pinMode(VBAT_PIN, INPUT);
|
||
pinMode(VOUT_PIN, INPUT);
|
||
|
||
pinMode(LED_PIN, OUTPUT);
|
||
pinMode(BTN_PIN, INPUT);
|
||
pinMode(FAN_PIN, OUTPUT);
|
||
|
||
// Инициализируем климатический сенсор
|
||
dht.begin();
|
||
|
||
// Коэффициенты делителей напряжений
|
||
k12 = r12_2 / (r12_1 + r12_2);
|
||
k5 = r5_2 / (r5_1 + r5_2);
|
||
kbat = rbat_2 / (rbat_1 + rbat_2);
|
||
kout = rout_2 / (rout_1 + rout_2);
|
||
|
||
modem.controlGPIO(1, 0);
|
||
modem.controlGPIO(2, 0);
|
||
modem.controlGPIO(3, 0);
|
||
modem.controlGPIO(4, 0);
|
||
|
||
sprint("Init");
|
||
printParams();
|
||
sprint_P(str_help);
|
||
|
||
initEEPROM();
|
||
}
|
||
|
||
void loop() {
|
||
|
||
if (millis() - t > PERIOD) {
|
||
getStatus();
|
||
t = millis();
|
||
//sprint("Status!");
|
||
}
|
||
|
||
checkModem();
|
||
|
||
if (!cmdFromModem) {
|
||
readSerial(command, CMD_SIZE);
|
||
}
|
||
|
||
if (command[0] != '\0') {
|
||
sprint(">", false);
|
||
sprint(command);
|
||
|
||
if (!strcmp_P(command, cmd_status)) {
|
||
getStatusMessage(message);
|
||
returnAnswer(message);
|
||
} else if (!strcmp_P(command, cmd_help)) {
|
||
sprint_P(str_help);
|
||
sendHelp();
|
||
} else if (!strcmp_P(command, cmd_sms_on)) {
|
||
smsOn(true);
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_sms_off)) {
|
||
smsOn(false);
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_auth_on)) {
|
||
authOn(true);
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_auth_off)) {
|
||
authOn(false);
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_fwd_on)) {
|
||
fwdOn(true);
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_fwd_off)) {
|
||
fwdOn(false);
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_on)) {
|
||
mainPowerOn();
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_off)) {
|
||
mainPowerOff();
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_reset)) {
|
||
mainReset();
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_a)) {
|
||
a_PowerBreak();
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_b)) {
|
||
b_PowerBreak();
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_forward)) {
|
||
forwardLastSMS();
|
||
} else if (!strcmp_P(command, cmd_modem_reset) && !cmdFromModem) {
|
||
modem.reset();
|
||
modem.init();
|
||
returnAnswer();
|
||
} else if (!strcmp_P(command, cmd_modem_console) && !cmdFromModem) {
|
||
modemConsole();
|
||
} else if (!strcmp_P(command, cmd_edit_ab) && !cmdFromModem) {
|
||
editAddressBook();
|
||
} else if (!strcmp_P(command, cmd_show_ab) && !cmdFromModem) {
|
||
printAddressBook();
|
||
} else {
|
||
sprint_P(str_help);
|
||
sendHelp();
|
||
}
|
||
}
|
||
|
||
ledOn();
|
||
delay(5);
|
||
ledOff();
|
||
|
||
if (buttonPressed()) {
|
||
ledOn();
|
||
if (btnCount < BTN_COUNT) btnCount++;
|
||
} else {
|
||
ledOff();
|
||
btnCount = 0;
|
||
btnTrigger = false;
|
||
}
|
||
|
||
if (btnCount >= BTN_COUNT && !btnTrigger) {
|
||
btnTrigger = true;
|
||
if (entryNotEmpty(0)) {
|
||
loadPhoneNumber(0, phone);
|
||
modem.callUp(phone);
|
||
sprint("Out call: ", phone);
|
||
while (true) {
|
||
ledOn();
|
||
event = modem.getEvent(message, phone, datetime, l_buffer, LONG_BUFFER_SIZE, NO_CHECK);
|
||
ledOff();
|
||
delay(150);
|
||
|
||
if (event == BUSY || event == NO_CARRIER || event == NO_ANSWER) break;
|
||
if (event == ANSWER) t = millis();
|
||
|
||
if (!buttonPressed()) btnTrigger = false;
|
||
|
||
if (millis() - t > CALL_TIMEOUT || (buttonPressed() && !btnTrigger)) {
|
||
btnTrigger = true;
|
||
break;
|
||
}
|
||
}
|
||
modem.hangup();
|
||
sprint("Call over");
|
||
} else {
|
||
flash(5);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Запрос статуса
|
||
word getStatus() {
|
||
unsigned int stat = 0;
|
||
|
||
// Get sensors
|
||
getTH();
|
||
if (temp > 28) stat |= TEMP_WARN;
|
||
if (hum > 85) stat |= HUM_WARN;
|
||
|
||
loud = analogRead(A_PIN);
|
||
if (loud > 250) stat |= LOUD_WARN;
|
||
|
||
getVs();
|
||
if (v12 < 10) stat |= POWER_WARN;
|
||
if (vbat < 6.4) stat |= BAT_WARN;
|
||
|
||
return stat;
|
||
}
|
||
|
||
//
|
||
void printAll() {
|
||
sprint("phone: ", phone);
|
||
sprint("date: ", datetime);
|
||
sprint("msg: ", message);
|
||
sprint("msg len: ", strlen(message));
|
||
sprint("cmd: ", command);
|
||
|
||
sprint("t: ", temp);
|
||
sprint("h: ", hum);
|
||
sprint("l: ", loud);
|
||
|
||
sprint("mdm: ", modemOK, true);
|
||
sprint("sms: ", smsOn(), true);
|
||
sprint("auth: ", authOn(), true);
|
||
sprint("fwd: ", fwdOn(), true);
|
||
|
||
sprint("Vcc: ", vcc);
|
||
sprint("V12: ", v12);
|
||
sprint("V5: ", v5);
|
||
sprint("Vbat: ", vbat);
|
||
sprint("Vout: ", vout);
|
||
}
|
||
|
||
// Формируем читабельную строку со статусом
|
||
void getStatusMessage(char *message) {
|
||
word stat = getStatus();
|
||
char s[10];
|
||
|
||
message[0] = '\0';
|
||
if (stat != 0) {
|
||
strcat(message, "WARNING");
|
||
} else {
|
||
strcat(message, "OK");
|
||
}
|
||
|
||
strcat(message, "\nT: ");
|
||
itoa(temp, s, 10);
|
||
strcat(message, s);
|
||
strcat(message, "C");
|
||
if (stat & TEMP_WARN) strcat(message, " !");
|
||
|
||
strcat(message, " H: ");
|
||
itoa(hum, s, 10);
|
||
strcat(message, s);
|
||
strcat(message, "%");
|
||
if (stat & HUM_WARN) strcat(message, " !");
|
||
|
||
strcat(message, " L: ");
|
||
itoa(loud, s, 10);
|
||
strcat(message, s);
|
||
strcat(message, "UE");
|
||
if (stat & LOUD_WARN) strcat(message, " !");
|
||
|
||
strcat(message, "\nVcc: ");
|
||
ftoa(vcc, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, "\nV12: ");
|
||
ftoa(v12, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, " V5: ");
|
||
ftoa(v5, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, "\nVbat: ");
|
||
ftoa(vbat, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, " Vout: ");
|
||
ftoa(vout, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, "\n\nPower: ");
|
||
if (stat & POWER_WARN) strcat(message, "Off");
|
||
else strcat(message, "On");
|
||
|
||
strcat(message, " Battery: ");
|
||
if (stat & BAT_WARN) strcat(message, "Low");
|
||
else strcat(message, "Ok");
|
||
|
||
strcat(message, "\nSMS: ");
|
||
if (smsOn()) strcat(message, "On");
|
||
else strcat(message, "Off");
|
||
|
||
strcat(message, " Auth: ");
|
||
if (authOn()) strcat(message, "On");
|
||
else strcat(message, "Off");
|
||
|
||
strcat(message, " Fwd: ");
|
||
if (fwdOn()) strcat(message, "On");
|
||
else strcat(message, "Off");
|
||
}
|
||
|
||
// Обработка событий модема
|
||
void checkModem() {
|
||
cmdFromModem = false;
|
||
command[0] = '\0';
|
||
|
||
switch (modem.getEvent(message, phone, datetime, l_buffer, LONG_BUFFER_SIZE)) {
|
||
case ERR:
|
||
sprint("Mdm err!");
|
||
modemOK = false;
|
||
if (modemErrCount < MAX_ERROR) modemErrCount++;
|
||
|
||
if (modemErrCount >= MAX_ERROR) {
|
||
sprint("Rst mdm...");
|
||
modem.reset();
|
||
if (modem.init()) {
|
||
sprint("Mdm OK");
|
||
modemOK = true;
|
||
}
|
||
}
|
||
return;
|
||
|
||
case SMS:
|
||
sprint("SMS: ", phone);
|
||
flash(3);
|
||
|
||
if (authOn() && !authOK(phone)) {
|
||
strcpy_P(command, cmd_forward);
|
||
} else {
|
||
strncpy(command, message, CMD_SIZE);
|
||
}
|
||
cmdFromModem = true;
|
||
break;
|
||
|
||
case CALL:
|
||
sprint("Call: ", phone);
|
||
|
||
if (authOn() && !authOK(phone)) {
|
||
modem.hangup();
|
||
sprint("Unauth call");
|
||
} else {
|
||
modem.answer();
|
||
t = millis();
|
||
while (!modem.ifcallEnd()) {
|
||
ledOn();
|
||
delay(1000);
|
||
ledOff();
|
||
|
||
if (millis() - t > CALL_TIMEOUT || buttonPressed()) {
|
||
modem.hangup();
|
||
break;
|
||
}
|
||
}
|
||
sprint("Call over");
|
||
}
|
||
cmdFromModem = true;
|
||
break;
|
||
|
||
case NONE:
|
||
cmdFromModem = false;
|
||
break;
|
||
}
|
||
|
||
modemErrCount = 0;
|
||
modemOK = true;
|
||
}
|
||
|
||
// Консоль модема
|
||
void modemConsole() {
|
||
sprint_P(str_modem_cons_on);
|
||
sprint("Timeout is ", TIMEOUT, false);
|
||
sprint(" ms after last command");
|
||
|
||
t = millis();
|
||
byte i = 0;
|
||
while (millis() - t < TIMEOUT) {
|
||
if (Serial1.available()) {
|
||
while(Serial1.available()) {
|
||
s_buffer[i++] = Serial1.read();
|
||
if(i == BUFFER_SIZE) break;
|
||
}
|
||
|
||
Serial.write(s_buffer, i);
|
||
i = 0;
|
||
}
|
||
|
||
if (Serial.available()) {
|
||
Serial1.write(Serial.read());
|
||
t = millis();
|
||
}
|
||
}
|
||
sprint_P(str_modem_cons_off);
|
||
}
|
||
|
||
// Читаем команды с COM-порта
|
||
void readSerial(char *com, byte com_size) {
|
||
com[0] = '\0';
|
||
com[com_size - 1] = '\0';
|
||
|
||
byte i = 0;
|
||
while (Serial.available() > 0 && i < com_size - 1) {
|
||
com[i] = Serial.read();
|
||
if (com[i] == '\r') {
|
||
com[i] = '\0';
|
||
} else if (com[i] == '\n') {
|
||
com[i] = '\0';
|
||
break;
|
||
}
|
||
i++;
|
||
}
|
||
}
|
||
|
||
// Отправляем ответ
|
||
void returnAnswer(const char * answer) {
|
||
sprint(answer);
|
||
|
||
if (modemOK && smsOn() && cmdFromModem) {
|
||
modem.sendSMS(phone, answer);
|
||
}
|
||
}
|
||
|
||
void sendHelp() {
|
||
if (modemOK && smsOn() && cmdFromModem) {
|
||
if (authOn() && !authOK(phone)) return;
|
||
modem.sendSMS(phone, str_help);
|
||
}
|
||
}
|
||
|
||
void forwardLastSMS() {
|
||
char main_phone[PHONE_SIZE];
|
||
|
||
sprint("Get SMS from: ", false);
|
||
sprint(phone);
|
||
sprint("at: ", false);
|
||
sprint(datetime);
|
||
sprint(message);
|
||
|
||
if (fwdOn() && entryNotEmpty(0)) {
|
||
loadPhoneNumber(0, main_phone);
|
||
s_buffer[0] = '\0';
|
||
strcat(s_buffer, "SMS from ");
|
||
strcat(s_buffer, phone);
|
||
strcat(s_buffer, " at ");
|
||
strcat(s_buffer, datetime);
|
||
modem.sendSMS(main_phone, s_buffer);
|
||
modem.sendSMS(main_phone, message);
|
||
}
|
||
}
|
||
|
||
// Управление подключенным оборудованием
|
||
void mainPowerOn() {
|
||
if (!isPowerOn()) {
|
||
modem.controlGPIO(1, 1);
|
||
delay(500);
|
||
modem.controlGPIO(1, 0);
|
||
}
|
||
}
|
||
|
||
void mainPowerOff() {
|
||
modem.controlGPIO(1, 1);
|
||
delay(6000);
|
||
modem.controlGPIO(1, 0);
|
||
}
|
||
|
||
void mainReset() {
|
||
modem.controlGPIO(2, 1);
|
||
delay(500);
|
||
modem.controlGPIO(2, 0);
|
||
}
|
||
|
||
void a_PowerBreak() {
|
||
modem.controlGPIO(3, 1);
|
||
delay(5000);
|
||
modem.controlGPIO(3, 0);
|
||
}
|
||
|
||
void b_PowerBreak() {
|
||
modem.controlGPIO(4, 1);
|
||
delay(5000);
|
||
modem.controlGPIO(4, 0);
|
||
}
|
||
|
||
bool isPowerOn() {
|
||
getVs();
|
||
if (v12 > 10) return true;
|
||
else return false;
|
||
}
|
||
|
||
// Адресная книга
|
||
bool savePhoneNumber(byte index, char * phone) {
|
||
if (index > AB_MAX_INDEX) return false;
|
||
|
||
addr = AB_ADDR + index * PHONE_SIZE;
|
||
|
||
for (byte i = 0; i < PHONE_SIZE; i++)
|
||
EEPROM.update(addr + i, phone[i]);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool delPhoneNumber(byte index) {
|
||
if (index > AB_MAX_INDEX) return false;
|
||
|
||
clearBuffer(phone, PHONE_SIZE);
|
||
strcpy(phone, "<NONE>");
|
||
|
||
return savePhoneNumber(index, phone);
|
||
}
|
||
|
||
bool loadPhoneNumber(byte index, char * phone) {
|
||
if (index > AB_MAX_INDEX) return false;
|
||
|
||
addr = AB_ADDR + index * PHONE_SIZE;
|
||
|
||
for (byte i = 0; i < PHONE_SIZE - 1; i++)
|
||
phone[i] = EEPROM.read(addr + i);
|
||
phone[PHONE_SIZE - 1] = '\0';
|
||
|
||
return true;
|
||
}
|
||
|
||
bool entryNotEmpty(byte index) {
|
||
char phone[PHONE_SIZE];
|
||
|
||
loadPhoneNumber(index, phone);
|
||
return strcmp(phone, "<NONE>");
|
||
}
|
||
|
||
void printPhoneNumber(byte index) {
|
||
if (index > AB_MAX_INDEX) {
|
||
sprint("Max index is: ", AB_MAX_INDEX);
|
||
return;
|
||
}
|
||
|
||
loadPhoneNumber(index, phone);
|
||
sprint("", index, false);
|
||
sprint(": ", false);
|
||
sprint(phone);
|
||
}
|
||
|
||
void printAddressBook() {
|
||
sprint("i Phone");
|
||
for (byte i = 0; i <= AB_MAX_INDEX; i++)
|
||
printPhoneNumber(i);
|
||
}
|
||
|
||
void clearAddressBook() {
|
||
for (byte i = 0; i <= AB_MAX_INDEX; i++)
|
||
delPhoneNumber(i);
|
||
}
|
||
|
||
void editAddressBook() {
|
||
char *p;
|
||
char indexString[4];
|
||
byte index, i = 0;
|
||
|
||
sprint_P(str_eab);
|
||
sprint_P(str_help_ab);
|
||
sprint_P(str_format_ab);
|
||
|
||
t = millis();
|
||
while (millis() - t < TIMEOUT) {
|
||
readSerial(s_buffer, BUFFER_SIZE);
|
||
|
||
if (s_buffer[0] != '\0') {
|
||
t = millis();
|
||
|
||
if (!strcmp_P(s_buffer, cmd_exit)) {
|
||
break;
|
||
} else if (!strcmp_P(s_buffer, cmd_show)) {
|
||
printAddressBook();
|
||
} else if (!strcmp_P(s_buffer, cmd_clear)) {
|
||
clearAddressBook();
|
||
} else {
|
||
p = strstr(s_buffer, ":");
|
||
i = 0;
|
||
while(s_buffer[i] != ':' && i < BUFFER_SIZE) i++;
|
||
|
||
if (p == NULL || i == 0 || i > 1) {
|
||
sprint_P(str_format_ab);
|
||
} else {
|
||
// Get index
|
||
clearBuffer(indexString, 4);
|
||
strncpy(indexString, s_buffer, i);
|
||
index = atoi(indexString);
|
||
// Get phone
|
||
i = 0;
|
||
p = strstr(s_buffer, ":") + 1;
|
||
strcpy(phone, p);
|
||
|
||
if (strcmp(phone, "delete")) {
|
||
// Save
|
||
savePhoneNumber(index, phone);
|
||
sprint("OK");
|
||
} else {
|
||
// Delete
|
||
delPhoneNumber(index);
|
||
sprint("OK");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
sprint_P(str_help);
|
||
}
|
||
|
||
// Утилиты
|
||
void clearBuffer(char *in_buffer, byte in_size) {
|
||
for(byte i = 0; i < in_size - 1; i++) in_buffer[i] = '\0';
|
||
}
|
||
|
||
void printParams() {
|
||
if(smsOn()) sprint("SMS on | ", false); else sprint("SMS off | ", false);
|
||
if(authOn()) sprint("Auth on | ", false); else sprint("Auth off | ", false);
|
||
if(smsOn()) sprint("Fwd on"); else sprint("Fwd off");
|
||
}
|
||
|
||
bool authOK(char *phone) {
|
||
char t_phone[PHONE_SIZE];
|
||
|
||
for(byte i = 0; i <= AB_MAX_INDEX; i++) {
|
||
loadPhoneNumber(i, t_phone);
|
||
if (!strcmp(phone, t_phone)) return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void sprint(const char *description, const byte data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const char *data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const int data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const unsigned int data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const long int data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const long unsigned int data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const float data, const bool ln) {
|
||
Serial.print(description);
|
||
Serial.print(data);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint(const char *description, const bool ln) {
|
||
Serial.print(description);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void sprint_P(const char *description, const bool ln) {
|
||
int len = strlen_P(description);
|
||
char c;
|
||
|
||
for (byte i = 0; i < len; i++) {
|
||
c = pgm_read_byte_near(description + i);
|
||
Serial.print(c);
|
||
}
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
bool smsOn() {
|
||
addr = PARAM_ADDR + SMS_ON_INDEX;
|
||
return (bool)EEPROM.read(addr);
|
||
}
|
||
|
||
void smsOn(bool temp) {
|
||
addr = PARAM_ADDR + SMS_ON_INDEX;
|
||
EEPROM.update(addr, (byte)temp);
|
||
}
|
||
|
||
bool authOn() {
|
||
addr = PARAM_ADDR + AUTH_ON_INDEX;
|
||
return (bool)EEPROM.read(addr);
|
||
}
|
||
|
||
void authOn(bool temp) {
|
||
addr = PARAM_ADDR + AUTH_ON_INDEX;
|
||
EEPROM.update(addr, (byte)temp);
|
||
}
|
||
|
||
bool fwdOn() {
|
||
addr = PARAM_ADDR + FWD_ON_INDEX;
|
||
return (bool)EEPROM.read(addr);
|
||
}
|
||
|
||
void fwdOn(bool temp) {
|
||
addr = PARAM_ADDR + FWD_ON_INDEX;
|
||
EEPROM.update(addr, (byte)temp);
|
||
}
|
||
|
||
void fanPWM(byte power) {
|
||
analogWrite(FAN_PIN, power);
|
||
}
|
||
|
||
void fanOn() {
|
||
digitalWrite(FAN_PIN, HIGH);
|
||
}
|
||
|
||
void fanOff() {
|
||
digitalWrite(FAN_PIN, LOW);
|
||
}
|
||
|
||
void ledPWM(byte power) {
|
||
analogWrite(LED_PIN, power);
|
||
}
|
||
|
||
void ledOn() {
|
||
digitalWrite(LED_PIN, HIGH);
|
||
}
|
||
|
||
void ledOff() {
|
||
digitalWrite(LED_PIN, LOW);
|
||
}
|
||
|
||
void flash(byte count) {
|
||
for (byte i = 0; i < count; i++) {
|
||
ledOn();
|
||
delay(5);
|
||
ledOff();
|
||
delay(150);
|
||
}
|
||
}
|
||
|
||
bool buttonPressed() {
|
||
if (digitalRead(BTN_PIN) == LOW) return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
float readvcc() {
|
||
byte i;
|
||
float tmp = 0.0;
|
||
|
||
// 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
|
||
// works on an Arduino 168 or 328
|
||
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
|
||
#endif
|
||
|
||
delay(3); // 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
|
||
|
||
tmp = (high<<8) | low;
|
||
tmp = (typVbg * 1023.0) / tmp;
|
||
|
||
return tmp;
|
||
}
|
||
|
||
void getVs() {
|
||
v12 = 0.0;
|
||
v5 = 0.0;
|
||
vbat = 0.0;
|
||
vout = 0.0;
|
||
|
||
v12 += readvcc() * analogRead(V12_PIN);
|
||
v5 += readvcc() * analogRead(V5_PIN);
|
||
vbat += readvcc() * analogRead(VBAT_PIN);
|
||
vout += readvcc() * analogRead(VOUT_PIN);
|
||
|
||
vcc = readvcc();
|
||
v12 = v12 / 1024.0 / k12;
|
||
v5 = v5 / 1024.0 / k5;
|
||
vbat = vbat / 1024.0 / kbat;
|
||
vout = vout / 1024.0 / kout;
|
||
}
|
||
|
||
void printVs() {
|
||
sprint("Vcc: ", vcc);
|
||
sprint("V12: ", v12);
|
||
sprint("V5: ", v5);
|
||
sprint("Vbat: ", vbat);
|
||
sprint("Vout: ", vout);
|
||
}
|
||
|
||
void getTH() {
|
||
int check;
|
||
|
||
check = dht.read();
|
||
switch (check) {
|
||
case DHT_OK:
|
||
temp = dht.getTemperatureC();
|
||
hum = dht.getHumidity();
|
||
break;
|
||
case DHT_ERROR_TIMEOUT:
|
||
temp = 253;
|
||
break;
|
||
case DHT_ERROR_CHECKSUM:
|
||
temp = 254;
|
||
break;
|
||
}
|
||
}
|
||
|
||
void ftoa(float f, char *s) {
|
||
int d1, d2;
|
||
char t[10];
|
||
|
||
s[0] = '\0';
|
||
|
||
d1 = (int)f;
|
||
f = f - d1;
|
||
f = f * 100;
|
||
d2 = (int)f;
|
||
|
||
itoa(d1, t, 10);
|
||
strcat(s, t);
|
||
strcat(s, ".");
|
||
itoa(d2, t, 10);
|
||
strcat(s, t);
|
||
}
|
||
|
||
void initEEPROM() {
|
||
int flag_addr = PARAM_ADDR + EEPROM_INIT_INDEX;
|
||
|
||
if (EEPROM.read(flag_addr) != INIT_FLAG) {
|
||
clearAddressBook();
|
||
smsOn(false);
|
||
authOn(true);
|
||
fwdOn(true);
|
||
EEPROM.write(flag_addr, INIT_FLAG);
|
||
}
|
||
}
|