Externer Inhalt
www.youtube.com
Inhalte von externen Seiten werden ohne Ihre Zustimmung nicht automatisch geladen und angezeigt.
Mit 17 LEDs kann das ja jeder
Gestern kurz getestet. Ich mußte mir erst noch einen Raspberry einrichten, da der andere ja im Dauertest für die Treppenstufen belegt ist.
Läuft - sieht zumindest so aus.
Mehr als eine kurze Prüfung, ob etwas blinkt, habe ich gestern nicht mehr geschafft.
Code, Bilder etc kommen noch.
Das Endlighten-Acryl ist auch schon unterwegs. Ein Stück Holz werde ich noch irgendwo finden.
Ob das ganze Schlussendlich mit einem Rasp umgesetzt wird, kann ich noch gar nicht sicher sagen.
Zwei Arduinos sind auch auf dem Weg zu mir. Der würde (mit DCF-Uhr) diesem Projekt eher gerecht werden.
Ich habe die Farbwerte noch verändert, da man sonst gelb von weiß nicht wirklich unterscheiden kann.
Jetzt probiere ich gerade, wie man mit einem Button die Sekundenanzeige auf 0 setzen kann.
Und mit erneutem Klick eben wieder aktivieren kann.
Es blinkt
So recht will auch das mit dem Button noch nicht laufen.
Wenn ich den Button drücke, dann wird genau für das kurze Event das Script aktiviert.
Also für den Bruchteil einer Sekunde während des Drückens.
# Simple demo of of the WS2801/SPI-like addressable RGB LED lights.
import time, datetime
import RPi.GPIO as GPIO
import Adafruit_WS2801
import Adafruit_GPIO.SPI as SPI
GPIO.setmode(GPIO.BCM)
SENSOR_PIN2 = 2
GPIO.setup(SENSOR_PIN2, GPIO.IN, GPIO.PUD_UP)
GPIO.setwarnings(False)
# Configure the count of pixels:
PIXEL_COUNT = 6
# Alternatively specify a hardware SPI connection on /dev/spidev0.0:
SPI_PORT = 0
SPI_DEVICE = 0
pixels = Adafruit_WS2801.WS2801Pixels(PIXEL_COUNT, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE), gpio=GPIO)
r_color_max = 255
g_color_max = 55
b_color_max = 55
def display_binary(h,m,s):
_r = '{:06b}'.format(h)
_g = '{:06b}'.format(m)
_b = '{:06b}'.format(s)
for i in range(6):
r = r_color_max if _r[i] == '1' else 0
g = g_color_max if _g[i] == '1' else 0
b = b_color_max if _b[i] == '1' else 0
pixels.set_pixel_rgb(i,r,g,b)
pixels.show()
def display_binarys(h,m,s):
_r = '{:06b}'.format(h)
_g = '{:06b}'.format(m)
_b = '{:06b}'.format(s)
for i in range(6):
r = r_color_max if _r[i] == '1' else 0
g = g_color_max if _g[i] == '1' else 0
b = 0 if _b[i] == '1' else 0
pixels.set_pixel_rgb(i,r,g,b)
pixels.show()
def sekunde(channel):
t = datetime.datetime.now()
display_binary(t.hour, t.minute, t.second)
time.sleep(1)
def osekunde(channel):
t = datetime.datetime.now()
display_binarys(t.hour, t.minute, t.second)
time.sleep(1)
try:
GPIO.add_event_detect(SENSOR_PIN2 , GPIO.RISING, callback=osekunde)
while True:
time.sleep(0.01)
except KeyboardInterrupt:
print "Beende..."
GPIO.cleanup()
Alles anzeigen
Ich probiere noch weiter, aber wenn jemand einen Tipp hat: immer raus damit.
Dem ist so,
ich verstehe das so,
mit GPIO.add_event_detect registrierst Du einen Event, welcher prüfen soll ob SENSOR_PIN2 von
low nach high( GPIO.RISING ) wechselt und dann die Funktion osekunde (callback=osekunde) aufruft.
Das tut diese und dann bleibst Du in der while True Schleife gefangen solange bis Du per KeyboardInterrupt
beendest.
Das heisst, entweder rufst Du innerhalb der while True Schleife die Funktion wieder auf oder
Du hast eine Schleife innerhalb der osekunden Funktion.
Dein eigentlicher Wunsch, Sekunden reset und erneuter Start ist damit aber nicht gelöst.
2 Probleme die es zu lösen gilt.
1) Wenn Du einen Sekunden reset machen willst, mußt du die Sekunden, welche von datetime.now() geliefert werden
ignorieren in dem Du display_binary mit t.hour, t.minute und 0 aufrufst und dann selbst iterierst.
2) Die Logik braucht einen boolschen Wert, welcher erkennt, dass der erste Druck der Reset und der 2te Druck der Start der Uhr ist
also etwas wie
reset_seconds = False if reset_seconds else True
Ist es das was Du willst?
Oder soll jeder button druck einen second reset machen und den Loop neu starten?
def display_binary(h,m,s):
_r = '{:06b}'.format(h)
_g = '{:06b}'.format(m)
_b = '{:06b}'.format(s)
for i in range(6):
r = r_color_max if _r[i] == '1' else 0
g = g_color_max if _g[i] == '1' else 0
b = b_color_max if _b[i] == '1' else 0
pixels.set_pixel_rgb(i,r,g,b)
pixels.show()
def display_binarys(h,m,s):
_r = '{:06b}'.format(h)
_g = '{:06b}'.format(m)
_b = '{:06b}'.format(s)
for i in range(6):
r = r_color_max if _r[i] == '1' else 0
g = g_color_max if _g[i] == '1' else 0
b = 0 if _b[i] == '1' else 0
pixels.set_pixel_rgb(i,r,g,b)
pixels.show()
Alles anzeigen
Da habe ich mich etwas verwirrend ausgedrückt.
Mit "Sekundenanzeige auf 0" meinte ich nur, dass man den b-Wert auf 0 setzt. Hier im Code also der zweite Part b = 0 if _b[i] == '1' else 0, damit man die Sekundenanzeige deaktivieren kann.
Aber ich sehe schon, wo das Problem liegt.
Durch den Buttonpress löse ich für den Moment etwas aus. Das hat aber keine vorherige Definition.
Meine Vermutung:
Erst muss der Zustand definiert sein, welcher dann durch einen ersten Druck geändert wird. (IST Zustand bei Start: def Button: off)
Dieser Zustand muss dann neu geschrieben werden. Neuer IST Zustand für die vorherige Definition. (IST Zustand bei Druck def Button= on)
Bei erneutem Druck muss der IST Zustand erneut abgefragt werden (der ist ja jetzt anders als zuvor) und wieder geändert werden. (Wenn bei Druck Zustand = on, dann ändern auf off)
Und das Script selber reagiert dann auf die Abfrage des Zustands Button.
Wenn Button off: callback:display_binary
Wenn Button on: callbackk:display_binarys
Wobei auch das schon wieder falsch klingt. Es soll ja der Zustand durch 1-maligen Druck geändert werden, und nicht, so lange der Button gedrückt wird.
Vermutlich ist GPIO.RISING schon der falsche Ansatz. Button und Schalter sind ja zwei Dinge. Logisch, wenn man es als Problem vorliegen hat
Das ist ein ganz normaler Taster (wie in einer Tastatur).
Also geschlossen, so lange gedrückt. Offen, wenn nicht gedrückt.
Ok, aber je nachdem wie der Treiber bzw. die API für die Tastenabfrage geschrieben ist,
kann nur ein Zeichen oder immer wieder das gleiche Zeichen angezeigt werden.
Ich habe mal versucht dies per signal in Python darzustellen.
import signal
import os
import time, datetime
r_color_max = 255
g_color_max = 255
b_color_max = 255
use_seconds = True
def display_binary(h,m,s=0):
print '{}:{}:{}'.format(h,m,s)
_r = '{:06b}'.format(h)
print '_r:{}'.format(_r)
_g = '{:06b}'.format(m)
print '_g:{}'.format(_g)
_b = '{:06b}'.format(s)
print '_b:{}'.format(_b)
for i in range(6):
r = r_color_max if _r[i] == '1' else 0
g = g_color_max if _g[i] == '1' else 0
b = b_color_max if _b[i] == '1' else 0
print 'LED{} = {}'.format(i,(r,g,b))
def receive_signal(signum, stack):
global use_seconds
print 'Received signal:{}'.format(signum)
use_seconds = False if use_seconds else True
signal.signal(signal.SIGUSR1, receive_signal)
print 'My PID is:', os.getpid()
while True:
print 'Waiting...use_seconds:{}'.format(use_seconds)
t = datetime.datetime.now()
if use_seconds:
display_binary(t.hour,t.minute,t.second)
else:
display_binary(t.hour,t.minute)
time.sleep(1)
Alles anzeigen
Wenn Du das Skript in einer Shell ausführst bekommst Du als erstes die PID angezeigt.
In einer anderen Shell führst Du dann
kill -USR1 PID (das simuliert den Tastendruck)
aus. PID natürlich durch den richtigen Wert ersetzen.
Generell sollte das auch mit dem Taster und den LEDs funktionieren sofern der Tastendruck
nur einmal die Funktion, welche aufgerufen werden soll, aufruft.
Mit der Uhr bin ich auch noch nicht weiter. Mir hängt auch der Gedanke im Kopf fest, dass das ganze mit einem Arduino umzusetzen irgendwie sinniger erscheint.
Aber da bin ich noch bei 0.
Kein Grund die Form nicht mal zu überdenken.
Das ging mir gerade durch den Kopf:
wesentlich schwerer zu fertigen und nicht gerade leichter zu lesen. Aber man könnte die dann auch hinlegen und als Moodlight verwenden.
Dann den Code vielleicht nur alle 60 Sekunden in den Loop setzen. Wieder per Taster.
Welcher Arduino kommt den da in frage? Einige unterstützen RTCs
Und wie sieht es mit dem setzen der Uhrzeit aus?
Muß ja, jenachdem, jedesmal gemacht werden wenn der Arduino vom Strom genommen wird.
Der Code ansich (nur die display binary funktion) könnte so aussehen.
void display_binary(uint8_t h, uint8_t m, uint8_t s=0) {
for (int i = 5; i >= 0; --i)
{
uint8_t r = (((h >> i) & 0x1) == 1) ? 255 : 0;
uint8_t g = (((m >> i) & 0x1) == 1) ? 255 : 0;
uint8_t b = (((s >> i) & 0x1) == 1) ? 255 : 0;
c = Color(r, g, b);
strip.setPixelColor(5-i, c);
}
}
Der Aufruf wäre dann in der Form
Das andere (Color Struktur, strip Klasse etc...) kann vom Treppenstuffenprojekt übernommen und angepasst werden.
Wenn ein Arduino mit RTC zum Einsatz kommt, könnt darüber ein Alarm gestzt werden welcher minütlich die
Funktion aufruft und ansonst im sleep modus sich befindet.
Gruß
Claudia
Und wie sieht es mit dem setzen der Uhrzeit aus?
Ich habe ein DCF77 Modul bestellt. Damit hatte ich schon bei dem qlock-Projekt Kontakt: qlock2 Nachbau
Das halte ich noch immer für die beste Methode. Spart Tasten und ist immer genau genug.
Der Zähler im Arduino ging am Tag ~30 Sekunden vor. Wenn man jetzt 1x am Tag die DCF-Zeit abfragt, sollte das passen.
Ist noch auf dem Weg zu mir.
Das qlock2 sieht ja richtig super aus. Respekt - gute Arbeit.
DCF77 - das löst das Problem, ja
Und mit http://playground.arduino.cc/Code/DCF77 hast Du auch gleich Beispiele am Start.
Bin gespannt auf das Ergebnis.
Gruß
Claudia
Ich probiere gerade ein wenig mit verschiedenen Materialien herum.
Holz in grob sieht vielversprechend aus.
.
Bei 6 LEDs sind es in einem WS2801-Strang etwa 185mm Länge.
Geplant hatte ich mal mit 100mm. Naja - dann wird es halt wesentlich größer.
Ganz konkret weiß ich noch nicht, wohin das ganze führt. Größe, Material, Layout.
Aber lesen kann ich es mit Sekunden nicht. Ohne geht es. Dann sind es ja auch nur 3 Farbvarianten und man hat 60 Sekunden Zeit.
Aber ohne Sekunden sieht es nur halb so schön aus. Da muss ich noch eine Tasteroption einbauen, die zwischen den beiden Ansichten umschaltet.
Umsetzung am Arduino habe ich noch nicht begonnen. Die jetzigen Tests sind noch alle am Rasp.
Und ein kurzes Video:
Dann noch mal ein Hi an @ClaudiaF ... ich komme wieder nicht weiter.
Ich habe mir das hier zusammengedichtet:
#include <Adafruit_WS2801.h>
#include <SPI.h>
#include <Time.h>
uint8_t dataPinStrip = 10;
uint8_t clckPinStrip = 9;
uint8_t num_LEDs = 6;
uint8_t hue = 0;
uint32_t c = 0;
Adafruit_WS2801 strip = Adafruit_WS2801(num_LEDs, dataPinStrip, clckPinStrip);
void display_binary(uint8_t h, uint8_t m, uint8_t s=0) {
for (int i = 5; i >= 0; --i)
{
uint8_t r = (((h >> i) & 0x1) == 1) ? 255 : 0;
uint8_t g = (((m >> i) & 0x1) == 1) ? 255 : 0;
uint8_t b = (((s >> i) & 0x1) == 1) ? 255 : 0;
c = (r, g, b);
strip.setPixelColor(5-i, c);
}
{
display_binary(12, 30, 0);
}
}
Alles anzeigen
Die Time-Library ist installiert.
Aber der Code compiliert nicht mal durch. Es endet mit:
core.a(main.cpp.o): In Funktion `main':
/usr/share/arduino/hardware/arduino/cores/arduino/main.cpp:11: Nicht definierter Verweis auf `setup'
/usr/share/arduino/hardware/arduino/cores/arduino/main.cpp:14: Nicht definierter Verweis auf `loop'
collect2: error: ld returned 1 exit status
Aus der Readme zur TimeLib geht das hervor:
The functions available in the library include:
ZitatAlles anzeigenhour(); // the hour now (0-23)
minute(); // the minute now (0-59)
second(); // the second now (0-59)
day(); // the day now (1-31)
weekday(); // day of the week, Sunday is day 0
month(); // the month now (1-12)
year(); // the full four digit year: (2009, 2010 etc)there are also functions to return the hour in 12 hour format
hourFormat12(); // the hour now in 12 hour format
isAM(); // returns true if time now is AM
isPM(); // returns true if time now is PMnow(); // returns the current time as seconds since Jan 1 1970
Daher vermute ich, dass auch der Zeitaufruf anders sein muss. Wobei der Compilierungsfehler sicher nur etwas mit meinem Unwissen in c zu tun hat.
Hallo Don,
meines Wissens muß jedes Arduino Projekt mindestens die Routinen setup und loop haben.
Im setup wird alles initialisiert, wie strip.begin (siehe Lichterkette), und im loop werden
dann die Funktionen aufgerufen.
Gib mir mal kurz Zeit - poste gleich den Code wie ich denke das der funktionieren soll.
Gruß
Claudia
Don,
welche Time library hast Du eingebunden bzw. wo hast Du die her?
Cheers
Claudia
Ich habe die Library von Michael Margolis eingebunden und dieser Code kompiliert.
#include <Adafruit_WS2801.h>
#include <SPI.h>
#include <TimeLib.h>
#include <Time.h>
uint8_t dataPinStrip = 10;
uint8_t clckPinStrip = 9;
uint8_t num_LEDs = 6;
// uint8_t hue = 0;
uint32_t c = 0;
Adafruit_WS2801 strip = Adafruit_WS2801(num_LEDs, dataPinStrip, clckPinStrip);
uint32_t Color(uint8_t r, uint8_t g, uint8_t b)
{
return ((((r << 8) | g) << 8) | b);
}
void display_binary(int h, int m, int s=0) {
for (int i = num_LEDs-1; i >= 0; --i)
{
uint8_t r = (((h >> i) & 0x1) == 1) ? 255 : 0;
uint8_t g = (((m >> i) & 0x1) == 1) ? 255 : 0;
uint8_t b = (((s >> i) & 0x1) == 1) ? 255 : 0;
c = Color(r, g, b);
strip.setPixelColor(5-i, c);
}
strip.show();
}
void setup()
{
strip.begin();
}
void loop()
{
time_t t = now();
display_binary(hour(t), minute(t), second(t));
delay(1.0);
}
Alles anzeigen
Solltest Du keine Sekunden wollen, ersetze second(t) mit 0 innerhalb der loop Funktion (bzw rufe ohne second(t) auf).
Edit: strip.show() vergessen und ein Color Object wäre auch schön.
Cheers
Claudia
1000 Dank. Wird so bald wie möglich getestet.
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!