Forum: Mikrocontroller und Digitale Elektronik AVR: Resetpin als GPIO --> Problem


von Johannes (menschenskind)


Lesenswert?

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

von Oliver S. (oliverso)


Lesenswert?

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

von Egberto (Gast)


Lesenswert?

Etwas wenig Info - Code?
Fuse gesetzt?

Grüße,

Egberto

von Einer K. (Gast)


Lesenswert?

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.

von Johannes (menschenskind)


Angehängte Dateien:

Lesenswert?

@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
von Einer K. (Gast)


Lesenswert?

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.

von Johannes (menschenskind)


Lesenswert?

@Fanboy
Dass die Helligkeit nicht verändert wird. Anscheinend wird das lange 
Drücken nicht korrekt detektiert.

von Thomas E. (thomase)


Lesenswert?

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.

von Johannes (menschenskind)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

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

von Michael F. (sharpals)


Lesenswert?

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
von Johannes (menschenskind)


Lesenswert?

@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)

von Dietrich L. (dietrichl)


Lesenswert?

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.

von Stromtuner (Gast)


Lesenswert?

externen Pull-Up drann, dann sollte es gehen...

StromTuner

von Stromtuner (Gast)


Lesenswert?

hatte die Seite noch offen, war kurz ein rauchen - hat sich 
überschnitten

StromTuner

von Egberto (Gast)


Lesenswert?

@Johannes H.

man aber den RESET Pin auch ohne Fuse für eine Taste benutzen (via 
ADC)...

von Egberto (Gast)


Lesenswert?

bei mir hat die Entrprellroutine nach dem sleep mal Probleme bereitet - 
versuch da mal mit einer Pause zu experimentieren...

von Peter D. (peda)


Lesenswert?

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"

von Johannes (menschenskind)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Thomas E. (thomase)


Lesenswert?

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.

von Johannes (menschenskind)


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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
Noch kein Account? Hier anmelden.