2 gleiche Codes, 2 unterschiedliche Ergebnisse

Aehm. ne. Eigentlich nicht
Wenn die Abfrage in #58 richtig war, ist die Taste 0 der erste Wert gewesen und Du bekommst dann auch 0 zurück.

Das mit dem lange drücken schau ich gleich mal. Evtl. ist da noch ein delay() am Start.

Der Code muss sowieso noch überarbeitet werden.
Die Verschachtelungstiefe ist viel zuviel.

Das sind Anweisungen an die Formatierungsroutine, die mit STRG-T aufgerufen wird, diesen Bereich nicht zu verändern.

Geht nur in der IDE 1 und auch nur, wenn man selbst ein wenig Hand anlegt.
Eine Beschreibung dazu was möglich wäre, gibt es genauso wie ein angepasstes File für die IDE irgendwo von mir...

Hier Anleitung. Ist schon schick, wenn man alles hat und nicht kastriert ist :slight_smile:

1 Like

Sehr schön.

Wenn du Langeweile hast :wink: , kannst du aus der Tastenbehandlung eine Lib machen.
Zusatzideen:

  • Fehlerwert 255 "Taste nicht sauber erkannt" (+ Kalibrier-Utility, die entsrechenden Code generiert)
  • Unterscheidung "Fehler" von "keine Taste gedrückt"
  • Bereichsgrößen und Trennbereiche zwischen zwei Tasten "optimieren"

(Andere liefern 0 für keine Taste und '0' ... '9' ... für die entsprechende Taste)

Interessant, dass die switch-case Version besser optimiert als die Schleife.

2 Likes

Danke :slight_smile:

Na das wird dauern, aber ich habs auch schon im Auge gehabt.
Wird eine Herausforderung. Ich werd mich dran versuchen.

Ich denke mit dem notwendigen abs() wird das vermutlich zusammenhängen.

1 Like

Ihr seid einfach auf einem anderen Level, Gott sei dank gibt es das Internet haha

Da kannst Du auch hinkommen.
Oder meinst Du, ich hab das mit dem Löffel in der Wiege eingeflöst bekommen :rofl:

Unbedingt muss aber der Code noch aufgeräumt werden.
Ich hab mal angefangen.
Aus dem setup() muss das beschreiben des Displays raus.
Der Teil gehört dahin, wo auch der Rest herkommt.
Und dann mal das delay() für die Eingabe auf was sinnvolles herunter gesetzt.

code

// SD CARD ===============================================================

#include <SD.h>
#include <SPI.h>

constexpr uint8_t chipSelect {9};

// LCD ===================================================================

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

constexpr uint8_t lines {4};
constexpr uint8_t cols {20};
LiquidCrystal_I2C lcd(0x27, cols, lines);

// LEDs ==================================================================

#include <FastLED.h>

constexpr uint8_t NUM_LEDS {16};
constexpr uint8_t DATA_PIN {5};
constexpr uint8_t CLOCK_PIN {13};

CRGB leds[NUM_LEDS];

// VARIABLEN =============================================================

constexpr uint8_t maxPlayer {lines}; // Entspricht den Zeilen auf dem Display
uint8_t player = 0;                                       // Zeigt an, welcher Spieler dran ist
//uint8_t playerS;                                          // playerSelect, damit man während der Auswahl in der while-Schleife bleibt
uint8_t playerN;                                          // playerNumber, Anzahl der Spieler
uint8_t r = 1;                                            // round, Nummer der Runde
uint8_t i = 0;                                            // index, sorgt dafür, dass unsigned long nicht überschritten wird (9 Nummern max.)

int qC = 0;                                           // questionCheck
unsigned long a;                                      // answer, Antwort nach eingabe
uint8_t points[maxPlayer] = {0, 0, 0, 0};

uint8_t cursorX = 5;                                      // cursorXVariable, um den Cursor bei der Eingabe zu steuern
uint8_t old_inp[9];                                       // Array, der die vorherige Eingabe speichert, sodass man löschen kann

int ledP[maxPlayer] = {0, -7, 8, -15};

int ans = 1000;


