Med en enda RGB LED (eller en LED strip) för att visa information: klocka, termometer och en konstig kommunikatör (2 / 7 steg)
Steg 2: OnePixel klocka
Pågrund av RGB-lysdioder du inte kan producera något mörka färger på dem: det finns inget sådant som en brun LED. Du kommer alltid vill också de rikaste, mest mättade färgerna. Så vad återstår här är spektrum cirkeln i enhetlig ljusstyrka, och vi måste extrahera från det den maximala mängden omisskännligt tydliga färger. Dessa färger måste vara enkelt och omedelbart berättade isär: vad vår klocka vara med om det lämnar utrymme för tvivel? Jag tillbringade mycket tid experimentera, själv övertyga och försöker pressa mer ur lamporna än de kan göra, och slutligen var tvungen att medge: det finns endast sex enkelt, absolut och utan tvekan distinguishable RGB LED färger:
Röd, Orange, grön, Cyan, blå och Magenta.
Varför orange och inte gul? Eftersom gul på en enda LED ser ut för mycket som grön och är inte lätt att identifiera utan hänvisning. Du kan se det själv: skriva en enkel skiss ändra RGB ledde från rött (255, 0, 0) till gult (127, 127, 0) varje sekund. Du ser röda och gröna färger.
Sex är ett bra antal för att hantera klockor, var det inte tillräcklig för mina behov. Det är möjligt att pressa något i intervallet lila, vilket resulterade i sju färger, men som hjälper inte exakt med en klocka. Så jag bestämde mig att använda en extra uppsättning av tio färger för uppgifter där en liten fel (förvirrande närliggande nyanser) är acceptabelt:
Röd, Orange, gul, grön, Aquamarine, Skyblue, blå, lila, Fuchsia och vit.
(namnen är preliminära, naturligtvis. Bara fina orden. Det är faktiskt mer som cyan-grön, cyan-blå, blå-magenta, röd-magenta, etc. Se tabellen i skissen nedan).
Vita är den här listan eftersom det inte är slutgiltiga. Det är inte en färg, men i själva verket en avsaknad av någon nyans, det lämnar mycket till fantasin och lätt kan misstas för något annat (framför allt cyan). Vad är mer, som en RGB LED gör vit ur kombinerar tre basfärger, det ser faktiskt olikt beroende på en betraktningsvinkel: om man tittar på LED från en punkt ser du mer röd, från en annan-mer grön etc.
Den sista viktiga "färgen" (eller, mer korrekt, bristen därav) är "svart". Medan det inte kan förmedla någon meningsfull information (eftersom det ser likadan ut som en vände-off LED) är det mycket bra som avgränsare.
Så jag hade två färguppsättningar. Även ursprungligen jag hoppats att göra en intuitiv analog klocka var klar vid den tiden som jag har att hålla sig med digital. Det vill säga med visar siffror med färgade koder. De två uppsättningarna är naturligtvis perfekt för visar minuter (eller sekunder): den sex-färg som kan visa ten, den tio-färg är bra för dem (eftersom det inte är ett stort problem om du förvirra de närliggande färgerna – har du bara en minut fel). Bara två blinkar av en RGB LED.
Vad sägs om timmar? Samma synsätt är inte bra här: för det första 10-färg är inte slutgiltig nog, och för det andra displayen blir vanlig tråkig med samma TEN färger upprepa om och om igen. Jag försökte några lösningar, men sedan såg på mitt armbandsur och det slog mig: om normala urtavlan kan dividera antalet timmar på en dag med två (visar 12 istället för 24) så varför inte kan jag dela dem vidare? Trots allt, gör jag en krans, inte ett atomur. Och, egentligen, kan man blanda ihop 6 klockan med midnatt? Så konventionen gjordes: en "urtavlan" av min OnePixel klocka kommer att vara 6-timmar, vilket innebär samma färger för 12 och 6, 1 och 7, 2 och 8, etc. Denna konvention visade sig vara mycket lämplig: den enda gången jag inte kunde läsa den exakta tiden bort lampan var 1: a januari och hade mer att göra med gårdagens party än något (vaknat, jag kunde inte berätta om det är mörkt fortfarande eller redan).
Det är möjligt att korrelera siffror och färger på något sätt, föredrar jag att göra det enligt spektra – utan att behöva komma ihåg något. Se diagrammen ovan.
I slutändan var garland klockan visar tiden i streck: long en för timmar, två korta sådana för minuter. I efter året fyllde jag mitt hem med mycket olika varianter av samma enhet, de flesta av dem sport mer än en LED, men principen återstod (kolla videon). Det enda jag inte är säker om nuförtiden är den vita färgen för 9: Jag tror jag ska göra det lite mer pinkyish att undvika förväxling med Cyan. Det kan ha varit bättre att infoga vit mellan två Cyan nyanser av 10-färg cykel, men nu är det för sent för mig, som jag redan ganska brukade dessa klockor som de är.
Här är en skiss som gör att du kan se tiden i en enda RGB LED på tre olika sätt (lägen bytte av en knapp, den fjärde läge ska förklaras i steg 4). Du behöver en extern klocka modul. Om du inte har en tid biblioteket kan du förvandla din Arduino till en tidsangivning enhet (ändras skissen). Jag skulle föreslå du får RTC modulen om du tänker gräva i Arduino klockor-det är verkligen ganska billigt och bra.
< p > #include < Wire.h >< br > #define RED 3 / / pins RGB LED är ansluten till
#define grön 5
#define blå 6
#define BUTTON_PIN 7 < /p >< p > int temperatur;
byte sekund, minut, timme.
byte temperPos, prevPos, nextPos;
byte r, g, b;
byte läge = 0; < /p >< p > / / sine wave array
CONST uint8_t lyser [360] = {
0, 0, 0, 0, 0, 1, 1, 2, //8
2, 3, 4, 5, 6, 7, 8, 9,
11, 12, 13, 15, 17, 18, 20, 22,
24, 26, 28, 30, 32, 35, 37, 39, //32
42, 44, 47, 49, 52, 55, 58, 60,
63, 66, 69, 72, 75, 78, 81, 85, //48
88, 91, 94, 97, 101, 104, 107, 111,
114, 117, 121, 124, 127, 131, 134, 137, //64
141, 144, 147, 150, 154, 157, 160, 163,
167, 170, 173, 176, 179, 182, 185, 188, //96
191, 194, 197, 200, 202, 205, 208, 210,
213, 215, 217, 220, 222, 224, 226, 229,
231, 232, 234, 236, 238, 239, 241, 242,
244, 245, 246, 248, 249, 250, 251, 251,
252, 253, 253, 254, 254, 255, 255, 255,
255, 255, 255, 255, 254, 254, 253, 253,
252 251, 251, 250, 249, 248, 246, 245,
244 242, 241, 239, 238, 236, 234, 232,
231, 229, 226, 224, 222, 220, 217, 215,
213, 210, 208, 205, 202, 200, 197, 194,
191, 188, 185, 182, 179, 176, 173, 170,
167, 163, 160, 157, 154, 150, 147, 144,
141, 137, 134, 131, 127, 124, 121, 117,
114 111, 107, 104, 101, 97, 94, 91,
88, 85, 81, 78, 75, 72, 69, 66,
63 60, 58, 55, 52, 49, 47, 44,
42, 39, 37, 35, 32, 30, 28, 26,
24, 22, 20, 18, 17, 15, 13, 12,
11, 9, 8, 7, 6, 5, 4, 3,
2, 2, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
en matris med förväg ordnad RGB värden
för 10mm RGB LED.
byte RGBready [13] [3] = {
{255, 0, 0}, / / timme = 0, min = 0
{229, 26, 0}, / / min = 1
{201, 54, 0}, / / timme = 1
{181, 74, 0}, / / min = 2
{0, 255, 0}, / / timme = 2, min = 3
{0, 218, 36}, / / min = 4
{0, 174, 81}, / / timme = 3
{0, 99, 156}, / / min = 5
{0, 0, 255}, / / timme = 4, min = 6
{74, 0, 181}, / / min = 7
{131, 0, 124}, / / timme = 5
{196, 0, 59}, / / min = 8
{95, 78, 81,} / / min = 9
}; < /p >< p > / / dessa matriser punkt till exakta färger av timmar och minuter i RGBready
Jag använder dem eftersom mitt projekt RGBready kan hålla mer förväg ordnad
färger än bara klocka (som termometer). Och det är lättare.
byte hourColor [6] = {0,2,4,6,8,10}.
byte minuteColor [10] = {0,1,3,4,5,7,8,9,11,12}; < /p >< p > void setup() {
Wire.BEGIN();
Serial.BEGIN(9600);
Serial.println("Starting");
pinMode (BUTTON_PIN, INPUT_PULLUP); knappen ansluter till GND
} < /p >< p > void loop() {< /p >< p > / / få och skriva ut gång
getTime();
Serial.Print ("tid är");
Serial.Print(Hour);
Serial.Print(":");
Serial.Print(Minute);
Serial.Print(":");
Serial.Print(Second);
Serial.println(".");
timme % = 6; Konvertera timmar till 6-timmars "urtavlan"
timme = minut %6.
minut = understödja; < /p >< p > / / ändra lägen bör du tryck på och håll ned knappen
(läsning sker mellan display cykler)
Jag bestämde mig mot ISR här att hålla skissen till punkten
om (! digitalRead(BUTTON_PIN)) läge ++; < /p >< p > läge % = 4; Vi har bara tre lägen < /p >< p > Växla (läge) {
fall 0: showTimeFades(); bryta;
fall 1: showTimeTransitions(); bryta;
fall 2: simpleMode(); bryta;
fall 3: analogClock(); bryta;
}
} < /p >< p > / / följande två funktioner används för att få tid från ett DS3231 chip
de bärgades från Time library tror jag
själva tiden biblioteket förvandlar din Arduino till en klocka, så om du
har inte en RTC-modul, du bör hämta den
och ändra funktionen getTime() att arbeta med det
void getTime)
{
DS3231 RTC chip adressen är 0x68
Wire.beginTransmission(0x68);
Wire.write(byte(0));
Wire.endTransmission(); < /p >< p > Wire.requestFrom (0x68, 3, 1); begära första tre byte, nära anslutning
för det andra = bcdToDec (Wire.read());
minuter = bcdToDec (Wire.read());
timme = bcdToDec(Wire.read());
Vi behöver inte någon ytterligare information som veckodag, år, etc
från klockan, så Läs bara första 3 byte.
} < /p >< p > / / Konvertera binary coded decimal till normala decimaltal
byte bcdToDec(byte val) {
tillbaka ((val/16 * 10) + (val % 16));
} < /p >< p > / / The OnePixel klocka lägen
1-läge som jag använt på en krans
void showTimeFades()
{
int delayVal = 4; Anger den totala display hastigheten < /p >< p > / / fade-in fade-out timmar färg
för (int k = 0; k < 241; k ++)
{
r = (uint16_t)(RGBready[hourColor[hour]][0]*lights[k]) >> 8.
g = (uint16_t)(RGBready[hourColor[hour]][1]*lights[k]) >> 8.
b = (uint16_t)(RGBready[hourColor[hour]][2]*lights[k]) >> 8.
setRGBpoint (0, r, g, b);
Delay(delayVal);
} < /p >< p > / / fade-in fade-out minut-tens färg
för (int k = 0; k < 241; k ++)
{
r = (uint16_t)(RGBready[hourColor[minute/10]][0]*lights[k]) >> 8.
g = (uint16_t)(RGBready[hourColor[minute/10]][1]*lights[k]) >> 8.
b = (uint16_t)(RGBready[hourColor[minute/10]][2]*lights[k]) >> 8.
setRGBpoint (0, r, g, b);
fördröjning (delayVal >> 1); två gånger snabbare än timmar
} < /p >< p > / / fade-in fade-out minut-sådana färg
för (int k = 0; k < 241; k ++)
{
r = (uint16_t)(RGBready[minuteColor[minute%10]][0]*lights[k]) >> 8.
g = (uint16_t)(RGBready[minuteColor[minute%10]][1]*lights[k]) >> 8.
b = (uint16_t)(RGBready[minuteColor[minute%10]][2]*lights[k]) >> 8.
setRGBpoint (0, r, g, b);
fördröjning (delayVal >> 1); två gånger snabbare än timmar
}
} < /p >< p > / / 2 - sinusvåg övergångar mellan färger
void showTimeTransitions()
{
int delayVal = 4; ställa in övergångar hastighet
Fade-in
för (int k = 0; k < 121; k ++)
{
r = (uint16_t)(RGBready[hourColor[hour]][0]*lights[k]) >> 8.
g = (uint16_t)(RGBready[hourColor[hour]][1]*lights[k]) >> 8.
b = (uint16_t)(RGBready[hourColor[hour]][2]*lights[k]) >> 8.
setRGBpoint (0, r, g, b);
Delay(delayVal);
} < /p >< p > / / övergångar
shiftColors (hourColor [timme], hourColor [minut/10], delayVal);
Delay(50); kort stopp på minuten-tens värde
shiftColors (hourColor [minut/10], minuteColor [minut 10] %, delayVal);
uttoning
för (int k = 120; k < 241; k ++)
{
r = (uint16_t)(RGBready[minuteColor[minute%10]][0]*lights[k]) >> 8.
g = (uint16_t)(RGBready[minuteColor[minute%10]][1]*lights[k]) >> 8.
b = (uint16_t)(RGBready[minuteColor[minute%10]][2]*lights[k]) >> 8.
setRGBpoint (0, r, g, b);
Delay(delayVal);
}
} < /p >< p > / / 3 - den enklaste möjliga läget, kan vara bra som en start för något
void simpleMode()
{
int delayVal = 333;
r = RGBready [hourColor [timme]] [0];
g = RGBready [hourColor [timme]] [1];
b = RGBready [hourColor [timme]] [2];
setRGBpoint (0, r, g, b);
Delay(delayVal); < /p >< p > r = RGBready [hourColor [minut/10]] [0];
g = RGBready [hourColor [minut/10]] [1];
b = RGBready [hourColor [minut/10]] [2];
setRGBpoint (0, r, g, b);
Delay(delayVal); < /p >< p > r = RGBready [minuteColor [minut % 10]] [0];
g = RGBready [minuteColor [minut % 10]] [1];
b = RGBready [minuteColor [minut % 10]] [2];
setRGBpoint (0, r, g, b);
Delay(delayVal); < /p >< p > setRGBpoint (0, 0, 0, 0);
fördröjning (delayVal >> 1);
} < /p >< p > void analogClock()
{
int delayVal = 8;
för (int k = 0; k < 52; k ++)
{
r = (float)(RGBready[hourColor[hour]][0]*(60-minute) + RGBready [hourColor [(hour+1) %6]] [0] * minut) / 60;
g = (float)(RGBready[hourColor[hour]][1]*(60-minute) + RGBready [hourColor [(hour+1) %6]] [1] * minut) / 60;
b = (float)(RGBready[hourColor[hour]][2]*(60-minute) + RGBready [hourColor [(hour+1) %6]] [2] * minut) / 60; < /p >< p > r = (uint16_t)(r*(lights[k]*2+30)) >> 8.
g = (uint16_t)(g*(lights[k]*2+30)) >> 8.
b = (uint16_t)(b*(lights[k]*2+30)) >> 8.
setRGBpoint (0, r, g, b);
Delay(delayVal);
}
för (int k = 51; k > 0; k--)
{
r = (float)(RGBready[hourColor[hour]][0]*(60-minute) + RGBready [hourColor [(hour+1) %6]] [0] * minut) / 60;
g = (float)(RGBready[hourColor[hour]][1]*(60-minute) + RGBready [hourColor [(hour+1) %6]] [1] * minut) / 60;
b = (float)(RGBready[hourColor[hour]][2]*(60-minute) + RGBready [hourColor [(hour+1) %6]] [2] * minut) / 60; < /p >< p > r = (uint16_t)(r*(lights[k]*2+30)) >> 8.
g = (uint16_t)(g*(lights[k]*2+30)) >> 8.
b = (uint16_t)(b*(lights[k]*2+30)) >> 8.
setRGBpoint (0, r, g, b);
Delay(delayVal);
}
Delay(delayVal*30);
} < /p >< p > / / funktion för färgskiftning mellan
positioner i matrisen RGBready. Här en använder den
sinusvåg algoritm och ljus [] förväg ordnad matrisen ovan
delayVal anger hastigheten för övergång
void shiftColors (byte cur, byte nästa, byte delayVal)
{
uint16_t färg [3], nextColor [3].
lång colorStep [3].
showRGBcolor(cur); med tydlig första färgen
beräkna steg i unsigned int format att undvika att använda flöten
för (byte k = 0; k < 3; k ++) {
färg [k] = RGBready [cur] [k] << 8;
nextColor [k] = RGBready [Nästa] [k] << 8;
colorStep [k] = ((långa) nextColor [k] - färg [k]) / 255;
}
Ange färger i 120 (360/3) steg, konvertera tillbaka till byte
för (byte k = 0; k < 120; k ++)
{
setRGBpoint (0, (color[0]+colorStep[0]*lights[k]) >> 8,
(color[1]+colorStep[1]*lights[k]) >> 8,
(color[2]+colorStep[2]*lights[k]) >> 8);
Delay(delayVal);
}
showRGBcolor(next); avsluta med tydlig andra färgen
} < /p >< p > / / två äldre funktioner för att aktivera lysdioder.
Jag använder dem här att behålla överensstämmelsen mellan exempel skisser
båda är för gemensam anod lysdioder. Om du använder gemensam katod sådana,
ta bort den "255-" bitar.
void setRGBpoint (uint8_t LED uint8_t röd, uint8_t grön, uint8_t blå)
{
analogWrite (röd, 255-röd);
analogWrite (grön, 255-grön);
analogWrite (blå, 255-blå);
} < /p >< p > void showRGBcolor (byte hoprullade)
{
analogWrite (röd, 255-RGBready[curLED][0]);
analogWrite (gröna, 255-RGBready[curLED][1]);
analogWrite (blå, 255-RGBready[curLED][2]);
} < /p >
Märker färgtabellen i skissen? Jag återkommer till det i sista steget.