Für 36 LEDs benötigt man übrigends nur 7 Pins wenn man charlieplexed:
http://www.josepino.com/pic_projects...ntrol_leds.jpc
Druckbare Version
Für 36 LEDs benötigt man übrigends nur 7 Pins wenn man charlieplexed:
http://www.josepino.com/pic_projects...ntrol_leds.jpc
Schon ... aber das Tastverhältnis wird irgendwann gruselig, oder? ;-)
Stimmt, aber ich möchte die 4 Segmente separat als 3x3 Matrizen verschalten (bitte nicht nach Sinn und Unsinn dieser Maßnahme fragen ;)) und brauche daher pro Segment 4 Pins, insgesamt also 16.Zitat:
Zitat von radbruch
Das habe ich leider überflogen obwohl du es gleich zu Beginn erklärt hast. Sorry.Zitat:
...ich möchte die 4 Segmente separat als 3x3 Matrizen verschalten
Die logische Zuordnung der LEDs zu den einzelnen "Segmenten" geschieht eh softwaremässig. Es ist dann egal ob du 4x9 oder 1x36 aufbaust.Zitat:
Ich bin noch in der Phase in der es einfacher ist, wenn die Schaltung auch dem Aufbau der Logik entspricht
Ich schätze mal dass man das kurze Nachleuchten der LEDs nutzen kann. Aber Erfahrung habe ich damit auch keine, über 12LEDs/4Pins bin ich noch nicht hinaus.Zitat:
aber das Tastverhältnis wird irgendwann gruselig
gyrosp, ich kann dir die 4*9 Matrix nur ans Herz legen, denn 4 * charlieplex gleichzeitig ansteuern - viel Vergnügen, da ist das Multiplexen erheblich einfacher. Zumal das Tastverhältnis auch gegen Charlieplexen spricht, da du nur eine von 9 LEDs gleichzeitig leuchten lassen kannst. Ob die 3*3 Leds pro Segment optisch in einer Reihe oder kreisrund oder sonstwie angeordnet sind spielt wirklich keine Rolle.
Wenn du unbedingt eine 4*3*3 Matrix auf eine mehr als ungünstige und komplizierte Weise (sowohl hardware- als auch softwaremäßig) ansteuern möchtest, dann ist das natürlich dein gutes Recht :)
Viel Glück
MeckPommER
Mhh, ich denke vielleicht doch nochmal drüber nach ;). Ich werde jetzt erstmal ein paar Versuchsaufbauten machen.Zitat:
Zitat von MeckPommER
AS1110 oder aehnliches von anderen Herstellern?
Hallo
Ich habe nun einen kleinen Test mit 2*12 LEDs an 8 Pins gemacht. Gesteuert wird mit dem asuro (8MHz, ATMega8) in C. Die "Lücken" beim Schwenken sind die Impuls/Pause-Zeiten der PWM. Nochmal der Hinweis: Beim Charlieplexing brennt (pro Leiste) immer nur eine LED!
Bild hier
http://www.youtube.com/watch?v=dboh5SFD29g
Das Programm gibt per ISR je LED-Leiste ein Bitmuster mit PWM aus:
Das ist allerdings echt nur ein Testcode, die ISR läuft gnadenlos über. Aber als Einstieg schon mal nicht schlecht. Mit ein paar Optimierungen sollten 36 LEDs kein Problem sein.Code:#include <avr/io.h>
#include <avr/interrupt.h>
#define pin1a_on DDRB |= (1<<PB1); PORTB |= (1<<PB1)
#define pin1a_off DDRB |= (1<<PB1); PORTB &=~(1<<PB1)
#define pin1a_x DDRB &=~(1<<PB1); PORTB &=~(1<<PB1)
#define pin2a_on DDRB |= (1<<PB2); PORTB |= (1<<PB2)
#define pin2a_off DDRB |= (1<<PB2); PORTB &=~(1<<PB2)
#define pin2a_x DDRB &=~(1<<PB2); PORTB &=~(1<<PB2)
#define pin3a_on DDRB |= (1<<PB4); PORTB |= (1<<PB4)
#define pin3a_off DDRB |= (1<<PB4); PORTB &=~(1<<PB4)
#define pin3a_x DDRB &=~(1<<PB4); PORTB &=~(1<<PB4)
#define pin4a_on DDRB |= (1<<PB5); PORTB |= (1<<PB5)
#define pin4a_off DDRB |= (1<<PB5); PORTB &=~(1<<PB5)
#define pin4a_x DDRB &=~(1<<PB5); PORTB &=~(1<<PB5)
#define pin1b_on DDRC |= (1<<PC0); PORTC |= (1<<PC0)
#define pin1b_off DDRC |= (1<<PC0); PORTC &=~(1<<PC0)
#define pin1b_x DDRC &=~(1<<PC0); PORTC &=~(1<<PC0)
#define pin2b_on DDRC |= (1<<PC1); PORTC |= (1<<PC1)
#define pin2b_off DDRC |= (1<<PC1); PORTC &=~(1<<PC1)
#define pin2b_x DDRC &=~(1<<PC1); PORTC &=~(1<<PC1)
#define pin3b_on DDRD |= (1<<PD4); PORTD |= (1<<PD4)
#define pin3b_off DDRD |= (1<<PD4); PORTD &=~(1<<PD4)
#define pin3b_x DDRD &=~(1<<PD4); PORTD &=~(1<<PD4)
#define pin4b_on DDRD |= (1<<PD5); PORTD |= (1<<PD5)
#define pin4b_off DDRD |= (1<<PD5); PORTD &=~(1<<PD5)
#define pin4b_x DDRD &=~(1<<PD5); PORTD &=~(1<<PD5)
volatile unsigned char count72kHz, pwm;
unsigned int bitmustera=0b111111111111, bitmusterb=0b110010010011;
/* uses 72kHz timer => Sleep(x) = x/72kHz [sec] */
void Sleep(unsigned char time72kHz)
{
count72kHz = 0;
while (count72kHz < time72kHz);
}
void Msleep(unsigned char dauer)
{
while(dauer--) Sleep(72);
}
int main(void)
{
//unsigned char i;
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
OCR2 = 0x6E; // 36kHz @8MHz
TIMSK |= (1 << OCIE2); // 36kHz counter for sleep
sei();
while(1)
{
for(pwm=50; pwm > 0; pwm--) Msleep(5);
for(pwm=0; pwm < 50; pwm++) Msleep(5);
}
return(0);
}
/* uses timer2 (36kHz for IR communication */
/* counts falling and rising edge => 36kHz*2 = 72kHz */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
static unsigned char bit=0, count=0;
count72kHz ++;
pin1a_x;
pin2a_x;
pin3a_x;
pin4a_x;
if(count < pwm) {
if((bitmustera & (1<<bit))==1){
pin1a_on;
pin2a_off;
pin3a_x;
pin4a_x;
}
if((bitmustera & (1<<bit))==2){
pin1a_on;
pin2a_x;
pin3a_off;
pin4a_x;
}
if((bitmustera & (1<<bit))==4){
pin1a_on;
pin2a_x;
pin3a_x;
pin4a_off;
}
if((bitmustera & (1<<bit))==8){
pin1a_off;
pin2a_on;
pin3a_x;
pin4a_x;
}
if((bitmustera & (1<<bit))==16){
pin1a_x;
pin2a_on;
pin3a_off;
pin4a_x;
}
if((bitmustera & (1<<bit))==32){
pin1a_x;
pin2a_on;
pin3a_x;
pin4a_off;
}
if((bitmustera & (1<<bit))==64){
pin1a_off;
pin2a_x;
pin3a_on;
pin4a_x;
}
if((bitmustera & (1<<bit))==128){
pin1a_x;
pin2a_off;
pin3a_on;
pin4a_x;
}
if((bitmustera & (1<<bit))==256){
pin1a_x;
pin2a_x;
pin3a_on;
pin4a_off;
}
if((bitmustera & (1<<bit))==512){
pin1a_off;
pin2a_x;
pin3a_x;
pin4a_on;
}
if((bitmustera & (1<<bit))==1024){
pin1a_x;
pin2a_off;
pin3a_x;
pin4a_on;
}
if((bitmustera & (1<<bit))==2048){
pin1a_x;
pin2a_x;
pin3a_off;
pin4a_on;
}
}
pin1b_x;
pin2b_x;
pin3b_x;
pin4b_x;
if(count > pwm) {
if((bitmusterb & (1<<bit))==1){
pin1b_on;
pin2b_off;
pin3b_x;
pin4b_x;
}
if((bitmusterb & (1<<bit))==2){
pin1b_on;
pin2b_x;
pin3b_off;
pin4b_x;
}
if((bitmusterb & (1<<bit))==4){
pin1b_on;
pin2b_x;
pin3b_x;
pin4b_off;
}
if((bitmusterb & (1<<bit))==8){
pin1b_off;
pin2b_on;
pin3b_x;
pin4b_x;
}
if((bitmusterb & (1<<bit))==16){
pin1b_x;
pin2b_on;
pin3b_off;
pin4b_x;
}
if((bitmusterb & (1<<bit))==32){
pin1b_x;
pin2b_on;
pin3b_x;
pin4b_off;
}
if((bitmusterb & (1<<bit))==64){
pin1b_off;
pin2b_x;
pin3b_on;
pin4b_x;
}
if((bitmusterb & (1<<bit))==128){
pin1b_x;
pin2b_off;
pin3b_on;
pin4b_x;
}
if((bitmusterb & (1<<bit))==256){
pin1b_x;
pin2b_x;
pin3b_on;
pin4b_off;
}
if((bitmusterb & (1<<bit))==512){
pin1b_off;
pin2b_x;
pin3b_x;
pin4b_on;
}
if((bitmusterb & (1<<bit))==1024){
pin1b_x;
pin2b_off;
pin3b_x;
pin4b_on;
}
if((bitmusterb & (1<<bit))==2048){
pin1b_x;
pin2b_x;
pin3b_off;
pin4b_on;
}
}
if(bit<11) bit++; else { bit=0; if(count) count --; else count=49; }
}
Gruß
mic
Sieht nice aus :-)
Aber der Nachteil liegt auf der Hand: hast du 36 LEDs, leuchtet nur eine von 36 - also kann eine LED nur 1/36 der Zeit an sein, was keine gute Leuchtkraft mehr zuläßt. Teilst du die 36 LEDs in 4 Gruppen auf, mußt du 4 Charlie-Matrix-Felder gleichzeitig bedienen ... das ist dann schon etwas heftiger vom Programmieraufwand her.
Falls man aber wirklich nur wenige Pins zur Verfügung hat, ist Charlieplexing eine sehr feine Sache!
Gruß MeckPommER
Ich verstehe nicht, was gegen Schieberegister mit eingebauten Konstantstromquellen spricht...