// (C) 2015, Bridan Wang, CC BY-NC-SA 3.0 TW
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)
const byte IR_CODE[][18] PROGMEM = {
// X, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, *, #,up,dn,rt,lf,ok
0,22,25,13,12,24,94, 8,28,90,82,66,74,70,21,67,68,64,
0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
};
void (*FUNC_JUMP[])(void) = {
FUNC_N, // none
FUNC_1, // 1
FUNC_N, // FUNC_2, // 2
FUNC_3, // 3
FUNC_4, // 4
FUNC_N, // FUNC_5, // 5
FUNC_6, // 6
FUNC_N, // FUNC_7, // 7
FUNC_N, // FUNC_8, // 8
FUNC_N, // FUNC_9, // 9
FUNC_N, // FUNC_0, // 0
FUNC_S, // *
FUNC_P, // #
FUNC_N, // FUNC_U, // up
FUNC_N, // FUNC_D, // down
FUNC_R, // right
FUNC_L, // left
FUNC_N, // FUNC_K // ok
};
void PROCESS_10ms(void){
IR_CHECK();
if (A_IN(A4) < 200){ // right X
if (servo_set[2] > 120) servo_set[2]--;
}
else if (A_IN(A4) >= 800){
if (servo_set[2] < 160) servo_set[2]++;
else servo_hold[2] = 255;
}
else
servo_hold[2] = 0;
if (A_IN(A0) < 200){ // left Y
if (servo_set[4] > 60) servo_set[4]--;
}
else if (A_IN(A0) >= 800) {
if (servo_set[4] < 150) servo_set[4]++;
}
if (A_IN(A1) < 200){ // left X
if (servo_set[1] != 0) servo_set[1]--;
}
else if (A_IN(A1) >= 800){
if (servo_set[1] < 180) servo_set[1]++;
}
if (A_IN(A3) < 200){ // right Y
if (servo_set[3] > 60) servo_set[3]--;
}
else if (A_IN(A3) >= 800) {
if (servo_set[3] < 150) servo_set[3]++;
}
}
byte pre_ir;
byte ir_code;
byte step_no = 0;
void IR_CHECK() { // for KEYES IR
byte i;
byte j;
j = ir.key();
// Serial.print("IR - ");
// Serial.println(j);
if (j == pgm_read_byte(&IR_CODE[0][i])) {
if (pgm_read_byte(&IR_CODE[1][i])==0 || pre_ir!=j) {
pre_ir = ir_code;
if (pgm_read_byte(&IR_CODE[1][i])==0 || pre_ir!=j) {
pre_ir = ir_code;
ir_code = i;
(*FUNC_JUMP[i])();
break;
}
}
}
ir.loop();
}
{
}
void FUNC_1(void) // left Y
{
if (servo_set[4] < 150) servo_set[4]++;
}
void FUNC_4(void)
{
if (servo_set[4] > 60) servo_set[4]--;
}
void FUNC_3(void) // right Y
{
if (servo_set[3] < 150) servo_set[3]++;
}
void FUNC_6(void)
{
if (servo_set[3] > 60) servo_set[3]--;
}
void FUNC_S(void) // right X
{
if (servo_set[2] < 160) servo_set[2]++;
else servo_hold[2] = 255;
}
void FUNC_P(void)
{
if (servo_set[2] > 120) servo_set[2]--;
}
void FUNC_R(void) // left X
{
if (servo_set[1] != 0) servo_set[1]--;
}
void FUNC_L(void)
{
if (servo_set[1] < 180) servo_set[1]++;
}
除了參考前文 ROSA 系統開發 12 ─ SERVO 驅動及 ROSA 系統開發 13 ─ SERVO 多工同步控制程式碼外,紅外線接收器模組建議使用 pin D2,並把 IR_CHECK() 安插在 PROCESS_10ms(),如果把 IR_CHECK() 放在 PROCESS_100ms(),會感覺馬達轉動頓頓的,那是因為 100 ms 時間間隔太長轉動不連順,IR_CHECK()運用函數指標陣列 (Array of Function Pointers)技巧可直接跳至副程式執行,少了 switch case 判別式,程式碼看起來清爽許多。IR_CODE 陣列第一行儲存紅外線遙控碼,第二行儲存遙控碼是否被禁止連續發射,0 並未被禁止。
另外,PROCESS_10ms()有些與 FUNC_X()重複程式碼,在此先不整合,因為下一章節還會有程式改作。最後,引用 ROSA 系統開發 10 ─ 蜂鳴器 (Buzzer) 程式,將 mBot 紅外線遙控碼改成 KEYES 遙控器碼,然後定義遙控器按鍵功能,
KEY
|
FUNCTION
|
CODE
|
1
|
左側馬達前進
|
22
|
4
|
左側馬達後退
|
12
|
←
|
左旋
|
68
|
→
|
右轉
|
67
|
3
|
右側馬達前進
|
13
|
6
|
右側馬達後退
|
94
|
#
|
夾子開
|
74
|
*
|
夾子閉
|
66
|
pre_ir、ir_code 與 step_no 三變數是預留給程序控制使用的。
沒有留言:
張貼留言