找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7822|回復(fù): 1
收起左側(cè)

Arduino紅外遙控舵機(jī)代碼(帶LCD12864顯示)

[復(fù)制鏈接]
ID:426684 發(fā)表于 2018-12-9 17:30 | 顯示全部樓層 |閱讀模式
IMG_20181209_170405.jpg

硬件:


Arduino UNO

紅外遙控接受接受模塊

LCD12864 液晶顯示屏

紅外發(fā)射器


代碼:

#include "InfraredRemote.h"

#include "LCD12864RSPI.h"    //3,8,9 引腳

#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] )

unsigned char show0[]={0xBA, 0xEC,0xCD, 0xE2,0xD2, 0xA3,0xBF, 0xD8,0xB6, 0xE6,0xBB, 0xFA};    //紅外遙控舵機(jī)

unsigned char show1[]={0xD2, 0xA3,0xBF, 0xD8,0xD6, 0xB8,0xC1, 0xEE,0x3A, 0x00};                    //遙控指令:

unsigned char show2[]={0xD0, 0xFD,0xD7, 0xAA,0xBD, 0xC7,0xB6, 0xC8,0x3A, 0x00};                    //旋轉(zhuǎn)角度:

unsigned char show3[]={0x28, 0x00,0xB0, 0xB4,0x30, 0x00,0xB8, 0xB4,0xD4, 0xAD,0x29, 0x00};         //(按0復(fù)原)

#define PWM_pin 2                  //舵機(jī)引腳

int pulsewidth = 0;                      //高電平時間

char d[3];                                  //定義年值存儲數(shù)組,3位

void setup()

{

Serial.begin(9600);

pinMode(PWM_pin,OUTPUT);

pinMode(IR_IN,INPUT_PULLUP);//設(shè)置紅外接收引腳為輸入

Serial.flush(); //清除串口緩沖器內(nèi)容函數(shù)。

timer1_init();//定時器初始化

startRun(0);

LCDA.Initialise();

delay(100);

LCDA.DisplayString(0,1,show0,AR_SIZE(show0));

LCDA.DisplayString(1,0,show1,AR_SIZE(show1));

LCDA.DisplayString(1,5," ",AR_SIZE(" "));

LCDA.DisplayString(2,0,show2,AR_SIZE(show1));

LCDA.DisplayString(2,5,"0",AR_SIZE("0"));

LCDA.DisplayString(3,1,show3,AR_SIZE(show3));

}

void loop()

