PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit PCF8574P eine Led dimmen?



AsuroPhilip
08.07.2011, 18:05
Hallöchen

Kann man mit einem PCF8574P eine Led dimmen, wenn ja wie?

Habe noch nichts dazu gefunden!

Einschalten mache ich so:

I2CTWI_transmitByte(pcf, 0b00000001);


mfG
Philip ;)

RobotMichi
09.07.2011, 13:51
Hallo,

nein, das geht leider nicht.
Der PCF8574 ist ein I/O-Expander, d.h. er kennt nur die Zustände Ein und Aus.
Du könntest allerdings einen PCF8591 verwenden, der hat einen Port, der als D/A-Wandler verwendet wird --> du kannst die Spannung einstellen

lg
Michi

Richard
09.07.2011, 14:59
Hallo,

nein, das geht leider nicht.
Der PCF8574 ist ein I/O-Expander, d.h. er kennt nur die Zustände Ein und Aus.
Du könntest allerdings einen PCF8591 verwenden, der hat einen Port, der als D/A-Wandler verwendet wird --> du kannst die Spannung einstellen

lg
Michi

Mann könnte aber auch alle 8 Pin mit Widerständen versehen und diese auf der LED Seite parallel schalten und so je nach gesetztem Pin Pin's den Gesamt R für die LED einstellen. Dazu muss man die Widerstände natürlich so berechnen das niemals der für die LED maximale Strom überschritten werden kann. Also alle 8 Ein (parallel) zusammen nur 20 mA zulassen. Je weniger parallel liegen, je dunkler wird die LED. :-)

Gruß Richard

AsuroPhilip
09.07.2011, 18:07
@Richard Das ist ja dann nur Port verschwendung.... :(

@RobotMichi Gut, dass kommt noch auf meine Bestellliste :p Nur habe ich mit einem D/A Wandler noch keine erfahrung ;) Wie sehe dann z.B. so ein Code aus?


der hat einen Port, der als D/A-Wandler verwendet wird

Gibs denn auch einen mit mehreren D/A-Ports ??

mfG
Philip

radbruch
09.07.2011, 18:30
Hallo

Wenn du mehrere LEDs dimmen willst, wie wär's denn dann mit Charlieplexing?

https://www.roboternetz.de/community/showthread.php?46211-LED-Matrix-am-RP6&p=443747&viewfull=1#post443747
https://www.roboternetz.de/community/showthread.php?38986-Charlieplexing-vs.-Schieberegister&p=371657&viewfull=1#post371657

Gruß

mic

SlyD
09.07.2011, 18:43
> Gibs denn auch einen mit mehreren D/A-Ports ??


Klar gibts da welche mit mehreren Kanälen aber die Gehäuse werden Dir nicht gefallen (SMD)

z.B.
TLC59116
TLC5922
oder
MAX6965
etc.


Alternative wäre einen Mikrocontroller entsprechend zu programmieren.


MfG,
SlyD


EDIT:
Den hier: http://focus.ti.com/lit/ds/symlink/tlc5940.pdf

Gibts auch in DIP --> TLC5940NT
Der hat aber kein I2C Bus Interface sondern SPI.
Kann man aber in Software emulieren - oder an die RP6-M32 Erweiterung ranhängen.

AsuroPhilip
09.07.2011, 19:05
Könnte nicht auch ein Atmega 8 die aufgabe übernehmen?

-> aber wie sage ich den atmega, die helligkeit, die die m32 bestimmt?

BMS
09.07.2011, 19:08
Hallo,
also man kann die LED auch dimmen, indem man den Pin am Portexpander schnell ein- und ausschaltet per I2C. Das müsste aber "häufig genug" (ca >25x pro Sekunde) geschehen, damit es für das menschliche Auge nicht flackert. Klarer Nachteil ist natürlich, dass bei dieser Variante dein Mikrocontroller fast nur noch damit beschäftigt ist, die Befehle über I2C zu senden. Wenn der µC noch nebenher was anderes machen soll, dann kostet das ziemlich Performance.
Hast du wirklich keinen PWM-Ausgang mehr frei am Mikrocontroller? Und wie viele LEDs möchtest du insgesamt ansteuern?
Kann man mit einem PCF8574P eine Led dimmen, wenn ja wie?Also nur eine? ;)
Grüße, Bernhard

