#include "config.h" #include "platform.h" #include #define SMS_END "\032\n" #define SIM800_DELAY_TIME 100 void sim800_wait_newline() { while (1) { char c = uart_read_char(); if (c == '\n') { return; } } } void sim800_wait_for(PGM_P str) { PGM_P curr_pos = str; LED1_Set(); while (1) { char p = pgm_read_byte(curr_pos); if (p == '\0') { break; } char c = uart_read_char(); if (c == '\r') { continue; } if (c == p) { curr_pos++; } else { curr_pos = str; } } LED1_Reset(); } void sim800_wait_for_ok() { sim800_wait_for(PSTR("OK\n")); } void sim800_start() { LED2_Set(); GSM_EN_Set(); _delay_ms(1000); // зажимаем кнопку на секунду GSM_KEY_Set(); _delay_ms(1100); GSM_KEY_Reset(); // еще 2 секунды на загрузку модуля _delay_ms(3000); // врубаем юарт uart_init(); uart_write_fstr(PSTR("AT\n")); sim800_wait_for_ok(); // вырубить echo mode (повторяет команду, которая прилетела) ATE0 _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("ATE1\n")); // TODO поставить 0 чтобы модем лишнюю херню не слал sim800_wait_for_ok(); // после готовности смс все сразу станет понятно sim800_wait_for(PSTR("SMS Ready\n")); while (1) { _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("AT+CREG?\n")); sim800_wait_for(PSTR("+CREG: ")); char mode = uart_read_char(); uart_read_char(); // запятая char status = uart_read_char(); if (mode == '0' && status == '1') { break; } } } void sim800_stop() { // вырубить модуль uart_write_fstr(PSTR("AT+CPOWD=1\n")); sim800_wait_for(PSTR("DOWN\n")); // придет NORMAL POWER DOWN uart_deinit(); GSM_EN_Reset(); LED2_Reset(); } uint16_t sim800_get_battery() { _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("AT+CBC\n")); sim800_wait_for(PSTR("+CBC:")); for (uint8_t i = 0; i < 2; i++) { sim800_wait_for(PSTR(",")); } // по идее тут будет напряжение // 4 цифры, но мне не важно на самом деле сколько uint16_t result = 0; while (1) { char c = uart_read_char(); if (c == ' ' || c == '\r') { continue; } // туда попадет и символ конца строки if (c < '0' || c > '9') { break; } result *= 10; result += c - '0'; } // ждем ок, то есть конец команды sim800_wait_for_ok(); return result; } void sim800_prepare_sms() { _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("AT+CMGF=1\n")); // PDU режим sim800_wait_for_ok(); _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("AT+CMGS=\"+79208109798\"\n")); // PDU режим sim800_wait_for(PSTR(">")); } void sim800_wait_for_sms_send() { sim800_wait_for(PSTR("+CMGS")); } static void num2buff(char* buffer, uint16_t num) { int8_t len; // длинна числа if (num < 10) len = 1; else if (num < 100) len = 2; else if (num < 1000) len = 3; else if (num < 10000) len = 4; else len = 5; buffer[len] = '\0'; // вставляем конец строки for (; len > 0; len--) { uint8_t digit = (num % 10) + '0'; num /= 10; buffer[len - 1] = (char)digit; } } void sim800_send_telemetry() { platform_read_sensors(); uint16_t bat = sim800_get_battery(); sim800_prepare_sms(); char buff[6]; // sprintf(buff, "F1=%d F2=%d\033\n", sensor_1, sensor_2); _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("F1=")); num2buff(buff, sensor_1); uart_write_str(buff); uart_write_fstr(PSTR(" F2=")); num2buff(buff, sensor_2); uart_write_str(buff); uart_write_fstr(PSTR(" BAT=")); num2buff(buff, bat); uart_write_str(buff); uart_write_fstr(PSTR(SMS_END)); sim800_wait_for_sms_send(); } int main() { platform_init(); // врубаем модем sim800_start(); // рабочая отправка сообщений sim800_prepare_sms(); _delay_ms(SIM800_DELAY_TIME); uart_write_fstr(PSTR("I'm working!" SMS_END)); // сама смска sim800_wait_for_sms_send(); // отправляем сразу же телеметрию sim800_send_telemetry(); // рубим модем sim800_stop(); for (;;) { uint16_t time = 0; while (1) { if (SPEED_Gpio & SPEED_Pin) { // (скорость отпущена, пин подтянут к питанию) // если скорости нет, шлем смс раз в час if (time > 60 * 60) { break; } } else { // если скорость зажата, то максимальное ожидание 60 секунд if (time > 60) { break; } } time++; systick_sync(); } sim800_start(); sim800_send_telemetry(); sim800_stop(); } }