Vorstellung und Newbie Fragen

Hallo Gemeinde,

ich bin Anfänger im Arduino Bereich und habe schon (recht mühsam)erste Erfolge erzielt.
Ich kann mit Strom umgehen und meine (Basic) Programmiererfahrungen endeten mit dem C64.
Hier ein paar Fragen:
Wie poste ich ein arduino-Sketch ?? mit "Insert-Media" ??

Wie kann ich denn eine numerische Variable in eine LCD-Ausgabefähige Textvariable umsetzen?
Hintergrund: ich habe eine Tastaturabfrage (5 Tasten-Keyboard) an einem Analogeingang realisiert und möchte im Display erstmal einen Text ausgeben (Keine, Hoch, Runter, Rechts, Links und Enter)

Wenn Ihr mit verraten könnt wie das mit dem Sketch-Posten so geht könnt Ihr das mal lesen

LC

Hallo und willkommen :0)

Am einfachsten ist es code hier mittels ['code] Dein Code ['/code] zu posten (' weglassen natuerlich ;0)).

Wegen deines Code problems wuerde ich dir mal das LCD Keypad Example von NUelectronics ans Herz legen (Hab kurz einige Kommentare hinzugefuegt):

#include <LCD4Bit_mod.h> 
LCD4Bit_mod lcd = LCD4Bit_mod(2);       //Library um das LCD anzusteuern (http://www.nuelectronics.com/download/projects/LCD4Bit_mod.zip)

//Die anzuzeigenden Meldungen
char msgs[5][15] = {"Rechts OK ", 
                    "Hoch OK    ", 
                    "Runter OK  ", 
                    "Links OK  ", 
                    "Start OK" };
                              
//In diesem Array stehen die AnalogRead Werte der einzelnen Knoepfe.
//Diese muessen von der Reihenfolge mit denen im oberen Array uebereinstimmen.                              
int  adc_key_val[5] ={30, 150, 360, 535, 760 };

//Wieviele Knoepfe gibts insgesamt
int NUM_KEYS = 5;

//Variable um das AnalogRead Signal zu speichern
int adc_key_in;

//Werte fuer die Erkennung 
//Im Grunde wird hiermit versucht dem System klar zu machen, ob etwas gedrueckt oder lange gehalten wird.
//Den sinn wirst du spaetestens weiter unten verstehen
int key=-1;
int oldkey=-1;



void setup() { 
  pinMode(13, OUTPUT);  //Die LED an 13 wird hier als Heartbeat benutzt

  lcd.init();
  lcd.clear();
  lcd.printIn("Keypad test:");
    
}

void loop() {

  adc_key_in = analogRead(0);    //Lese den Wert des Knopfes
  
  digitalWrite(13, HIGH);  
  
  key = get_key(adc_key_in);       //Mit der Funktion getKey wird der Analogwert in 
                                               //die entsprechende Buttonnummer umgewandelt. 
                                                 //Entsprechend dem Array oben.
      
      if (key != oldkey)                   //Falls der gedrueckte Wert nicht dem entspricht, 
                                                 //den wir zuletzt hatten, wurde ein neuer Knopf gedrueckt.
      {
    delay(50);                               //Debounce Zeit. Dafuer findet man im Playground ein Tutorial
      adc_key_in = analogRead(0);  //Hier wird der Analogwert nochmal gelesen
    key = get_key(adc_key_in);       //und wiederum umgewandelt.
    if (key != oldkey)                   //Wieder der Check, ob es WIRKLICH ein neuer Knopfdruck war      
    {                  
      oldkey = key;                         //Da wir uns jetzt 200% sicher sind, dass es sich um einen neuen 
                                                 //Knopfdruck handelt koennen wir diesen als aktuellen speichern.
      if (key >=0){                         //Wenn irgendetwas gedrueckt wurde (0 waere 'nichts' gedrueckt)
      lcd.cursorTo(2, 0);               //Dann beweg den Zeiger in die Zweite Reihe
              lcd.printIn(msgs[key]);  //Und Zeige die Message, die zum Key passt.
                                                 //Dies wird durch 'msgs[key]' erreicht. Hier wird einfach 1 -> 5 
                                                 //weitergereicht und damit dann die entsprechende Nachricht ausgewaehlt.
                                                 //Deswegen ist es so wichtig, dass die Arrays gleich aufgebaut sind.
      }
    }
  }
  
  //delay(1000);
  digitalWrite(13, LOW);
  

 
  
  
}

//Her wird der Analogwert in eine Zahl von 1 bis 5 umgewandelt.
int get_key(unsigned int input)
{
      int k;
    
      //Das gesamte Array mit den Werten wird durchlaufen
      //int  adc_key_val[5] ={30, 150, 360, 535, 760 };
      //'k' ist die Stelle im Array und im if wird ueberprueft, ob der Wert zum input passt.
      //Wenn das stimmt wird 'k' zurureckgegeben - also nicht der Wert sondern die Nummer 
      //fuer den Knopf.
      for (k = 0; k < NUM_KEYS; k++)
      {
            if (input < adc_key_val[k])
            {
           return k;
        }
      }
    
      //Falls zwar ein Wert gelesen wurde, dieser aber keinem Knopf zuweisbar ist, 
      //dann wird -1 gesendet.
    if (k >= NUM_KEYS)
        k = -1;     // No valid key pressed
    
    return k;
}

Erstmal vielen Dank für den Tipp... hatte ich echt übersehen...

Was mir zuerst am Code von NUelectronics aufgefallen ist das keine Mittelwertbildung stattfindet und das kann selbst bei 1% Widerständen zum "Werteflimmern" führen.
Nun... dann habe ich mal den Mut und zeige Euch mal meinen bisherigen Lösungsansatz (in der Hoffung das Ihr nicht die Hände über dem Kopf zusammen schlagt)

#include <LiquidCrystal.h>

// LiquidCrystal CTC420L01 im 4-Bit-Modus:
// rs an pin 8
// rw an pin 7
// enable an pin 6
// d4, d5, d6, d7 an Pins 5, 4, 3, 2
LiquidCrystal lcd( 8, 7, 6, 5, 4, 3, 2);
// Variablen
// taste = Abfragewert der Tastatur
// i = Laufvariable für Mittelwert-Schleife
// Backlightpin = Anschlußpin für BackLight
// Soundpin = Anschlußpin für Beeper
  int taste = 0;
  int tastegedr = 0;

  unsigned char i;
  char Backlightpin = 9;
  char Soundpin = 10;
  char*tastentxt[6][6] = {"keine" , "hoch", "runter" , " rechts", " Links" , " Set"};

void setup()
{
  pinMode(Backlightpin,OUTPUT);    //Dimmbarer Ausgang für Backlight
  analogWrite(Backlightpin,255);   //Licht voll an
  pinMode(Soundpin,OUTPUT);        //Soundausgang


  lcd.begin(4,20);                 // Definition eines 4 Reihen 20 Zeichen-Display
  lcd.clear();                     // Displayinhalt löschen
  lcd.noCursor();                  // Cursorblinken aus
        lcd.setCursor(1,0);
        lcd.print("Photo-Timer");
}

void loop()
{

  TastenLesen();
  DisplayAusgabe();

 
}


void TastenLesen()
{
    taste = 0;
    for (unsigned char i = 0;i< 8; i++)  // for Schleife zum 8-fachen aufsummieren 
    {                                    // des Tastaturwertes.
      taste = taste + analogRead(0);     // Einlesen und Mittelwertbildung
    }                                    // durch mathem. Teilung durch
    taste = taste >> 3;                  // die Anzahl der Schleifendurchläufe = binär 8

    if (taste > 1020)
     
    {
      tastegedr = 0;// keine Taste
   

          lcd.setCursor(0,1);
          lcd.print("Taste = "); 
          lcd.print(tastegedr);
          delay(30);
    }
    else
    {
      if (taste > 970 && taste < 976)//973   // Abfrage des eingelesenen Wertes "taste"
      {                                      // und Vergleich mit den Nominal-Werten
        tastegedr = 1;  // Set-Taste         // der jeweiligen Tast
              analogWrite(Soundpin,127);       //PWM macht noch keinen Ton... vielleicht umsteigen auf Digital
              delay(10);                      
              analogWrite(Soundpin,0);         //Sound aus        
                      
                                             // Für Debugging eingefügt
             lcd.setCursor(0,1);             // Positionierung im Display Reihe 1 Spalte 0
             lcd.print("Taste = ");          // Textausgabe 
             lcd.print(tastegedr);           // gefolgt von Inhalt der Variablen "taste"
             delay(30);                      // Kurze Pause
      }
      else
      {
        if (taste > 894 && taste < 900)//897
        {
          tastegedr = 2;  // Up-Taste
              analogWrite(Soundpin,127);       // tastenpiep
              delay(10);                      
              analogWrite(Soundpin,0);         //Sound aus          
          
                lcd.setCursor(0,1);
                lcd.print("Taste = "); 
                lcd.print(tastegedr);
                delay(30);
        }
        else
        {
          if (taste > 346 && taste < 352)//349
          {
            tastegedr = 3; //Down-Taste
              analogWrite(Soundpin,127);       //Tastenpiep
              delay(10);                      
              analogWrite(Soundpin,0);         //Sound aus
              
                  lcd.setCursor(0,1);
                  lcd.print("Taste = "); 
                  lcd.print(tastegedr);
                  delay(30);
          }
          else
          {
            if (taste > 716 && taste < 722)//719
            {
              tastegedr = 4; // Links-Taste
              analogWrite(Soundpin,127);       // Tastenpiep
              delay(10);                      
              analogWrite(Soundpin,0);         // Sound aus
              
                    lcd.setCursor(0,1);
                    lcd.print("Taste = "); 
                    lcd.print(tastegedr);
                    delay(30);
            }
            else
            {
              if (taste > 936 && taste < 942)//939
              {
                tastegedr = 5; // Rechts-Taste
               
              analogWrite(Soundpin,127);       // Tastenpiep
              delay(10);                      
              analogWrite(Soundpin,0);         // Sound aus
              
                      lcd.setCursor(0,1);
                      lcd.print("Taste = "); 
                      lcd.print(tastegedr);
                      delay(30);
              }
              else
              {

                
              }
            }
          }
        }
      }
    }
delay(200); // das ist eine "Antiflimmerpause"
  }


void DisplayAusgabe() 
{

  {

    lcd.setCursor(0,2);
    lcd.print("Sie drücken:");
    //lcd.print(tastentxt[tastegedr][6]);
    //lcd.print(tastentxt[6][tastegedr]);
    delay(500);
    //lcd.clear();
    delay(5);
  }
  
}

Ich schätze mal der Array-Ansatz ist völlig daneben...oder ??
Mir ging es darum aus der Varable tastegedr (das funktioniert) den numerischen Wert (0-5) in einen Text umzusetzen den dann in Display geprintet wird.

Das war bisher alles recht mühsam und ich habe lange gebraucht das bis hierher auch nur halbwegs zu verstehen...deswegen auch die endlosen Kommentare

Freue mich über Tipps und schaue mir mal die NUelectronic Lösung an.

LC

Das einzige, was mir als Unterschied beim ueberfliegen auffaellt ist deine Mittelwertsberechnung.. mag mich jetzt irren, aber die Aufloesung der Analog Pins ist so gering, dass es im Endeffekt eh nicht viel ausmacht wenn man um einige Prozent daneben liegt. Hatte bislang bei den Analogpins jedenfalls nicht das Problem, dass angelegte Widerstaende unterschiedliche Ergebnisse lieferten - also kannst du, denke ich, auch ohne Mittelwert arbeiten.

Was ich bei dir nicht verstehe ist, warum du tastentxt Mehrdimensional anlegst aber nur eine Dimension nutzt? Oder uebersehe ich da jetzt irgendwas?

Ansonsten hast du einiges 'unnoetiges' an Code in TastenLesen(). Anders als beim C64 oder vielen anderen Umgebungen ist es beim Arduino noetig darauf zu achten, was man an Code schreibt und vorallem wie viel. Wenn man redundanten Code einsparen kann sollte man dies tun.
Versuch mal folgendes:

void TastenLesen()
{
      //Funktionsinterne Variablen
    taste = 0;

      
      //Mittelwertbildung und Tastenfindung
    for (unsigned char i = 0;i< 8; i++)  // for Schleife zum 8-fachen aufsummieren
    {                                    // des Tastaturwertes.
      taste = taste + analogRead(0);     // Einlesen und Mittelwertbildung
    }                                    // durch mathem. Teilung durch
    taste = taste >> 3;                  // die Anzahl der Schleifendurchläufe = binär 8

      
      
      //So sieht das ganze etwas weniger kompliziert aus, findest du nicht? 
      //Das Ergebnis duerfte im Endeffekt das selbe bleiben, da du ja Ranges annimmst und nicht nur 
      //Schaust ob etwas groesser ist als das andere. 
            if (taste > 1020)
            {
            tastegedr = 0;// keine Taste
            }
            if (taste > 970 && taste < 976)//973   
            {                                      
              tastegedr = 1;  // Set-Taste        
            }
            if (taste > 894 && taste < 900)//897
            {
              tastegedr = 2;  // Up-Taste
            }            
            if (taste > 346 && taste < 352)//349
            {
              tastegedr = 3; //Down-Taste
            }            
            if (taste > 716 && taste < 722)//719
            {
              tastegedr = 4; // Links-Taste
            }            
            if (taste > 936 && taste < 942)//939
            {
              tastegedr = 5; // Rechts-Taste
            }
                  
                  
                  //Es reicht ja diesen Code zu erledigen, wenn man den Knopf hat ;0) 
                  //muss ja schliesslich nicht in jeder Abfrage stehen, wenn es doch dalles das selbe ist.
                  if(tastegedr != 0)
                  {
                    analogWrite(Soundpin,127);       //PWM macht noch keinen Ton... vielleicht umsteigen auf Digital
                    delay(10);
                    analogWrite(Soundpin,0);         //Sound aus

                                                   // Für Debugging eingefügt
                   lcd.setCursor(0,1);             // Positionierung im Display Reihe 1 Spalte 0
                   lcd.print("Taste = ");          // Textausgabe
                   lcd.print(tastegedr);           // gefolgt von Inhalt der Variablen "taste"
                   delay(30);                      // Kurze Pause
                  }
                  else //Keine Taste gedrueckt.
                  {
                   lcd.setCursor(0,1);             // Positionierung im Display Reihe 1 Spalte 0
                   lcd.print("Taste = ");          // Textausgabe
                   lcd.print("Keine");           // gefolgt von Inhalt der Variablen "taste"
                   delay(30);                      // Kurze Pause                  
                  }
                  
              }
            }
    }
  delay(200); // das ist eine "Antiflimmerpause"
  }