AsuroPhilip
09.07.2011, 19:13
Hast du wirklich keinen PWM-Ausgang mehr frei am Mikrocontroller?
Alles schon belegt :(


Wenn der µC noch nebenher was anderes machen soll, dann kostet das ziemlich Performance.
Ja, der µC muss noch viel im Hintergrund machen!


Und wie viele LEDs möchtest du insgesamt ansteuern?
Zwei, könnten aber mehrere im laufe der Zeit werden!

Wenn ich einen PWM-Ausgang frei mache, wie mache ich das dann?


mfG
Philip

radbruch
09.07.2011, 19:27
Du kannst jeden beliebigen Pin verwenden, das Stichwort lautet "Software-PWM":

http://www.rn-wissen.de/index.php/Pwm#PWM_per_Software
http://www.mikrocontroller.net/articles/Soft-PWM

AsuroPhilip
09.07.2011, 21:19
Ich glaub ihr habt einen post übersehen....


Könnte nicht auch ein Atmega 8 die aufgabe übernehmen?

-> aber wie sage ich den atmega, die helligkeit, die die m32 bestimmt?

BMS
09.07.2011, 21:42
Könnte nicht auch ein Atmega 8 die aufgabe übernehmen -> aber wie sage ich den atmega, die helligkeit, die die m32 bestimmt?
Das funktioniert auch, damit wird der Hauptcontroller sogar entlastet.
Für den Atmega8 brauchst du dann ein Programm für z.B. einen I2C-Slave. Solche Programme gibt es bereits im Internet, kann aber auch selber programmiert werden. Dann musst du das Programm "nur" noch anpassen, um die LED über PWM zu dimmen.
Grüße, Bernhard

Richard
09.07.2011, 22:00
@Richard Das ist ja dann nur Port verschwendung.... :(



Stimmt natürlich aber mit diesem Baustein halt eine realisierbare Lösung. Ein echtes PWM Signal über I²C Senden wird eher weniger gut klappen. Aber es gibt ziemlich viele I²C Bausteine, möglich das es auch welche mit PWM Ausgängen gibt. Aber das war hier ja nicht die Frage. :-) Außerdem, so ein DAC besteht letztendlich auch nur aus einem R2R Netzwerk hat also intern noch viel mehr "Ausgänge". :-) Bei den Preisen und der möglichen Anzahl der Ausgänge ist "Verschwendung" relativ. :-)

Gruß Richard

AsuroPhilip
09.07.2011, 22:18
Ein echtes PWM Signal über I²C Senden wird eher weniger gut klappen.

Wieso, kann man nicht einfach nur "20" Senden und der atmega macht nur 20% der Leuchtkraft??


mfG
Philip

BMS
09.07.2011, 22:26
Wieso, kann man nicht einfach nur "20" Senden und der atmega macht nur 20% der Leuchtkraft??
Bei der Variante mit Atmega8 und entsprechender Programmierung ist das möglich.

-----

Verwendest jedoch du die PCF... dann musst du ständig ein- und ausschalt- Befehle senden, solange der Portexpander keine weitere Intelligenz hat.
;)

AsuroPhilip
09.07.2011, 22:33
Verwendest jedoch du die PCF... dann musst du ständig ein- und ausschalt- Befehle senden, solange der Portexpander keine weitere Intelligenz hat.

Das wäre ja dann auch wieder belastung des µC, deswegen wäre es ja besser einen andern µC bzw. PCF zu verwenden.

Richard
10.07.2011, 09:44
Das wäre ja dann auch wieder belastung des µC, deswegen wäre es ja besser einen andern µC bzw. PCF zu verwenden.

Genau, oder eben einen 8 Bit Port und 8 Widerstände vom I²C Chip "opfern", nicht elegant aber in der Not frisst der Teufel Fliegen.

Gruß Richard

