Stap 2: Programmeren - Arduino-kant
Wij zullen de IRremote Arduino library (https://github.com/shirriff/Arduino-IRremote) gebruiken voor de afgelegen deel van IR. Deze bibliotheek kan worden gebruikt voor het verzenden van vooraf gedefinieerde gegevens via IR, evenals van LIRC. Maar We zullen gebruiken alleen voor haar hulpfuncties (voor te stellen de frequentie 38KHz IR en tijdsinstellingen tijdens het verzenden van berichten beheren).
In de vorige instructable vonden we dat om te kunnen communiceren de air conditioner-opdrachten die we nodig hadden voor het verzenden van een lock-reeks, een constante inleiding, de lock volgorde weer, dan de werkelijke lading. Ook de Arduino kan heel goed hebben de invoering in de code en gewoon wachten tot de nettolading. Wij kunnen enkel de waarden van de opties verzenden en maak de Arduino een sjabloon met deze waarden wijzigen, maar het om eenvoudig te houden zullen we gewoon bieden de hele lading en laat het stuur deze zo is. Voor het verzenden van de bits zal het schakelen van de IR LED op en uit volgens de de tijdsinstellingen eerder gevonden.
De Arduino fungeert hier als een "slaaf", nooit het initiëren van een communicatie zelf. Zoals ik ben van plan om meerdere gebruik van dit toestel, die ik wil de mededelingen één teken 'Ik allereerst' zin 'verzenden door IR' te maken, gevolgd door 19 bytes van lading. De Arduino stuurt het bericht naar de airconditioner.
Aan de Arduino-kant de code kan kijken een beetje overdreven ingewikkeld, maar het is omdat het is verondersteld om te dienen als een radio relay ook, zodat de communicatie tussen de Pi en Arduino via seriële interface niet altijd alleen om het IR signaal.
Hier is de bron van de arduino die worden gebruikt voor het verzenden van opdrachten naar de airconditioner.
Een beetje uitleg:
-> de lus code alleen controles als een opdracht klaar is. In dat geval wordt de opdracht (voor nu alleen maar "een IR bericht verzenden") uitgevoerd.
-> de SerialEvent() heet na een loop, als er seriële gegevens in de buffer. In deze functie die de opdracht wordt gelezen, de nettolading is bereid en vervolgens een vlag is ingesteld op de loop functie vertellen dat een opdracht klaar is
serialEvent ontvangt ASCII-tekens HEX waarden vertegenwoordigen. Om het te converteren gebruiken we de functie sscanf met de "%x" (hexadecimaal) optie opmaken. We slaan de ontvangen tekens in een 5 char-array en vul deze met: '0 x' + de 2 chars + '\0' (tot finish de tekenreeks).
char hexConvert [5] = "0 x";
ASCII is ontvangen
for (int i = 0; ik < 19; i ++) {}
hexConvert [2] = Serial.read();
hexConvert [3] = Serial.read();
hexConvert [4] = '\0';
de ontvangen tekens converteren naar een numerieke waarde in nettolading [i]
sscanf (hexConvert, "%x", & (payload[i]));
}
Op dit moment bevat de nettolading [i] de binaire waarde vertegenwoordigd door de ontvangen tekens.
In het verzenden opdracht juiste timings gebruikt voor het verzenden van sloten, invoering en lading. Om gegevens te verzenden, moet de code verzenden van elke bit afzonderlijk met de functie irsend.mark(duration) en irsend.space(duration). Zoals uitgelegd in de vorige instructable de duur gaat van 400us (eigenlijk moet dichter bij 420 denk ik) voor het merk (op staat), en 400us of 1300us voor de ruimte (uit staat) voor het verzenden van een 0 of een 1, respectievelijk.
Voor het verzenden van elke bit van elke byte de volgende code wordt gebruikt:
voor (int s = 0; s < payloadSize; s+ +) {}
voor (int i = 7; ik > = 0; i--) {/ / meest significante Bit voorop
irsend.Mark(irSpace);
irsend.Space ((lading [s] >> i) & 1 == 1? irOne: irZero);
}
}
Als u niet bekend met bitsgewijze bewerkingen bent zijn er overvloed van leerprogramma's beschikbaar op het net.
Wat gebeurt er hier is:
Voor elke byte van de lading (werkt op dezelfde manier met de intro):
Voor ik ga van 7 0
verschuiving van de byte voor ik naar rechts gelederen
Kijk naar het laatste stukje
Als dat beetje behoort, een signaal van "irOne" ons (1300us), anders sturen een signaal van "irZero" (400us)
In feite is wat we verkrijgen door het verschuiven van de byte recht van N rangen (het toevoegen van nullen aan de linker kant) de n beetje aan de rechtse kant. Wanneer maskeren met een bitsgewijze AND (en) we nemen alleen de meest rechtse bit 1, krijgen dus wereldwijd we de nde bits waarde.
In het volgende voorbeeld met 5B in hexa = 0101 1011 in binary. De haakjes zijn hier om te benadrukken de verschoven bits, vanwege de goede leesbaarheid...
Ik = 7 = > shift (0) 101 1011 voor 7 rangen = > 0000 000(0)
masker met 1 = > 0000 0000 & 0000 0001 = 0 = > verzenden irZero
Ik = 6 = > shift (01) 01 1011 voor 6 gelederen = > 0000 00(01)
masker met 1 > 0000 0001 = & 0000 0001 = 1 = > verzenden irOne
Ik = 5 = > shift (010) 1 1011 voor 5 gelederen = > 0000 0(010)
masker met 1 = > 0000 0010 & 0000 0001 = 0 = > verzenden irZero
Ik = 4 = > verschuiven (0101) 1011 voor 4 rangen = > 0000 (0101)
masker met 1 = > 0000 0101 & 0000 0001 = 1 = > verzenden irOne
Ik = 3 = > shift (0101 1) 011 voor 3 rangen = > 000 (0-1011)
masker met 1 = > 0000 1011 & 0000 0001 = 1 = > verzenden irOne
Ik = 2 = > shift (0101 10) 11 voor 2 rangen = > 00 (01-0110)
masker met 1 = > 0001 0110 & 0000 0001 = 0 = > verzenden irZero
Ik = 1 = > shift (0101 101) 1 voor 1 rang = > 0(010 1101)
masker met 1 = > 0010 1101 & 0000 0001 = 1 = > verzenden irOne
Ik = 0 = > verplaatsing (0101 1011) 0 rang = > (0101 1011)
masker met 1 = > 0101 1011 & 0000 0001 = 1 = > verzenden irOne
Dus stuurde we stukjes in links naar de juiste volgorde.
Merk op dat IRremote bibliotheek gebruikt pin3 om berichten te verzenden. Ik veronderstel dat het zou kunnen gebruiken de pin 11 (dezelfde timer voor PWM) door aanpassing van de pin van de doelgroep in de bibliotheek-code, maar ik heb het niet getest.