一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何測(cè)試紅外傳感器以確保其正常工作

454398 ? 來(lái)源:網(wǎng)絡(luò)整理 ? 作者:網(wǎng)絡(luò)整理 ? 2019-11-28 10:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

概述

如何測(cè)試紅外傳感器以確保其正常工作

在說(shuō)CdS光電管之間有一些區(qū)別:

IR檢測(cè)器經(jīng)過(guò)特殊過(guò)濾以用于紅外光,它們不擅長(zhǎng)檢測(cè)可見(jiàn)光。另一方面,光電管擅長(zhǎng)檢測(cè)黃/綠可見(jiàn)光,而不擅長(zhǎng)紅外光

紅外檢測(cè)器內(nèi)部有一個(gè)解調(diào)器,用于尋找38 KHz的調(diào)制IR。只是無(wú)法檢測(cè)到紅外LED發(fā)光,它必須以38KHz的PWM頻率閃爍。光電管沒(méi)有任何類(lèi)型的解調(diào)器,可以檢測(cè)到光電管響應(yīng)速度(大約1KHz)內(nèi)的任何頻率(包括DC)。

紅外檢測(cè)器是數(shù)字輸出的-它們可以檢測(cè)38KHz紅外信號(hào),輸出低電平(0V)或它們沒(méi)有檢測(cè)到并輸出高電平(5V)。光電管就像電阻一樣,電阻會(huì)根據(jù)它們所暴露的光量而變化

在本教程中,我們將展示如何

測(cè)試紅外傳感器以確保其正常工作

將原始IR代碼讀入微控制器

創(chuàng)建相機(jī)間隔計(jì)

從微控制器上的遙控器收聽(tīng)“命令”

某些統(tǒng)計(jì)信息

這些統(tǒng)計(jì)信息適用于Adafruit商店(也稱(chēng)為PNA4602)中的紅外探測(cè)器。幾乎所有光電管的規(guī)格都略有不同,盡管它們的工作原理幾乎相同。如果有數(shù)據(jù)表,您將需要參考它

尺寸:正方形,探測(cè)器面積7mm x 8mm

輸出:檢測(cè)到38KHz載波時(shí)為0V(低),否則為5V(高)

靈敏度范圍::800nm至1100nm,峰值響應(yīng)在940nm。頻率范圍為35KHz至41KHz,峰值檢測(cè)頻率為38KHz

電源: 3-5V DC 3mA

PNA4602數(shù)據(jù)表( (現(xiàn)已停產(chǎn))或 GP1UX311QS 或 TSOP38238 (與引腳兼容的替代品)

您可以測(cè)量的內(nèi)容

從這些數(shù)據(jù)表圖表中可以看到,峰值頻率檢測(cè)在 38 KHz ,峰值LED顏色為 940 nm 。您可以使用大約35 KHz至41 KHz的頻率,但靈敏度會(huì)下降,因此遠(yuǎn)距離也無(wú)法檢測(cè)到。同樣,您可以使用850至1100 nm的LED,但它們不能與900至1000nm的LED一樣工作,因此請(qǐng)確保獲得匹配的LED!

嘗試獲取940nm-記住940nm不是可見(jiàn)光(它的紅外光)!

測(cè)試IR傳感器

由于傳感器內(nèi)部有半導(dǎo)體/芯片,因此必須使用3-5V的電源才能正常工作。將其與光電池和FSR進(jìn)行對(duì)比,它們像電阻一樣發(fā)揮作用,因此可以用萬(wàn)用表簡(jiǎn)單地進(jìn)行測(cè)試。

在這里,我們將按以下方式連接檢測(cè)器:

Pin 1是輸出,因此我們將其接線連接到可見(jiàn)的LED和電阻器

引腳2接地

引腳3為VCC,連接到3-5V

當(dāng)檢測(cè)器看到IR時(shí)信號(hào),它將拉低輸出,從而打開(kāi)LED指示燈-由于LED指示燈為紅色,因此我們比IR更容易看到它!

我們將使用4節(jié)3號(hào)1.3V電池(我使用NiMH),以便為傳感器供電大約4V。

2個(gè)電池(3V)可能太少。如果您有三節(jié)AA電池座,則3塊電池應(yīng)該沒(méi)問(wèn)題

如果周?chē)幸粋€(gè)電池,也可以從Arduino等微控制器獲得5V電壓。接地連接到中間引腳。

紅色LED的正(較長(zhǎng))頭連接到+ 6V引腳,負(fù)(較短引線)通過(guò)200到1000歐姆的電阻連接到第一個(gè)引腳。

現(xiàn)在抓住電視,DVD,計(jì)算機(jī)等遙控器,將其指向檢測(cè)器,同時(shí)按下一些按鈕,每當(dāng)遙控器發(fā)出信號(hào)時(shí),LED應(yīng)該會(huì)閃爍兩次按下。

紅外遙控信號(hào)

現(xiàn)在我們知道傳感器可以正常工作了,我們想弄清楚發(fā)送的是什么嗎?但是在執(zhí)行此操作之前,我們首先要仔細(xì)檢查數(shù)據(jù)是如何從紅外遙控器(在您的手中)發(fā)送到紅外接收傳感器(在面包板上)的

在此示例中,我們將使用索尼電源/off來(lái)自Sony電視遙控器的IR代碼。它非常簡(jiǎn)單,并且經(jīng)常記錄在案!

假設(shè)我們有一個(gè)Sony遙控器,我們可以確切地查看從IR LED發(fā)射出的光。我們將連接一個(gè)基本的光傳感器(如基本的光電管?。┎⑦M(jìn)行監(jiān)聽(tīng)。我們不會(huì)使用像PNA4602這樣的解碼器(到目前為止),因?yàn)槲覀兿M吹轿唇獯a的信號(hào)。我們看到的是以下內(nèi)容:

基本上我們看到脈沖或IR信號(hào)。黃色的“塊”表示IR LED處于傳輸狀態(tài),而只有一條線時(shí),IR LED處于熄滅狀態(tài)。 (請(qǐng)注意,處于3VDC的電壓僅僅是由于我連接傳感器的方式,如果我將上拉交換為下拉,則它將在地面。)

第一個(gè)“塊”大約是2.5毫秒長(zhǎng)(請(qǐng)參見(jiàn)側(cè)面的光標(biāo)和測(cè)量值)

如果您放大這些塊之一……

您會(huì)發(fā)現(xiàn)它們并不是真正的“障礙”,而是非??斓拿}沖! p》

如果一直放大…

您可以測(cè)量IR脈沖的頻率。正如您可以從光標(biāo)和側(cè)面的測(cè)量值看出的那樣,頻率大約為37.04KHz

OK,因此現(xiàn)在我們可以了解如何發(fā)送IR代碼了。紅外發(fā)射器LED迅速以38KHz的高頻率脈沖化(PWM-脈寬調(diào)制),然后該P(yáng)WM同樣被慢速地脈沖化開(kāi)和關(guān),時(shí)間約為1-3 ms。

為什么不只打開(kāi)和關(guān)閉LED?為什么會(huì)有PWM“載波”脈沖?原因很多!

一個(gè)原因是,這會(huì)使LED冷卻。紅外LED最多可消耗1 A(1000毫安?。┑?a href="http://www.www27dydycom.cn/tags/電流/" target="_blank">電流。大多數(shù)LED僅占用20mA左右。這意味著IR LED是為大功率噴砂而設(shè)計(jì)的,但它們只能承受幾微秒的時(shí)間。通過(guò)PWM‘ing,可以讓LED冷卻一半的時(shí)間

另一個(gè)原因是電視將僅收聽(tīng)特定頻率的PWM。因此,在37KHz的Sony遙控器上無(wú)法使用僅要求50KHz的JVC DVD播放器。

最后,最重要的原因是通過(guò)對(duì)載波施加脈沖,可以減少環(huán)境照明的影響。電視只尋找時(shí)鐘頻率約為37KHz的亮度變化。就像對(duì)我們來(lái)說(shuō)分辨音頻音調(diào)之間的差異比確定音調(diào)的精確音高(至少對(duì)大多數(shù)人而言)一樣容易

好,所以現(xiàn)在我們知道了載波頻率。其37KHz。接下來(lái)讓我們找到脈沖寬度!

回頭看第一張示波器圖片

第一個(gè)脈沖為2.5毫秒。我們可以使用光標(biāo)來(lái)測(cè)量剩余的脈沖。我將為您保留12張圖像,讓您知道脈沖是:

PWM ON 關(guān)閉

2.4毫秒0.6毫秒

1.2 ms0.6 ms

0.6 ms0.6 ms

1.2 ms0.6 ms

0.6 ms0.6 ms

1.2 ms0.6 ms

0.6 ms0.6 ms

0.6毫秒0.6毫秒

1.2毫秒0.6毫秒

0.6毫秒0.6毫秒

0.6毫秒0.6毫秒

0.6毫秒0.6毫秒

0.6毫秒270毫秒

因此,假設(shè)您沒(méi)有價(jià)格為$ 1000的示波器,您還能如何讀取這些信號(hào)?像PNA4602這樣的IR解碼器很好地幫了我們一個(gè)忙,它“濾出”了38KHz信號(hào),因此我們只能得到毫粘范圍內(nèi)的大信號(hào)塊。對(duì)于微控制器來(lái)說(shuō),這要容易得多。那就是我們?cè)谙乱还?jié)中要做的!

使用紅外傳感器

好消息是,連接此傳感器非常容易。只需將輸出連接到數(shù)字引腳即可。壞消息是,Arduino的友好的 digitalRead()程序太慢了,無(wú)法可靠地讀取快速信號(hào),因此我們直接從引腳D2使用硬件引腳讀取功能,這就是行“ IRpin_PIN&BV(IRpin))”。此技巧特定于基于ATmega328的板,例如Arduino Uno,Adafruit Metro等。

完全組裝的Adafruit METRO 328-兼容Arduino IDE

產(chǎn)品ID:50

