Forum: Compiler & IDEs Display-Menü programmieren


von Andy S. (andy11)


Angehängte Dateien:

Lesenswert?

Ich habe die Befürchtung, dass diese Zeilen:
in LCD_sheet0.c:
1
if( !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) ) //Next-page Taste gedrückt wird dann soll er nicht zurück ins Hauptprogramm sindern die nächste Seite anzeigen
2
  {
3
    displayLoad_POSSIBILITIESofACTING1();
4
  }
5
  else
6
  {
7
    //Wenn Auswahl getroffen dann schreibe in eine Variable welche Auswahl getroffen wurde:
8
    Auswahl_derPOSITION = pos0;
9
  }

in LCD_sheet1.c:
1
if( !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) ) //Next-page Taste gedrückt wird dann soll er nicht zurück ins Hauptprogramm sindern die nächste Seite anzeigen
2
  {
3
    displayLoad_POSSIBILITIESofACTING0();
4
  }
5
  else
6
  {
7
    //Wenn Auswahl getroffen dann schreibe in eine Variable welche Auswahl getroffen wurde:
8
    Auswahl_derPOSITION = pos1;
9
  }

eine Endlosschleife bilden.
Ich bilde mir ein das mit dem Schlüsseöwort inline beseitigt zu haben, 
jedoch noch zur Sicherheit hier reingestellt.

Das Problem was ich habe ist dass die ersten 2 Sheets miteinander 
zusammenhängen und ich diese durch nextpage angezeigt bekommen will.

Besides:
Eingabe Tasten: OK_TASTE  NEXT_PAGE_TASTE  RUNTER   RAUF


Danke für die Hilfe.

lg andy

von M.K. B. (mkbit)


Lesenswert?

Hi Andy,

ich weiß nicht genau, wie sich dein Menü verhält. Vielleicht postest du 
am besten mal eine Zeichnung, die das Problem verdeutlicht.

Ich habe jedoch auch noch etwas anderes gefunden, dass ein ähnliches 
Verhalten verursachen könnte.
Im Main-Loop rufst du immer displayLoad_POSSIBILITIESofACTING1 auf. 
Ist da so beabsichtigt?
Wenn du also immer bei Sheet 1 bleibst, dann liegt das Problem dort.

von Andy S. (andy11)


Angehängte Dateien:

Lesenswert?

Also ich habe das ganze gestern schon natürlich überarbeitet und zum 
Teil testbereit gestellt, dh die Hardware fehlt mir noch, und dann kann 
ich shcon Fehler suchen oder im Idealfall auch nicht.

Mk Bit schrieb:
> ich weiß nicht genau, wie sich dein Menü verhält. Vielleicht postest du
> am besten mal eine Zeichnung, die das Problem verdeutlicht.

Also: Da ich nicht wusste wie man so etwas progammiert habe ich mir ein 
eigenes System überlegt und entwickelt. Eine Zeichnung wäre nicht sehr 
einfach zu machen, da ich meine ganzen Überlegungen graphisch darstellen 
muss, und obwohl es noch nicht komplett fertig ist hätte ich wohl ohne 
meine jetzigen Kommentare nichts mehr im Überblick.

Es funktioniert von der Reihenfolge her so:

-->Zeige Begrüßung an und warte bis OK gedrückt wird

-->Zeige Sheet0 an (Auswahlmöglichkeiten)
   solange bis entweder OK gedrückt wird oder Pfeil nach rechts(TASTEN)

//Wenn Ok gedrückt wird dann wird das Unterprogramm verlassen und im 
Hauptprogramm fortgesetzt, und dort wird dann ausgewertet was ausgewählt 
wurde und je nachdem ob im Sheet 1 oder im Sheet 2 zeigt er das 
Untermenü an. (Also ziemlich primitiv)

//Wenn Pfeil nach rechts nedeutet das, dass die nächste Sheet angezeigt 
wird. Nächste Sheet deshalb da ich nur 4 Zeilen habe, jedoch aber 5 
Funktionen.

Und meine Angst ist jetzt dass wenn jemand immer hin und her wechselt 
dass da etwas passiert da ja das eine immer das andere aufruft, und 
deshalb auch inline. Aber trotzdem findet immer alles im if statt, also 
wahrscheinlich Fehlerquelle.

lg andy

Mk Bit schrieb:
> Im Main-Loop rufst du immer displayLoad_POSSIBILITIESofACTING1 auf.