Hoffe, dass der Code funktioniert - musste grad freihand schreiben ;0)

Hallo Nachtwind.....

Dank erstmal....

ich habe mir gerne mal Deine vereinfachte Tatsaturabfrage zu eigen gemacht und erfolgreich angepasst.

Ein Wort zur Mittelwertbildung: Ich habe zuerst auch direkt auf Wert abgefragt aber dann halt festgestellt das es durchaus ein "Werteflimmern" geben kann und damit die Tastatur-Routine nicht greift und wie Du siehst habe ich ja "nur +- 3 Werte zur "Fensterbildung" genutzt.

mein Sketch sieht nun so aus:

#include <LiquidCrystal.h>

// LiquidCrystal CTC420L01 im 4-Bit-Modus:
LiquidCrystal lcd( 8, 7, 6, 5, 4, 3, 2); // RS=8, RW=7, Enable=6, D4, D5, D6, D7 an Pins 5, 4, 3, 2

// Variablen
  int taste = 0;            // taste = Abfragewert der Tastatur
  int tastegedr = 0;        // taste = Abfragewert der Tastatur
  unsigned char i;          // i = Laufvariable für Mittelwert-Schleife
  char Backlightpin = 9;    // Backlightpin = Anschlußpin für BackLight
  char Soundpin = 10;       // Soundpin = Anschlußpin für Beeper