我們肯定喜歡Adafruit的ATmega328,并且將lota用于我們自己的項(xiàng)目。該處理器具有大量的GPIO,模擬輸入,硬件UART SPI和I2C,。。.

$ 17.50

入庫(kù)

添加到購(gòu)物車(chē)

下載:Project Zip 或 ir_codes。 ino | 在Github上查看

復(fù)制代碼

/* Raw IR decoder sketch!

This sketch/program uses the Arduno and a PNA4602 to

decode IR received. This can be used to make a IR receiver

(by looking for a particular code)

or transmitter (by pulsing an IR LED at ~38KHz for the

durations detected

Code is public domain, check out www.ladyada.net and adafruit.com

for more tutorials!

*/

// We need to use the ’raw‘ pin reading methods

// because timing is very important here and the digitalRead()

// procedure is slower!

//uint8_t IRpin = 2;

// Digital pin #2 is the same as Pin D2 see

// http://arduino.cc/en/Hacking/PinMapping168 for the ’raw‘ pin mapping

#define IRpin_PIN PIND

#define IRpin 2

// the maximum pulse we’ll listen for - 65 milliseconds is a long time

#define MAXPULSE 65000

// what our timing resolution should be, larger is better

// as its more ‘precise’ - but too large and you wont get

// accurate timing

#define RESOLUTION 20

// we will store up to 100 pulse pairs (this is -a lot-)

uint16_t pulses[100][2]; // pair is high and low pulse

uint8_t currentpulse = 0; // index for pulses we‘re storing

void setup(void) {

Serial.begin(9600);

Serial.println(“Ready to decode IR!”);

}

void loop(void) {

uint16_t highpulse, lowpulse; // temporary storage timing

highpulse = lowpulse = 0; // start out with no pulse length

// while (digitalRead(IRpin)) { // this is too slow!

while (IRpin_PIN & (1 《《 IRpin)) {

// pin is still HIGH

// count off another few microseconds

highpulse++;

delayMicroseconds(RESOLUTION);

// If the pulse is too long, we ’timed out‘ - either nothing

// was received or the code is finished, so print what

// we’ve grabbed so far, and then reset

if ((highpulse 》= MAXPULSE) && (currentpulse != 0)) {

printpulses();

currentpulse=0;

return;

}

}

// we didn‘t time out so lets stash the reading

pulses[currentpulse][0] = highpulse;

// same as above

while (! (IRpin_PIN & _BV(IRpin))) {

// pin is still LOW

lowpulse++;

delayMicroseconds(RESOLUTION);

if ((lowpulse 》= MAXPULSE) && (currentpulse != 0)) {

printpulses();

currentpulse=0;

return;

}

}

pulses[currentpulse][1] = lowpulse;

// we read one high-low pulse successfully, continue!

currentpulse++;

}

void printpulses(void) {

Serial.println(“ Received: OFF ON”);

for (uint8_t i = 0; i 《 currentpulse; i++) {

Serial.print(pulses[i][0] * RESOLUTION, DEC);

Serial.print(“ usec, ”);

Serial.print(pulses[i][1] * RESOLUTION, DEC);

Serial.println(“ usec”);

}

// print it in a ’array‘ format

Serial.println(“int IRsignal[] = {”);

Serial.println(“// ON, OFF ”);

for (uint8_t i = 0; i 《 currentpulse-1; i++) {

//Serial.print(“ ”); // tab

Serial.print(“pulseIR(”);

Serial.print(pulses[i][1] * RESOLUTION , DEC);

Serial.print(“);”);

Serial.println(“”);

//Serial.print(“ ”);

Serial.print(“delayMicroseconds(”);

Serial.print(pulses[i+1][0] * RESOLUTION , DEC);

Serial.println(“);”);

}

//Serial.print(“ ”); // tab

Serial.print(“pulseIR(”);

Serial.print(pulses[currentpulse-1][1] * RESOLUTION, DEC);

Serial.print(“);”);

}

/* Raw IR decoder sketch!

This sketch/program uses the Arduno and a PNA4602 to

decode IR received. This can be used to make a IR receiver

(by looking for a particular code)

or transmitter (by pulsing an IR LED at ~38KHz for the

durations detected

Code is public domain, check out www.ladyada.net and adafruit.com

for more tutorials!

*/

// We need to use the ’raw‘ pin reading methods

// because timing is very important here and the digitalRead()

// procedure is slower!

//uint8_t IRpin = 2;

// Digital pin #2 is the same as Pin D2 see

// http://arduino.cc/en/Hacking/PinMapping168 for the ’raw‘ pin mapping

#define IRpin_PIN PIND

#define IRpin 2

// the maximum pulse we’ll listen for - 65 milliseconds is a long time

#define MAXPULSE 65000

// what our timing resolution should be, larger is better

// as its more ‘precise’ - but too large and you wont get

// accurate timing

#define RESOLUTION 20

// we will store up to 100 pulse pairs (this is -a lot-)

uint16_t pulses[100][2]; // pair is high and low pulse

uint8_t currentpulse = 0; // index for pulses we‘re storing

void setup(void) {

Serial.begin(9600);

Serial.println(“Ready to decode IR!”);

}

void loop(void) {

uint16_t highpulse, lowpulse; // temporary storage timing

highpulse = lowpulse = 0; // start out with no pulse length

// while (digitalRead(IRpin)) { // this is too slow!

while (IRpin_PIN & (1 《《 IRpin)) {

// pin is still HIGH

// count off another few microseconds

highpulse++;

delayMicroseconds(RESOLUTION);

// If the pulse is too long, we ’timed out‘ - either nothing

// was received or the code is finished, so print what

// we’ve grabbed so far, and then reset

if ((highpulse 》= MAXPULSE) && (currentpulse != 0)) {

printpulses();

currentpulse=0;

return;

}

}

// we didn‘t time out so lets stash the reading

pulses[currentpulse][0] = highpulse;

// same as above

while (! (IRpin_PIN & _BV(IRpin))) {

// pin is still LOW

lowpulse++;

delayMicroseconds(RESOLUTION);

if ((lowpulse 》= MAXPULSE) && (currentpulse != 0)) {

printpulses();

currentpulse=0;

return;

}

}

pulses[currentpulse][1] = lowpulse;

// we read one high-low pulse successfully, continue!

currentpulse++;

}

void printpulses(void) {

Serial.println(“ Received: OFF ON”);

for (uint8_t i = 0; i 《 currentpulse; i++) {

Serial.print(pulses[i][0] * RESOLUTION, DEC);

Serial.print(“ usec, ”);

Serial.print(pulses[i][1] * RESOLUTION, DEC);

Serial.println(“ usec”);

}

// print it in a ’array‘ format

Serial.println(“int IRsignal[] = {”);

Serial.println(“// ON, OFF ”);

for (uint8_t i = 0; i 《 currentpulse-1; i++) {

//Serial.print(“ ”); // tab

Serial.print(“pulseIR(”);

Serial.print(pulses[i][1] * RESOLUTION , DEC);

Serial.print(“);”);

Serial.println(“”);

//Serial.print(“ ”);

Serial.print(“delayMicroseconds(”);

Serial.print(pulses[i+1][0] * RESOLUTION , DEC);

Serial.println(“);”);

}

//Serial.print(“ ”); // tab

Serial.print(“pulseIR(”);

Serial.print(pulses[currentpulse-1][1] * RESOLUTION, DEC);

Serial.print(“);”);

}

如果您在指向Sony IR遙控器并按下ON按鈕的同時(shí)運(yùn)行此程序,則會(huì)得到以下內(nèi)容。。.

如果您忽略第一個(gè)OFF脈沖(這只是從Arduino開(kāi)始的時(shí)間打開(kāi)第一個(gè)接收到的IR信號(hào))和最后一個(gè)打開(kāi)脈沖(即下一個(gè)代碼的開(kāi)始),您會(huì)找到Sony電源代碼:

PWM開(kāi)啟關(guān)閉

2.5 ms0.6毫秒

1.2 ms0.6 ms

0.6 ms0.6 ms

1.2 ms0.6 ms

0.6 ms0.6 ms

1.2 ms0.6 ms

0.6 ms0.6 ms

0.6 ms0.6 ms

1.2 ms0.6 ms

0.6 ms0.6 ms

0.6 ms0.6 ms

0.6毫秒0.6毫秒

0.6毫秒27.2毫秒

現(xiàn)在,我們可以讀取紅外代碼了,制作一個(gè)間隔計(jì)

好,讓我們做一個(gè)基礎(chǔ)項(xiàng)目。我們要做的第一個(gè)是制作一個(gè)間隔計(jì)。間隔計(jì)基本上是一種電子設(shè)備,可使照相機(jī)每隔幾分鐘左右關(guān)閉一次。這可以用于游戲中時(shí)光倒流項(xiàng)目或風(fēng)箏攝影或其他照片項(xiàng)目。

我們將要使用的相機(jī)具有一個(gè)紅外遙控器,您可以將其關(guān)閉(大多數(shù)高端相機(jī)都有)。

首先我們要弄清楚通過(guò)讀取按下按鈕時(shí)發(fā)送的信號(hào)來(lái)讀出代碼。然后,我們將獲取這些數(shù)據(jù),并使Arduino每分鐘一次將該代碼輸出到IR LED中。

好,第一步很簡(jiǎn)單,將遙控器對(duì)準(zhǔn)IR傳感器,然后按一下按鈕,我們得到了

看起來(lái)像發(fā)送的數(shù)據(jù)是:

PWM ON OFF

2.0 ms27 ms

0.4 ms1.5 ms

0.5 ms3.5 ms

0.5 ms62.2毫秒

2.0毫秒27毫秒

0.5毫秒1.5毫秒

0.5毫秒3.5毫秒

0.5 ms

如果仔細(xì)觀察,您會(huì)發(fā)現(xiàn)它實(shí)際上只是

PWM ON OFF

2.0 ms27 ms

0.4毫秒1.5毫秒

0.5毫秒3.5毫秒

0.5毫秒62.2毫秒

已發(fā)送兩次。兩次發(fā)送相同的信號(hào)是很常見(jiàn)的-加倍以確保收到信號(hào)

下一步,我們需要將940nm IR LED連接到Arduino的輸出

然后我們將寫(xiě)一個(gè)草圖

下載: Project Zip 或 intervalometer.ino | 在Github上查看

復(fù)制代碼

// This sketch will send out a Nikon D50 trigger signal (probably works with most Nikons)

// See the full tutorial at https://learn.adafruit.com/ir-sensor/making-an-intervalometer

// MIT License, attribution appreciated Limor Fried, Adafruit Industries

int IRledPin = 13; // LED connected to digital pin 13

// The setup() method runs once, when the sketch starts

void setup() {

// initialize the IR digital pin as an output:

pinMode(IRledPin, OUTPUT);

Serial.begin(9600);

}

void loop()

{

Serial.println(“Sending IR signal”);

SendNikonCode();

delay(60*1000); // wait one minute (60 seconds * 1000 milliseconds)

}

// This procedure sends a 38KHz pulse to the IRledPin

// for a certain # of microseconds. We’ll use this whenever we need to send codes

void pulseIR(long microsecs) {

// we‘ll count down from the number of microseconds we are told to wait

cli(); // this turns off any background interrupts

while (microsecs 》 0) {

// 38 kHz is about 13 microseconds high and 13 microseconds low

digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen

delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working

digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds

delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working

// so 26 microseconds altogether

microsecs -= 26;

}

sei(); // this turns them back on

}

void SendNikonCode() {

// This is the code for my particular Nikon, for others use the tutorial

// to ’grab‘ the proper code from the remote

pulseIR(2080);

delay(27);

pulseIR(440);

delayMicroseconds(1500);

pulseIR(460);

delayMicroseconds(3440);

pulseIR(480);

delay(65); // wait 65 milliseconds before sending it again

pulseIR(2000);

delay(27);

pulseIR(440);

delayMicroseconds(1500);

pulseIR(460);

delayMicroseconds(3440);

pulseIR(480);

}

// This sketch will send out a Nikon D50 trigger signal (probably works with most Nikons)

// See the full tutorial at https://learn.adafruit.com/ir-sensor/making-an-intervalometer

// MIT License, attribution appreciated Limor Fried, Adafruit Industries

int IRledPin = 13; // LED connected to digital pin 13

// The setup() method runs once, when the sketch starts

void setup() {

// initialize the IR digital pin as an output:

pinMode(IRledPin, OUTPUT);

Serial.begin(9600);

}

void loop()

{

Serial.println(“Sending IR signal”);

SendNikonCode();

delay(60*1000); // wait one minute (60 seconds * 1000 milliseconds)

}

// This procedure sends a 38KHz pulse to the IRledPin

// for a certain # of microseconds. We’ll use this whenever we need to send codes

void pulseIR(long microsecs) {

// we‘ll count down from the number of microseconds we are told to wait

cli(); // this turns off any background interrupts

while (microsecs 》 0) {

// 38 kHz is about 13 microseconds high and 13 microseconds low

digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen

delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working

digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds

delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working

// so 26 microseconds altogether

microsecs -= 26;

}

sei(); // this turns them back on

}

void SendNikonCode() {

// This is the code for my particular Nikon, for others use the tutorial

// to ’grab‘ the proper code from the remote

pulseIR(2080);

delay(27);

pulseIR(440);

delayMicroseconds(1500);

pulseIR(460);

delayMicroseconds(3440);

pulseIR(480);

delay(65); // wait 65 milliseconds before sending it again

pulseIR(2000);

delay(27);

pulseIR(440);

delayMicroseconds(1500);

pulseIR(460);

delayMicroseconds(3440);

pulseIR(480);

}

void pulseIR(long microsecs)是我們的幫助程序,它將像之前看到的那樣創(chuàng)建PWM IR信號(hào)。我使用示波器進(jìn)行了微調(diào),以使延遲加起來(lái)正確。我們使用不常討論的cli()和sei()過(guò)程關(guān)閉中斷。 Arduino在后臺(tái)執(zhí)行了一些操作,例如尋找要讀取或?qū)懭氲拇袛?shù)據(jù),跟蹤時(shí)間等。大多數(shù)情況下,我們可以忽略它,但是對(duì)于像這樣的微妙的高速信號(hào),我們希望保持安靜,以便我們會(huì)得到一個(gè)很好的干凈信號(hào)

如果您查看SendNikonCode(),您將看到我們?cè)谏弦粋€(gè)項(xiàng)目中通過(guò)對(duì)來(lái)自紅外傳感器的脈沖進(jìn)行計(jì)時(shí)推導(dǎo)出的IR命令代碼。

并且效果很好,請(qǐng)確保將IR LED正確對(duì)準(zhǔn)相機(jī)。

讀取IR命令

對(duì)于我們的最終項(xiàng)目,我們將使用遙控器將消息發(fā)送到微控制器。例如,這對(duì)于可以用IR遙控器控制的機(jī)器人可能很有用。這對(duì)于想要在遠(yuǎn)處無(wú)需電線控制的項(xiàng)目也可能是好的。您可以使用任何所需的遙控器,也可以從毫無(wú)戒心的行家那里竊取其中之一。

我們將使用之前草圖中的代碼進(jìn)行原始紅外讀取,但是這次我們將編輯打印機(jī)的外部它為我們提供了C數(shù)組中的脈沖,這將使我們更易于用于模式匹配。

下載:文件

復(fù)制代碼

void printpulses(void) {

Serial.println(“ Received: OFF ON”);

for (uint8_t i = 0; i 《 currentpulse; i++) {

Serial.print(pulses[i][0] * RESOLUTION, DEC);

Serial.print(“ usec, ”);

Serial.print(pulses[i][1] * RESOLUTION, DEC);

Serial.println(“ usec”);

}

// print it in a ’array‘ format

Serial.println(“int IRsignal[] = {”);

Serial.println(“// ON, OFF (in 10’s of microseconds)”);

for (uint8_t i = 0; i 《 currentpulse-1; i++) {

Serial.print(“ ”); // tab

Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);

Serial.print(“, ”);

Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);

Serial.println(“,”);

}

Serial.print(“ ”); // tab

Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);

Serial.print(“, 0};”);

} void printpulses(void) {

Serial.println(“ Received: OFF ON”);

for (uint8_t i = 0; i 《 currentpulse; i++) {

Serial.print(pulses[i][0] * RESOLUTION, DEC);

Serial.print(“ usec, ”);

Serial.print(pulses[i][1] * RESOLUTION, DEC);

Serial.println(“ usec”);

}

// print it in a ‘a(chǎn)rray’ format

Serial.println(“int IRsignal[] = {”);

Serial.println(“// ON, OFF (in 10‘s of microseconds)”);

for (uint8_t i = 0; i 《 currentpulse-1; i++) {

Serial.print(“ ”); // tab

Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);

Serial.print(“, ”);

Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);

Serial.println(“,”);

}

Serial.print(“ ”); // tab

Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);