wkrug
10.07.2011, 10:11
Und warum dann nicht gleich einen ATMEGA 8 als PWM Quelle verwenden ?
Der kann dann die PWM Signale für die LED's erzeugen. Eventuell könnte man noch einen ULN2803 als Treiber nachschalten.
Letztlich dürfte dasauch die preiswertese Lösung sein.
Als Verbindung zwischen dem Steuercontroller und dem Dimm- Controller würde ich SPI verwenden, weil das einfacher zu handeln ist als TWI ( I²C ).
Beide Schnittstellen sind als Hardware in den ATMEGA Controllern eingebaut.
Das Protokoll kann man sich dann selber ausdenken. Also entweder alle 8 Dimmwerte nacheinander übertragen, oder ein Kanalbyte gefolgt von einem Wertbyte bei Bedarf senden.
Eine weitere Möglichkeit wäre Dich am DMX 512 Protokoll ( serielle Schnittstelle ) zu orientieren.
Dadurch wäre dann die Ansteuerung von 512 Kanälen möglich und die Dimm Controller wären auch als abgesetzte Einheit über größere Entfernungen ( mehrere Hunder Meter ) ansteuerbar.

Es gibt da also eine Menge möglicher Lösungen.

Richard
10.07.2011, 12:28
Und warum dann nicht gleich einen ATMEGA 8 als PWM Quelle verwenden ?


Einfach weil explizit nach dem 8574 gefragt wurde. Natürlich gibt es andere möglicher Weise bessere Methoden, keine Frage! Ich habe hier auch schon von LED Treiber für bis zu 256 LED's !einzeln dimmbar! gelesen. :-) Fragt sich was die Teile kosten und wer das noch Löten kann...

Grüße Richard

AsuroPhilip
10.07.2011, 13:06
Natürlich gibt es andere möglicher Weise bessere Methoden, keine Frage!

Was wäre den eine bessere Lösung?


256 LED's !einzeln dimmbar!

2-4 reichen :p


mfG
Philip

AsuroPhilip
16.07.2011, 20:31
so... habe jetzt ein paar Ports der m32 frei gemacht ;-> Welche sind jetzt genau PWM-Ports (ohne software-pwm?) ? Wie kann man von da aus eine Led dimmen?

mfG
Philip

wkrug
16.07.2011, 20:56
Beim ATMEGA 8 Dil Variante sind das.
OC1A = PIN 15
OC1B = PIN 16
OC2 = PIN 17

Diese 3 Pins können als PWM arbeiten.
OC1A und OC1B laufen mit dem Timer 1
OC2 mit Timer 2

Bei einem anderen Controller nach OC Pins suchen.

Die Timer werden für den entsprechenden PWM Mode konfiguriert und die OCx Pins aktiviert und ein passender Prescaler gewählt.
Je nach dem Wert den man ins Comparematch Register schreibt kommt dann eine entsprechende Pulsweite raus.
Man kann gerade Timer 1 sehr vielseitig PWM- mässig programmieren. Vom 8Bit PWM bis 16Bit PWM ( 9 und 10Bit gehen auch soweit ich weiss ) ist da einiges möglich. Auch ein Ausgangssignal mit 50% Duty Cycle und änderbarer Frequenz.
Fast PWM solltest Du nicht machen, weil da keine Werte mit 0 ( = kein Signal ) möglich ist.
Initialisierungsstrings müsste ich jetzt zusammensuchen, da ich jetzt nicht ganz genau weiss was Du konkret brauchst hilft Dir das auch wenig.
Alles läuft dann in Hardware und benötigt deshalb keine zusätzliche Rechenleistung mehr, ausser zum Schreiben der Comparematch Register.

AsuroPhilip
16.07.2011, 21:07
Danke schonmal, aber ich meinte die pins vom atmega32. Hast du ein Beispielcode?

wkrug
17.07.2011, 09:27
Ok die Pins 40 Pin Dil Variante:
OC0 = PIN 4 Timer0
OC1A = PIN 19 Timer1
OC1B = PIN 18 Timer 1
OC2 = PIN 21 Timer 2

Der Code ist für nen ATMEGA 16 mit 8MHz Quarz und sollte auch auf nem 32 laufen.

Code in "C" für CodeVision:



// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
OCR1AL=uc_redtable[uc_red]; /* Werte für die PWM's übernehmen */
OCR1BL=uc_greentable[uc_green];
}

// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
OCR2=uc_bluetable[uc_blue]; /* Werte für die PWM's übernehmen */
}



// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Phase Correct PWM top=00FFh
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA1;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Phase Correct PWM top=FFh
// OC2 output: Non-Inverted PWM
ASSR=0x00;
TCCR2=0x62;
TCNT2=0x00;
OCR2=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x45;