Ich könnte auch das Programm ohne Main Loop machen, jedoch wird es mir 
dann nie möglich sein dass ich wieder alle Möglichkeiten anzeige (was 
mir jetzt zwar auch nicht gelingt weil das ganze in einer 
Linienverfolgungsschleife endet oder Ausweichmodus-Schleife und ich dort 
nicht irgendwelche Abfragen machen will da das meinen Regelkreis 
durcheinanderbringen könnte, aber ja).

lg andy

von Peter D. (peda)


Lesenswert?

In  der Regel will man nicht durch die Menüs durchsausen, solange der 
Finger auf der Taste ist, sondern nur ins nächste Menü.
D.h. man braucht eine Flankenerkennung um den Vorgang des Drückens zu 
erkennen und nicht den Zustand des Gedrückt seins.
Außerdem ist es unpraktisch, jedesmal aufs neue Entprellcode zu 
schreiben und Delay ist kein sonderlich wirksames Entprellen.

Besser ist also "Divide et impera", d.h. man lagert Entprellen und 
Flanke erkennen in eine eigene Funktion aus:

Beitrag "Universelle Tastenabfrage"

Nebenbei kann man damit auch ganz einfach lang/kurz, Repeat, 
2-Tasten-Funktionen usw. realisieren.


Peter

von Andy S. (andy11)


Lesenswert?

Peter Dannegger schrieb:
> In  der Regel will man nicht durch die Menüs durchsausen, solange der
> Finger auf der Taste ist, sondern nur ins nächste Menü.

Das hatte ich wohl nicht bedacht, du hast aber recht, das wird 
höchstwahrsheinlich passieren wenn ich zulange draufdrücken bleibe.

Wie schauts aus wenn ich sowas mache:
1
}
2
 while( !(EINGABE_TASTEN & (1<<OK_TASTE)) || !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) );
3
4
_delay_ms(500);
5
.
6
.
7
.
8
Auswertung

Dann habe ich 500ms Zeit die Taste auszulassen.

Peter Dannegger schrieb:
> D.h. man braucht eine Flankenerkennung um den Vorgang des Drückens zu
> erkennen und nicht den Zustand des Gedrückt seins.

Ja das wäre wohl die elegantere und deppensichere Lösung. Mir fallt da 
nur ein Interrupt ein der das bewerkstelligen könnte, int0, int1, dieser 
erkennt flanken, aber ist jetzt halt die Frage ob ich die noch verwende.

Peter Dannegger schrieb:
> und Delay ist kein sonderlich wirksames Entprellen.

Was kannst du mir für alternativen aufzählen?
Ich wüsste so auf die schnelle keine

Peter Dannegger schrieb:
> d.h. man lagert Entprellen und
> Flanke erkennen in eine eigene Funktion aus

Ich könnte mithilfe einer Variable arbeiten um dies zu realisieren, zB:
Wenn OK == 1 dann
  Funktion();

Funktion()
{
  var = 1;
  _delay_ms(20);
}

Auswertung:
.
.
.
var = 0;

Und gefragt wird halt die Variable var und nicht mehr TATSEROK


Ist das prinzipiell so in Ordnung?

lg andy

von Andy S. (andy11)


Lesenswert?

Sprich das ganze schaut dann pro sheet so aus:
1
/*
2
 * LCD_sheet0.c
3
 *
4
 *  Created on: 23.09.2010
5
 *      Author: Andy S
6
 */