Serial.print(“, 0};”);

}

我上傳了新草圖,并按了 Play Apple遙控器上的按鈕并獲得以下內(nèi)容:

下載:文件

復(fù)制代碼

int IRsignal[] = { // ON, OFF (in 10’s of microseconds)

912, 438,

68, 48,

68, 158,

68, 158,

68, 158,

68, 48,

68, 158,

68, 158,

68, 158,

70, 156,

70, 158,

68, 158,

68, 48,

68, 46,

70, 46,

68, 46,

68, 160,

68, 158,

70, 46,

68, 158,

68, 46,

70, 46,

68, 48,

68, 46,

68, 48,

66, 48,

68, 48,

66, 160,

66, 50,

66, 160,

66, 52,

64, 160,

66, 48,

66, 3950,

908, 214,

66, 3012,

908, 212,

68, 0}; int IRsignal[] = { // ON, OFF (in 10‘s of microseconds)

912, 438,

68, 48,

68, 158,

68, 158,

68, 158,

68, 48,

68, 158,

68, 158,

68, 158,

70, 156,

70, 158,

68, 158,

68, 48,

68, 46,

70, 46,

68, 46,

68, 160,

68, 158,

70, 46,

68, 158,

68, 46,

70, 46,

68, 48,

68, 46,

68, 48,

66, 48,

68, 48,

66, 160,

66, 50,

66, 160,

66, 52,

64, 160,

66, 48,

66, 3950,

908, 214,

66, 3012,

908, 212,

68, 0};

我們將嘗試檢測(cè)該代碼。

讓我們開(kāi)始一個(gè)名為 IR Commander的新草圖(您可以從GitHub下方的綠色按鈕下載最終代碼,或在完整的代碼列表中單擊Download Project Zip)。

打開(kāi)此頁(yè)面上代碼的GitHub存儲(chǔ)庫(kù)

下載:Project Zip 或 ircommander.ino | 在Github上查看

復(fù)制代碼

/* Raw IR commander

This sketch/program uses the Arduno and a PNA4602 to

decode IR received. It then attempts to match it to a previously

recorded IR signal. Limor Fried, Adafruit Industries

MIT License, please attribute

check out learn.adafruit.com for more tutorials!

*/

// We need to use the ’raw‘ pin reading methods

// because timing is very important here and the digitalRead()

// procedure is slower!

//uint8_t IRpin = 2;

// Digital pin #2 is the same as Pin D2 see

// http://arduino.cc/en/Hacking/PinMapping168 for the ’raw‘ pin mapping

#define IRpin_PIN PIND

#define IRpin 2

// the maximum pulse we’ll listen for - 65 milliseconds is a long time

#define MAXPULSE 65000

#define NUMPULSES 50

// what our timing resolution should be, larger is better

// as its more ‘precise’ - but too large and you wont get

// accurate timing

#define RESOLUTION 20

// What percent we will allow in variation to match the same code

#define FUZZINESS 20

// we will store up to 100 pulse pairs (this is -a lot-)

uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse

uint8_t currentpulse = 0; // index for pulses we‘re storing

#include “ircommander.h”

void setup(void) {

Serial.begin(9600);

Serial.println(“Ready to decode IR!”);

}

void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

if (IRcompare(numberpulses, ApplePlaySignal,sizeof(ApplePlaySignal)/4)) {

Serial.println(“PLAY”);

}

if (IRcompare(numberpulses, AppleRewindSignal,sizeof(AppleRewindSignal)/4)) {

Serial.println(“REWIND”);

}

if (IRcompare(numberpulses, AppleForwardSignal,sizeof(AppleForwardSignal)/4)) {

Serial.println(“FORWARD”);

}

delay(500);

}

//KGO: added size of compare sample. Only compare the minimum of the two

boolean IRcompare(int numpulses, int Signal[], int refsize) {

int count = min(numpulses,refsize);

Serial.print(“count set to: ”);

Serial.println(count);

for (int i=0; i《 count-1; i++) {

int oncode = pulses[i][1] * RESOLUTION / 10;

int offcode = pulses[i+1][0] * RESOLUTION / 10;

#ifdef DEBUG

Serial.print(oncode); // the ON signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 0]); // the ON signal we want

#endif

// check to make sure the error is less than FUZZINESS percent

if ( abs(oncode - Signal[i*2 + 0]) 《= (Signal[i*2 + 0] * FUZZINESS / 100)) {

#ifdef DEBUG

Serial.print(“ (ok)”);

#endif

} else {

#ifdef DEBUG

Serial.print(“ (x)”);

#endif

// we didn’t match perfectly, return a false match

return false;

}

#ifdef DEBUG

Serial.print(“ ”); // tab

Serial.print(offcode); // the OFF signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 1]); // the OFF signal we want

#endif

if ( abs(offcode - Signal[i*2 + 1]) 《= (Signal[i*2 + 1] * FUZZINESS / 100)) {

#ifdef DEBUG

Serial.print(“ (ok)”);

#endif

} else {

#ifdef DEBUG

Serial.print(“ (x)”);

#endif

// we didn‘t match perfectly, return a false match

return false;

}

#ifdef DEBUG

Serial.println();

#endif

}

// Everything matched!

return true;

}