// Definitionen
  #define beep 127          // Sound an für Tastenpieps
  #define nobeep 0          // Sound aus nach Tastenpieps

void setup()
{
  pinMode(Backlightpin,OUTPUT);    //Dimmbarer Ausgang für Backlight
  analogWrite(Backlightpin,255);   //Licht voll an
  pinMode(Soundpin,OUTPUT);        //Soundausgang


  lcd.begin(4,20);                 // Definition eines 4 Reihen 20 Zeichen-Display
  lcd.clear();                     // Displayinhalt löschen
  lcd.noCursor();                  // Cursorblinken aus
  lcd.setCursor(4,0);              // Cursor für Zentrierte Textausgabe positionieren
  lcd.print("Photo-Timer");        // Textausgabe
}

void loop()
{
  TastenLesen();
  DisplayAusgabe();
}

  void TastenLesen()
{
    //Funktionsinterne Variablen
    taste = 0;

                                              // Mittelwertbildung und Tastenfindung
    for (unsigned char i = 0;i< 8; i++)         // for Schleife zum 8-fachen aufsummieren
    {                                    // des Tastaturwertes.
      taste = taste + analogRead(0);          // Einlesen und Mittelwertbildung
    }                                    // durch mathem. Teilung durch
    taste = taste >> 3;                          // die Anzahl der Schleifendurchläufe >>3 = binär 8

                if (taste > 1020)                         // Ab hier beginnt die Auswertung :
            {                                         // Welche Taste wurde denn nun gedrückt ?
            tastegedr = 0;// keine Taste              // Abgefragt werden die Spannungswerte
            }                                         // die durch einen Spannungsteiler
            if (taste > 970 && taste < 976)//973      // an den analogen Eingang (Pin 0)
            {                                         // geführt werden.
              tastegedr = 1;  // Set-Taste            // Der Spannungswert wird durch verschiedene
            }                                         // Widerstände an den Tasten variiert.
            if (taste > 894 && taste < 900)//897      // Je nach Analog-Wert bekommt die Variable
            {                                         // tastegedr einen Wert von
              tastegedr = 2;  // Up-Taste             // 0 = Keine Taste,
            }                                         // 1 = Set oder Enter-Taste
            if (taste > 346 && taste < 352)//349      // 2 = Up-Taste
            {                                         // 3 = Down-Taste
              tastegedr = 3; //Down-Taste             // 4 = Links-Taste
            }                                         // 5 = Rechts-Taste
            if (taste > 716 && taste < 722)//719
            {
              tastegedr = 4; // Links-Taste
            }
            if (taste > 936 && taste < 942)//939
            {
              tastegedr = 5; // Rechts-Taste
            }

                  if(tastegedr != 0)                  // Wenn ungleich 0 dann hier weiter abarbeiten
                  {
                    analogWrite(Soundpin,beep);          //Tastenpieps
                    delay(10);
                    analogWrite(Soundpin,nobeep);          //Sound aus
                  }
}


