Ein neues Projekt ist gerade unterwegs: Ähnlich dem FNordlicht bzw. BlinkM suchte ich eine Lösung eine einzelne RGB-LED seriell anzusteuern, die 100 einzelnen LEDs werden etwa einen Meter entfernt voneinander sein, so dass die bereits existierenden RGB Treiber für 8 oder 64 LEDs nicht wirklich praktikabel oder zu teuer waren. Momentan liefert digikey die PIC12F508 samt RGB-LEDs und pcb-pool wird nächste Woche die passenden Platinen in den Briefkasten werfen.
Statt I2C wird in dem PIC ein 24-Bit Schieberegister mit Latch realisiert. Nach dem Latch liegen dann die drei Software PWMs. Da links und rechts auch noch Lötpads hinmüssen, ist die Platine mit 10mmx17mm dann doch größer geworden als ursprünglich geplant, aber immer noch kleiner und deutlich günstiger.
Der PIC-Code samt Arduino-Library folgt sobald die ersten Tests erfolgreich waren.
Update 1:
Die Platinen sind zwar noch unterwegs, aber der PIC-Code ist mittlerweile fertig. Vorerst nur mit einem 8-Bit PWM, später folgt vielleicht ein Upgrade auf 10-Bit.
Ursprünglich sollte der Latch über den Watchdog-Timer erfolgen (wenn 18ms lang kein Taktsignal vorliegt, werden die Daten aus dem Schieberegister in die PWM-Register kopiert). Da unter den einzelnen Prozessoren der WDT-Timer aber schwanken kann (laut Datenblatt zwischen 9ms und 30ms) erfolgt jetzt die Übernahme über den integrierten Timer nach 10ms.
Update 2:Von pcb-pool kam jetzt das erste Bild vom Produktionsprozess. So wie es ausschaut, wird am Wochenende alles zusammengebaut.
Update 3:Alle Platinen sind nun bestückt und verlötet, morgen erfolgt der Upload des PIC-Codes:
Update 4:Die LEDs sind jetzt auch alle verbaut, fehlt nur noch der Funktionstest.
;; PWM-Code fuer RGB-Dot ;; Copyright 2010 Wolfgang Jung (w@elektrowolle.de) list p=12f508 #include p12f508.inc __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC ;; Register REG_B_RED EQU 0x08 REG_B_GREEN EQU 0x09 REG_B_BLUE EQU 0x0A REG_C_RED EQU 0x0B REG_C_GREEN EQU 0x0C REG_C_BLUE EQU 0x0D REG_LCLK EQU 0x0E REG_OVERFLOW EQU 0x0F REG_PWMCNT EQU 0x10 REG_WORK EQU 0x11 ;; Pinassignments PIN_RED EQU H'0' PIN_GREEN EQU H'1' PIN_BLUE EQU H'2' PIN_SDIN EQU H'3' PIN_SDOUT EQU H'5' PIN_SCLK EQU H'4' ;; Konstanten DEF_OPTION EQU 0xC7 ; Kein Wakeup, Kein Pull-Up, TOCS=fOSC/4, TOSE=1, PSA=TMR0, Prescale=256 DEF_TIMEOUT EQU 39 ; Bei 4 MHz und Prescale=256 -> etwa 10ms ORG 0x000 ;; startup MOVLW DEF_OPTION OPTION ;; Port-Config OIIOOO MOVLW 0x18 TRIS GPIO L_MAIN MOVF GPIO, W ; Lade Port nach W XORWF REG_LCLK, W ; XOR mit letztem CLK MOVWF REG_WORK BTFSS REG_WORK, PIN_SCLK ; Flanke von SCLK? GOTO L_NO_EDGE L_EDGE_DETECTED: BTFSC REG_LCLK, PIN_SCLK GOTO L_FALLING_EDGE L_RISING_EDGE: ;; steigende Flanke -> SDIN auswerten CLRF REG_OVERFLOW BCF STATUS, C ; clear CARRY-Flag BTFSC GPIO, PIN_SDIN BSF STATUS, C ; CARRY-Flag enthaelt nun SDIN, nun das Bit durch die 24-Bit schieben RLF REG_B_RED, 1 RLF REG_B_GREEN, 1 RLF REG_B_BLUE, 1 ;; letztes Bit merken fuer das naechste Modul BTFSC STATUS, C BSF REG_OVERFLOW, 0 GOTO L_CLR_WDT L_FALLING_EDGE: ;; Fallende Flanke -> letztes Bit wieder auf SDOUT schreiben BCF GPIO, PIN_SDOUT BTFSC REG_OVERFLOW, 0 BSF GPIO, PIN_SDOUT L_CLR_WDT: ;; Timer0 zuruecksetzen, Prescaler muss danach angepasst werden MOVLW 0 MOVWF TMR0 MOVLW DEF_OPTION OPTION ;; letzten Input merken MOVF GPIO, W MOVWF REG_LCLK L_NO_EDGE: ;; Keine Flanke seit DEF_TIMEOUT timer0 MOVLW DEF_TIMEOUT SUBWF TMR0, W ;; Prescaler muss angepasst werden MOVLW DEF_OPTION OPTION ;; Skip, wenn tmr0 < DEF_TIMEOUT BTFSS STATUS, C GOTO L_DO_PWM L_COPY_BUFFER_TO_PWM: ;; Daten aus Schieberegister in PWM-Register MOVF REG_B_RED, W MOVWF REG_C_RED MOVF REG_B_GREEN, W MOVWF REG_C_GREEN MOVF REG_B_BLUE, W MOVWF REG_C_BLUE L_DO_PWM: DECF REG_PWMCNT, F ; Ist pwmCnt == 0? BTFSS STATUS, Z GOTO L_PWM_RED ;;; PWMCnt == 0 -> Also alle Pins auf high BSF GPIO, PIN_RED BSF GPIO, PIN_GREEN BSF GPIO, PIN_BLUE L_PWM_RED: MOVF REG_PWMCNT, W SUBWF REG_C_RED, W BTFSS STATUS, Z ; Skip, wenn pwmCnt > red GOTO L_PWM_GREEN MOVF REG_C_RED, W ; Wenn red==0, dann niemals an BTFSS STATUS, Z BCF GPIO, PIN_RED L_PWM_GREEN: MOVF REG_PWMCNT, W SUBWF REG_C_GREEN, W BTFSS STATUS, Z GOTO L_PWM_BLUE MOVF REG_C_GREEN, W BTFSS STATUS, Z BCF GPIO, PIN_GREEN L_PWM_BLUE: MOVF REG_PWMCNT, W SUBWF REG_C_BLUE, W BTFSS STATUS, Z GOTO L_MAIN ; Zurueck zum Anfang MOVF REG_C_BLUE, W BTFSS STATUS, Z BCF GPIO, PIN_BLUE
Sehr snappy! Ganz unreligiös gefragt: Warum PIC nicht AVR? (Hab dir das die Info über das Giessharz gemailt)
War nur ein reiner Preisgrund. Der PIC kostet fast ein Drittel des billigsten ATTiny. Bei der Stückzahl spielt der Preis schon eine gewisse Rolle.