int listenForIR(void) {

currentpulse = 0;

while (1) {

uint16_t highpulse, lowpulse; // temporary storage timing

highpulse = lowpulse = 0; // start out with no pulse length

// while (digitalRead(IRpin)) { // this is too slow!

while (IRpin_PIN & (1 《《 IRpin)) {

// pin is still HIGH

// count off another few microseconds

highpulse++;

delayMicroseconds(RESOLUTION);

// If the pulse is too long, we ’timed out‘ - either nothing

// was received or the code is finished, so print what

// we’ve grabbed so far, and then reset

// KGO: Added check for end of receive buffer

if (((highpulse 》= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {

return currentpulse;

}

}

// we didn‘t time out so lets stash the reading

pulses[currentpulse][0] = highpulse;

// same as above

while (! (IRpin_PIN & _BV(IRpin))) {

// pin is still LOW

lowpulse++;

delayMicroseconds(RESOLUTION);

// KGO: Added check for end of receive buffer

if (((lowpulse 》= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {

return currentpulse;

}

}

pulses[currentpulse][1] = lowpulse;

// we read one high-low pulse successfully, continue!

currentpulse++;

}

}

void printpulses(void) {

Serial.println(“ Received: OFF ON”);

for (uint8_t i = 0; i 《 currentpulse; i++) {

Serial.print(pulses[i][0] * RESOLUTION, DEC);

Serial.print(“ usec, ”);

Serial.print(pulses[i][1] * RESOLUTION, DEC);

Serial.println(“ usec”);

}

// print it in a ’array‘ format

Serial.println(“int IRsignal[] = {”);

Serial.println(“// ON, OFF (in 10’s of microseconds)”);

for (uint8_t i = 0; i 《 currentpulse-1; i++) {

Serial.print(“ ”); // tab

Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);

Serial.print(“, ”);

Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);

Serial.println(“,”);

}

Serial.print(“ ”); // tab

Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);

Serial.print(“, 0};”);

}

/* Raw IR commander

This sketch/program uses the Arduno and a PNA4602 to

decode IR received. It then attempts to match it to a previously

recorded IR signal. Limor Fried, Adafruit Industries

MIT License, please attribute

check out learn.adafruit.com for more tutorials!

*/

// We need to use the ‘raw’ pin reading methods

// because timing is very important here and the digitalRead()

// procedure is slower!

//uint8_t IRpin = 2;

// Digital pin #2 is the same as Pin D2 see

// http://arduino.cc/en/Hacking/PinMapping168 for the ‘raw’ pin mapping

#define IRpin_PIN PIND

#define IRpin 2

// the maximum pulse we‘ll listen for - 65 milliseconds is a long time

#define MAXPULSE 65000

#define NUMPULSES 50

// what our timing resolution should be, larger is better

// as its more ’precise‘ - but too large and you wont get

// accurate timing

#define RESOLUTION 20

// What percent we will allow in variation to match the same code

#define FUZZINESS 20

// we will store up to 100 pulse pairs (this is -a lot-)

uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse

uint8_t currentpulse = 0; // index for pulses we’re storing

#include “ircommander.h”

void setup(void) {

Serial.begin(9600);

Serial.println(“Ready to decode IR!”);

}

void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

if (IRcompare(numberpulses, ApplePlaySignal,sizeof(ApplePlaySignal)/4)) {

Serial.println(“PLAY”);

}

if (IRcompare(numberpulses, AppleRewindSignal,sizeof(AppleRewindSignal)/4)) {

Serial.println(“REWIND”);

}

if (IRcompare(numberpulses, AppleForwardSignal,sizeof(AppleForwardSignal)/4)) {

Serial.println(“FORWARD”);

}

delay(500);

}

//KGO: added size of compare sample. Only compare the minimum of the two

boolean IRcompare(int numpulses, int Signal[], int refsize) {

int count = min(numpulses,refsize);

Serial.print(“count set to: ”);

Serial.println(count);

for (int i=0; i《 count-1; i++) {

int oncode = pulses[i][1] * RESOLUTION / 10;

int offcode = pulses[i+1][0] * RESOLUTION / 10;

#ifdef DEBUG

Serial.print(oncode); // the ON signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 0]); // the ON signal we want

#endif

// check to make sure the error is less than FUZZINESS percent

if ( abs(oncode - Signal[i*2 + 0]) 《= (Signal[i*2 + 0] * FUZZINESS / 100)) {

#ifdef DEBUG

Serial.print(“ (ok)”);

#endif

} else {

#ifdef DEBUG

Serial.print(“ (x)”);

#endif

// we didn‘t match perfectly, return a false match

return false;

}

#ifdef DEBUG

Serial.print(“ ”); // tab

Serial.print(offcode); // the OFF signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 1]); // the OFF signal we want

#endif

if ( abs(offcode - Signal[i*2 + 1]) 《= (Signal[i*2 + 1] * FUZZINESS / 100)) {

#ifdef DEBUG

Serial.print(“ (ok)”);

#endif

} else {

#ifdef DEBUG

Serial.print(“ (x)”);

#endif

// we didn’t match perfectly, return a false match

return false;

}

#ifdef DEBUG

Serial.println();

#endif

}

// Everything matched!

return true;

}

int listenForIR(void) {

currentpulse = 0;

while (1) {

uint16_t highpulse, lowpulse; // temporary storage timing

highpulse = lowpulse = 0; // start out with no pulse length

// while (digitalRead(IRpin)) { // this is too slow!

while (IRpin_PIN & (1 《《 IRpin)) {

// pin is still HIGH

// count off another few microseconds

highpulse++;

delayMicroseconds(RESOLUTION);

// If the pulse is too long, we ‘timed out’ - either nothing

// was received or the code is finished, so print what

// we‘ve grabbed so far, and then reset

// KGO: Added check for end of receive buffer

if (((highpulse 》= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {

return currentpulse;

}

}

// we didn’t time out so lets stash the reading

pulses[currentpulse][0] = highpulse;

// same as above

while (! (IRpin_PIN & _BV(IRpin))) {

// pin is still LOW

lowpulse++;

delayMicroseconds(RESOLUTION);

// KGO: Added check for end of receive buffer

if (((lowpulse 》= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {

return currentpulse;

}

}

pulses[currentpulse][1] = lowpulse;

// we read one high-low pulse successfully, continue!

currentpulse++;

}

}

void printpulses(void) {

Serial.println(“ Received: OFF ON”);

for (uint8_t i = 0; i 《 currentpulse; i++) {

Serial.print(pulses[i][0] * RESOLUTION, DEC);

Serial.print(“ usec, ”);

Serial.print(pulses[i][1] * RESOLUTION, DEC);

Serial.println(“ usec”);

}

// print it in a ‘a(chǎn)rray’ format

Serial.println(“int IRsignal[] = {”);

Serial.println(“// ON, OFF (in 10‘s of microseconds)”);

for (uint8_t i = 0; i 《 currentpulse-1; i++) {

Serial.print(“ ”); // tab

Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);

Serial.print(“, ”);

Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);

Serial.println(“,”);

}

Serial.print(“ ”); // tab

Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);

Serial.print(“, 0};”);

}

下載:Project Zip 或 ircommander .h | 在Github上查看

復(fù)制代碼

/******************* our codes ************/

int ApplePlaySignal[] = {

// ON, OFF (in 10’s of microseconds)

912, 438,

68, 48,

68, 158,

68, 158,

68, 158,

68, 48,

68, 158,

68, 158,

68, 158,

70, 156,

70, 158,

68, 158,

68, 48,

68, 46,

70, 46,

68, 46,

68, 160,

68, 158,

70, 46,

68, 158,

68, 46,

70, 46,

68, 48,

68, 46,

68, 48,

66, 48,

68, 48,

66, 160,

66, 50,

66, 160,

66, 50,

64, 160,

66, 50,

66, 3950,

908, 214,

66, 3012,

908, 212,

68, 0};

int AppleForwardSignal[] = {

// ON, OFF (in 10‘s of microseconds)

908, 444,

64, 50,

66, 162,

64, 162,

64, 162,

64, 52,

64, 162,

64, 162,

64, 162,

64, 164,

62, 164,

64, 162,

64, 52,

62, 52,

64, 52,

64, 50,

64, 164,

64, 50,

64, 164,

64, 162,

64, 50,

66, 50,

66, 50,

64, 50,

66, 50,

64, 52,

64, 50,

66, 160,

66, 50,

64, 162,

66, 50,

64, 162,

64, 50,

66, 3938,

906, 214,

66, 3014,

906, 214,

64, 0};

int AppleRewindSignal[] = {

// ON, OFF (in 10’s of microseconds)

908, 442,

66, 48,

66, 162,

66, 160,

66, 160,

66, 50,

66, 160,

66, 160,

66, 160,

68, 158,

68, 160,

66, 160,

66, 50,

66, 48,

66, 50,

66, 48,

66, 162,

66, 160,

66, 48,

68, 48,

66, 160,

66, 50,

66, 50,

66, 48,

66, 50,

66, 48,

68, 48,

66, 160,

66, 50,

66, 160,

66, 50,

66, 160,

66, 48,

68, 3936,

906, 214,

66, 0};

/******************* our codes ************/

int ApplePlaySignal[] = {

// ON, OFF (in 10‘s of microseconds)

912, 438,

68, 48,

68, 158,

68, 158,

68, 158,

68, 48,

68, 158,

68, 158,

68, 158,

70, 156,

70, 158,

68, 158,

68, 48,

68, 46,

70, 46,

68, 46,

68, 160,

68, 158,

70, 46,

68, 158,

68, 46,

70, 46,

68, 48,

68, 46,

68, 48,

66, 48,

68, 48,

66, 160,

66, 50,

66, 160,

66, 50,

64, 160,

66, 50,

66, 3950,

908, 214,

66, 3012,

908, 212,

68, 0};

int AppleForwardSignal[] = {

// ON, OFF (in 10’s of microseconds)

908, 444,

64, 50,

66, 162,

64, 162,

64, 162,

64, 52,

64, 162,

64, 162,

64, 162,

64, 164,

62, 164,

64, 162,

64, 52,

62, 52,

64, 52,

64, 50,

64, 164,

64, 50,

64, 164,

64, 162,

64, 50,

66, 50,

66, 50,

64, 50,

66, 50,

64, 52,

64, 50,

66, 160,

66, 50,

64, 162,

66, 50,

64, 162,

64, 50,

66, 3938,

906, 214,

66, 3014,

906, 214,

64, 0};

int AppleRewindSignal[] = {

// ON, OFF (in 10‘s of microseconds)

908, 442,

66, 48,

66, 162,

66, 160,

66, 160,

66, 50,

66, 160,

66, 160,

66, 160,

68, 158,

68, 160,

66, 160,

66, 50,

66, 48,

66, 50,

66, 48,

66, 162,

66, 160,

66, 48,

68, 48,

66, 160,

66, 50,

66, 50,

66, 48,

66, 50,

66, 48,

68, 48,

66, 160,

66, 50,

66, 160,

66, 50,

66, 160,

66, 48,

68, 3936,

906, 214,

66, 0};

此代碼使用了先前草圖的一部分。我們要做的第一部分是創(chuàng)建一個(gè)函數(shù),該函數(shù)只偵聽(tīng)I(yíng)R代碼,并將脈沖時(shí)序放入 pulses [] 數(shù)組中。它將返回它聽(tīng)到的脈沖數(shù)作為返回值。

下載:文件

復(fù)制代碼

int listenForIR(void) {

currentpulse = 0;

while (1) {

uint16_t highpulse, lowpulse; // temporary storage timing

highpulse = lowpulse = 0; // start out with no pulse length

// while (digitalRead(IRpin)) { // this is too slow!

while (IRpin_PIN & (1 《《 IRpin)) {

// pin is still HIGH

// count off another few microseconds

highpulse++;

delayMicroseconds(RESOLUTION);

// If the pulse is too long, we ’timed out‘ - either nothing

// was received or the code is finished, so print what

// we’ve grabbed so far, and then reset

if ((highpulse 》= MAXPULSE) && (currentpulse != 0)) {

return currentpulse;

}

}

// we didn‘t time out so lets stash the reading

pulses[currentpulse][0] = highpulse;

// same as above

while (! (IRpin_PIN & _BV(IRpin))) {

// pin is still LOW

lowpulse++;

delayMicroseconds(RESOLUTION);

if ((lowpulse 》= MAXPULSE) && (currentpulse != 0)) {

return currentpulse;

}

}

pulses[currentpulse][1] = lowpulse;

// we read one high-low pulse successfully, continue!

currentpulse++;

}

} int listenForIR(void) {

currentpulse = 0;

while (1) {

uint16_t highpulse, lowpulse; // temporary storage timing

highpulse = lowpulse = 0; // start out with no pulse length

// while (digitalRead(IRpin)) { // this is too slow!

while (IRpin_PIN & (1 《《 IRpin)) {

// pin is still HIGH

// count off another few microseconds

highpulse++;

delayMicroseconds(RESOLUTION);

// If the pulse is too long, we ’timed out‘ - either nothing

// was received or the code is finished, so print what

// we’ve grabbed so far, and then reset

if ((highpulse 》= MAXPULSE) && (currentpulse != 0)) {

return currentpulse;

}

}

// we didn‘t time out so lets stash the reading

pulses[currentpulse][0] = highpulse;

// same as above

while (! (IRpin_PIN & _BV(IRpin))) {

// pin is still LOW

lowpulse++;

delayMicroseconds(RESOLUTION);

if ((lowpulse 》= MAXPULSE) && (currentpulse != 0)) {

return currentpulse;

}

}

pulses[currentpulse][1] = lowpulse;

// we read one high-low pulse successfully, continue!

currentpulse++;

}

}

我們新的循環(huán)() 開(kāi)始只是聽(tīng)脈沖

下載:文件

復(fù)制代碼

void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

} void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

}

運(yùn)行此命令時(shí),它將打印出類(lèi)似。。.

確定時(shí)間,讓草圖將收到的數(shù)據(jù)與存儲(chǔ)數(shù)組中的數(shù)據(jù)進(jìn)行比較:

如您所見(jiàn),會(huì)有一些變化。因此,當(dāng)我們進(jìn)行比較時(shí),我們無(wú)法精確找到相同的值,我們必須有點(diǎn)“模糊”。我們會(huì)說(shuō)值可以相差20%-應(yīng)該足夠了。

下載:文件

復(fù)制代碼

// What percent we will allow in variation to match the same code \ #define FUZZINESS 20

void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

for (int i=0; i《 numberpulses-1; i++) {

int oncode = pulses[i][1] * RESOLUTION / 10;

int offcode = pulses[i+1][0] * RESOLUTION / 10;

Serial.print(oncode); // the ON signal we heard

Serial.print(“ - ”);

Serial.print(ApplePlaySignal[i*2 + 0]); // the ON signal we want

// check to make sure the error is less than FUZZINESS percent

if ( abs(oncode - ApplePlaySignal[i*2 + 0]) 《= (oncode * FUZZINESS / 100)) {

Serial.print(“ (ok)”);

} else {

Serial.print(“ (x)”);

}

Serial.print(“ ”); // tab

Serial.print(offcode); // the OFF signal we heard

Serial.print(“ - ”);

Serial.print(ApplePlaySignal[i*2 + 1]); // the OFF signal we want

if ( abs(offcode - ApplePlaySignal[i*2 + 1]) 《= (offcode * FUZZINESS / 100)) {

Serial.print(“ (ok)”);

} else {

Serial.print(“ (x)”);

}

Serial.println();

}

} // What percent we will allow in variation to match the same code \ #define FUZZINESS 20

void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

for (int i=0; i《 numberpulses-1; i++) {

int oncode = pulses[i][1] * RESOLUTION / 10;

int offcode = pulses[i+1][0] * RESOLUTION / 10;

Serial.print(oncode); // the ON signal we heard

Serial.print(“ - ”);

Serial.print(ApplePlaySignal[i*2 + 0]); // the ON signal we want

// check to make sure the error is less than FUZZINESS percent

if ( abs(oncode - ApplePlaySignal[i*2 + 0]) 《= (oncode * FUZZINESS / 100)) {

Serial.print(“ (ok)”);

} else {

Serial.print(“ (x)”);

}

Serial.print(“ ”); // tab

Serial.print(offcode); // the OFF signal we heard

Serial.print(“ - ”);

Serial.print(ApplePlaySignal[i*2 + 1]); // the OFF signal we want

if ( abs(offcode - ApplePlaySignal[i*2 + 1]) 《= (offcode * FUZZINESS / 100)) {

Serial.print(“ (ok)”);

} else {

Serial.print(“ (x)”);

}

Serial.println();

}

}

此循環(huán)在經(jīng)歷每個(gè)脈沖時(shí)都會(huì)做一些數(shù)學(xué)運(yùn)算。它將比較我們聽(tīng)到的代碼和我們嘗試匹配的代碼之間的絕對(duì)( abs())差異(oncode-ApplePlaySignal [i * 2 + 0]),然后確保錯(cuò)誤小于代碼長(zhǎng)度的FUZZINESS百分比(oncode * FUZZINESS/100)

我們發(fā)現(xiàn)我們必須對(duì)存儲(chǔ)的值進(jìn)行一些調(diào)整,以使它們每次都匹配100%。 IR不是一個(gè)精確定時(shí)的協(xié)議,因此必須使FUZZINESS達(dá)到20%或更多不是一件壞事

最后,我們可以將 loop()轉(zhuǎn)換為自己的功能根據(jù)其是否匹配我們要求的代碼,它們將返回 true 或 false 。我們還注釋了打印功能

下載:文件

復(fù)制代碼

boolean IRcompare(int numpulses, int Signal[]) {

for (int i=0; i《 numpulses-1; i++) {

int oncode = pulses[i][1] * RESOLUTION / 10;

int offcode = pulses[i+1][0] * RESOLUTION / 10;

/*

Serial.print(oncode); // the ON signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 0]); // the ON signal we want

*/

// check to make sure the error is less than FUZZINESS percent

if ( abs(oncode - Signal[i*2 + 0]) 《= (Signal[i*2 + 0] * FUZZINESS / 100)) {

//Serial.print(“ (ok)”);

} else {

//Serial.print(“ (x)”);

// we didn’t match perfectly, return a false match

return false;

}

/*

Serial.print(“ ”); // tab

Serial.print(offcode); // the OFF signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 1]); // the OFF signal we want

*/

if ( abs(offcode - Signal[i*2 + 1]) 《= (Signal[i*2 + 1] * FUZZINESS / 100)) {

//Serial.print(“ (ok)”);

} else {

//Serial.print(“ (x)”);

// we didn‘t match perfectly, return a false match

return false;

}

//Serial.println();

}

// Everything matched!

return true;

} boolean IRcompare(int numpulses, int Signal[]) {

for (int i=0; i《 numpulses-1; i++) {

int oncode = pulses[i][1] * RESOLUTION / 10;

int offcode = pulses[i+1][0] * RESOLUTION / 10;

/*

Serial.print(oncode); // the ON signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 0]); // the ON signal we want

*/

// check to make sure the error is less than FUZZINESS percent

if ( abs(oncode - Signal[i*2 + 0]) 《= (Signal[i*2 + 0] * FUZZINESS / 100)) {

//Serial.print(“ (ok)”);

} else {

//Serial.print(“ (x)”);

// we didn’t match perfectly, return a false match

return false;

}

/*

Serial.print(“ ”); // tab

Serial.print(offcode); // the OFF signal we heard

Serial.print(“ - ”);

Serial.print(Signal[i*2 + 1]); // the OFF signal we want

*/

if ( abs(offcode - Signal[i*2 + 1]) 《= (Signal[i*2 + 1] * FUZZINESS / 100)) {

//Serial.print(“ (ok)”);

} else {

//Serial.print(“ (x)”);

// we didn‘t match perfectly, return a false match

return false;

}

//Serial.println();

}

// Everything matched!

return true;

}

然后,我們?yōu)椤暗箮А焙汀翱爝M(jìn)”按鈕獲取了更多的IR命令數(shù)據(jù),并將所有代碼數(shù)組數(shù)據(jù)放入了 ircodes.h ,以防止主草圖太長(zhǎng)且不可讀(您可以從github獲取所有代碼)

最后,主循環(huán)如下所示:

下載:文件

復(fù)制代碼

void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

if (IRcompare(numberpulses, ApplePlaySignal)) {

Serial.println(“PLAY”);

}

if (IRcompare(numberpulses, AppleRewindSignal)) {

Serial.println(“REWIND”);

}

if (IRcompare(numberpulses, AppleForwardSignal)) {

Serial.println(“FORWARD”);

}

} void loop(void) {

int numberpulses;

numberpulses = listenForIR();

Serial.print(“Heard ”);

Serial.print(numberpulses);

Serial.println(“-pulse long IR signal”);

if (IRcompare(numberpulses, ApplePlaySignal)) {

Serial.println(“PLAY”);

}

if (IRcompare(numberpulses, AppleRewindSignal)) {

Serial.println(“REWIND”);

}

if (IRcompare(numberpulses, AppleForwardSignal)) {

Serial.println(“FORWARD”);

}

}

我們會(huì)根據(jù)所有已知的代碼進(jìn)行檢查,并在得到匹配項(xiàng)時(shí)將其打印出來(lái)。現(xiàn)在,您可以使用此代碼并將其轉(zhuǎn)換為其他內(nèi)容,例如根據(jù)所按下按鈕移動(dòng)的機(jī)器人。

測(cè)試后,成功!

CircuitPython

使用CircuitPython,您可以輕松地從Python代碼讀取紅外傳感器脈沖。內(nèi)置于CircuitPython中的是一個(gè)特殊的pulseio模塊,該模塊實(shí)際上為您完成了讀取快速I(mǎi)R接收器脈沖的大部分工作。使用Python代碼甚至更好,您可以非常輕松地存儲(chǔ)和處理大量的脈沖長(zhǎng)度列表。甚至還有一個(gè)方便的Adafruit CircuitPython IRRemote模塊,該模塊簡(jiǎn)化了一些用于讀取通用遙控器的處理邏輯。 CircuitPython使讀取紅外信號(hào)變得非常容易!

硬件和設(shè)置

要讀取原始的IR信號(hào),您需要將IR傳感器連接到板上,如前頁(yè)所示。在此示例中,我們假設(shè)傳感器輸出連接到您板上的引腳D2。

如上所述,您還需要在CircuitPython板上安裝Adafruit CircuitPython IRRemote庫(kù)。

首先請(qǐng)確保為您的電路板運(yùn)行最新版本的Adafruit CircuitPython。

接下來(lái),您需要安裝必要的庫(kù)以使用硬件-仔細(xì)按照以下步驟從Adafruit的CircuitPython中查找和安裝這些庫(kù)庫(kù)包。我們的簡(jiǎn)介指南上有一個(gè)很棒的頁(yè)面,介紹如何為快速和非表達(dá)板安裝庫(kù)包。

請(qǐng)記住非表達(dá)板,例如,您需要從束中手動(dòng)安裝必要的庫(kù):

adafruit_irremote.mpy

,或從Adafruit CircuitPython IRRemote版本頁(yè)面上的最新版本下載文件。

在繼續(xù)之前,請(qǐng)確保您開(kāi)發(fā)板的lib文件夾或根文件系統(tǒng)已復(fù)制 adafruit_irremote.mpy 模塊。

用法

下一步連接到開(kāi)發(fā)板的串行REPL,因此您位于CircuitPython 》》》

然后導(dǎo)入必要的 board 和 pulseio 模塊:

下載:文件

復(fù)制代碼

import board

import pulseio import board

import pulseio

現(xiàn)在創(chuàng)建PulseIn類(lèi)的實(shí)例,該實(shí)例讀取pu來(lái)自紅外傳感器的輸出。脈沖只是從高到低的變化,反之亦然,而PulseIn類(lèi)將記錄每個(gè)脈沖的微秒持續(xù)時(shí)間。讓我們創(chuàng)建一個(gè)脈沖輸入,它可以記住最多200個(gè)脈沖的持續(xù)時(shí)間(足以記錄大多數(shù)遠(yuǎn)程控制代碼):

下載:文件

復(fù)制代碼

pulses = pulseio.PulseIn(board.D2, maxlen=200, idle_state=True) pulses = pulseio.PulseIn(board.D2, maxlen=200, idle_state=True)

讓我們分解所有傳入的參數(shù)到PulseIn初始化程序:

板針-這是必填參數(shù),用于指示哪個(gè)針連接到IR接收器的輸出。

maxlen -指定要記錄的脈沖持續(xù)時(shí)間數(shù)。對(duì)于大多數(shù)遙控器,值200足以存儲(chǔ)足夠的脈沖持續(xù)時(shí)間。如果將此值設(shè)置得太高,則可能會(huì)使用超出板子可用空間的內(nèi)存,因此請(qǐng)謹(jǐn)慎選擇使用的值。

idle_state -這是一個(gè)布爾值,表示“默認(rèn)或脈沖引腳的空閑狀態(tài)。對(duì)于IR接收器,它們通常在高邏輯或True狀態(tài)下處于空閑狀態(tài),因此將idle_state設(shè)置為T(mén)rue表示正常狀態(tài)為高邏輯電平。

一旦有了脈沖輸入對(duì)象,便可以與之交互好像它是持續(xù)時(shí)間值的列表一樣。在內(nèi)部,PulseIn類(lèi)始終在偵聽(tīng)來(lái)自引腳的脈沖(即,從當(dāng)前的高/低邏輯電平到相反的電平變化),并保存脈沖的持續(xù)時(shí)間。您可以列出接收到的脈沖數(shù),就像讀取列表的長(zhǎng)度一樣:

下載:文件

復(fù)制代碼

len(pulses) len(pulses)

值為零表示傳感器尚未接收到脈沖。嘗試將遙控器對(duì)準(zhǔn)傳感器,然后按一個(gè)按鈕。然后再次讀取脈沖長(zhǎng)度:

下載:文件

復(fù)制代碼

len(pulses) len(pulses)

現(xiàn)在我們需要研究一些脈沖持續(xù)時(shí)間!首先,讓我們告訴脈沖類(lèi)暫時(shí)停止監(jiān)聽(tīng)脈沖。這很有用,這樣您就可以在最后看到的脈沖上進(jìn)行操作,而不會(huì)引起其他脈沖增加更多的噪聲或偽像:

下載:文件

復(fù)制代碼

pulses.pause() pulses.pause()

現(xiàn)在,通過(guò)讀取以下值來(lái)研究一些脈沖持續(xù)時(shí)間:如果脈沖對(duì)象是一個(gè)列表。例如,讀取前三個(gè)持續(xù)時(shí)間:

下載:文件

復(fù)制代碼

pulses[0]

pulses[1]

pulses[2] pulses[0]

pulses[1]

pulses[2]

每個(gè)持續(xù)時(shí)間是指脈沖處于特定邏輯電平的時(shí)間(以毫秒為單位)。第一個(gè)脈沖的最大值為65535,因?yàn)樗韨鞲衅鞯却}沖開(kāi)始的時(shí)間(即,處于默認(rèn)高邏輯電平空閑狀態(tài)的時(shí)間)。就像上一頁(yè)中的Arduino代碼一樣,您可以忽略第一個(gè)值。

