mikrocontroller.net

Forum: Compiler & IDEs Display-Menü programmieren


Autor: Andy S. (andy11)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die Befürchtung, dass diese Zeilen:
in LCD_sheet0.c:
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
  {
    displayLoad_POSSIBILITIESofACTING1();
  }
  else
  {
    //Wenn Auswahl getroffen dann schreibe in eine Variable welche Auswahl getroffen wurde:
    Auswahl_derPOSITION = pos0;
  }

in LCD_sheet1.c:
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
  {
    displayLoad_POSSIBILITIESofACTING0();
  }
  else
  {
    //Wenn Auswahl getroffen dann schreibe in eine Variable welche Auswahl getroffen wurde:
    Auswahl_derPOSITION = pos1;
  }

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

Autor: M.K. B. (mkbit)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andy S. (andy11)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andy S. (andy11)
Datum:

Bewertung
0 lesenswert
nicht 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:
}
 while( !(EINGABE_TASTEN & (1<<OK_TASTE)) || !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) );

_delay_ms(500);
.
.
.
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

Autor: Andy S. (andy11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sprich das ganze schaut dann pro sheet so aus:
/*
 * LCD_sheet0.c
 *
 *  Created on: 23.09.2010
 *      Author: Andy S
 */

//Unterprogramme------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <string.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <inttypes.h>
#include <math.h>
#include <avr/eeprom.h>
#include <stdbool.h>

//Headerfiles+Subroutines---------------------------------------------
#include "Unterprogramme.h"
#include "lcd-routines.h"
#include "uart.h"
#include "protocol.h"
//--------------------------------------------------------------------

uint8_t pos0 = 0;

inline void displayLoad_POSSIBILITIESofACTING0()  //INLINE da sonst Probleme wenn mehrere Pages mit Rücksprungadresse
{
  //LCD-Menü Deklarationen und Definitionen:

  show0();

  do
  {
    if(EINGABE_TASTEN & (1<<RAUF_TASTE)) //Wenn auf Runtertaste gedrückt wir dann:
    {
      _delay_ms(20); //entprellen
      if(pos0 < 5)      //POSITION wird nie überschritten
        pos0++;  //zähle Position hoch
    }

    else if(EINGABE_TASTEN & (1<<RUNTER_TASTE))   //Wenn Runtertaste gedrückt wird dann:
    {
      _delay_ms(20); //entprellen
      if(pos0 > 0)      //POSITION wird nie unterschritten
        pos0--;    //zähle Position runter
    }
    //Im Endeffekt ist der Wertebereich von 1 bis 4, also 4 Werte da 4 Zeilen

    switch(pos0)  //Schau dir die Position an wo der Zeiger gerade ist.
    {
      case 1: show0();            //Wenn auf erster Stelle dann lass den Benutzer wissen, dass er da ist indem er "<" rechtsbündig anzeigt
          lcd_setcursor(ENDZEICHEN,pos0);  //Auf letzte Position
          lcd_string(SETZE_AUSWAHL);    //"<" anzeigen
          break;

      case 2: show0();
          lcd_setcursor(ENDZEICHEN,pos0);
          lcd_string(SETZE_AUSWAHL);
          break;

      case 3: show0();
          lcd_setcursor(ENDZEICHEN,pos0);
          lcd_string(SETZE_AUSWAHL);
          break;

      case 4: show0();
          lcd_setcursor(ENDZEICHEN,pos0);
          lcd_string(SETZE_AUSWAHL);
          break;

      default:showERROR("!!FEHLER!!", "Datei: sheet0.c", "Funkt: switch(pos0)", "###############");  //Wenn position überschritten wird dann FEHLER
    }

    tasten_abfrage(); //schau nach welche Tasten gedrückt worden sind und merke dies in Variablen
  }
  while( (tasterOK == true) || (tasterNEXT == true) );

  if( tasterNEXT == true ) //Next-page Taste gedrückt wird dann soll er nicht zurück ins Hauptprogramm sindern die nächste Seite anzeigen
  {
    tasterNEXT = false;
    displayLoad_POSSIBILITIESofACTING1();
  }
  else
  {
    tasterOK = false;
    //Information steckt jetzt in pos0
    pos1 = 0; //Damit in der Auswertung unterschieden werden kann welche Sheet jetzt doch benutzt wird
  }
}

inline void show0()
{
  lcd_clear();
  lcd_setcursor(0, 1);
  lcd_string("Linienverfolgung....");
  lcd_setcursor(0, 2);
  lcd_string("Ausweichmodus.......");
  lcd_setcursor(0, 3);
  lcd_string("Spracherkennung.....");
  lcd_setcursor(0, 4);
  lcd_string("Linien + Ausweich...");
}


und weiters:
inline void tasten_abfrage()
{
  if( !(EINGABE_TASTEN & (1<<OK_TASTE)) )
    tasterOK = true;

  if( !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) )
    tasterNEXT = true;
}


lg andy

Autor: Andy S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Andy S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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):
.
.
.
   case 4: show0();
          lcd_setcursor(ENDZEICHEN,pos0);
          lcd_string(SETZE_AUSWAHL);
          break;

      default:showERROR("!!FEHLER!!", "Datei: sheet0.c", "Funkt: switch(pos0)", "###############");  //Wenn position überschritten wird dann FEHLER
    }

    tasten_abfrage(); //schau nach welche Tasten gedrückt worden sind und merke dies in Variablen
  }
  while( (tasterOK == true) || (tasterNEXT == true) );

  if( tasterNEXT == true ) //Next-page Taste gedrückt wird dann soll er nicht zurück ins Hauptprogramm sindern die nächste Seite anzeigen
  {
.
.
.

inline void tasten_abfrage()
{
  if( !(EINGABE_TASTEN & (1<<OK_TASTE)) )
    tasterOK = true;

  if( !(EINGABE_TASTEN & (1<<NEXT_PAGE_TASTE)) )
    tasterNEXT = true;
}



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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

   WC_Licht =  aktueller Zustand vom WC Licht

   while( 1 ) {

     WC_Licht_Now = aktueller Zustand vom WC Licht

     if( WC_Licht_Now != WC_Licht && WC_Licht_Now == eingeschaltet ) {
       jemand hat das Licht eingeschaltet
     }

     WC_Licht = WC_Licht_Now;
  }

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.