constexpr uint8_t readPin {A3};
constexpr uint8_t buttons {12};
constexpr uint16_t btnVal[buttons] {1022, 316, 187, 512, 241, 158, 341, 195, 137, 256, 164, 121,};
//
void setup()
{
  Serial.begin(115200);
  delay(500);
  Serial.println(F("Start...."));
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  // KEYBOARD ================
  //**String key = "3 12 6 1 1022 315 186 511 241 158 340 195 136 255 164 120 0 0 0 0";
  //**keyboard.setupKey(key);
  lcd.init();
  lcd.backlight();
  if (!SD.begin(chipSelect))
  {
    lcd.setCursor(3, 1);
    lcd.print(F("Keine SD-Karte"));
    lcd.setCursor(4, 2);
    lcd.print(F("gefunden ://"));
    delay(10000);
  }
  lcd.setCursor(3, 1);
  lcd.print(F("Willkommen bei"));
  lcd.setCursor(4, 2);
  lcd.print(F("Trivia Guess"));
  for (byte b = 0; b < cols; b++)
  {
    lcd.setCursor(b, 0);                                  // Welcome LCD
    lcd.print('-');
    lcd.setCursor(b, 3);
    lcd.print('-');
  }
  for (byte b = 0; b < NUM_LEDS ; b++)
  {
    if (b < 4)                        // 0 ... 3
    { leds[b] = CRGB::Blue; }
    else if (b < 8)                   // 5 ... 7
    { leds[b] = CRGB::Red;  }
    else if (b < 12)                  // 8 ... 11
    { leds[b] = CRGB::Green; }
    else if (b < 16)                  // 12 ... 15
    { leds[b] = CRGB::Yellow; }
    if ((b + 1) % 4 == 0)             // 3, 7, 11 , 15 :-)
    {
      FastLED.show();
      delay(150);
    }
  }
  for (byte b = 0; b < NUM_LEDS; b++)
  {
    leds[NUM_LEDS - 1 - b] = CRGB::Black;
    if ((b + 1) % 4 == 0)
    {
      FastLED.show();
      delay(150);
    }
  }
  randomSeed(analogRead(0));
}

uint16_t getBtnValue()
{
  constexpr uint8_t steps {10};
  uint16_t value[steps] = {0};
  uint16_t maxValue = 0;
  uint16_t minValue = 1024;
  uint16_t myValue = 0;
  static uint16_t lastValue = 0;
  for (byte b = 0; b < steps; b++)
  { value[b] = analogRead(readPin); }
  for (byte b = 0; b < steps; b++)
  {
    if (maxValue < value[b])
    { maxValue = value[b]; }
    if (minValue > value[b])
    { minValue = value[b]; }
    myValue += value[b];
  }
  myValue -= (minValue + maxValue);
  myValue /= (steps - 2);
  if (abs(myValue - lastValue) > 10)
  { lastValue = myValue; }
  else
  { myValue = lastValue; }
  return myValue;
}