接下來(lái)的兩個(gè)值很有趣,下一個(gè)脈沖值顯示傳感器接收到的脈沖長(zhǎng)約9毫秒(約9000)微秒)。然后,傳感器在約4毫秒內(nèi)未收到脈沖。這對(duì)值代表一個(gè)脈沖和遙控信號(hào)的開(kāi)始。最好看到?9ms開(kāi)和?4m關(guān)的值,因?yàn)檫@是IR碼的常見(jiàn)序言或開(kāi)始!

事實(shí)證明,這對(duì)脈沖在不同的遙控器之間如此常見(jiàn),以至于其中許多可以用類(lèi)似的代碼讀取。 Adafruit CircuitPython IRRemote庫(kù)是一個(gè)非常簡(jiǎn)單的IR遠(yuǎn)程控制解碼庫(kù),可簡(jiǎn)化許多脈沖和遠(yuǎn)程解碼邏輯。讓我們使用此模塊簡(jiǎn)化脈沖分析,首先將其導(dǎo)入,然后創(chuàng)建一個(gè)遠(yuǎn)程解碼器:

下載:文件

復(fù)制代碼

import adafruit_irremote

decoder = adafruit_irremote.GenericDecode() import adafruit_irremote

decoder = adafruit_irremote.GenericDecode()

