En komplett starter guide till AVRs (7 / 10 steg)
Steg 7: IR-fjärrkontroller
Så började jag med att efter ladayada IR tutorial:
http://www.Ladyada.net/Learn/sensors/IR.html
Det var ett riktigt snabba sätt att få in IR och jag är varierar mycket tacksam för det, men den är konstruerad med en rymlig arduino i åtanke och jag arbetade med en ATtiny2313 som inte har någonstans nära nog RAM att göra jobbet.
Med hennes skiss med en liten fjärrkontroll som jag hade liggande jag registreras på strömbrytaren och fick detta:
int PowerSignal [] [2] = {
ON, OFF (i 10 mikrosekunder)
{1138, 574},
{66, 76},
{66, 78},
{68, 70},
{70, 76},
{66, 76},
{68, 74},
{68, 78},
{68, 210},
{72, 216},
{68, 214},
{70, 216},
{78, 206},
{70, 214},
{70, 216},
{70, 216},
{68, 72},
{74, 72},
{68, 216},
{68, 76},
{66, 78},
{70, 214},
{68, 78},
{66, 72},
{70, 74},
{68, 216},
{74, 70},
{68, 214},
{72, 216},
{72, 68},
{74, 214},
{66, 216},
{70, 214},
{72, 5014},
{1134, 292},
{62, 5532},
{1142, 294},
{58, 0}};
38/på par, några av dem för stor för en enda byte, så om jag skulle göra så här jag skulle behöva 152 byte.
Jag hade nog blixt, även om det skulle ta en bra mängd utrymme jag kunde avvara det, men om jag skulle spela in de inkommande signalerna som det jag skulle blåsa min RAM budget utan att ens överväga andra saker jag behöver RAM för.
Jag kunde ha kontrollerat koden som kom in, men sedan timing blir lite svårt.
Jag tänkte på det för ett tag och jag märkte ett mönster i min IR-kod.
Signalerna var antingen mindre än 1ms eller de var större.
Använda ladyada's kod, hade det en tolerans på 20%, vilket skulle innebära att någon av de låga siffror skulle matcha varandra.
Det fanns i princip ingen skillnad mellan en 680 och 780 mikrosekunder, med toleransen.
Det var ett liknande fall för den större då 1ms värden, det finns några undantag, men de flesta passar regeln.
Tänkte jag, vad händer om jag behandla dem som enda bitar, 0.. då 1ms och en 1 om det var större.
Packade i sånt kom jag upp med detta:
11000000 = 0xC0
00000000 = 0x00
01010101 = 0x55
01010101 = 0x55
00000100 = 0x04
00010000 = 0x10
00010001 = 0x11
01000101 = 0x45
01011101 = 0x5D
1100
Efter att ignorera den senaste nibble (halv ett byte) jag kunde lagra den inkommande signalen på en gång i endast 9 byte, och jämför signalen skulle bara ta upp 9 också!
Om jag ville ha fler funktioner skulle inte jag vara ont om flash för att lagra koder och är så små att de kunde lätt ha förvarats i EEPROM om jag behövde.
Ytterligare en fördel var att kontrollera om koden matchade var ingen mer sedan 9 enkla byte jämförelser.
Ta en titt på den bifogade uppförandekoden.
På toppen finns det en uppsättning definierar blir koden enklare att följa och upprätthålla.
Efter det är mönstret ovan nämnda, lagras som en röding och anges hexadecimalt.
Allt annat är i grunden i listenForIR-funktion som kallas kontinuerligt från den huvudsakliga loopen.
Observera, detta är bara enkla demo kod, i ett sista projekt kommer du att använda ett avbrott för att vakna när IR upptäcker något.
Jag har en version av koden som gör detta.
Så, hur fungerar listenForIR?
Kan bryta ner.
Vi börjar med ett tag loop som försöker få 9 byte data från IR.
Vi börjar genom att ställa in timern till en 256 prescaler.
På 1MHz kan oss tid upp till 65ms utan att flöda över.
IR-mottagare hålla data pin hög standard kommer låga när en pulsbreddsmodulerad signal tas emot.
Så vi väntar tills vi får en låg, och om vi tar längre tid då 56ms väntar vi lösa ut.
När vi har en låg vi behöver tid, men vi behöver inte tid så länge som tidigare och vi kunde använda en högre nivå av Exakthet, så ändrar vi prescaler till 8.
Om låga hålls för längre sedan 1ms, då vi hoppa ut, annars slutar öglan tidigt som stiftet går hög.
Den nästa bit kod har en nice användning av bitvis operationer som låter oss hålla reda på ändringar snabbt och billigt (billig cpu och minnesanvändning):
current_byte << = 1;
current_byte | = staten.
While(IR_LOW); vid en låg längre då ovanstående timeout
Vi börjar genom att flytta alla bitar kvar.
Vi sedan eller värdet av antingen 1 eller 0, som lägger sitt värde för LSB (minst signifikanta biten).
Vi sedan vänta, incase det var en lång låg som vi hoppade ut på tidigare.
Vi gör sedan samma sak för den höga delen av koden.
När vi har alla 8 bitar (4 par låg & hög), vi lagra det och börja om igen.
Förutsatt att vi får alla 9 byte, vi avsluta loopen och helt enkelt jämföra den mot vår kod.
Om de alla matchar växla vi LED.