Arduino硬體開發--紅外遙控舵機
阿新 • • 發佈:2019-01-11
硬體:Arduino uno板、紅外遙控器、紅外接收三極體、舵機、杜綁線;
埠:紅外接收管VOUT腳接11,舵機訊號接9;
效果:隨機按紅外遙控器1~9之間數字,對就舵機旋轉20、40、60、80、100、120、140、160、180度;
程式碼:
//接收紅外資訊,解碼獲取對應數字,控制舵機旋轉對應角度。 #include <IRremote.h>//紅外庫 int RECV_PIN = 11; //紅外接收VOUT引腳定義 int SERVOPIN = 9; //舵機驅動引腳定義 int myangle;//定義角度變數 int pulsewidth;//定義脈寬變數 //編碼示例遙控數字1~9代表舵機20-180角度 long d20 = 0x00ff30CF; long d40 = 0x00FF18E7; long d60 = 0x00FF7A85; long d80 = 0x00FF10EF; long d100 = 0x00FF38C7; long d120 = 0x00FF5AA5; long d140 = 0x00FF42BD; long d160 = 0x00FF4AB5; long d180 = 0x00FF52AD; IRrecv irrecv(RECV_PIN); decode_results results;//結構宣告 void setup() { // put your setup code here, to run once: pinMode(RECV_PIN, INPUT); //紅外VOUT埠模式,輸入 pinMode(SERVOPIN, OUTPUT); //舵機埠模式,輸出 Serial.begin(9600);//波特率9600 irrecv.enableIRIn();//開啟紅外接收 Serial.println("system is read now!"); } int on = 0; unsigned long last = millis(); void loop() { // put your main code here, to run repeatedly: if (irrecv.decode(&results)) { if (millis() - last > 250) { on = !on; digitalWrite(13, on ? HIGH : LOW); dump(&results); } if (results.value == d20) { Serial.println("20 degree"); startRun(20); } if (results.value == d40) { Serial.println("40 degree"); startRun(40); } if (results.value == d60) { Serial.println("60 degree"); startRun(60); } if (results.value == d80) { Serial.println("80 degree"); startRun(80); } if (results.value == d100) { Serial.println("100 degree"); startRun(100); } if (results.value == d120) { Serial.println("120 degree"); startRun(120); } if (results.value == d140) { Serial.println("140 degree"); startRun(140); } if (results.value == d160) { Serial.println("160 degree"); startRun(160); } if (results.value == d180) { Serial.println("180 degree"); startRun(180); } last = millis(); irrecv.resume(); } } void dump(decode_results *results) { int count = results->rawlen; if (results->decode_type == UNKNOWN) { Serial.println("Could not decode message"); } else { if (results->decode_type == NEC) { Serial.print("Decoded NEC: "); } else if (results->decode_type == SONY) { Serial.print("Decoded SONY: "); } else if (results->decode_type == RC5) { Serial.print("Decoded RC5: "); } else if (results->decode_type == RC6) { Serial.print("Decoded RC6: "); } Serial.print(results->value, HEX); Serial.print(" ("); Serial.print(results->bits, DEC); Serial.println(" bits)"); } Serial.print("Raw ("); Serial.print(count, DEC); Serial.print("): "); for (int i = 0; i < count; i++) { if ((i % 2) == 1) { Serial.print(results->rawbuf[i]*USECPERTICK, DEC); } else { Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); } Serial.print(" "); } Serial.println(""); } void servopulse(int servopin, int myangle) /*定義一個脈衝函式,用來模擬方式產生PWM值*/ { pulsewidth = (myangle * 11) + 500; //將角度轉化為500-2480 的脈寬值 digitalWrite(SERVOPIN, HIGH); //將舵機介面電平置高 delayMicroseconds(pulsewidth);//延時脈寬值的微秒數 digitalWrite(SERVOPIN, LOW); //將舵機介面電平置低 delay(20 - pulsewidth / 1000); //延時週期內剩餘時間 } void startRun(int degree) { if (degree > 0 && degree <= 180) //判斷收到資料值是否符合範圍 { //直接獲取旋轉角度 Serial.print("moving servo to "); Serial.print(degree, DEC); Serial.println(); for (int i = 0; i <= 50; i++) //產生PWM個數,等效延時以保證能轉到響應角度 { servopulse(SERVOPIN, degree); //模擬產生PWM } } }
總結:基本實現預期效果,但遙控器必須對準接收管才能執行動作,如果非對準,雖然接收到訊號,串列埠列印”Could not decode message“,還未發現原因。