mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Variable einer Schleife ersetzen


Autor: Lokus Pokus (derschatten)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verwende folgende Schleife:
  while(1)
  {
    for (tpos=text1;pgm_read_byte(tpos)!='~';tpos++)
    {
        for (softx=0;softx<FONTWIDTH;softx++)
        {
        adcval = ReadChannel(6);
        ScrollLeft();
        PrintScrollColumn(pgm_read_byte(tpos),softx,0);
        Warte(adcval/1);
        }
    }
  }
  return 0;

Die Variable text1 ist eine Globale:
prog_uint8_t text1[] = "Das ist der erste Text ~";
prog_uint8_t text2[] = "Das ist der zweite Text ~";

Jetzt möchte ich gerne innerhalb der for-schleife eine Abfrage verwenden 
die mir tpos=text1 in tpos=text2 ändert. Sodas der 2te Text ausgegeben 
wird.

Also zb.:

if (ReadChannel(7) > 500) ...

Geht das? Wenn ja, wie?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Jetzt möchte ich gerne innerhalb der for-schleife eine Abfrage verwenden
> die mir tpos=text1 in tpos=text2 ändert. Sodas der 2te Text ausgegeben
> wird.
Du willst mitten in der Ausgabe des ersten Strings direkt an die selbe 
Postition des 2. Strings? Oder soll einfach der 2. String von vorne 
ausgegeben werden?

> if (ReadChannel(7) > 500) ...
Wo hättest du die Umschaltung gern?

BTW:
Mit C-üblichen nullterminierten Strings kannst du auch so schreiben:
    for (tpos=text1;pgm_read_byte(tpos);tpos++) ...

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

Bewertung
0 lesenswert
nicht lesenswert
Ich kann die Fragestellung auch nicht interpretieren. Hauptsächlich 
allerdings deshalb, weil ich mir aus deinem geposteten Codeabschnitt 
überhaupt keinen Reim machen kann. Was soll das Ziel sein? Dass die 
Buchstaben von links nach rechts langsam ausgegeben werden? Eine Art 
Scheibenwischereffekt?

Aber ich denke, du solltest als erstes anfangen, dir ein paar 
Hilfsfunktionen zu machen. Einzelzeichen ausgeben. String ausgeben.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Jetzt möchte ich gerne innerhalb der for-schleife eine Abfrage verwenden
>die mir tpos=text1 in tpos=text2 ändert. Sodas der 2te Text ausgegeben
>wird.


>for (tpos=text1;pgm_read_byte(tpos)!='~';tpos++)

Bastel dir einen Pointer, der statt fest auf "text1" zeigt, variabel 
ist.
Dann kannst du dir eine Abfrage bauen, in deren "then"-Zweig dieser 
Variablen die Adresse von text1 und in "else"-Zweig die Adresse von 
text2 zugewiesen wird.
Das kann man dann quasi unendlich erweitern...
Im Prinzip kannst du auch einfach tpos die jeweilige Adresse zuweisen.

Ich bin mir nicht sicher, aber vielleicht könnte es so gehen:

[c]
if (BedingungfuerText1)
   { tpos = text1;}
else
   { tpos = text2;}
for (;pgm_read_byte(tpos)!='~';tpos++)
.
.
.
}

Autor: Lokus Pokus (derschatten)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Funktion:
Das ganze ist eine Scrollschriftanzeige die den Text auf einem 12x10 
LED-Board ausgibt.
Dabei wird Buchstabenweise aus der Variabel text1 / text2 ausgelesen und 
nach links verschoben.


Die Umschaltung müßte meiner Meinung nach direkt in der FOR-Schleife 
passieren, weil ich gerne auch wärend dem Scrollen auf den anderen Text 
umschalten möchte, der anschließen natürlich von vorne beginnen soll.
Also denke ich müßte man die Schleife auch mit einem break; abbrechen.

Mit nullterminierten meinst du wohl Leerzeichen, oder?
Das ist nicht so toll, da Leerzeichen sowohl auch am Schluss noch 
erwünscht sind um den Scroller Platz zu schaffen für eine Wiederholung.