7
8
//Unterprogramme------------------------------------------------------
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <stdint.h>
12
#include <avr/io.h>
13
#include <string.h>
14
#include <util/delay.h>
15
#include <avr/pgmspace.h>
16
#include <avr/interrupt.h>
17
#include <avr/eeprom.h>
18
#include <inttypes.h>
19
#include <math.h>
20
#include <avr/eeprom.h>
21
#include <stdbool.h>
22
23
//Headerfiles+Subroutines---------------------------------------------
24
#include "Unterprogramme.h"
25
#include "lcd-routines.h"
26
#include "uart.h"
27
#include "protocol.h"
28
//--------------------------------------------------------------------
29
30
uint8_t pos0 = 0;
31
32
inline void displayLoad_POSSIBILITIESofACTING0()  //INLINE da sonst Probleme wenn mehrere Pages mit Rücksprungadresse
33
{
34
  //LCD-Menü Deklarationen und Definitionen:
35
36
  show0();
37
38
  do
39
  {
40
    if(EINGABE_TASTEN & (1<<RAUF_TASTE)) //Wenn auf Runtertaste gedrückt wir dann:
41
    {
42
      _delay_ms(20); //entprellen
43
      if(pos0 < 5)      //POSITION wird nie überschritten
44
        pos0++;  //zähle Position hoch
45
    }
46
47
    else if(EINGABE_TASTEN & (1<<RUNTER_TASTE))   //Wenn Runtertaste gedrückt wird dann:
48
    {
49
      _delay_ms(20); //entprellen
50
      if(pos0 > 0)      //POSITION wird nie unterschritten
51
        pos0--;    //zähle Position runter
52
    }
53
    //Im Endeffekt ist der Wertebereich von 1 bis 4, also 4 Werte da 4 Zeilen
54
55
    switch(pos0)  //Schau dir die Position an wo der Zeiger gerade ist.
56
    {
57
      case 1: show0();            //Wenn auf erster Stelle dann lass den Benutzer wissen, dass er da ist indem er "<" rechtsbündig anzeigt
58
          lcd_setcursor(ENDZEICHEN,pos0);  //Auf letzte Position
59
          lcd_string(SETZE_AUSWAHL);    //"<" anzeigen
60
          break;
61
62
      case 2: show0();
63
          lcd_setcursor(ENDZEICHEN,pos0);
64
          lcd_string(SETZE_AUSWAHL);
65
          break;
66
67
      case 3: show0();
68
          lcd_setcursor(ENDZEICHEN,pos0);
69
          lcd_string(SETZE_AUSWAHL);
70
          break;
71
72
      case 4: show0();
73
          lcd_setcursor(ENDZEICHEN,pos0);
74
          lcd_string(SETZE_AUSWAHL);
75
          break;
76
77
      default:showERROR("!!FEHLER!!", "Datei: sheet0.c", "Funkt: switch(pos0)", "###############");  //Wenn position überschritten wird dann FEHLER
78
    }
79
80
    tasten_abfrage(); //schau nach welche Tasten gedrückt worden sind und merke dies in Variablen
81
  }
82
  while( (tasterOK == true) || (tasterNEXT == true) );
83
84
  if( tasterNEXT == true ) //Next-page Taste gedrückt wird dann soll er nicht zurück ins Hauptprogramm sindern die nächste Seite anzeigen
85
  {
86
    tasterNEXT = false;
87
    displayLoad_POSSIBILITIESofACTING1();
88
  }
89
  else
90
  {
91
    tasterOK = false;
92
    //Information steckt jetzt in pos0
93
    pos1 = 0; //Damit in der Auswertung unterschieden werden kann welche Sheet jetzt doch benutzt wird
94
  }
95
}
96
97
inline void show0()
98
{
99
  lcd_clear();
100
  lcd_setcursor(0, 1);
101
  lcd_string("Linienverfolgung....");
102
  lcd_setcursor(0, 2);
103
  lcd_string("Ausweichmodus.......");
104
  lcd_setcursor(0, 3);
105
  lcd_string("Spracherkennung.....");
106
  lcd_setcursor(0, 4);
107
  lcd_string("Linien + Ausweich...");
108
}

und weiters:
1
inline void tasten_abfrage()
2
{
3
  if( !(EINGABE_TASTEN & (1<<OK_TASTE)) )
4
    tasterOK = true;
5
6
  if( !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) )
7
    tasterNEXT = true;
8
}

lg andy

von Andy S. (Gast)


Lesenswert?

Peter Dannegger schrieb:
> D.h. man braucht eine Flankenerkennung um den Vorgang des Drückens zu
> erkennen und nicht den Zustand des Gedrückt seins.

Ok damit habe ich gar nichts bewirkt komme ich gerade drauf.
Aber wie mache ich das ohne Interrupt? Ich muss ja die steigende Flanke 
erkennen.
Mit einem PCINT geht es auch nicht, da wenn ich wieder auslasse wieder 
der PCINT aktiviert wird.

Die 3 Interrupts Int1, Int2, Int3 sind leider schon besetzt und hin und 
her schalten kann ich nicht, da müsste ich zuviele Abfragen machen also 
die Timer stehen mir auch nicht zur verfügung.

Ich sehe einfach keinen Weg das ohne Flankensteuerung realisieren zu 
können.

