Hallo zusammen,
ich bräuchte mal kurz eure Hilfe, weil iwie komm ich hier nicht weiter.
Ich habe mir aus den Tutorials ein Programm versucht zusammen zu
basteln, dass folgendes macht:
Ich habe am PC0 (ADC) einen FSR-Sensor (funktioniert ähnlich wien Poti
nur ändert er den Widerstand auf Druck).
Bei PB1 (0C1A) habe ich ein paar LED's angeschlossen übern Transistor.
Das Programm soll, wenn Druck auf dem FSR-Sensor ist, die LED's
aufleuchten lassen und per PWM dimmen. Liegt kein Druck auf dem Sensor
soll auch nix passieren. Ich habe beides einzeln hinbekommen, also Druck
auf den Sensor --> LED's fangen an zu leuchten und ich habe das
Programm, wo ein LED Fading statt findet. Wenn ich die beiden zusammen
wurschtel macht er nur ein wirres LED Fading, egal ob Druck oder nicht.
Leider check ich nicht so ganz warum und es würde mich sehr freuen, wenn
mich einer von euch in die richtige Richtung schubsen könnte :)
Danke schonmal
Ach ja, µC ist ein ATMega48
Danke für die schnellen Antworten.
Dass mit den 255 Stufen ist natürlich ein Übertragungsfehler gewesen,
welchen ich übersehen hatte, jetzt läuft die PWM auch sauber rauf und
runter.
Wenn ich das so mache, wie Karl Heinz gesagt hat, dann macht der µC nach
dem Start 3 mal die PWM und dann leuchten die LED's auf höchster Stufe
kontinuierlich.
Also mein Verdacht ist, dass ich erstens nicht aus der Fadingschleife
raus gehe, bzw. diese nicht nach einem PWM-Durchlauf beende.
Und was ich überhaupt nicht verstehe, warum der µC gar nicht auf den
Sensor reagiert?
Maximilian schrieb:> Also mein Verdacht ist, dass ich erstens nicht aus der Fadingschleife> raus gehe, bzw. diese nicht nach einem PWM-Durchlauf beende.
Quatsch.
Du musst systematischer testen.
Was mir an deinem Code schon mal nicht gefällt ist, dass du an den Pins
rumfummelst. Den Pin mit der LED schaltest du am ANFANG einmal auf
Ausgang. Und dann lässt du ihn auch in Ruhe. Die Helligkeit stellst du
nicht mittels irgendwelchen Portausgaben ein, sondern immer nur in dem
du das OCR Register umstellst. Du verlierst sonst unweigerlich den
Überblick.
> Und was ich überhaupt nicht verstehe, warum der µC gar nicht auf den> Sensor reagiert?
Dann musst du das eben erst mal testen, welche ADC Werte du bekommst.
Konfigurier dir eine PWM.
Dann stellst du erst mal fest, ob ein OCR Wert von 0 einer
ausgeschalteten oder einer eingeschalteten LED entspricht.
Danach konfigurierst du dir (im selben Programm) den ADC und gibst den
ADC Wert direkt auf die PWM, ohne Schnickschnack.
Und erst dann, wenn das funktioniert, machst du von dort aus weiter.
Ein Komplettprogramm aus Einzelteilen zusammenzuwürfeln funktioniert
meistens nicht. Du musst das wie ein neues Programm betracheten. Du
kannst dir aus einem anderen, älteren Projekt Codeteile mittels
Copy&Paste einfügen, das ist schon ok. Aber du musst das wie "Im Prinzip
schreib ich das neu, nur hab ich den Code schon" betrachten. So nach dem
Muster "Och da mach ich eine Mischung aus diesen beiden Programmen", das
wird meistens nix.
Jo haste Recht, bin wohl bissi zu planlos an die ganze Sache ran
gegangen. Jetzt bastel ichs nochmal neu und hoffe, dass es dann besser
klappt.
Aber danke soweit schonmal gell :)
Ok funktioniert soweit, danke nochmal.
Jetzt habe ich noch eine kleine Frage:
Und zwar möchte ich, dass solange der Sensor gedrückt wird die LED voll
leuchtet und sobald der Benutzer runter geht, die PWM beginnt. Leider
funktioniert es bei mir nur so, dass ich drücke und dann gleich die PWM
beginnt. Habe das mit einer if (druck > bestimmter Wert) Abfrage
gemacht:
if (Druck > bestimmter Wert1)
{
PORTB |= _BV(1);
}
if else (Druck < bestimmter Wert1) && (Druck > bestimmter Wert2))
{
for (i=0; i<1; i++) pwm_8_8(step_time/2);
}
else
{
PORTB &= 255-_BV(1); // 0 auf Bit 1 Ausgeben, Rest so lassen
}
}
Aber es mag nicht so wie ich will leider...
> if (Druck > bestimmter Wert1)> {> PORTB |= _BV(1);> }
Nochmal: Wenn die PWM den Pin unter ihrer Fuchtel hat, dann hat sie den
auch unter ihrer Fuchtel. Da kannst du an den Portpin zuweisen, bis du
schwarz wirst, das bewirkt gar nichts.
Wenn du die LED aufleuchten lassen willst, dann musst du ans OCR
Register einen Wert zuweisen, der 'voll aufgedreht' bedeutet.
Daher ja auch die Reihenfolge
1
intmain()
2
{
3
PortpinaufAusgang
4
5
PWMkonfigurieren
6
7
PWMeinschalten
8
9
---abhierhatdiePWMdieKontrolleüberdenPortpin---
10
11
while(1){
12
13
Messen
14
15
if(Messwert>Grenzwert)
16
OCR1A=Wertfür"Led volle Helligkeit"
17
18
elseif(Messwert<andererGrenzwert)
19
OCR1A=Wertfür"LED dunkel"
20
21
else
22
PWMeinmaldurchdimmen
23
}
24
}
nochmal im Klartext: vergiss den Portpin. Du hast keine Kontrolle mehr
über den Portpin. Die Kontrolle hast du an den PWM-Mechanismus des
Timers abgegeben. Also musst du auch mit diesem Mechanismus arbeiten. Du
musst nur einen entsprechenden Wert ans OCR Register zuweisen und der
Timer sorgt dann dafür, dass die LED auch mit dieser Helligkeit
leuchtet.
Ok, habs so umgebastelt, doch jetzt ist es so, dass wenn der obere
Grenzwert überschritten wird, leuchten die leds, lass ich los fährt der
µC auch die PWM, aber 2 mal hintereinander.
Danach springt er nur zufallsmäßig in die PWM nei, des hängt doch
bestimmt mit dem Zähler zam oder? Kann ich den iwie modifizieren, dass
der nach einer PWM stoppt und dann beim nächsten Aufruf wieder neu
startet oder so?
p.S.: Bitte blöden Fragen verzeihen, bin noch bissi am hinein wurschteln
:)
Es ist wieder mal an der Zeit an etwas zu erinnern:
Wenn du qualifizierte Kommentare zu deinem Code willst, dann musst du
den Code auch zeigen. Hier kann keiner wissen, wie und wodurch sich ein
bestimmtes Verhalten in deinem Code ergibt, wenn man deinen Code nicht
kennt.
Häng einfach dein C-File als Attachment an. Das ist für dich am
einfachsten und für uns auch.
Maximilian schrieb:> Danach springt er nur zufallsmäßig in die PWM nei, des hängt doch> bestimmt mit dem Zähler zam oder? Kann ich den iwie modifizieren, dass> der nach einer PWM stoppt und dann beim nächsten Aufruf wieder neu> startet oder so?
Dir scheint da etwas durcheinander zu kommen.
PWM ist der Mechanismus, der es dir ermöglicht die LED auf jede
beliebige Helligkeit zu setzen.
Das du den Mechanismus dazu benutzt, eine Aufleuchten und wieder
Runterdimmen zu implementieren ist aber eine andere Sache. Das ist zwar
nett, hat aber mit der PWM nur insofern zu tun, dass der Mechanismus die
PWM benutzt um das zu realisieren.
Und wenn eine for-Schleife zu Ende ist, dann ist sie auch zu Ende.
Maximilian schrieb:> Also ADC und PWM laufen alleine, nur das oben genannte Problem mag noch> net so gern laufen
OK. Ich seh mir das File jetzt nicht an. Ich hab extra noch
dazugeschrieben: Häng das C-File so wie es ist als Attachment mit an. Du
brauchst es weder umkopieren, du brauchst ihm auch keine andere
Dateiendung zu geben. Du brauchst gar nichts tun, als das C-File (mit
der Endung .c) so wie es ist als Attachment anzugeben. Das ist für dich
supersimpel und hier im Forum löst das dann das Syntaxhighlighting für
C-Files aus.
du würdest dir leichter tun, wenn du dir endlich mal eine etwas
vernünftige Form deines Codes angewöhnen würdest
1
if(adcval>30)
2
OCR1A=0;
3
4
elseif(adcval<29)
5
OCR1A=250;
6
7
else
8
pwm_8_8(step_time/2);
Eine Frage an dich:
Ohne jetzt kompliziert zu denken ... welchen Wert muss adcval haben,
damit du jemals in die PWM Funktion reinkommst?
(UNd vergleich noch mal deinen Code mit dem Skelett von weiter oben. Wo
hab ich die Initialisierung und Konfigurierung der PWM und wo hast du
sie. Was muss daher gegeben sein, damit die LED überhaupt unter PWM
Kontrolle steht?)
Meinst du jetzt den Wert bei dem Programm, wann er rein springt oder
welchen ich haben möchte, ich beantworte einfach beides, geht
schneller:)
Also der Sensor sitzt unter einem Silikonkissen und durch rumprobieren
habe ich festgestellt, dass wenn man 30 als Richtwert nimmt, die Arbeit
für den späteren Benutzer am besten ist.
Wenn ich es jetzt laufen lassen, dann ist es komischerweise nicht
Wertabhängig sondern so bissi zufallsmäßig, also man kann 10 mal mit dem
selben Druck draufdrücken (überprüfe es an der Widerstandsänderung übers
Multimeter) und es leuchtet kurz auf und beim 11 mal fährt er wie
gewollt die PWM.
Maximilian schrieb:> Also der Sensor sitzt unter einem Silikonkissen und durch rumprobieren> habe ich festgestellt, dass wenn man 30 als Richtwert nimmt, die Arbeit> für den späteren Benutzer am besten ist.
Der Wert wird aber höcht wahrscheinlich nicht ständig 30 sein. Je
nachdem wie gut dein ADC die Referenzspannung gebuffert hat, ist er auch
mal 29 oder 31. Und wenn der Sensor ein bischen rauscht, dann ist er
auch mal 28 oder 32
Deine Hysterese, in der du die LED nur 'blinken' lässt, ist verdammt
klein. Du willst doch haben, dass sie nur dann voll aufleuchtet, wenn
jemand auf den Sensor draufdrückt. D.h. da kommt dann plötzlich ein
extrem großer Wert vom ADC! Extrem groß ist zwar größer als 30, aber 31
ist es auch.
Ja das ist schon sehr richtig.
Also die 30 ist nur son Richtwert-grenzwert: so fest soll der Benutzer
quasi mindestens Drücken, damit die LEDs aufleuchten.
Aber die 2 Sachen was mir einfach nicht einleuchten wollen (hab die
halbe Nacht dran rumgetüftelt, leider kein pos. Ergebniss), die PWM
startet nicht immer, des macht den Eindruck, als müsste man den
richtigen Zeitpunkt "treffen" und wenn ich diesen getroffen habe, dann
fährt sie 2 mal und nicht nur 1 mal.
Woran kann das denn liegen?
Maximilian schrieb:> Ja das ist schon sehr richtig.> Also die 30 ist nur son Richtwert-grenzwert: so fest soll der Benutzer> quasi mindestens Drücken, damit die LEDs aufleuchten.> startet nicht immer, des macht den Eindruck, als müsste man den> richtigen Zeitpunkt "treffen" und wenn ich diesen getroffen habe, dann> fährt sie 2 mal und nicht nur 1 mal.> Woran kann das denn liegen?
Weil dein Wert vom ADC eben nicht 29 oder 30 ist.
Mach halt deine Hysterese mal ein bischen größer und erlaub einen
größeren Toleranzbereich, in dem durchgedimmt werden soll.
Alternativ: Häng eine UART an und lass dir die Werte vom ADC mal
ausgeben, damit du selber mal siehst, dass die Werte eben nicht so schön
sind, wie du dir das in Gedanken vorstellst. Die werden ein wenig
schwanken. Und diese Schwankungen must du zumindest in den Grenzwerten
berücksichtigen, damit dir die Funktionalität da nicht dauernd aus einem
Bereich in den anderen wechselt.
Dein ADC liefert Werte von 0 bis 1023 für 0 bis 2.56V
D.h. eine Schwankung des ADC Wertes von 2 entspricht einer Änderung der
Spannung von 5 MILLI-Volt! 5-tausendstel Volt. Ist dein Sensor wirklich
so rauschfrei? Die reale Welt ist nicht so ideal, wie du dir das
vorstellst.