Med en enda RGB LED (eller en LED strip) för att visa information: klocka, termometer och en konstig kommunikatör (5 / 7 steg)
Steg 5: Konstiga 6-bitars Communicator
Någon, se min klocka-garland för första gången, noterade att det skulle kunna användas som en hemlig kommunikationsenhet. Tja, varför inte? Detta är mindre användbart än klockan eller termometern, men kan hända att vara en bra och rolig leksak för någon med barn.
Det är uppenbart att en RGB LED, fysiskt som består av tre lysdioder med separat katoder (eller anoder), i själva verket är en 3-bitars enhet. Genom att leverera dess ben med 0 eller 1 värden du ger det tre bitar av information och det visar dem i färgade kod. Om vi betraktar red som en LSB och blå som en MSB (eller BGR = B000), vi kan faktiskt tilldela färger till siffrorna 0 – 7: svart för 0, röd för 1 (B001), grönt för 2 (B010), orange (R + G) för 3 (B011), blå för 4 (B100), magenta (R + B) för 5 (B101), cyan (G + B) för 6 (B110) och vitt (R + G + B) för 7 (B111). Problemet med detta tillvägagångssätt döljer i "svart" färg (noll), eftersom det blir informativ och kan inte användas som avgränsare. Med bara tre bitar kommer inte vi kunna skicka något meningsfullt i bara en färg, och vi faktiskt har problem att skicka noll, som det ser ut exakt samma som en vände-off LED och ingen kommer att märka att vi försöker kommunicera med dem.
De flesta digitala kommunikationsprotokoll Använd mer än en kanal bara för det: att Visa mottagaren att information överförs faktiskt, och det bör överväga spänning frånvaron som en nolla, inte ingenting. Detta tar form av en spärr signal, en klocksignal eller några andra närvarande på en extra tråd bärsignal. I vårt fall vi kunde ha lagt till en enda färg LED bara för detta, men eftersom vi använder en RGB LED genom våra OnePixel konvention, vi kan inte. Så bärsignal måste överföras av RGB LED och vi måste ägna en kanal till den, lämnar oss med endast två informationsbitar per enskild färg. Så, om vi använder röd som bärare, får vi red för 0, orange för 1 (B01), magenta för 2 (B10) och vitt för 3 (B11).
Två bitar räcker inte, men vi kan stapla dem tillsammans i sekvenser. Dessutom kan vi använda annat transportföretag färger. Till exempel om vi använder röd som bärare för den första två bitar, grönt för den mellersta två bitar och blå för de sista två bitarna vi får en fin tre färger 6-bit-sekvens. Vi kan använda "svart" avgränsare mellan sådana sekvenser att överföra informationen tydligt.
Tekniskt sett är vi inte begränsade till 6 bitar: vi kan lägga till en fjärde färg, med röda igen som transportören, och överföra full byte. Problemet här är att det finns två färger i sekvens, och om de är samma (gillar, säger, i B00111100 – rött, vitt, vitt, rött eller B00011000 – rött, cyan, cyan, röd), kan det vara svårt att avkoda dem. Tack och lov, 6 bitar är ganska tillräckligt för att överföra meddelanden som meningsfull.
Kolla ASCII-tabellen. De första 32 koderna är för kontrolltecken, vi behöver inte dem. Gå sedan skiljetecken, siffror och alfabetet med versaler, och alla dessa symboler passar in i 6 bitar (64 olika värden). Om vi tar ASCII-tabellen från rymden (32) till _ (95) får vi allt vi behöver för att kommunicera i 6 bitar. Som en sida noterar dike tidigt persondatorer också gemena tecken för att minska kostnaderna på karaktär generation marker.
OK, är här hemliga meddelande skissen. Det tar allt du skriver i fönstret Serial Monitor (ändra gemener symboler till versaler) och visar det på en enda RGB LED. Observera att Serial Monitor måste ställas in upp till 115200 baud. Den skriver också tabellen karaktär vid start för lättare avkodning (du kan också kontrollera de ovanstående lathund, det visar den första färgen i lodrät pil, den andra en horisontell fyllning och den tredje som pricken).
#define RED 3 / / pins RGB LED är ansluten till
#define grön 5
#define blå 6
tabellen i färger. Den här var kalibrerad för en 10mm RGB LED
uint8_t RGBready [13] [3] = {
{255, 0, 0}, / / 00xxxx
{128, 127, 0}, / / 01xxxx
{206, 0, 49}, / / 10xxxx
{110, 90, 54}, / / 11xxxx vit
{26, 155, 74}, / / 11xxxx cyan
{0, 255, 0}, / / xx00xx
{179, 75, 0}, / / xx01xx
{0, 168, 87}, / / xx10xx
{90, 110, 54}, / / xx11xx vit
{158, 10, 87}, / / xx11xx rosa
{0, 0, 165}, / / xxxx00
{206, 0, 49}, / / xxxx01
{0, 212, 42}, / / xxxx10
{90, 90, 74}, / / xxxx11 vit
{139, 105, 10}, / / xxxx11 gul
{0,0,0} / / 'svart'
};
uint8_t meddelande [100], räkna; char array och counter
nedan finns varaktigheterna för färger och "svart" paus mellan, i ms
uint16_t signalDuration = 400, pauseBetween = 100;
void setup() {
Serial.BEGIN(115200);
skriva ut en teckentabell
Serial.println ("karaktär bord");
för (uint8_t k = 0; k < 16; k ++)
{
om (k < 10) Serial.print("0");
Serial.Print(k);
Serial.Print(":");
Serial.write(k+32);
Serial.Print("");
Serial.Print(k+16);
Serial.Print(":");
Serial.write(k+16+32);
Serial.Print("");
Serial.Print(k+32);
Serial.Print(":");
Serial.write(k+32+32);
Serial.Print("");
Serial.Print(k+48);
Serial.Print(":");
Serial.write(k+48+32);
Serial.println();
}
}
void loop() {
Count = 0; släpp teckenräknare
medan (Serial.available()) / / läsa strängen om tillgängligt, konvertera det till vårt bord
{
uint8_t incomingChar = Serial.read ();
vanliga tecken
om (incomingChar > 31 & & incomingChar < 96) {meddelande [antal] = incomingChar; räkna ++;}
små bokstäver måste konverteras till versaler
annars om (incomingChar > 96 & & incomingChar < 123) {meddelande [antal] = incomingChar - 32; räkna ++;}
}
om det finns inkommande sträng, Visa det på LED
om (count > 0) {
för (uint8_t k = 0; k
funktionen att färgkoda och Visa information på LED
void sendRGBmessage(uint8_t letter)
{
brev = brev - 32. konvertera från ASCII till våra format
showRGBcolor (brev >> 4); övre 2 bitar
Delay(signalDuration);
showRGBcolor (4 + ((brev >> 2) & 3)); mellersta 2 bitar
Delay(signalDuration);
showRGBcolor (8 + (brev & 3)); lägre 2 bitar
Delay(signalDuration);
showRGBcolor(12); paus mellan tecken
Delay(pauseBetween);
}
funktionen för att göra den faktiska LED tända
för gemensam anod LED; vid gemensam katod bort "255-' bitar
void showRGBcolor(byte curLED)
{
analogWrite (röd, 255-RGBready[curLED][0]);
analogWrite (gröna, 255-RGBready[curLED][1]);
analogWrite (blå, 255-RGBready[curLED][2]);
}