Was gibt es für Alternativen das ganze Softwaretechnisch zu lösen?

lg andy

von Karl H. (kbuchegg)


Lesenswert?

Andy S. schrieb:

> Ich sehe einfach keinen Weg das ohne Flankensteuerung realisieren zu
> können.

Du bist nicht sehr phantasievoll. Aber das wissen wir schon.

Wenn du jetzt nachsiehst, und feststellst ob am WC das Licht nicht 
brennt
und
du in einer halben Stunde feststellst, dass diesmal am WC das Licht 
brennt

dann
muss wohl irgendwer in der Zwischenzeit das Licht eingeschaltet haben.


Dein µC braucht dazu allerdings keine halbe Stunde, sondern der kann 
alle paar Mykrosekunden nachsehen, so wie halt gerade Zeit ist. Stellt 
er eine Veränderung fest, so hat jemand eine Taste gedrückt (oder 
losgelassen)

von Andy S. (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Du bist nicht sehr phantasievoll. Aber das wissen wir schon.
>
> Wenn du jetzt nachsiehst, und feststellst ob am WC das Licht nicht
> brennt
> und
> du in einer halben Stunde feststellst, dass diesmal am WC das Licht
> brennt
>
> dann
> muss wohl irgendwer in der Zwischenzeit das Licht eingeschaltet haben.
>
>
> Dein µC braucht dazu allerdings keine halbe Stunde, sondern der kann
> alle paar Mykrosekunden nachsehen, so wie halt gerade Zeit ist. Stellt
> er eine Veränderung fest, so hat jemand eine Taste gedrückt (oder
> losgelassen)

Also ich weiß jetzt nicht so recht ob du dir mein Coding angeschaut hast 
oder nicht, aber ich geh jetzt einmal davon aus dass es schon so ist 
weil ich nicht respektlos wirken will und Hilfe brauche und jeder Fehler 
macht.

Dieser Abschnitt dürfte wohl genau das machen was du gemeint hast wenn 
ich mich bei deinem Text verlesen habe (wenn ja dann bitte korr):
1
.
2
.
3
.
4
   case 4: show0();
5
          lcd_setcursor(ENDZEICHEN,pos0);
6
          lcd_string(SETZE_AUSWAHL);
7
          break;
8
9
      default:showERROR("!!FEHLER!!", "Datei: sheet0.c", "Funkt: switch(pos0)", "###############");  //Wenn position überschritten wird dann FEHLER
10
    }
11
12
    tasten_abfrage(); //schau nach welche Tasten gedrückt worden sind und merke dies in Variablen
13
  }
14
  while( (tasterOK == true) || (tasterNEXT == true) );
15
16
  if( tasterNEXT == true ) //Next-page Taste gedrückt wird dann soll er nicht zurück ins Hauptprogramm sindern die nächste Seite anzeigen
17
  {
18
.
19
.
20
.
1
inline void tasten_abfrage()
2
{
3
  if( !(EINGABE_TASTEN & (1<<OK_TASTE)) )
4
    tasterOK = true;
5
6
  if( !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) )
7
    tasterNEXT = true;
8
}

Das führt aber auch nicht zur Lösung denn wenn ich jetzt drücken bleibe 
speichert er das in einer Variable und wenn er jetzt aus der Funktion 
rauskommt und ich immer gedrückt halte dann ist die variable nur kurz 
false und dann wieder true bei der nächsten Tastenabfrage.

lg andy

von Karl H. (kbuchegg)


Lesenswert?

Andy S. schrieb:

> Dieser Abschnitt dürfte wohl genau das machen was du gemeint hast

No.
Das macht er nicht.

Veränderung feststellen bedeutet immer, dass man den Zustand jetzt mit 
dem Zustand vergleicht, an dem man das letzte mal nachgesehen hat. Dazu 
muss man sich diesen 'Zustand an dem das letzte mal nachgesehen wurde' 
aber irgendwo merken.

Und all diese Zutaten finde ich nicht in deinem Code.

1
   WC_Licht =  aktueller Zustand vom WC Licht
2
3
   while( 1 ) {
4
5
     WC_Licht_Now = aktueller Zustand vom WC Licht
6
7
     if( WC_Licht_Now != WC_Licht && WC_Licht_Now == eingeschaltet ) {
8
       jemand hat das Licht eingeschaltet
9
     }
10
11
     WC_Licht = WC_Licht_Now;
12
  }

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.