Du musst jetzt nur noch die OCR Register mit Werten füllen und das Ding macht PWM.
Timer 1 ist, da die Bereiche mit Timer 2 zusammen passen mussten und DMX ohnehin nicht mehr als 256 Werte kennt, auf 8 Bit Modus eingestellt.
Timer 0 hab ich in diesem Beispiel nicht für PWM Erzeugung verwendet.
In den Overflow Interrupts bei Timer 1 und Timer 2 werden die aktuellen Helligkeitswerte in die OCR Register übernommen. Das vermeidet Glitches, Du kannst das aber auch ignorieren wenn Dich die Interrupts stören. Der Code ist Teil meiner DMX RGB Lampe mit High Power LED's.
Timer 0 ist hier nicht für die PWM Generierung verwendet - Ich brauchte nur 3 PWM Quellen.

Das Ganze ist nur ein Beispiel, man kann die PWM Quellen sehr vielseitig konfigurieren. Datenblatt lesen ist aber da Pflicht!

radbruch
17.07.2011, 12:29
Hallo

Ich würde das weiterhin mit Soft-PWM lösen. Irgendein Timer läuft ja eh meist schon mit, da muss man dann nur noch seine eigene Funktion einklinken:

#include <avr/io.h>
#include <avr/interrupt.h>

#define led1_init DDRD |= (1<<PD2) // LEDs an PD2 und PD3
#define led1_on PORTD |= (1<<PD2)
#define led1_off PORTD &= ~(1<<PD2)
#define led2_init DDRD |= (1<<PD3)
#define led2_on PORTD |= (1<<PD3)
#define led2_off PORTD &= ~(1<<PD3)

volatile unsigned char p=0;
volatile unsigned char led1_pwm=0, led2_pwm=0;

void pause_ms(unsigned int dauer)
{
while(dauer--)
{
p=36;
while(p); // p wird in der ISR runtergezählt
}
}

int main(void)
{
cli();
// Timer2: FastPWM, no prescaling, no OC2-Pin
TCCR2 = (1 << WGM20) | (1 << WGM21) | (0 << COM20) | (0 << COM21) | (1 << CS20);
OCR2 = 0x91; // duty cycle for 36kHz
TIMSK |= (1 << TOIE2);
led1_init;
led2_init;
sei();

while(1)
{
led1_pwm+=15;
if(led2_pwm) led2_pwm /=2; else led2_pwm=255;
pause_ms(500);
}
return(0);
}

SIGNAL (SIG_OVERFLOW2)
{
static char led_pwm=0;

TCNT2 += 0x25; // Frequenzkorrektur 36kHz

if(led_pwm)
{
if(led_pwm>led1_pwm) led1_off;
if(led_pwm>led2_pwm) led2_off;
}
else
{
if(led1_pwm) led1_on;
if(led2_pwm) led2_on;
}
led_pwm++;

if(p) p--; // 1/36000 Sek.
}Für einen 8MHz-Mega8 auf Basis der 36kHz des Timer2 (aus der asuro-Lib). Soll das nun ein Mega8 oder ein Mega32 werden? Oder gar der RP6?

Gruß

mic

AsuroPhilip
17.07.2011, 13:36
Danke schon mal für die antworten, werde es mal testen ;)

Soll ein Mega32 werden.

mfG
Philip

SlyD
17.07.2011, 18:06
so... habe jetzt ein paar Ports der m32 frei gemacht


Das hört sich für mich jetzt so an als ob er das RP6-M32 Erweiterungsboard meint und keinen einzelnen MEGA32.
Du musst da natürlich die Pinbelegung beachten.
PD5 / OC1A ist auf der M32 als Hardware PWM Port verfügbar die anderen aber alle nicht (OC2 ist mit dem Buzzer verbunden, wenn Du den nicht brauchst... ).

--> Software PWM ist schon die bessere Lösung gibt hier im Forum ja Libs dazu.

wkrug
17.07.2011, 19:19
Software PWM ist schon die bessere Lösung gibt hier im Forum ja Libs dazu.
Im Prinzip ist das schon richtig, aber das erzeugt auch eine Menge Prozessorlast. Wenns möglich ist würde ich immer Hardware PWM den Vorzug geben.
Es sei denn man braucht mehr Ausgänge, oder die Ausgänge müssen frei wählbar sein, oder die Timer sind mit anderen Aufgaben belegt.