{

remote_decode(); //譯碼

if( adrL_code == 0x45 )  {

LCDA.DisplayString(1,5," 1 ",AR_SIZE(" 1 "));

//Serial.println("1");

startRun(10);

} else if( adrL_code == 0x46) {

LCDA.DisplayString(1,5," 2 ",AR_SIZE(" 2 "));

//Serial.println("2");

startRun(20);

}else if( adrL_code == 0x47 ) {

LCDA.DisplayString(1,5," 3 ",AR_SIZE(" 3 "));

//Serial.println("3");

startRun(30);

} else if( adrL_code == 0x44 )  {

LCDA.DisplayString(1,5," 4 ",AR_SIZE(" 4 "));

//Serial.println("4");

startRun(40);

} else if( adrL_code == 0x40 )  {

LCDA.DisplayString(1,5," 5 ",AR_SIZE(" 5 "));

//Serial.println("5");

startRun(50);

} else if( adrL_code == 0x43 )  {

LCDA.DisplayString(1,5," 6 ",AR_SIZE(" 6 "));

//Serial.println("6");

startRun(60);

} else if( adrL_code == 0x07 )  {

LCDA.DisplayString(1,5," 7 ",AR_SIZE(" 7 "));

//Serial.println("7");

startRun(70);

} else if( adrL_code == 0x15) {

LCDA.DisplayString(1,5," 8 ",AR_SIZE(" 8 "));

//Serial.println("8");

startRun(80);

} else if( adrL_code == 0x09 ){

LCDA.DisplayString(1,5," 9 ",AR_SIZE(" 9 "));

//Serial.println("9");

startRun(90);

} else if( adrL_code == 0x19) {

LCDA.DisplayString(1,5," 0 ",AR_SIZE(" 0 "));

//Serial.println("0");

startRun(0);

} else if( adrL_code == 0x16) {

LCDA.DisplayString(1,5," * ",AR_SIZE(" * "));

//Serial.println("*");

startRun(100);

} else if( adrL_code == 0x0d) {

LCDA.DisplayString(1,5," # ",AR_SIZE(" # "));

//Serial.println("#");

startRun(110);

} else if( adrL_code == 0x18) {

LCDA.DisplayString(1,5," Up",AR_SIZE(" Up"));

//Serial.println("Up");

startRun(120);

} else if( adrL_code == 0x08 ){

LCDA.DisplayString(1,5," L ",AR_SIZE(" L "));

//Serial.println("left");

startRun(130);

} else if( adrL_code == 0x1C ){

LCDA.DisplayString(1,5," OK",AR_SIZE(" OK"));

//Serial.println(" OK ");

startRun(140);

} else if(adrL_code == 0x5A)  {

LCDA.DisplayString(1,5," R ",AR_SIZE(" R "));

//Serial.println("Right");

startRun(150);

} else if( adrL_code == 0x52 )  {

LCDA.DisplayString(1,5," D ",AR_SIZE(" D "));

//Serial.println("Down");

startRun(160);

}

adrL_code = 0x00;

adrH_code = 0x00;

ir_code = 0x00;

}


void servopulse(int servopin, int myangle) /*定義一個脈沖函數(shù),用來模擬方式產(chǎn)生PWM值*/

{

pulsewidth = (myangle * 11) + 500; //將角度轉(zhuǎn)化為500-2480 的脈寬值

digitalWrite(servopin, HIGH); //將舵機(jī)接口電平置高

delayMicroseconds(pulsewidth);//延時脈寬值的微秒數(shù)

digitalWrite(servopin, LOW); //將舵機(jī)接口電平置低

delay(20 - pulsewidth / 1000); //延時周期內(nèi)剩余時間

}


void startRun(int degree) {

if (degree >= 0 && degree <= 180) //判斷收到數(shù)據(jù)值是否符合范圍

{

//直接獲取旋轉(zhuǎn)角度

dtostrf(degree,3,0,d);

LCDA.DisplayString(2,5,(unsigned char *)d,AR_SIZE(d));

//Serial.print("moving servo to ");

//Serial.print(degree, DEC);

//Serial.println();

for (int i = 0; i <= 50; i++) //產(chǎn)生PWM個數(shù),等效延時以保證能轉(zhuǎn)到響應(yīng)角度

{

servopulse(PWM_pin, degree); //模擬產(chǎn)生PWM

}

}

}



InfraredRemote.h

#ifndef __InfraredRemote__H__
#define __InfraredRemote__H__
#include <Arduino.h>
#define IR_IN 11 //紅外接收
extern void timer1_init(void);        //定時器初始化函數(shù)
extern char logic_value();//判斷邏輯值“0”和“1”子函數(shù)
extern void pulse_deal();//接收地址碼和命令碼脈沖函數(shù)
extern void remote_decode(void);
extern void remote_deal(void);//執(zhí)行譯碼結(jié)果函數(shù)
extern unsigned int ir_code;// 用戶編碼值
extern unsigned int adrL_code;//命令碼
extern unsigned int adrH_code;//命令碼反碼
#endif

InfraredRemote.cpp

