// подключаем библиотеку для работы I²C #include // подключаем библиотеку для работы с модулями IMU #include // подключаем библиотеку для работы с GPRS устройством #include // подключаем библиотеку для эмуляции Serial порта // она нужна для работы библиотеки GPRS_Shield_Arduino #include #define GPRS_BUFFER_LENGTH 46 #define TELEPHONE_NUM_LENGTH 12 // порог скорости вращения гироскопа #define ROTATE_SPEED_TRESHOLD 10 // время задержки, после которой будет совершён исходящий вызов #define OUTCOMING_CALL_TIMEOUT 5000 // порог после которого будем звонить #define OUTCOMING_CALL_TRESHOLD 500 // индикаторный светодиод расположен на 13 пине #define INDICATOR_PIN 13 char fathersNumber[] = "+74993221317"; char incomingPhoneNumber[GPRS_BUFFER_LENGTH]; // создаём объект класса GPRS, передаём ему // номера пинов PK, ST и скорость 9600 бод GPRS gprs(6, 5, 9600); // создаём объект для работы с гироскопом Gyroscope gyro; unsigned long waitTime = 0; unsigned long rotateTime = 0; int rotateCounter = 0; void setup() { //настраиваем пин 13 в режим выхода, pinMode(INDICATOR_PIN, OUTPUT); // подаём на пин 13 «низкий уровень» digitalWrite(INDICATOR_PIN, LOW); // включаем GPRS Shield gprs.powerUpDown(); while (!gprs.init()) { // завелся ли GPRS Shield? digitalWrite(INDICATOR_PIN, !digitalRead(INDICATOR_PIN)); // если связи нет, ждём 1 секунду // процесс повторяется в цикле, // пока не появится ответ от GPRS устройства delay(1000); } digitalWrite(INDICATOR_PIN, LOW); // запускаем гироскоп gyro.begin(); } void loop() { // если функция возвращает true if (gyroCall()) { // звоним на заданный в коде номер gprs.callUp(fathersNumber); // индикация звонка calling(); } // каждую секунду ожидаем входящий звонок if (millis() - waitTime > 1000) { incomingCall(); // запоминаем текущее время waitTime = millis(); } } void incomingCall() { // ожидаем звонка if (gprs.ifcallNow()) { // если поступает входящий звонок, // подаём на пин 13 «высокий уровень», чтобы // зажечь светодиод на 13 пине digitalWrite(INDICATOR_PIN, HIGH); // считываем номер входящего звонка gprs.isCallActive(incomingPhoneNumber); if (!strncmp(incomingPhoneNumber, fathersNumber, TELEPHONE_NUM_LENGTH)) { // если звонит папа // по истечении 3 секунд берём трубку delay(3000); gprs.answer(); // индикация звонка calling(); } else { // если нет, кладём трубку gprs.callEnd(); } } } bool gyroCall() { // считываем абсолютную скорость вращения гироскопа по трём осям float bearRotate = abs(gyro.readDegPerSecX()) + abs(gyro.readDegPerSecY()) + abs(gyro.readDegPerSecZ()); // если это не случайные помехи if (bearRotate > ROTATE_SPEED_TRESHOLD) { // запоминаем текущее время rotateTime = millis(); // увеличиваем счётчик вращения ++rotateCounter; // увеличиваем яркость светодиода analogWrite(INDICATOR_PIN, map(rotateCounter, 0, OUTCOMING_CALL_TRESHOLD, 0, 255)); } else if (millis() - rotateTime > OUTCOMING_CALL_TIMEOUT) { // если же скорость вращение была ниже порога в течении 5 секунд // гасим светодиод digitalWrite(INDICATOR_PIN, LOW); // обнуляем счётчик вращения rotateCounter = 0; } // возвращаем результат // превысил ли счётчик вращения порог срабатывания исходящего звонка return (rotateCounter > OUTCOMING_CALL_TRESHOLD); } void calling() { while (!gprs.ifcallEnd()) { // моргаем и ждём пока абонент не положит трубку digitalWrite(INDICATOR_PIN, HIGH); delay(50); digitalWrite(INDICATOR_PIN, LOW); delay(200); digitalWrite(INDICATOR_PIN, HIGH); delay(50); digitalWrite(INDICATOR_PIN, LOW); } }