uint8_t getKeyValue()
{
  constexpr uint32_t debounceTime {50};
  static uint32_t lastPressTime = 0;
  static uint16_t lastValue = 0;
  static bool isPressed = false;
  uint16_t myValue = getBtnValue();
  uint8_t ret = 255;
  if (millis() - lastPressTime > debounceTime)
  {
    if (isPressed == false)
    {
      isPressed = true;
      lastValue = myValue;
      lastPressTime = millis();
      /*
        // Diese Variante braucht 24 Bytes mehr Variablenplatz....  !!!
        for (byte b = 0; b < buttons; b++)
        {
        if (abs(myValue - btnVal[b]) < 3)
        {
          ret = b;
          break;
        }
        }
      */
/*INDENT-OFF*/
      switch (myValue)
      {
        case btnVal[ 0]-2 ... btnVal[ 0]+2:  ret =  0; break;
        case btnVal[ 1]-2 ... btnVal[ 1]+2:  ret =  1; break;
        case btnVal[ 2]-2 ... btnVal[ 2]+2:  ret =  2; break;
        case btnVal[ 3]-2 ... btnVal[ 3]+2:  ret =  3; break;
        case btnVal[ 4]-2 ... btnVal[ 4]+2:  ret =  4; break;
        case btnVal[ 5]-2 ... btnVal[ 5]+2:  ret =  5; break;
        case btnVal[ 6]-2 ... btnVal[ 6]+2:  ret =  6; break;
        case btnVal[ 7]-2 ... btnVal[ 7]+2:  ret =  7; break;
        case btnVal[ 8]-2 ... btnVal[ 8]+2:  ret =  8; break;
        case btnVal[ 9]-2 ... btnVal[ 9]+2:  ret =  9; break;
        case btnVal[10]-2 ... btnVal[10]+2:  ret = 10; break;
        case btnVal[11]-2 ... btnVal[11]+2:  ret = 11; break;
        default:                            ret = 255; break;
      }
      Serial.print(F("Taste: "));
      Serial.print(ret);
      Serial.println(F(" ausgelöst"));
/*INDENT-ON*/
    }
    else if (lastValue != myValue)
    { isPressed = false; }
  }
  return ret;
}
//
void getPlayerNumber()
{
  uint8_t playerTemp = 0;
  lcd.clear();
  lcd.setCursor(2, 1);
  lcd.print(F("Spieleranzahl:"));
  lcd.blink();
  while (playerN == 0)
  {
    uint8_t inp = getKeyValue(); //**inp = keyboard.getKeyPressed();
    if (inp <= maxPlayer)
    {
      lcd.setCursor(16, 1);
      lcd.print(inp);
      playerTemp = inp;
    }
    if (inp == 12 && playerTemp > 0)
    {
      playerN = playerTemp;
      lcd.clear();
      lcd.setCursor(cursorX, 3);
    }
    delay(50);
  }
}
// LOOP ==================================================================
void loop()
{
  if (playerN == 0)
  { getPlayerNumber(); }
  //
  long solution[playerN];
  while (r < 2)
  {
    if (qC == 0)
    {
      char question[] = "000_0.txt";
      question[1] += random(5);            // Zufallszahl von '0' bis '4'
      question[2] += random(8);            // Zufallszahl von '0' bis '7'
      Serial.println(question);
      File text = SD.open(question, FILE_READ);
      if (text)
      {
        while (text.available())
        { Serial.print(text.read()); }
      }
      else
      { Serial.println(F("Datei konnte nicht gefunden werden")); }
      text.close();
      qC = 1;
    }
    uint8_t inp = getKeyValue(); //**inp = keyboard.getKeyPressed();
    switch (inp)
    {
      case 0 ... 9:
        if (i < 9)
        {
          lcd.setCursor(cursorX, 3);
          lcd.print(inp);
          Serial.println(a);
          Serial.print(F(" * 10 + "));
          Serial.print(inp);
          a = a * 10 + inp;
          cursorX ++;
          Serial.print(F(" = "));
          Serial.println(a);
          old_inp[i] = inp;
          i++;
          delay(250);
        }
        break;
      case 10:
        if (cursorX > 0)
        {
          cursorX --;
          lcd.setCursor(cursorX, 3);
          lcd.print(' ');
          i --;
          a = (a - old_inp[i]) / 10;
          delay(250);
        }
        break;
      case 11:
        if (i > 0)
        {
          solution[player] = a;
          // Reset
          i = 0;
          a = 0;
          cursorX = 5;
          memset(old_inp, 0, sizeof(old_inp));
          lcd.clear();
          lcd.setCursor(cursorX, 3);
          for (byte b = 0; b < 9; b++)
          {
            Serial.print(old_inp[b]);
            Serial.print(',');
          }
          if (player + 1 == playerN)
          {
            lcd.noBlink();
            for (byte b = 0; b < playerN; b++)
            {
              lcd.setCursor(0, b);
              lcd.print('S');
              lcd.print(b + 1);
              lcd.print(": ");
              lcd.print(solution[b]);
              delay(1000);                               // Maybe verlängern, nach Testen
              solution[b] = abs(ans - solution[b]);
            }
            for (byte b = 0; b < playerN; b++)
            {
              lcd.setCursor(4, b);
              for (byte c = 4; c < cols; c++)
              { lcd.print(' '); }
              lcd.setCursor(4, b);
              lcd.print(solution[b]);
            }
            Serial.println(solution[3]);
            delay(1000);                                  // Maybe verlängern, nach Testen
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print(F("A: "));
            lcd.print(ans);
            delay(1000);                                  // Maybe verlängern, nach Testen
            lcd.setCursor(0, 1);
            for (byte b = 0; b < sizeof(points); b++)
            {
              Serial.print(points[b]);
              Serial.print(", ");
            }
            int minV = solution[0];
            for (byte b = 0; b < playerN; b++)
            { minV = min(solution[b], minV);  }
            Serial.println(minV);
            for (byte b = 0; b < playerN; b++)        // Punktevergabe
            {
              if (minV == solution[b])                   // Falls der Kleinste Wert des Arrays an Position 0(1,2,3) ist...
              {
                points[b]++;                           // Im Punkte-Array an dieser Stelle +1
                Serial.println(F("points: "));
                Serial.print(points[b]);
                lcd.clear();
                if (points[b] == 4)
                {
                  r++;
                  lcd.setCursor(2, 1);
                  lcd.print(F("Spieleranzahl:"));
                }
                else                                        // Reset
                {
                  lcd.setCursor(cursorX, 3);
                  player = 0;
                }
                lcd.blink();
                /*INDENT-OFF*/
                // Je nach Spieler wird die enstprechende LED angesteuert
                switch (b)
                {
                  case 0: leds[abs(ledP[b])] = CRGB::Blue;   break;
                  case 1: leds[abs(ledP[b])] = CRGB::Red;    break;
                  case 2: leds[abs(ledP[b])] = CRGB::Green;  break;
                  case 3: leds[abs(ledP[b])] = CRGB::Yellow; break;
                }
                /*INDENT-ON*/
                ledP[b] ++;
                FastLED.show();
              }
            }
            delay(2500);
          }
          else
          {
            player ++;
          }
          delay(250);
        }
        break;
    }
  }
  playerN = 0;
}
1 Like