Das beispiel oben könnte zwar funktionieren, erlaubt mir aber keine 
Änderung in der Schleife mehr.
Oder könnte ich die Abfrage direkt in die Schleife legen?

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

Bewertung
0 lesenswert
nicht lesenswert
Manfred W. schrieb:

> Mit nullterminierten meinst du wohl Leerzeichen, oder?

Nein.
Nullterminiert: eine binäre 0 am Ende.
So wie in C seit jeher Strings gebildet werden.
http://www.mikrocontroller.net/articles/FAQ#Wie_fu...

Danke für die Funktionsbeschreibung. Jetzt ist klarer was das Ziel ist.

Du könntest es zb so machen
  useText = 1;

  while(1)
  {
    if( useText == 1 )   // was soll eigentlich angezeigt werden: Text1 oder Text2?
      tpos = text1;
    else
      tpos = text2;

    while( pgm_read_byte( tpos ) )
    {
      //
      // ein Zeichen komplett ausgeben
      //
      for (softx=0;softx<FONTWIDTH;softx++)
      {
        adcval = ReadChannel(6);
        ScrollLeft();
        PrintScrollColumn(pgm_read_byte(tpos),softx,0);
        Warte(adcval/1);
      }

      tpos++;

      //
      // Welcher Text sol überhaupt angezeigt werden
      //
      if( ReadChannel(7) > 500 )
        wantText = 2;
      else
        wantText = 1;

      // Hat sich das geändert gegenüber dem was zur Zeit angezeigt
      // wird
      if( wantText != useText )
      {
        // ja, dann schalte um und brich die momentante Ausgabeschleife ab
        // weiter gehts dann mit while(1) und dort wird dann der neue Text
        // eingestellt, indem tpos den neuen Textanfang kriegt
        useText = wantText;
        break;
      }
    }
  }
  return 0;

Ich habe das jetzt absichtlich etwas ausführlich und einfach 
geschrieben, damit du es verstehst. Man kann das auch alles etwas 
kompakter lösen. Aber so gehts auch.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mit nullterminierten meinst du wohl Leerzeichen, oder?
Ein Leerzeichen ist 0x20
Eine NULL ist 0x00

Dieser String:
>>> prog_uint8_t text1[] = "Das ist der erste Text ~";
sieht im Speicher so aus:
@text1 'D', 'a', 's', ' ', 'i', ... 'e', 'x', 't', ' ', '~', '/0'
@text1 0x44 0x61 0x73 0x20 0x69 ... 0x65 0x78 0x74 0x20 0x7E 0x00
Es ist im Speicher also 1 Byte mehr reserviert, als dein String 
tatsächlich lang ist. Und in diesem Zeichen steht die binäre Null als 
Ende-Kennung.

Autor: Lokus Pokus (derschatten)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch erstmal. Das ganze funtkioniert wunderbar anhand des 
Beispieles.
Ich habe den Code jetzt etwas abgespeckt und wollte das ganze mit 
CASE-Anweisungen verwenden, weil ich ja nicht nur 2 oder 3 verschiedene 
Texte einbauen möchte, sondern mehrere ca. 10

Nur scheint es in C keine vernünftige Anwendungsweise dafür zu geben.
CASE kann nur immer einen ganzen Wert haben, also nicht ">500" zb.?
  tpos = text1;

  while(1)                          // Endlosschleife
  {
    while(pgm_read_byte(tpos))                // Aktuelles Zeichen lesen
    {
      for(softx=0;softx<FONTWIDTH;softx++)        // Pixel des Zeichens abarbeiten
      {
         adcval = ReadChannel(6);
        ScrollLeft();                  // Platz schaffen und Zeilen nach links schieben
        PrintScrollColumn(pgm_read_byte(tpos),softx,0);  // Ganz rechts eine Spalte des Zeichens ausgeben
        Warte(adcval/1);                // Ein bischen warten damit es nicht zu schnell wird
      }
      tpos++;
      switch(ReadChannel(7))                  // was soll eigentlich angezeigt werden
      {
            case (>1000:)
          tpos = text1;
          break;
            case (>500)
          tpos = text2;
          break;
        case (>100)
          tpos = text3;
          break;
      }
    }
  return 0;
  }

