Турель Bluetooth Nerf
Компоненты и расходные материалы
| | × | 1 | |
| | × | 1 | |
| Понижающий преобразователь LM2596 | | × | 1 | |
| | × | 3 | |
| двигатели постоянного тока 130 типа | | × | 2 | |
| выпрямительный диод FR207 | | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 30 | |
| Винт с потайной головкой M5 * 20 | | × | 4 | |
| | × | 15 | |
| металлический стержень 1,5 мм | | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| | × | 1 | |
| Источник питания 9 В (минимум 2,5 А) | | × | 1 | |
Приложения и онлайн-сервисы
Об этом проекте
Спасибо за проверку моего проекта турели Nerf, управляемой через Bluetooth. Я не думаю, что здесь слишком много объяснений, это турель Nerf, управляемая через Bluetooth либо с устройства Android, либо с ПК.
.................... https://www.littlefrenchkev.com/bluetooth-nerf-turret ............... .....
КАК ЭТО РАБОТАЕТ?
Ничего сверхсложного. Наклон и панорамирование осуществляются двумя сервоприводами, управляемыми Arduino Nano.
Дротики стреляют с помощью 2-х роликов, вращаемых 2-мя небольшими двигателями постоянного тока. Сервопривод толкает дротики в ролики, когда посылается команда стрелять. Магазин вмещает 7 дротиков.
Как упоминалось выше, им можно управлять через Bluetooth либо с устройства Android, либо с ПК.
КАК ПОСТРОИТЬ?
СБОРКА:
Штатив и магазин выпускаются в двух разных версиях. Один предназначен для сервоприводов MG-90, а другой - для сервоприводов MG996r. Сервоприводы MG996r могут потреблять много энергии. Если вы решите их использовать, убедитесь, что ваш источник питания соответствует требованиям.
Штатив:
Журнал:
ПРОВОДКА:
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ И ТЕСТ !!!
НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ ФОТО ПОТОМУ ЧТО НЕТ !!!
Код
Код Arduino Arduino
код для загрузки в Arduino. Код остается неизменным независимо от того, выберете ли вы управление турелью через приложение для Android или ПК. #include // ----- Объявление сервоприводов и переменных Servo recoil_servo; Servo pan_servo; Servo tilt_servo; const byte pan_limit_1 =0; const byte pan_limit_2 =180; const byte tilt_limit_1 =65; const byte tilt_limit_2 =180; const byte recoil_rest =180; // Угол сервопривода в состоянии покояconst byte recoil_pushing =125; // Угол, под которым сервопривод должен дотянуться до дротика // ----- Переменные, связанные с последовательной обработкой данных byte_from_app; const byte buffSize =30; byte inputBuffer [buffSize]; const byte startMarker =255; const byte endMarker =254; byte bytesRecvd =0; boolean data_received =false; // ----- Переменная, связанная с синхронизацией двигателя и зажиганием is_firing =false; bool can_fire =false; bool recoiling =false; unsigned long firing_start_time =0; unsigned long firing_current_time =0; const long firing_time =150; unsigned long recoil_start_time =0; unsigned long recoil_current_time =0; const long recoil_time =2 * firing_time; const byte motor_pin =12; boolean motors_ON =false; // 8 ===========================Dvoid setup () {// ----- определение режима вывода двигателя pinMode (motor_pin, OUTPUT); digitalWrite (motor_pin, LOW); // ----- подключает сервопривод к контактам recoil_servo.attach (9); pan_servo.attach (10); tilt_servo.attach (11); // ----- стартовая последовательность recoil_servo.write (recoil_rest); pan_servo.write (90); задержка (1000); tilt_servo.write (105); Serial.begin (9600); // начало последовательной связи} // 8 ===========================Dvoid loop () {getDataFromPC (); set_motor (); если (получено_данных) {переместить_власть (); set_recoil (); set_motor (); } fire ();} // 8 ===========================Dvoid getDataFromPC () {// ожидаемая структура данных [начальный байт , величина панорамирования, величина наклона, двигатель включен, кнопка запуска нажата, конечный байт] // начальный байт =255 // величина панорамирования =байт между 0 и 253 // величина наклона =байт между 0 и 253 // двигатель включен =0 для off - 1 on // кнопка активации нажата =0 для не нажатой - 1 для нажатой // end byte =254 if (Serial.available ()) {// Если данные доступны в последовательном интерфейсе byte_from_app =Serial.read (); // считываем следующий доступный символ if (byte_from_app ==255) {// ищем начальный байт, если найден:bytesRecvd =0; // сбрасываем полученный байт в 0 (чтобы начать заполнение inputBuffer с начала) data_received =false; } else if (byte_from_app ==254) {// ищем конечный байт, если он найден:data_received =true; // установить для data_received значение true, чтобы данные можно было использовать} else {// добавляем полученные байты в буфер inputBuffer [bytesRecvd] =byte_from_app; // добавляем символ во входной буфер bytesRecvd ++; // увеличить полученный байт (это действует как индекс) if (bytesRecvd ==buffSize) {// просто безопасность на случай, если inputBuffer заполнится (не должно происходить) bytesRecvd =buffSize - 1; // если bytesReceived> установленный размер буфера bytesReceived меньше, чем размер буфера}}}} // 8 ===========================Dvoid move_servo ( ) {byte pan_servo_position =map (inputBuffer [0], 0, 253, pan_limit_2, pan_limit_1); // конвертируем значение входного буфера в значение положения сервопривода pan_servo.write (pan_servo_position); // установка байта положения сервопривода панорамирования tilt_servo_position =map (inputBuffer [1], 0, 253, tilt_limit_2, tilt_limit_1); // конвертируем значение входного буфера в значение положения сервопривода tilt_servo.write (tilt_servo_position); // установка положения сервопривода панорамирования} // 8 ===========================Dvoid set_recoil () {if (inputBuffer [3] ==1) {// если кнопка огня нажата if (! Is_firing &&! Recoiling) {// и еще не стреляет или не откидывается can_fire =true; // установлено значение true (см. эффект в void fire ())}} else {// если кнопка огня не нажата can_fire =false; // set может стрелять в false (см. эффект в void fire ())}} // 8 ===========================Dvoid set_motor () {// ----- запускать и останавливать двигатели с помощью транзистора MOSFET. if (inputBuffer [2] ==1) {// если экран коснулся digitalWrite (motor_pin, HIGH); // включаем мотор motors_ON =true; } else {// если экран не касался digitalWrite (motor_pin, LOW); // выключаем двигатель motors_ON =false; }} // 8 ===========================Dvoid fire () {// если байт двигателя включен, включите двигатель и проверьте время было включено if (can_fire &&! is_firing &&motors_ON) {// if (can_fire &&! is_firing) {firing_start_time =millis (); recoil_start_time =миллис (); is_firing =истина; } firing_current_time =millis (); recoil_current_time =миллис (); if (is_firing &&firing_current_time - firing_start_time recoil_time) {is_firing =false; }}
файлы Python
Исполняемый файл и приложение для Android можно найти здесь:https://www.littlefrenchkev.com/bluetooth-nerf-turrethttps://github.com/LittleFrenchKev/Bluetooth_Nerf_turret Схема
Вот основная схема подключения.
Электропроводка разделена на небольшие секции, соединенные вместе с помощью соединителей Dupont. Это сделано для удобства сборки. Вот проводка Bluetooth HC-05.
Эта часть проводки включает в себя делитель напряжения, позволяющий снизить напряжение 5 В на выходе Arduino до примерно 3,3 В для вывода приемника HC-05.