void DisplayAusgabe()
{

    lcd.setCursor(0,1);                                    // Cursor im Display auf 2te Zeile Anfang setzten
    lcd.print("Tastennummer = ");                          // Text ausgeben
    lcd.print(tastegedr);                                  // dahinter die Tastennummer ausgeben
    delay(250);                                            // Kleine Pause

}

Woran ich mir die Zähne ausbeisse und Du hast es ja auch schon angesprochen:
ich möchte den Wert von tastegedr so auswerten das ich im Display nicht nur den numerischen Wert ausgebe sondern die Variable in einen Text zum Ausgeben im Display umsetze... meine Array Versuche waren da wohl mehr chaotischer Natur .......

LC

Deine Idee mit dem Array war schon gut, keine Angst.
Hast du schonmal versucht folgendes zu tun?

void DisplayAusgabe()
{
      char*tastentxt[6] = {"keine" , "hoch", "runter" , " rechts", " Links" , " Set"};

    lcd.setCursor(0,1);                                    // Cursor im Display auf 2te Zeile Anfang setzten
    lcd.print("Tastennummer = ");                          // Text ausgeben
    lcd.print(tastentxt[tastegedr]);                                  // dahinter die Tastennummer ausgeben
    delay(250);                                            // Kleine Pause

}

Hallo Nachtwind....

dank Deiner Hilfe bin ich (für meine Verhältnisse) recht gut weiter gekommen und kann berichten das es einwandfrei arbeitet.
Ich musste halt nur die entsprechenden Texte richtig sortieren bzw den Tastenwerten zuordnen.
Kleine Änderungen können große Wirkung haben.... Super

Sag mal.... hast Du da vielleicht noch sowas wie eine Menue-Vorlage ?
Oder Tipps wie ich ein Menue aufbauen kann ?

LC

Umm.. nein, nicht.. aber hier im Deutschen Forum hat jemand eine Menulib geschrieben, 'such' mal danach ;0)

Hallo Nachtwind,

habe ich gefunden und versuche mich daran....

Vielen Dank für Deine Unterstützung, die war lehr- und hilfreich

LC