Wie kann man sowas lösen?
Und was noch ein wenig unschön ist, das der Laufende Text verändert 
wird. Besser wäre, wenn die Anzeige komplett gelöscht wird und der 
Scroller mit dem neuen Text von vorne beginnt.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
switch-case braucht feste Vergleichswerte, keine Bereiche.
Du wirst ein paar if-Abfragen benutzen müssen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nur scheint es in C keine vernünftige Anwendungsweise dafür zu geben.
Mit einer If-Abfrage ginge das super...

BTW:
Deine forever loop hat ihren Namen nicht mehr verdient, weil sie durch 
ein return beendet wird   :-o
  while(1)                          // Endlosschleife
  {
    while(pgm_read_byte(tpos))                // Aktuelles Zeichen lesen
    {
      for(softx=0;softx<FONTWIDTH;softx++)        // Pixel des Zeichens 
      :
    }
    return 0;
  }

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Stegemann schrieb:
> Du brauchst ein C-Buch:
Als Tipp zum Sparen: es reichen auch die älteren Ausgaben, die für ein 
besseres Trinkgeld zu haben sind...

Autor: Lokus Pokus (derschatten)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs jetzt mit einigen IF hinbekommen.
Hat jetzt vielleicht noch jemand einen Tip für mich wie ich die Anzeige 
löschen kann bevor der nächste Text angezeigt wird?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steht das nicht im Datenblatt des Displays?
Du kannst natürlich auch verraten, welches LCD es ist; dann sieht 
bestimmt gerne jemand für dich nach...

Autor: Lokus Pokus (derschatten)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist kein LCD. Ist eine LED Platine mit 12x10 LEDs.

Noch eine andere Frage. Kann man bei einem else if kein or verwenden?

Also:
    if(useText==1) or (ReadChannel(7)>800)           // was soll eigentlich angezeigt werden: Text1 oder Text2?
      tpos=text1;
      else if(useText==2) or (ReadChannel(7)>400)
       tpos=text2;
    else
      tpos=text3;

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ALTA!!!  Kannst du mir mal verraten, wie du etwas programmieren 
möchtest, ohne die einfachste C-Syntax zu kennen?

Nimm ein C-Buch, oder von mir aus ein Online Tutorial, da steht alles 
der Reihe nach und auf einander aufbauend drin.

Du versuchst doch auch nicht, zum Beispiel Französisch zu lernen, indem 
du als erstes versuchst, einen französischen Buch zu schreiben, oder?

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... wie schon von Peter erwähnt:
Du brauchst ein C Buch!

...Natürlich kann man bei einem else if ein "OR" verwenden. Aber nicht 
so wie Du es gemacht hast.

Erst mal: guck mal auf Deine Klammersetzung. Was ist die else if 
Bedingung? Dein Compiler kann nicht hellsehen.

Zweitens: Wie wäre es mit:

else if ( ( Bedingung 1 ) || ( Bedingung 2 ) )



Werner

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...  Klaus  war schneller

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja, wenn er nicht C meint, sondern C++, dann geht es schon mit or...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der dezente Hinweis der Vorgängerposts geht in die Richtung:
    if( useText==1 || ReadChannel(7)>800 )           // was soll eigentlich angezeigt werden: Text1 oder Text2?
      tpos=text1;
    else if( useText==2 || (ReadChannel(7)>400 )
       tpos=text2;
    else
      tpos=text3;
Das Thema || sowie && wird in deinem neu zu kaufenden C-Buch unter dem 
Thema logische Operatoren abgehandelt. Binäre Verknüpfungen gehen mit | 
und &.

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

Bewertung
0 lesenswert
nicht lesenswert
Und für das löschen des Displays schreibst du dir jetzt als allererstes 
eien Funktion, die das macht (nachdem du in deinem neuen C-Buch 
nachgelesen hast, wie man Funktionen macht).

Diese Funktion rufst du dann auf, wenn du den Text wechselst.

Autor: Fred (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und ich würde mich mal dringends an deiner Stelle mit Array 
beschäftigen. Dann kannste deine Texte über einen Index ansprechen, und 
musst nicht immer extra eine Variable dafür definieren.

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.