이 프로젝트 정보
제 블루투스 제어 Nerf 터렛 프로젝트를 확인해 주셔서 감사합니다. 여기에서 설명할 것이 너무 많다고 생각하지 않습니다. 이것은 Android 기기나 PC에서 Bluetooth를 통해 제어되는 Nerf 포탑입니다.
..............https://www.littlefrenchkev.com/bluetooth-nerf-turret ........... .....
어떻게 작동합니까?
슈퍼 복잡한 것은 없습니다. 틸트 및 팬 이동은 Arduino Nano로 구동되는 2개의 서보에 의해 처리됩니다.
다트는 2개의 소형 DC 모터로 회전하는 2개의 롤러를 사용하여 쏘습니다. 사격 명령이 전송되면 서보가 다트를 롤러로 밀어 넣습니다. 탄창은 7개의 다트를 담을 수 있습니다.
위에서 언급했듯이 안드로이드 기기나 PC에서 블루투스를 통해 제어됩니다.
그것을 구축하는 방법?
조립:
삼각대와 매거진은 두 가지 버전으로 제공됩니다. 하나는 MG-90s 서보용으로, 다른 하나는 MG996r 서보용으로 설계되었습니다. MG996r 서보는 전력이 부족할 수 있습니다. 전원 공급 장치를 사용하기로 결정했다면 전원 공급 장치가 작업에 적합한지 확인하십시오.
삼각대:
잡지 :
배선:
소프트웨어 및 테스트 !!!
몇 장 추가 사진은 왜 안 되는지 !!!
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드"> 코드
<울> Arduino 코드
Arduino 코드Arduino
arduino에 업로드할 코드입니다. 안드로이드 앱을 통해 포탑을 제어하기로 선택하든 PC를 통해 제어하기로 선택하든 코드는 동일하게 유지됩니다.#include //-----서보 및 변수 선언Servo recoil_servo;Servo pan_servo;Servo tilt_servo;const 바이트 pan_limit_1 =0, const 바이트 pan_limit_2 =180, const 바이트 tilt_limit_1 =65, const 바이트 tilt_limit_2 =180, const 바이트 recoil_rest =180, // restconst에 있을 때 서보의 각도 byte recoil_pushed =125; // 서보가 다트를 푸시하기 위해 도달해야 하는 각도 //-----직렬 데이터 처리와 관련된 변수byte 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;//-----모터 타이밍 및 발사와 관련된 변수bool is_fireing =false;bool can_fire =false;bool 반동 =false;unsigned long firing_start_time =0;unsigned long firing_current_time =0;const long fire_time =150; unsigned long recoil_start_time =0; unsigned long recoil_current_time =0; const long recoil_time =2 * firing_time; const 바이트 motor_pin =12; 부울 모터_ON =false;//8============================Dvoid setup(){ //-----모터 핀 모드 정의 pinMode(motor_pin, OUTPUT); digitalWrite(모터 핀, LOW); //-----핀에 서보를 연결합니다. recoil_servo.attach(9); pan_servo.attach(10); tilt_servo.attach(11); //-----시작 시퀀스 recoil_servo.write(recoil_rest); pan_servo.write(90); 지연(1000); 틸트_서보.쓰기(105); Serial.begin(9600); // 직렬 통신 시작}//8==============================Dvoid loop(){ getDataFromPC(); set_motor(); if (data_received) { move_servo(); set_recoil(); set_motor(); } fire();}//8=============================Dvoid getDataFromPC() { //예상되는 데이터 구조 [시작 바이트 , 팬 양, 틸트 양, 모터 켜짐, 발사 버튼 눌림, 종료 바이트] //시작 바이트 =255 //팬 양 =0과 253 사이의 바이트 //틸트 양 =0과 253 사이의 바이트 //모터 켜짐 =0 for 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_fireing &&!recoiling) { //이미 발사하거나 반동하지 않고 can_fire =true; // true로 설정할 수 있음(void fire()의 효과 참조) } } else { // 발사 버튼을 누르지 않은 경우 can_fire =false; // false로 설정할 수 있습니다(void fire()의 효과 참조) }}//8============================Dvoid set_motor () { //----- MOSFET 트랜지스터를 사용하여 모터를 시작 및 중지합니다. if (inputBuffer[2] ==1) { //화면이 터치된 경우 digitalWrite(motor_pin, HIGH); //모터를 켭니다 motor_ON =true; } else { //화면이 터치되지 않은 경우 digitalWrite(motor_pin, LOW); //모터를 끕니다. motor_ON =false; }}//8============================Dvoid fire() { //모터 바이트가 켜져 있으면 모터를 켜고 다음을 확인합니다. 켜져 있었던 시간 if (can_fire &&!is_fireing &&motors_ON) { //if (can_fire &&!is_fireing) { firing_start_time =millis(); 반동_시작_시간 =밀리(); is_fireing =사실; } fireing_current_time =millis(); 반동_현재_시간 =millis(); if (is_fireing &&fireing_current_time - firing_start_time recoil_time) { is_fireing =false; }}
파이썬 파일
실행 및 안드로이드 앱은 여기에서 찾을 수 있습니다:https://www.littlefrenchkev.com/bluetooth-nerf-turrethttps://github.com/LittleFrenchKev/Bluetooth_Nerf_turret