Hallo,

falls ihr etwas sucht womit man an einem analogen Eingang mehrere Taster anschließen kann und diese sauber unterscheiden möchte, kann ich etwas beisteuern, Man "darf" nur einen Taster drücken. Drückt man mehrere gleichzeitig gewinnt immer der mit dem kleinsten ADC Wert. Das ADC Spacing zwischen den Werten bleibt gleich, wenn man sich Mühe gibt bei der Auswahl des Widerstandwertes. Berechnung erfolgt mit Excel.

Elektrisch sieht das für 5 Taster so aus

Für 6 Taster verwende ich von R1 beginnend
20k, 3,9k, 5,9k, 10k, 20k und 60,4k
R99 ist 2k
C1 ist 47nF
Die Abstände vom ADC sind konstant 171.

Sketch
// getestet mit Arduino Nano Every

struct Taster {
  const uint8_t pin {A0}; // Pin D14
  uint32_t lastMillis {};
  uint8_t temp {};
  uint8_t alt  {};
  uint8_t neu  {};
} taster;

uint8_t oldButton;

void setup (void)
{  
  Serial.begin(250000);
  Serial.println(F("\nuC Reset ###"));
}

void loop (void)
{
  // Demo für eine Anzeige bzw. Ausgabe
  const uint8_t n = aktiverTasterIst(taster);
  if ( oldButton != n ) {
    Serial.print(F("Taster ")); Serial.println(n);
    oldButton = n;
  }
}

uint8_t aktiverTasterIst (Taster &b)
{
  const uint32_t ms {millis()};
  bool stabil {false};
  
  if (ms - b.lastMillis >= 10) {
    b.lastMillis = ms;
    b.temp = readAnalogTasterPin(b.pin);
      
    if (b.neu == b.temp) {      // wenn eingelesener Taster gleich vorherigen eingelesen Taster,
      b.alt = b.temp;           // dann wird aktueller Taster als stabil betrachtet
      stabil = true;
    }
    
    else if (b.neu != b.temp) { // wenn eingelesener Taster verschieden vom vorherigen eingelesen Taster,
      b.neu = b.temp;           // dann Änderung merken
    }
  }
  
  return (stabil ? b.neu : b.alt);
}

uint8_t readAnalogTasterPin (const uint8_t pin)
{
  const uint8_t  BUTTONS {6};
  const uint16_t RESOLUTION {1024};
  const float AVG = RESOLUTION / float(BUTTONS);
  uint8_t taster {0};
  
  const uint16_t val = analogRead(pin);
  
  for (uint8_t i = 0; i < BUTTONS; i++) {
    if (val < ((i + 0.5) * AVG)) { 
      taster = i + 1; 
      break;
    }
  }
  return taster;
}

Ursprung des Ganzes ist
Pushing ADC limits with the perfect multi-button input resistor ladder – Ignorant of Things.pdf (1,9 MB)

Viel Spaß.

1 Like

Schick.
Der TO hat eine fertige Lösung eingekauft. :wink:
Aber gut zu wissen, wen ich fragen kann.

Vielen, ich hab gerade technische Probleme und das LCD geht nicht mehr an. Keine Ahnung was da passiert ist. Vlt hab ich versehentlich zwei Kontakte berührt die ich nicht hätte berühren dürfen. Ich schau mal ob sich in ein zwei Stunden wieder was tut

Wenns Display gar nicht geht, dann Kontaktprobleme, und Spannungsversorgung ausschließen.

1 Like

ok. läuft wieder

Funktioniert jetzt alles top soweit :slight_smile: Ich bau dann mal fertig und räum etwas auf

if (qC == 0)
    {
      char question[] = "000_0.txt";
      question[1] += random(5);            // Zufallszahl von '0' bis '4'
      question[2] += random(8);            // Zufallszahl von '0' bis '7'
      for (byte b = 0; b < 3; b++) 
      {
        question[4] = 'b +1';
        Serial.println(question);
        File text = SD.open(question, FILE_READ);
        if (text)
        {
          while (text.available())
          {
          char ch = text.read();
          Serial.print(ch); 
          }
        }
        else
        { Serial.println(F("Datei konnte nicht gefunden werden")); }
        text.close();
      }
      qC = 1;
    }

Ich versuche jetzt, das dieser Code die Dateien (Bsp. wenn random = 21)
021_1.txt
021_2.txt
021_3.txt
sucht.

deswegen question[4] = 'b +1';

Allerdings ist mein Serial Output:
021_1.txt
021_1.txt
021_1.txt

Wie mach ich das sonst?

question[4]++; habs schon

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.