解碼器類(lèi)使您可以輕松地等待并從遙控器上讀取脈沖列表。在使用前,請(qǐng)重新打開(kāi)脈沖輸入(記住它當(dāng)前已暫停)并清除其先前的輸入:

下載:文件

復(fù)制代碼

pulses.clear()

pulses.resume() pulses.clear()

pulses.resume()

現(xiàn)在,我們可以使用解碼器等待并返回脈沖了。運(yùn)行此代碼,并注意REPL停止并等待進(jìn)一步的輸入:

下載:文件

復(fù)制代碼

pulse = decoder.read_pulses(pulses) pulse = decoder.read_pulses(pulses)

將遙控器對(duì)準(zhǔn)接收器,然后按一個(gè)按鈕。您應(yīng)該看到REPL恢復(fù)正常運(yùn)行。這意味著解碼器能夠檢測(cè)到紅外遠(yuǎn)程信號(hào)并返回脈沖值的原始列表。

此脈沖列表是一個(gè)數(shù)組,其中包含來(lái)自接收器的每個(gè)高和低脈沖的長(zhǎng)度(以微秒為單位)。例如,您可以使用標(biāo)準(zhǔn)陣列長(zhǎng)度和打印操作來(lái)檢查檢測(cè)到多少脈沖變化并查看其長(zhǎng)度:

下載:文件

復(fù)制代碼

len(pulse)

pulse len(pulse)

pulse

解碼器在內(nèi)部執(zhí)行的一項(xiàng)非常有用的操作是檢測(cè)并忽略噪聲或無(wú)關(guān)的脈沖寬度,例如在檢測(cè)到遙控器之前較長(zhǎng)的起始脈沖寬度。這非常有用,因?yàn)樗?jiǎn)化了您的IR處理代碼-您可以集中精力查看“清理”的脈沖長(zhǎng)度!

嘗試記錄第二個(gè)脈沖:

下載:文件

復(fù)制代碼

pulse2 = decoder.read_pulses(pulses) pulse2 = decoder.read_pulses(pulses)

記住 read_pulses 函數(shù)將等待檢測(cè)到遠(yuǎn)程控制按下(或者如果以前發(fā)生過(guò)但未進(jìn)行處理,它將代替它)。按下遙控器上的同一按鈕可產(chǎn)生與第一次按下類(lèi)似的脈沖:

現(xiàn)在讓我們比較第一個(gè)和第二個(gè)脈沖列表,看它們是否匹配。一個(gè)簡(jiǎn)單的比較可能是檢查每個(gè)列表中的每個(gè)值并驗(yàn)證它們是否相同。讓我們用定義的簡(jiǎn)單Python函數(shù)進(jìn)行嘗試:

下載:文件

復(fù)制代碼

def simple_pulse_compare(pulse1, pulse2):

if len(pulse1) != len(pulse2):

return False

for i in range(len(pulse1)):

if pulse1[i] != pulse2[i]:

return False

return True

simple_pulse_compare(pulse, pulse2) def simple_pulse_compare(pulse1, pulse2):

if len(pulse1) != len(pulse2):

return False

for i in range(len(pulse1)):

if pulse1[i] != pulse2[i]:

return False

return True

simple_pulse_compare(pulse, pulse2)

哦,不,比較失敗并返回false!發(fā)生了什么,沒(méi)有按下相同的按鈕?事實(shí)證明,脈沖之間的時(shí)序可以以很小的方式變化。如果查看每個(gè)陣列的單個(gè)脈沖長(zhǎng)度,您會(huì)發(fā)現(xiàn)它們很接近,但并不完全相同。如果您比較原始脈沖,則需要添加一個(gè)“模糊性”來(lái)比較接近但不完全相同的值。

讓我們創(chuàng)建一個(gè)新的模糊比較功能,該功能將檢查彼此接近的脈沖(例如,彼此相差20%以?xún)?nèi)):

下載:文件

復(fù)制代碼

def fuzzy_pulse_compare(pulse1, pulse2, fuzzyness=0.2):

if len(pulse1) != len(pulse2):

return False

for i in range(len(pulse1)):

threshold = int(pulse1[i] * fuzzyness)

if abs(pulse1[i] - pulse2[i]) 》 threshold:

return False

return True

fuzzy_pulse_compare(pulse, pulse2) def fuzzy_pulse_compare(pulse1, pulse2, fuzzyness=0.2):

if len(pulse1) != len(pulse2):

return False

for i in range(len(pulse1)):

threshold = int(pulse1[i] * fuzzyness)

if abs(pulse1[i] - pulse2[i]) 》 threshold:

return False

return True

fuzzy_pulse_compare(pulse, pulse2)

成功!使用模糊比較時(shí),兩個(gè)脈沖似乎相同。默認(rèn)情況下,如果脈沖之間的相距在20%之內(nèi),則比較將認(rèn)為相同,但是您可以通過(guò)將Fuzzyness關(guān)鍵字設(shè)置為其他值來(lái)更改該模糊度。模糊度值是從0到1.0(或從0到0的百分比) 100%),其中脈沖必須在彼此定時(shí)的百分比之內(nèi)。較低的值較為嚴(yán)格,需要更多類(lèi)似的脈沖,而較高的值較不嚴(yán)格,可能會(huì)使噪聲或不正確的脈沖看起來(lái)相同。通常,除非您遇到更多有問(wèn)題的IR信號(hào),否則請(qǐng)堅(jiān)持20%的模糊度。

讓我們通過(guò)編寫(xiě)一個(gè)完整的程序來(lái)等待所有內(nèi)容,等待上面的按鈕被按下,然后將它們綁在一起

您可以在程序中使用記錄的脈沖列表來(lái)記住先前記錄的脈沖,并與之比較新的脈沖。要檢測(cè)其他按鍵,只需按上述步驟進(jìn)行記錄,并更新代碼中的脈沖列表。

將下面代碼頂部的脈沖列表更改為您記錄的值(只需從REPL復(fù)制并粘貼),然后將其保存為板上的 code.py :

下載IR CircuitPython示例

下載:Project Zip 或 IR.py | 在Github上查看

復(fù)制代碼

import board

import pulseio

import adafruit_irremote

IR_PIN = board.D2 # Pin connected to IR receiver.

# Expected pulse, pasted in from previous recording REPL session:

pulse = [9144, 4480, 602, 535, 600, 540, 595, 536, 599, 537, 600, 536,

596, 540, 595, 544, 591, 539, 596, 1668, 592, 1676, 593, 1667,

593, 1674, 596, 1670, 590, 1674, 595, 535, 590, 1673, 597, 541,

595, 536, 597, 538, 597, 538, 597, 1666, 594, 541, 594, 541, 594,

540, 595, 1668, 596, 1673, 592, 1668, 592, 1672, 601, 540, 592,

1669, 590, 1672, 598, 1667, 593]

print(’IR listener‘)

# Fuzzy pulse comparison function:

def fuzzy_pulse_compare(pulse1, pulse2, fuzzyness=0.2):

if len(pulse1) != len(pulse2):

return False

for i in range(len(pulse1)):

threshold = int(pulse1[i] * fuzzyness)

if abs(pulse1[i] - pulse2[i]) 》 threshold:

return False

return True

# Create pulse input and IR decoder.

pulses = pulseio.PulseIn(IR_PIN, maxlen=200, idle_state=True)

decoder = adafruit_irremote.GenericDecode()

pulses.clear()

pulses.resume()

# Loop waiting to receive pulses.

while True:

# Wait for a pulse to be detected.

detected = decoder.read_pulses(pulses)

print(’got a pulse.。?!?/p>

# Got a pulse, now compare.

if fuzzy_pulse_compare(pulse, detected):

print(’Received correct remote control press!‘)

import board

import pulseio

import adafruit_irremote

IR_PIN = board.D2 # Pin connected to IR receiver.

# Expected pulse, pasted in from previous recording REPL session:

pulse = [9144, 4480, 602, 535, 600, 540, 595, 536, 599, 537, 600, 536,

596, 540, 595, 544, 591, 539, 596, 1668, 592, 1676, 593, 1667,

593, 1674, 596, 1670, 590, 1674, 595, 535, 590, 1673, 597, 541,

595, 536, 597, 538, 597, 538, 597, 1666, 594, 541, 594, 541, 594,

540, 595, 1668, 596, 1673, 592, 1668, 592, 1672, 601, 540, 592,

1669, 590, 1672, 598, 1667, 593]

print(’IR listener‘)

# Fuzzy pulse comparison function:

def fuzzy_pulse_compare(pulse1, pulse2, fuzzyness=0.2):

if len(pulse1) != len(pulse2):

return False

for i in range(len(pulse1)):

threshold = int(pulse1[i] * fuzzyness)

if abs(pulse1[i] - pulse2[i]) 》 threshold:

return False

return True

# Create pulse input and IR decoder.

pulses = pulseio.PulseIn(IR_PIN, maxlen=200, idle_state=True)

decoder = adafruit_irremote.GenericDecode()

pulses.clear()

pulses.resume()

# Loop waiting to receive pulses.

while True:

# Wait for a pulse to be detected.

detected = decoder.read_pulses(pulses)

print(’got a pulse.。?!?/p>

# Got a pulse, now compare.

if fuzzy_pulse_compare(pulse, detected):

print(’Received correct remote control press!‘)

現(xiàn)在按下時(shí)在遙控器按鈕上,您應(yīng)該會(huì)看到一條消息打印在REPL上!這就是基本原始IR脈沖檢測(cè)以及與CircuitPython比較的全部?jī)?nèi)容!

