Hallo Bei meiner Schaltung habe ich 2 Taster, einer hängt an nem normalen GPIO, der andere Layoutbedingt am Resetpin (ATTiny85). In der finalen Codeversion funktioniert alles bis auf ein kleines Detail, was wohl mit der alternativ gesetzten Pinfunktion zu tun hat. Mit den 2 Tastern steuere ich RGB-LEDs. Wenn ich im Code testweise die Funktionen des "Problemtasters" dem anderen Taster zuweise, dann wird alles zur Zufriedenheit ausgeführt. Im Problemfall wird der µC aus dem Schlafzustand aufgeweckt, ändert einen Wert und geht dann wieder schlafen. Die Tasterauswertung erfolgt mit Peter Danneggers Entprellroutine, das Aufwecken erfolgt durch den PinChange-Interrupt. Irgendwas fehlt anscheinend noch beim "Function Override", aber ich kann's mir aus dem Datenblatt nicht ableiten. Danke für eure Tipps Hannes
Johannes H. schrieb: > Im Problemfall wird der µC aus dem Schlafzustand aufgeweckt, ändert > einen Wert und geht dann wieder schlafen. Das klingt doch ganz prima. Wo also ist das Problem? Oliver
Ich verstehe den Text nicht. Sehe auch keinen Schaltplan. Und auch keinen Code. Daraus folgt: Ich verstehe dein Problem nicht! ... Der Resetpin ist intern elektrisch etwas anders, als die andren. Denn er muss ja die 12V aushalten. Was genau anders ist, steht sicherlich im Datenblatt.
@Oliver S. Das war nur zur Beschreibung was der µC gerade macht, wenn das Problem auftritt. @Egberto Ja klar ist die Fuse gesetzt, sonst würde der Controller ja die ganze Zeit resetten... Zum Bild. Die internen AVR-Pullups sind aktiviert. Hier ist etwas Code, ich hoffe das reicht schon: Hier wird nach langem Drücken des Tasters der Wert für die LED-Helligkeit verändert:
1 | if( get_key_long(1<<KEY1) ){ |
2 | if( brightnessValue >= sizeof(brightnesses)/sizeof(uint8_t)-1 ) |
3 | brightnessValue = 0; |
4 | else
|
5 | brightnessValue += 1; |
6 | for(index = 0;index < 3;index += 1){ |
7 | LEDS[index].brightnessReduction = brightnesses[brightnessValue]; |
8 | } //cycle brightness |
9 | }
|
Und hier wird nach Durchlaufen der SwitchCase-Anweisung der µC in den Schlafzustand gelegt, wenn der Modus 7 eingestellt ist. Und auch nur in dem Modus tritt das Problem mit nur diesem Taster auf. Bei den anderen Modi klappt alles.
1 | /**** Case 7 All LEDs showing same color ******************************/
|
2 | case 7: for(index = 0;index < 3;index += 1) |
3 | LEDS[index].Color = COLOR[colorIndex]; |
4 | break; |
5 | /**** Default *********************************************************/
|
6 | default: break; |
7 | }
|
8 | |
9 | /**** Reduce Brightness *****************************************************/
|
10 | for(index=0;index<3;index+=1){ |
11 | LED_OUTPUT[index] = LEDS[index].Color; |
12 | LED_OUTPUT[index].r /= LEDS[index].brightnessReduction + brightnessAdjustRed; |
13 | LED_OUTPUT[index].g /= LEDS[index].brightnessReduction + brightnessAdjustGreen; |
14 | LED_OUTPUT[index].b /= LEDS[index].brightnessReduction + brightnessAdjustBlue; |
15 | }
|
16 | /**** Output of LED array to LEDs ********************************************/
|
17 | ws2812_setleds(LED_OUTPUT,3); //send COLOR to LEDs only when timer interrupt incremented pwmIndex |
18 | |
19 | /**** Put µC to sleep in constant color mode *********************************/
|
20 | if(modeIndex == 7){ |
21 | try_sleep(); |
22 | }
|
23 | |
24 | /**** Set µC in Idle mode after finished calculation inbetween timer interrupts (saves ~600µA) ************/
|
25 | GIMSK |= (1<<PCIE); |
26 | set_sleep_mode(SLEEP_MODE_IDLE); |
27 | sleep_mode(); |
28 | GIMSK &= ~(1<<PCIE); |
29 | }
|
:
Bearbeitet durch User
Johannes H. schrieb: > wenn das Problem > auftritt. Welches Problem plagt dich denn? Irgendwie kann ich das, in deinen Texten, noch nicht identifizieren.... Ich glaube, du hast vergessen dein Problem klar zu benennen. Oder ich habe es übersehen.
@Fanboy Dass die Helligkeit nicht verändert wird. Anscheinend wird das lange Drücken nicht korrekt detektiert.
Johannes H. schrieb: > Dass die Helligkeit nicht verändert wird. Anscheinend wird das lange > Drücken nicht korrekt detektiert. Das ist ja nur ein Symptom. So sucht man keine Fehler. Also suchen geht schon, aber finden tut man sie nicht. Du hast hoffentlich einen HV-Programmer oder einen Fusedoktor oder sowas ähnliches? Oder hast du deine letzte Option schon gezogen? Als erstes testest du, ob der Resetpin, der jetzt ja PB5 ist, überhaupt als Eingang funktioniert. Taster ran und bei gedrücktem Taster leuchtet eine LED. Loslassen und sie geht wieder aus. Haken dran. Dann baust du die Dannegger-Entprellung ein und testest, ob das immer noch funktioniert. Haken dran. Dann testest du die Press-Long Funktion des Dannegger-Codes. Nächster Haken. Jetzt kommt der zweite Taster dran. Erst separat und dann beide zusammen. Bis es funktioniert. Daß der Sleep-mode nicht erreicht wird oder irgendwelche Leds nicht gedimmt werden, interessiert bis dahin niemanden. Auch dich nicht.
Hi Thomas, Deine ausführliche Schritt-für-Schritt-Anleitung in Ehren, aber der Code funktioniert doch, nur eben nicht bei dem beschriebenen Fall. Das hatte ich doch (hoffentlich hinreichend) in meinem Text beschrieben. >In der finalen Codeversion funktioniert alles bis auf ein kleines >Detail, was wohl mit der alternativ gesetzten Pinfunktion zu tun hat. >Mit den 2 Tastern steuere ich RGB-LEDs. Wenn ich im Code testweise die >Funktionen des "Problemtasters" dem anderen Taster zuweise, dann wird >alles zur Zufriedenheit ausgeführt. Nen HV Programmer habe ich noch nicht, aber ich habe mehrere meiner fertigen Platinen hier vorliegen. Aber auch die bereits fertig programmierten sind verwendbar, weil der Problemfall, um den es geht, selten bis nie während der Nutzung benötigt wird.
Na, dann ist doch alles prima. Der hinreichend beschriebene Problemfall auf mehreren Platinen tritt im realen Leben so gut wie nie auf, und der Code funktioniert doch, und es bedarf keiner systematischen Fehlersuche. Dann wiederhole ich mal meine Frage von ganz oben: Wo also ist das Problem? Oliver
frage: was ist CP_EN ? So ganz komme ich jetzt nicht ganz mit. Wacht er auf, wenn der Pin gesetzt wird , oder nicht , oder unzuverlässig ? Wenn er nicht aufwacht, ist das bit im register gesetzt ? https://thewanderingengineer.com/2014/08/11/pin-change-interrupts-on-attiny85/ Laut datenblatt wirkt sich der interrupt auf alle ports aus und wenn du den reset umgewidmet hast, wird der genauso behandelt (insofern die maske gesetzt ist ). Wie programmierst du die dinger eigentlich neu ?
:
Bearbeitet durch User
@Oliver Lass es mich so formulieren: Mein Auto funktioniert wunderbar, nur wenn ich das Handschuhfach aufklappe leuchtet die Lampe da drin nicht. Ich würde aber gern rausfinden wieso und das abstellen ;) So ungefähr in der Wichtung liegt mein Problem. @Michael CP_EN ist das Chargepump_Enable Signal für die Ladungspumpe, die die LEDs versorgt. Ja aufwachen tut er, denn ein kurzes Drücken auf dem Problempin wird zuverlässig detektiert und die entsprechende Aktion ausgeführt. Aber wirklich nur in dem einen Modus klappt das mit dem langen Drücken nicht, in allen restlichen Modi klappt das ändern der Helligkeit. Seltsamerweise funktioniert das aber alles korrekt, wenn ich diese Helligkeitsänderung vom anderen Taster steuern lasse. (Testweise auf meiner Entwicklungsplatine, wo ich natürlich die RSTDISBL Fuse nicht aktiviere)
Johannes H. schrieb: > Zum Bild. Die internen AVR-Pullups sind aktiviert. Häng mal testweise externe Pull-Ups dran, zumindest am /RESET. Da der /RESET elektrisch anders ist als normale I/Os könnte hier eventuell ein Unterschied im Verhalten auftreten.
hatte die Seite noch offen, war kurz ein rauchen - hat sich überschnitten StromTuner
@Johannes H. man aber den RESET Pin auch ohne Fuse für eine Taste benutzen (via ADC)...
bei mir hat die Entrprellroutine nach dem sleep mal Probleme bereitet - versuch da mal mit einer Pause zu experimentieren...
Johannes H. schrieb: > Anscheinend wird das lange > Drücken nicht korrekt detektiert. Repeat-Maske richtig definiert? Werden auch immer beide Funktionen je Taste aufgerufen? Hier mal ein Beispiel mit Sleep: Beitrag "AVR Sleep Mode / Knight Rider"
So, also mit den Pullups oder der Konfiguration hat es nichts zu tun. Ich habe mal ein Board mit einer Version geflasht, wo ich diese Anweisung rausgenommen habe:
1 | if(modeIndex == 7){ |
2 | try_sleep(); |
3 | }
|
Da hat es funktioniert wie gedacht. Es muss also wohl mit der internen Elektronik dieses Reset Pins zusammenhängen. @Peter Ich verwende ja die "try_sleep" Funktion aus Deinem Beispiel ;) Falls ich das richtig verstanden habe: Ja für jeden Taster werden einmal getkeyshort und getkeylong abgefragt.
Johannes H. schrieb: > Ich verwende ja die "try_sleep" Funktion aus Deinem Beispiel ;) Für 2 Tasten mußt Du dann auch die REPEAT_MASK anpassen und auch beide Tasten an get_key_busy() übergeben.
Peter D. schrieb: > Für 2 Tasten mußt Du dann auch die REPEAT_MASK anpassen und auch beide > Tasten an get_key_busy() übergeben. Daran liegt es nicht. Es ist ganz eindeutig: Johannes H. schrieb: > Es muss also wohl mit der internen Elektronik dieses Reset Pins > zusammenhängen. Ich frage mich nur, was er hier will, wenn er die Ratschläge, die man ihm gibt und mit denen er seinen Fehler längst gefunden hätte, nicht annimmt. Daß er völlig beratungsresistent ist, hätte er auch gleich in seinen Ausgangspost schreiben können.
Peter D. schrieb: > und auch beide Tasten an get_key_busy() übergeben. Ach zu dumm, das hatte ich initial auch so gesetzt, aber beim Suchen des Fehlers hatte ich testweise was auskommentiert und so stand die Zeile die ganze Zeit bei mir im Code:
1 | if( get_key_busy(1<<KEY0) ) // || get_key_busy(1<<KEY1) ) // if KEYs are still busy return |
Jetzt funktioniert es. @Thomas Die Ratschläge waren gut, aber wie sich herausgestellt hat hatten diese ja nichts mit dem Problem zu tun. Erst Peters Fingerzeig hat die Lösung gebracht. Dass Du mich hier als "beratungsresistent" titulierst, finde ich nicht nett. Da könnte ich Dir im Gegenzug "Erkenntnisresitenz" unterstellen, da Du bei Deinem ersten Post überhaupt nicht realisiert hast, dass meine Tasterkonfiguration vollkommen korrekt ist.
:
Bearbeitet durch User
Johannes H. schrieb: > if( get_key_busy(1<<KEY0) || get_key_busy(1<<KEY1) ) Geht noch einfacher:
1 | if( get_key_busy(1<<KEY0 | 1<<KEY1) ) |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.