управление ip камерой с телефона через BT и ардуино нано
- Войдите на сайт для отправки комментариев
Всем привет!
Для меня этот проект был настоящий челендж в электротехнике и программировании и на этом форуме мне очень помогли с некоторыми вопросами. Решил поделиться наработками может тоже кому пригодится. Началось с покупки IP камеры с целью поиграться/разобраться. Решил повесить ее для наблюдения за машиной во дворе. Придумал крепление в возможностью регулировки по углу влево/вправо и вниз/вверх. т.к. машина стоит там где нашлось место. Поставил подключил и быстро понял что каждый раз открывать окно, снимать москитную сетку и поворачивать камеру руками не вариант. К креплению навесил сервопривод MG-90 для поворота влево/вправо (мне этого достаточно) управляется ардуино нано через блютуз HC-06 с любого андроида.

Под андроид программа в Аппинвенторе.

в верхней части выбор угла влево/вправо
кнопка выбора устройства блютуз / кнопка управления в ручном режиме
в автоматическом режиме камера направлена на точку А
точки В,С,D дополнительные на эти точки камера ходит с интевалом N минут указанных во втором столбце на N секунд указанных в 3 столбце.
углы и время задаются удерживанием кнопок ABCD более 3х секунд.
если интервал 0 то на эту точку камера не поворачивается.
Так выглядят потроха
электрика крупнее
Питается стандартным блоком питания для видеокамер 12в/2А. Для сервопривода отдельный регулятор напряжения на 5в+2 кондера и маленький радиатор из фольги. на нано и BT заклеены светодиоды черной изолентой иначе ночью кронштейн весело светится и мигает.
Для крепления сервопривода пришлось поковырять уголок нагретым ножом и паяльником. главное чтобы ось вращения кронштейна совпала с осью вращения сервы. серва заходит плотно, крепится на 2 шурупа, затем щели залил термоклеем.
сам кронштейн из полипропиленовой трубы 25 стенка чем тоньше тем лучше, чтобы влазила нано.
перечислю детали сверху вниз : заглушка, труба, 3 крепления к стене, 2 уголка 90гр., переход 25/20.
дальше черная деталь от регулируемой мебельной ноги идеально сопрягается с фланцем камеры по диаметру и отверстиям.
к качалке сервопривода закрепил сантехнический бурт для 25 трубы который вставлен в третий кронштейн и зафиксирован с боку шуропом от поворота.
Хороший проект! Скетчем не поделитесь?
#include <Wire.h> #include <SoftwareSerial.h> // Подключаем библиотеку для работы с Serial через дискретные порты #include <Servo.h> //Подключаем библиотеку Servo unsigned long timeX=777777 ; byte point[4]={ 150, 60, 90, 0}; //точки byte interval[4]={ 0, 30, 0, 0}; //интервал между просмотрами точки мин byte expo[4]={ 0, 30, 0, 0}; //время экспозиции в точке сек unsigned long old_time_int[4]={ 0, 0, 0, 0}; //время от начала интервала unsigned long old_time_exp[4]={ 0, 0, 0, 0}; //время от начала экспозиции boolean exp_status[4] = {false, false, false, false}; boolean rt = false; byte degmin=0; byte degmax=180; byte degstep=1; byte current_angle=90; //текущий угол byte old_angle=90; //старый угол byte speed2go=100; //скорость перемещения char ncmd; // Создаем переменную для команд Bluetooth имя Servo motor; SoftwareSerial BTSerial(2, 4); // RX, TX void setup() { // Устанавливаем скорость передачи данных по Bluetooth BTSerial.begin(9600); Serial.begin(9600); while (!Serial) ; // wait for serial delay(200); Serial.println("-------------------"); motor.attach(10); // Подключаем серву на 10 пин motor.write(current_angle); motor.detach(); } void loop() { if (BTSerial.available()){ // Если есть данные BT ncmd = (char)BTSerial.read(); // Читаем команды и заносим их в переменную. char преобразует код символа команды в символ Serial.println(ncmd); if (ncmd == 'r'){ // едем влево или вправо ncmd = ' '; old_angle=current_angle; while (!BTSerial.available()); // ждем данные current_angle= BTSerial.read(); // //Serial.print("r"); //Serial.println(current_angle); } // едем влево или вправо if (ncmd == 'i'){ // инициализация экрана ncmd = ' '; BTSerial.write((byte)current_angle); // предаем по ВТ текущий угол BTSerial.write((byte)point[0]); //угол 1 BTSerial.write((byte)point[1]); //угол 2 BTSerial.write((byte)point[2]); //угол 3 BTSerial.write((byte)point[3]); //угол 4 BTSerial.write((byte)interval[1]); //интервал 2 BTSerial.write((byte)interval[2]); //интервал 3 BTSerial.write((byte)interval[3]); //интервал 4 BTSerial.write((byte)expo[1]); // экспозиция 2 BTSerial.write((byte)expo[2]); // экспозиция 3 BTSerial.write((byte)expo[3]); // экспозиция 4 // Serial.print("i"); // Serial.println(current_angle); } // инициализация экрана if (ncmd == 't') { // режим реального времени вкл rt= true; // ncmd = ' '; BTSerial.write(byte(current_angle)); // предаем по ВТ текущий угол //Serial.print("t"); //Serial.println(current_angle); } // режим реального времени вкл if (ncmd == 'x'){ // выход из RT ncmd = ' '; rt= false; // режим реального времени выкл BTSerial.write(byte(current_angle)); // предаем по ВТ текущий угол for (int i=1; i < 4; i = i + 1){ //обнуляем счетчики и флаги old_time_int[i]=millis(); old_time_exp[i]=millis(); exp_status[i]=false; } //обнуляем счетчики и флаги //Serial.println("x"); } // выход из RT if (ncmd == 'a'){ // едем на точку А ncmd = ' '; old_angle=current_angle; current_angle=point[0]; //Serial.print("a"); //Serial.println(current_angle); } // едем на точку А if (ncmd == 'b'){ // едем на точку B ncmd = ' '; old_angle=current_angle; current_angle=point[1]; //Serial.print("b"); //Serial.println(current_angle); } // едем на точку B if (ncmd == 'c'){ // едем на точку C ncmd = ' '; old_angle=current_angle; current_angle=point[2]; //Serial.print("c"); //Serial.println(current_angle); } // едем на точку C if (ncmd == 'd'){ // едем на точку D ncmd = ' '; old_angle=current_angle; current_angle=point[3]; //Serial.print("d"); //Serial.println(current_angle); } // едем на точку D if (ncmd == 'A'){ // сохранить точку A ncmd = ' '; while (!BTSerial.available()); // ждем данные point[0] = BTSerial.read(); // Читаем новый угол //Serial.println("A"); } // сохранить точку A if (ncmd == 'B'){ // сохранить точку B ncmd = ' '; while (!BTSerial.available()); // ждем данные point[1] = BTSerial.read(); // Читаем новый угол while (!BTSerial.available()); // ждем данные interval[1] = byte(BTSerial.read()); // Читаем новый интервал 2 while (!BTSerial.available()); // ждем данные expo[1] = byte(BTSerial.read()); // Читаем новый экспозиция 2 //Serial.println("B"); } // сохранить точку B if (ncmd == 'C'){ // сохранить точку C ncmd = ' '; while (!BTSerial.available()); // ждем данные point[2] = BTSerial.read(); // Читаем новый угол while (!BTSerial.available()); // ждем данные interval[2] = byte(BTSerial.read()); // Читаем новый интервал while (!BTSerial.available()); // ждем данные expo[2] = byte(BTSerial.read()); // Читаем новый экспозиция //Serial.println("C"); } // сохранить точку C if (ncmd == 'D'){ // сохранить точку D ncmd = ' '; while (!BTSerial.available()); // ждем данные point[3] = BTSerial.read(); // Читаем новый угол while (!BTSerial.available()); // ждем данные interval[3] = byte(BTSerial.read()); // Читаем новый интервал while (!BTSerial.available()); // ждем данные expo[3] = byte(BTSerial.read()); // Читаем новый экспозиция //Serial.println("D"); } // сохранить точку D } // Если есть данные BT if (old_angle>current_angle){ // если новый угол меньше старого motor.attach(10); // Подключаем серву на 10 пин for (int i=old_angle-1; i >= current_angle; i = i - degstep){ motor.write(i); Serial.println(i); delay(speed2go); } motor.detach(); old_angle=current_angle; } // если новый угол меньше старого if (old_angle<current_angle){ // если новый угол больше старого motor.attach(10); // Подключаем серву на 10 пин for (int i=old_angle+1; i <= current_angle; i = i + degstep){ motor.write(i); Serial.println(i); delay(speed2go); } motor.detach(); old_angle=current_angle; } // если новый угол больше старого if (!(rt)){ // если режим реального времени выключен крутим камеру по точкам for (int i=1; i < 4; i = i + 1){ //цикл по точкам if ( interval[i]>0){ // если точка задана timeX = (unsigned long)(old_time_int[i]+interval[i]*60000); if ( !(exp_status[i]) && millis()>timeX){ // если пора ехать на точку Serial.println(timeX); delay(100); old_angle=current_angle; current_angle=point[i]; old_time_exp[i]=(unsigned long)millis(); exp_status[i]=true; break; } // если пора ехать на точку timeX = (unsigned long)expo[i]*1000; timeX = (unsigned long)(old_time_exp[i] + timeX); if (exp_status[i] && millis()>timeX){ // если пора ехать на базу Serial.println(timeX); Serial.println(millis()); old_angle=current_angle; current_angle=point[0]; old_time_int[i]=millis(); exp_status[i]=false; } // если пора ехать на базу } // если точка задана } //цикл по точкам } // если режим реального времени выключен крутим камеру по точкам } ///-------------end---------------Пожалуйста!
Вот прога на андроид
https://yadi.sk/d/nYH67jxUyZoZz
исходник в аппинвенторе
https://yadi.sk/d/XUtpJltiyZoYZ
хороший проектик, спасибо за исходники
Не думали, как сделать автоматическое наведение на авто? :)
Об этом тоже думал ;) но пока не моего ума дело. очень уж сложно даже просто поток с камеры получить.
А если рассмотреть другие варианты?
1. В машине установить всенаправленный радиоизлучатель (например, на 433МГц), а на камере направленнный приемник, чтобы он подстраивал камеру под максимальный уровень сигнала.
2. В машине установить Arduino + GSM + GPS модули, они будут посылать координаты на сервер. А ардуинка с камеры (c Wi-Fi или Ethernet модулем) будет мониторить сервер и поворачивать камеру исходя из полученных координат.
Когда надоест и кнопки нажимать каждый раз, буду эти варианты пробовать.