#include "InfraredRemote.h"
int Pulse_Width = 0;//存儲脈寬
unsigned int ir_code = 0x00;// 用戶編碼值
unsigned int adrL_code = 0x00;//命令碼
unsigned int adrH_code = 0x00;//命令碼反碼
void timer1_init(void)//定時器初始化函數(shù)
{
        TCCR1A = 0X00;
        TCCR1B = 0X05;//給定時器時鐘源                        //64us進(jìn)行一次計數(shù)器累加
        TCCR1C = 0X00;
        TCNT1 = 0X00;
        TIMSK1 = 0X00;  //禁止定時器溢出中斷
}
void remote_deal(void)//執(zhí)行譯碼結(jié)果函數(shù)
{ //數(shù)據(jù)顯示
        Serial.print("\nir_code:");
        Serial.println(ir_code,HEX);//16進(jìn)制顯示
        Serial.print("adrL_code:");
        Serial.println(adrL_code,HEX);//16進(jìn)制顯示
        Serial.print("adrH_code:");
        Serial.println(adrH_code,HEX);//16進(jìn)制顯示
}
char logic_value()//判斷邏輯值“0”和“1”子函數(shù)
{
        TCNT1 = 0X00;
        while(!(digitalRead(IR_IN))); //低等待
        Pulse_Width=TCNT1;
        TCNT1=0;
        if(Pulse_Width>=7&&Pulse_Width<=10)//低電平560us
        {
                while(digitalRead(IR_IN));//是高就等待
                Pulse_Width=TCNT1;
                TCNT1=0;
                if(Pulse_Width>=7&&Pulse_Width<=10)//接著高電平560us
                        return 0;
                else if(Pulse_Width>=25&&Pulse_Width<=27) //接著高電平1.7ms
                        return 1;
        }
        return -1;
}
void pulse_deal()//接收地址碼和命令碼脈沖函數(shù)
{
        int i;
        int j;
        ir_code=0x00;// 清零
        adrL_code=0x00;// 清零
        adrH_code=0x00;// 清零
        //解析遙控器編碼中的用戶編碼值
        for(i = 0 ; i < 16; i++)
        {
                if(logic_value() == 1) //是1
                        ir_code |= (1<<i);//保存鍵值
        }
        //解析遙控器編碼中的命令碼
        for(i = 0 ; i < 8; i++)
        {
                if(logic_value() == 1) //是1
                        adrL_code |= (1<<i);//保存鍵值
        }
        //解析遙控器編碼中的命令碼反碼
        for(j = 0 ; j < 8; j++)
        {
                if(logic_value() == 1) //是1
                        adrH_code |= (1<<j);//保存鍵值
        }
        remote_deal();
}
void remote_decode(void)//譯碼函數(shù)
{
        TCNT1=0X00;
        while(digitalRead(IR_IN))//是高就等待
        {
                //if(TCNT1>=1563) //當(dāng)高電平持續(xù)時間超過100ms,表明此時沒有按鍵按下
                //{
                //        ir_code=0x00ff;// 用戶編碼值
                //        adrL_code=0x00;//鍵碼前一個字節(jié)值
                //        adrH_code=0x00;//鍵碼后一個字節(jié)值
                //        return;
                //}
        }
        //如果高電平持續(xù)時間不超過100ms
        TCNT1=0X00;
        while(!(digitalRead(IR_IN))); //低等待
        Pulse_Width=TCNT1;
        TCNT1=0;
        if(Pulse_Width>=140&&Pulse_Width<=141)//9ms
        {
                while(digitalRead(IR_IN));//是高就等待
                Pulse_Width=TCNT1;
                TCNT1=0;
                if(Pulse_Width>=68&&Pulse_Width<=72)//4.5ms
                {
                        pulse_deal();
                        return;
                }
                else if(Pulse_Width>=34&&Pulse_Width<=36)//2.25ms
                {
                        while(!(digitalRead(IR_IN)));//低等待
                        Pulse_Width=TCNT1;
                        TCNT1=0;
                        if(Pulse_Width>=7&&Pulse_Width<=10)//560us
                        {
                                return;
                        }
                }
        }
}




評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:389836 發(fā)表于 2019-5-31 09:09 | 顯示全部樓層
還能液晶顯示,真不錯,樓主這個庫能分享下嗎?LCD12864RSPI.h
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表