此頁(yè)面上的代碼可以方便地進(jìn)行基本或未知的遠(yuǎn)程控制協(xié)議檢測(cè)。但是請(qǐng)注意,遙控器實(shí)際上是相當(dāng)先進(jìn)的,有時(shí)不能按您期望的方式工作-像多次按下按鈕一樣,實(shí)際上可能不會(huì)每次都發(fā)送完整的代碼,而遙控器可能會(huì)發(fā)送較短的重復(fù)代碼!這意味著此處顯示的基本原始IR檢測(cè)可能會(huì)失敗,因?yàn)樗幌M吹街貜?fù)代碼。

事實(shí)證明,常規(guī)的IR遠(yuǎn)程檢測(cè)是如此先進(jìn),最好由單獨(dú)的庫(kù)處理,該庫(kù)可以解碼重復(fù)代碼等。對(duì)于CircuitPython,請(qǐng)從Chris Young那里檢查IRLibCP模塊,它具有更多功能完備的IR遠(yuǎn)程解碼支持!
責(zé)任編輯:wv

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 紅外傳感器
    +關(guān)注

    關(guān)注

    9

    文章

    544

    瀏覽量

    48354
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    紅外傳感器技術(shù)分類(lèi):熱釋電、熱電堆與微測(cè)輻射熱計(jì)詳解

    上一篇文章講了紅外傳感器工作原理及應(yīng)用,紅外傳感器利用入射紅外輻射引起傳感器的溫度變化,進(jìn)而使某些物理參數(shù)變化來(lái)進(jìn)行目標(biāo)探測(cè)。
    的頭像 發(fā)表于 03-18 17:00 ?688次閱讀
    <b class='flag-5'>紅外傳感器</b>技術(shù)分類(lèi):熱釋電、熱電堆與微測(cè)輻射熱計(jì)詳解

    熱釋電紅外傳感器探測(cè)物體的工作原理及適應(yīng)性應(yīng)用

    熱釋電紅外傳感器憑借獨(dú)特的工作原理和廣泛的應(yīng)用領(lǐng)域,成為了智能技術(shù)中不可或缺的一部分廣泛應(yīng)用于安全監(jiān)控、自動(dòng)化控制和環(huán)境管理等領(lǐng)域。核心原理是通過(guò)探測(cè)物體發(fā)射的
    的頭像 發(fā)表于 03-14 17:22 ?684次閱讀
    熱釋電<b class='flag-5'>紅外傳感器</b>探測(cè)物體的<b class='flag-5'>工作</b>原理及適應(yīng)性應(yīng)用

    2025年紅外傳感器發(fā)展現(xiàn)狀:科技創(chuàng)新與市場(chǎng)擴(kuò)展的交匯點(diǎn)

    了技術(shù)創(chuàng)新與市場(chǎng)擴(kuò)展的雙重活力。 ? 技術(shù)創(chuàng)新與突破 紅外傳感器技術(shù)經(jīng)過(guò)多年的發(fā)展,已經(jīng)取得了顯著的成果。核心在于能夠檢測(cè)物體釋放的紅外輻射,并將其轉(zhuǎn)化為電信號(hào),從而實(shí)現(xiàn)非接觸式的測(cè)量和檢測(cè)。這一特性使得
    的頭像 發(fā)表于 02-20 18:13 ?851次閱讀

    紅外傳感器原理與應(yīng)用

    讀者呈現(xiàn)一個(gè)全面而深入的紅外傳感器世界。 紅外傳感器原理 紅外傳感器工作原理主要基于紅外輻射與物質(zhì)之間的相互作用。
    的頭像 發(fā)表于 01-23 18:02 ?1289次閱讀
    <b class='flag-5'>紅外傳感器</b>原理與應(yīng)用

    紅外傳感器工作原理及應(yīng)用

    紅外傳感器工作原理 紅外傳感器工作原理基于紅外輻射的特性。紅外輻射是電磁波譜中波長(zhǎng)介于可見(jiàn)光
    的頭像 發(fā)表于 11-19 15:30 ?3428次閱讀

    物聯(lián)網(wǎng)系統(tǒng)中常見(jiàn)的非接觸人體感應(yīng)方案_紅外傳感器詳解

    物聯(lián)網(wǎng)系統(tǒng)中為什么要使用 紅外傳感器 物聯(lián)網(wǎng)系統(tǒng)中使用紅外傳感器的原因主要基于紅外傳感器的獨(dú)特優(yōu)勢(shì)及其在多個(gè)應(yīng)用場(chǎng)景中的實(shí)用性。以下是詳細(xì)的分析: 紅外傳感器的獨(dú)特優(yōu)勢(shì) 非接觸式測(cè)量:
    的頭像 發(fā)表于 09-24 11:38 ?1187次閱讀
    物聯(lián)網(wǎng)系統(tǒng)中常見(jiàn)的非接觸人體感應(yīng)方案_<b class='flag-5'>紅外傳感器</b>詳解

    紅外傳感器和超聲波傳感器有什么區(qū)別

    紅外傳感器和超聲波傳感器是兩種常用的非接觸式傳感器,它們?cè)诠I(yè)自動(dòng)化、機(jī)器人技術(shù)、安全監(jiān)控、環(huán)境監(jiān)測(cè)等領(lǐng)域有著廣泛的應(yīng)用。這兩種傳感器各有特點(diǎn),適用于不同的場(chǎng)景和需求。
    的頭像 發(fā)表于 09-19 16:44 ?2883次閱讀

    熱釋電紅外傳感器的基本特性和應(yīng)用領(lǐng)域

    熱釋電紅外傳感器是一種基于熱釋電效應(yīng)的紅外傳感器。熱釋電效應(yīng)是指某些晶體在溫度變化時(shí),其內(nèi)部的正負(fù)電荷中心會(huì)發(fā)生相對(duì)位移,從而產(chǎn)生電勢(shì)差或電流的現(xiàn)象。這種效應(yīng)是熱釋電紅外傳感器
    的頭像 發(fā)表于 08-27 16:24 ?3971次閱讀

    紅外傳感器的主要優(yōu)點(diǎn)有哪些

    深入探討紅外傳感器的優(yōu)點(diǎn)之前,我們首先需要了解基本原理。紅外傳感器通常由紅外探測(cè)、光學(xué)系統(tǒng)、信號(hào)處理電路等部分組成。它們通過(guò)接收
    的頭像 發(fā)表于 08-20 09:31 ?2063次閱讀

    人體紅外傳感器輸出信號(hào)有哪些

    人體紅外傳感器是一種廣泛應(yīng)用于安防、監(jiān)控、智能家居等領(lǐng)域的傳感器,其主要功能是檢測(cè)人體的存在和運(yùn)動(dòng)。本文將介紹人體紅外傳感器的輸出信號(hào)及其應(yīng)用。 人體紅外傳感器
    的頭像 發(fā)表于 08-20 09:30 ?2337次閱讀

    人體紅外傳感器的數(shù)據(jù)屬于什么量

    人體紅外傳感器的數(shù)據(jù)主要屬于 開(kāi)關(guān)量 。下面將從幾個(gè)方面介紹。 一、人體紅外傳感器工作原理 人體紅外傳感器是一種利用紅外線感應(yīng)原理來(lái)檢測(cè)人
    的頭像 發(fā)表于 08-20 09:28 ?1340次閱讀

    人體紅外傳感器的數(shù)據(jù)類(lèi)型及工作原理

    人體紅外傳感器是一種利用紅外技術(shù)檢測(cè)人體活動(dòng)和位置的傳感器。它廣泛應(yīng)用于安防、智能家居、醫(yī)療健康等領(lǐng)域。 人體紅外傳感器的數(shù)據(jù)類(lèi)型 人體紅外傳感器
    的頭像 發(fā)表于 08-20 09:18 ?2311次閱讀

    人體紅外傳感器的作用是什么

    人體紅外傳感器是一種利用人體發(fā)出的紅外輻射來(lái)檢測(cè)人體存在的傳感器。它在許多領(lǐng)域都有廣泛的應(yīng)用,如安全監(jiān)控、智能照明、自動(dòng)門(mén)禁等。以下是關(guān)于人體紅外傳感器的介紹: 人體
    的頭像 發(fā)表于 08-20 09:16 ?2903次閱讀

    人體紅外傳感器能穿透玻璃嗎為什么

    檢測(cè)的是人體發(fā)出的紅外輻射,波長(zhǎng)范圍在8-14微米之間。而玻璃對(duì)紅外輻射的吸收和反射特性會(huì)隨著波長(zhǎng)的變化而變化,對(duì)于8-14微米范圍內(nèi)的紅外輻射,玻璃的透射率較低,因此人體
    的頭像 發(fā)表于 08-20 09:15 ?3519次閱讀

    紅外傳感器技術(shù)深度解析:原理、分類(lèi)、應(yīng)用與選型策略

    技巧,為讀者呈現(xiàn)一個(gè)全面而深入的紅外傳感器世界。 紅外傳感器原理 紅外傳感器工作原理主要基于紅外輻射與物質(zhì)之間的相互作用。
    的頭像 發(fā)表于 07-25 08:45 ?3453次閱讀
    <b class='flag-5'>紅外傳感器</b>技術(shù)深度解析:原理、分類(lèi)、應(yīng)用與選型策略