1114 lines
26 KiB
C++
1114 lines
26 KiB
C++
// ----------------------------------------------------------------------------------------------------
|
||
// Watchdog v3 - Leonardo
|
||
// EoF 2017
|
||
// ----------------------------------------------------------------------------------------------------
|
||
|
||
#include "watchdog_3.h"
|
||
|
||
GPRS modem(Serial1, MOD_PWR);
|
||
bool modemOK = false;
|
||
byte modemErrCount = 0;
|
||
DHT11 tSensor(T_PIN);
|
||
|
||
char command[CMD_SIZE];
|
||
char message[SMS_SIZE];
|
||
char phone[PHONE_SIZE];
|
||
char datetime[DATE_SIZE];
|
||
char s_buffer[SHORT_BUFFER_SIZE];
|
||
char l_buffer[LONG_BUFFER_SIZE];
|
||
char vl_buffer[SMS_SIZE + 80];
|
||
|
||
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 rin_1 = 200000; // 200K
|
||
const float rin_2 = 100000; // 100K
|
||
const float rbat_1 = 100000; // 100K
|
||
const float rbat_2 = 100000; // 100K
|
||
const float rusb_1 = 100000; // 100K
|
||
const float rusb_2 = 100000; // 100K
|
||
|
||
float vcc = 0.0;
|
||
float kin, kbat, kusb;
|
||
float vin, vbat, vusb;
|
||
|
||
// эту константу (typVbg) необходимо откалибровать индивидуально
|
||
const float typVbg = 1.08; // 1.0 -- 1.2
|
||
|
||
#ifdef MAIN
|
||
|
||
void setup() {
|
||
Serial.begin(COM_BR);
|
||
Serial1.begin(MOD_BR);
|
||
modem.powerOn();
|
||
modemOK = modem.init();
|
||
|
||
// Конфигурируем пины
|
||
pinMode(A_PIN, INPUT);
|
||
pinMode(BAT_T_PIN, INPUT);
|
||
pinMode(VIN_PIN, INPUT);
|
||
pinMode(VBAT_PIN, INPUT);
|
||
pinMode(VUSB_PIN, INPUT);
|
||
|
||
pinMode(LED_PIN, OUTPUT);
|
||
pinMode(BTN_PIN, INPUT);
|
||
pinMode(FAN_PIN, OUTPUT);
|
||
|
||
// Инициализируем климатический сенсор
|
||
tSensor.begin();
|
||
|
||
// Коэффициенты делителей напряжений
|
||
kin = rin_2 / (rin_1 + rin_2);
|
||
kbat = rbat_2 / (rbat_1 + rbat_2);
|
||
kusb = rusb_2 / (rusb_1 + rusb_2);
|
||
|
||
modem.controlGPIO(1, 0);
|
||
modem.controlGPIO(2, 0);
|
||
modem.controlGPIO(3, 0);
|
||
modem.controlGPIO(4, 0);
|
||
|
||
sprint("Init");
|
||
printParams();
|
||
printHelp();
|
||
}
|
||
|
||
void loop() {
|
||
if (millis() - t < PERIOD) {
|
||
getStatus();
|
||
t = millis();
|
||
}
|
||
|
||
checkModem();
|
||
|
||
if (!cmdFromModem) {
|
||
readSerial(command, CMD_SIZE);
|
||
}
|
||
|
||
if (command[0] != '\0') {
|
||
sprint(">", false);
|
||
sprint(command);
|
||
|
||
if (isCommandMatchIndex(command, CMD_INDEX_STATUS)) {
|
||
//printAll();
|
||
getStatusMessage(message);
|
||
returnAnswer(message);
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_HELP)) {
|
||
printHelp();
|
||
sendHelp();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_SMS_ON)) {
|
||
smsOn(true);
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_SMS_OFF)) {
|
||
smsOn(false);
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_AUTH_ON)) {
|
||
authOn(true);
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_AUTH_OFF)) {
|
||
authOn(false);
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_FWD_ON)) {
|
||
fwdOn(true);
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_FWD_OFF)) {
|
||
fwdOn(false);
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_ON)) {
|
||
mainPowerOn();
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_OFF)) {
|
||
mainPowerOff();
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_RESET)) {
|
||
mainReset();
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_A)) {
|
||
a_PowerBreak();
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_B)) {
|
||
b_PowerBreak();
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_FORWARD)) {
|
||
forwardLastSMS();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_MODEM_RESET) && !cmdFromModem) {
|
||
modem.reset();
|
||
modem.init();
|
||
returnAnswer();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_MODEM_CONSOLE) && !cmdFromModem) {
|
||
modemConsole();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_EDIT_AB) && !cmdFromModem) {
|
||
editAddressBook();
|
||
} else if (isCommandMatchIndex(command, CMD_INDEX_SHOW_AB) && !cmdFromModem) {
|
||
printAddressBook();
|
||
} else {
|
||
printHelp();
|
||
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, vl_buffer, VLONG_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);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
// Запрос статуса
|
||
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 (vin < 10) stat |= POWER_WARN;
|
||
if (vbat < 3.7) 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("Vin: ", vin);
|
||
sprint("Vbat: ", vbat);
|
||
sprint("Vusb: ", vusb);
|
||
}
|
||
|
||
// Формируем читабельную строку со статусом
|
||
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, " Vin: ");
|
||
ftoa(vin, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, "\nVbat: ");
|
||
ftoa(vbat, s);
|
||
strcat(message, s);
|
||
strcat(message, "V");
|
||
|
||
strcat(message, " Vusb: ");
|
||
ftoa(vusb, 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");
|
||
}
|
||
|
||
bool isCommandMatchIndex(const char *command, byte index) {
|
||
char t_command[CMD_SIZE];
|
||
|
||
if (!getCommand(index, t_command)) return false;
|
||
|
||
return !strcmp(command, t_command);
|
||
}
|
||
|
||
// Консоль модема
|
||
void checkModem() {
|
||
cmdFromModem = false;
|
||
command[0] = '\0';
|
||
|
||
switch (modem.getEvent(message, phone, datetime, vl_buffer, VLONG_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)) {
|
||
getCommand(CMD_INDEX_FORWARD, command);
|
||
} 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() {
|
||
printShortString(S_STRING_INDEX_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 == SHORT_BUFFER_SIZE) break;
|
||
}
|
||
|
||
Serial.write(s_buffer, i);
|
||
i = 0;
|
||
}
|
||
|
||
if (Serial.available()) {
|
||
Serial1.write(Serial.read());
|
||
t = millis();
|
||
}
|
||
}
|
||
printShortString(S_STRING_INDEX_MODEM_CONS_OFF);
|
||
}
|
||
|
||
// Обработка звонков
|
||
void incomingCall() {
|
||
//if (!modem.ifcallNow()) return;
|
||
|
||
if (!modem.isCallActive(phone, l_buffer)) return;
|
||
sprint("Call from: ", false);
|
||
sprint(phone);
|
||
|
||
if (authOn() && !authOK(phone)) {
|
||
modem.callEnd();
|
||
sprint("Call unauth");
|
||
return;
|
||
} else modem.answer();
|
||
|
||
while (!modem.ifcallEnd()) {
|
||
|
||
}
|
||
sprint("Call over");
|
||
}
|
||
|
||
// Читаем команды с GSM-модема
|
||
void readModem(char* msg, byte msg_size) {
|
||
msg[0] = '\0';
|
||
message[0] = '\0';
|
||
|
||
if (!modemOK) return;
|
||
|
||
if (modem.getSMS(message, phone, datetime, vl_buffer, VLONG_BUFFER_SIZE)) {
|
||
// sprint("Msg: ", message);
|
||
// sprint("Phn: ", phone);
|
||
// sprint("Dtm: ", datetime);
|
||
if (authOn() && !authOK(phone)) {
|
||
getCommand(CMD_INDEX_FORWARD, msg);
|
||
return;
|
||
}
|
||
strncpy(msg, message, msg_size);
|
||
}
|
||
}
|
||
|
||
// Читаем команды с 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;
|
||
|
||
message[0] = '\0';
|
||
getLongString(L_STRING_INDEX_HELP_1, l_buffer);
|
||
strcat(message, l_buffer);
|
||
getLongString(L_STRING_INDEX_HELP_2, l_buffer);
|
||
strcat(message, l_buffer);
|
||
|
||
modem.sendSMS(phone, message);
|
||
}
|
||
}
|
||
|
||
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);
|
||
l_buffer[0] = '\0';
|
||
strcat(l_buffer, "SMS from ");
|
||
strcat(l_buffer, phone);
|
||
strcat(l_buffer, " at ");
|
||
strcat(l_buffer, datetime);
|
||
modem.sendSMS(main_phone, l_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(5000);
|
||
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 (vin > 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;
|
||
|
||
printShortString(S_STRING_INDEX_EAB_MODE);
|
||
printLongString(L_STRING_INDEX_HELP_AB);
|
||
printLongString(L_STRING_INDEX_FORMAT_AB);
|
||
|
||
t = millis();
|
||
while (millis() - t < TIMEOUT) {
|
||
readSerial(s_buffer, SHORT_BUFFER_SIZE);
|
||
|
||
if (s_buffer[0] != '\0') {
|
||
t = millis();
|
||
|
||
if (isCommandMatchIndex(s_buffer, CMD_INDEX_EXIT)) {
|
||
break;
|
||
} else if (isCommandMatchIndex(s_buffer, CMD_INDEX_SHOW)) {
|
||
printAddressBook();
|
||
} else if (isCommandMatchIndex(s_buffer, CMD_INDEX_CLEAR)) {
|
||
clearAddressBook();
|
||
} else {
|
||
p = strstr(s_buffer, ":");
|
||
i = 0;
|
||
while(s_buffer[i] != ':' && i < SHORT_BUFFER_SIZE) i++;
|
||
|
||
if (p == NULL || i == 0 || i > 1) {
|
||
printLongString(L_STRING_INDEX_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");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
printHelp();
|
||
}
|
||
|
||
// Утилиты
|
||
void clearBuffer(char *in_buffer, byte in_size) {
|
||
for(byte i = 0; i < in_size - 1; i++) in_buffer[i] = '\0';
|
||
}
|
||
|
||
void printShortString(byte index, bool ln) {
|
||
getShortString(index, s_buffer);
|
||
Serial.print(s_buffer);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void printLongString(byte index, bool ln) {
|
||
getLongString(index, l_buffer);
|
||
Serial.print(l_buffer);
|
||
if (ln) Serial.println();
|
||
}
|
||
|
||
void printHelp() {
|
||
printLongString(L_STRING_INDEX_HELP_1, false);
|
||
printLongString(L_STRING_INDEX_HELP_2);
|
||
}
|
||
|
||
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();
|
||
}
|
||
|
||
// EEPROM utils
|
||
bool setCommand(byte index, const char *command) {
|
||
if (index > CMD_MAX_INDEX) return false;
|
||
|
||
addr = CMD_ADDR + index * CMD_SIZE;
|
||
|
||
for (byte i = 0; i < CMD_SIZE; i++)
|
||
EEPROM.update(addr + i, command[i]);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool getCommand(byte index, char *command) {
|
||
if (index > CMD_MAX_INDEX) return false;
|
||
|
||
addr = CMD_ADDR + index * CMD_SIZE;
|
||
|
||
for (byte i = 0; i < CMD_SIZE; i++)
|
||
command[i] = EEPROM.read(addr + i);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool setShortString(byte index, const char *s_buffer) {
|
||
if (index > S_STRING_MAX_INDEX) return false;
|
||
|
||
addr = S_STRING_ADDR + index * SHORT_BUFFER_SIZE;
|
||
|
||
for (byte i = 0; i < SHORT_BUFFER_SIZE; i++)
|
||
EEPROM.update(addr + i, s_buffer[i]);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool getShortString(byte index, char *s_buffer) {
|
||
if (index > S_STRING_MAX_INDEX) return false;
|
||
|
||
addr = S_STRING_ADDR + index * SHORT_BUFFER_SIZE;
|
||
|
||
for (byte i = 0; i < SHORT_BUFFER_SIZE; i++)
|
||
s_buffer[i] = EEPROM.read(addr + i);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool setLongString(byte index, const char *l_buffer) {
|
||
if (index > L_STRING_MAX_INDEX) return false;
|
||
|
||
addr = L_STRING_ADDR + index * LONG_BUFFER_SIZE;
|
||
|
||
for (byte i = 0; i < LONG_BUFFER_SIZE; i++)
|
||
EEPROM.update(addr + i, l_buffer[i]);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool getLongString(byte index, char *l_buffer) {
|
||
if (index > L_STRING_MAX_INDEX) return false;
|
||
|
||
addr = L_STRING_ADDR + index * LONG_BUFFER_SIZE;
|
||
|
||
for (byte i = 0; i < LONG_BUFFER_SIZE; i++)
|
||
l_buffer[i] = EEPROM.read(addr + i);
|
||
|
||
return true;
|
||
}
|
||
|
||
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() {
|
||
vin = 0.0;
|
||
vbat = 0.0;
|
||
vusb = 0.0;
|
||
|
||
vin += readvcc() * analogRead(VIN_PIN);
|
||
vbat += readvcc() * analogRead(VBAT_PIN);
|
||
vusb += readvcc() * analogRead(VUSB_PIN);
|
||
|
||
vcc = readvcc();
|
||
vin = vin / 1024.0 / kin;
|
||
vbat = vbat / 1024.0 / kbat;
|
||
vusb = vusb / 1024.0 / kusb;
|
||
}
|
||
|
||
void printVs() {
|
||
sprint("Vcc: ", vcc);
|
||
sprint("Vin: ", vin);
|
||
sprint("Vbat: ", vbat);
|
||
sprint("Vusb: ", vusb);
|
||
}
|
||
|
||
void getTH() {
|
||
int check;
|
||
|
||
check = tSensor.read();
|
||
switch (check) {
|
||
case DHT_OK:
|
||
temp = tSensor.getTemperatureC();
|
||
hum = tSensor.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);
|
||
}
|
||
|
||
#ifdef INIT
|
||
|
||
#define HELP_INIT "Usage: help | fill | print cmd | print short | print long"
|
||
|
||
void fillEEPROM() {
|
||
// ClearParams
|
||
smsOn(false);
|
||
authOn(true);
|
||
fwdOn(true);
|
||
|
||
// Fill commands
|
||
// -- 123456789012345
|
||
// 0 status
|
||
setCommand(CMD_INDEX_STATUS, "status");
|
||
// 1 help
|
||
setCommand(CMD_INDEX_HELP, "help");
|
||
// 2 sms on
|
||
setCommand(CMD_INDEX_SMS_ON, "sms on");
|
||
// 3 sms off
|
||
setCommand(CMD_INDEX_SMS_OFF, "sms off");
|
||
// 4 on
|
||
setCommand(CMD_INDEX_ON, "on");
|
||
// 5 off
|
||
setCommand(CMD_INDEX_OFF, "off");
|
||
// 6 reset
|
||
setCommand(CMD_INDEX_RESET, "reset");
|
||
// 7 a
|
||
setCommand(CMD_INDEX_A, "a");
|
||
// 8 b
|
||
setCommand(CMD_INDEX_B, "b");
|
||
// 9 forward
|
||
setCommand(CMD_INDEX_FORWARD, "forward");
|
||
// 10
|
||
setCommand(CMD_INDEX_10, "<NONE>");
|
||
// 11 modem reset
|
||
setCommand(CMD_INDEX_MODEM_RESET, "modem reset");
|
||
// 12 modem console
|
||
setCommand(CMD_INDEX_MODEM_CONSOLE, "modem console");
|
||
// 13 edit ab
|
||
setCommand(CMD_INDEX_EDIT_AB, "edit ab");
|
||
// 14 show ab
|
||
setCommand(CMD_INDEX_SHOW_AB, "show ab");
|
||
// 15 show
|
||
setCommand(CMD_INDEX_SHOW, "show");
|
||
// 16 clear
|
||
setCommand(CMD_INDEX_CLEAR, "clear");
|
||
// 17 exit
|
||
setCommand(CMD_INDEX_EXIT, "exit");
|
||
// 18 auth on
|
||
setCommand(CMD_INDEX_AUTH_ON, "auth on");
|
||
// 19 auth off
|
||
setCommand(CMD_INDEX_AUTH_OFF, "auth off");
|
||
// 20 forward on
|
||
setCommand(CMD_INDEX_FWD_ON, "forward on");
|
||
// 21 forward off
|
||
setCommand(CMD_INDEX_FWD_OFF, "forward off");
|
||
// 22
|
||
setCommand(CMD_INDEX_22, "<NONE>");
|
||
// 23
|
||
setCommand(CMD_INDEX_23, "<NONE>");
|
||
|
||
//Fill short strings
|
||
// -- 1234567890123456789012345678901
|
||
// 0 edit ab|show ab
|
||
setShortString(S_STRING_INDEX_1, "<NONE>");
|
||
// 1 Edit address book mode
|
||
setShortString(S_STRING_INDEX_EAB_MODE, "Edit address book mode");
|
||
// 2 Modem console mode on
|
||
setShortString(S_STRING_INDEX_MODEM_CONS_ON, "Modem console mode on");
|
||
// 3 Modem console mode off
|
||
setShortString(S_STRING_INDEX_MODEM_CONS_OFF, "Modem console mode off");
|
||
|
||
//Fill long strings
|
||
// -- 123456789012345678901234567890123456789012345678901234567890123
|
||
// 0 Usage: help/status/on/off/reset/a/b/modem reset|console/edit ab
|
||
setLongString(L_STRING_INDEX_HELP_1, "Usage: help/status/on/off/reset/a/b/modem reset|console/edit ab");
|
||
// 1 Type \"show\" to view, \"clear\" to erase, \"exit\" to return
|
||
setLongString(L_STRING_INDEX_HELP_AB, "Type \"show\" to view, \"clear\" to erase, \"exit\" to return");
|
||
// 2 Format: \"i:+xxxxxxxxxxx\" to update or \"i:delete\" to delete
|
||
setLongString(L_STRING_INDEX_FORMAT_AB, "Format: \"i:+xxxxxxxxxxx\" to update or \"i:delete\" to delete");
|
||
// 3 /show ab/sms on|off/auth on|off/fwd on|off
|
||
setLongString(L_STRING_INDEX_HELP_2, "/show ab/sms on|off/auth on|off/fwd on|off");
|
||
}
|
||
|
||
void setup() {
|
||
delay(5000);
|
||
Serial.println("Watchdog EEPROM init program");
|
||
Serial.println(HELP_INIT);
|
||
}
|
||
|
||
void loop() {
|
||
readSerial(command, CMD_SIZE);
|
||
|
||
if (command[0] != '\0') {
|
||
Serial.println(command);
|
||
|
||
if (!strcmp(command, "fill")) {
|
||
fillEEPROM();
|
||
Serial.println("EEPROM init complete");
|
||
} else if (!strcmp(command, "print cmd")) {
|
||
Serial.println("cmd: ");
|
||
for(byte i = 0; i <= CMD_MAX_INDEX; i++) {
|
||
getCommand(i, command);
|
||
Serial.print(i);
|
||
Serial.print(": ");
|
||
Serial.println(command);
|
||
}
|
||
} else if (!strcmp(command, "print short")) {
|
||
Serial.println("short: ");
|
||
for(byte i = 0; i <= S_STRING_MAX_INDEX; i++) {
|
||
getShortString(i, s_buffer);
|
||
Serial.print(i);
|
||
Serial.print(": ");
|
||
Serial.println(s_buffer);
|
||
}
|
||
} else if (!strcmp(command, "print long")) {
|
||
Serial.println("long: ");
|
||
for(byte i = 0; i <= L_STRING_MAX_INDEX; i++) {
|
||
getLongString(i, l_buffer);
|
||
Serial.print(i);
|
||
Serial.print(": ");
|
||
Serial.println(l_buffer);
|
||
}
|
||
} else if (!strcmp(command, "help")) {
|
||
Serial.println(HELP_INIT);
|
||
} else {
|
||
Serial.println(HELP_INIT);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|