Go Down

Topic: Nach Tastendruck Drehschalter auswerten  (Read 2700 times) previous topic - next topic

uwefed

Hallo Tommy,
das mit den Analogeingängen hatte ich als Beispielcode im Internet gefunden.
Sollte natürlich auch über die digitalen Eingänge funktionieren.

Gibt es einen Nachteil bei meiner Variante?
Das Einlesen eines analogen Eingangs braucht viel Zeit (standarteinstellung ca 100µS). Wenn man die Auflösung verringert geht es auch schneller. Ein digitaler Eingang wird mit digitalRead in ca 4µS eingelesen. Über direktes ansprechen der Ports geht es erheblich schneller.

Nach dem Einlesen des analogen Eingangs mußt du noch einen Vergleich mit einem Wert machen um zu wisse ob der Eingang High oder LOW ist. Auch da braucht ein bißchen Zeit.

Darum sollte man digitale Signale immer digital auslesen.

Grüße Uwe

agmue

Ein digitaler Eingang wird mit digitalRead in ca 4µS eingelesen.
Und 5 Eingänge benötigen 20 µs.

Darum sollte man digitale Signale immer digital auslesen.
Mit dieser Aussage könnte man prächtig eine Grundsatzdiskussion beginnen, will ich aber nicht. Mir wäre der Satz "Darum sollte man digitale Signale vorzugsweise digital auslesen." näher an der Realität.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Tommy56

Mit dieser Aussage könnte man prächtig eine Grundsatzdiskussion beginnen, will ich aber nicht. Mir wäre der Satz "Darum sollte man digitale Signale vorzugsweise digital auslesen." näher an der Realität.
Wofür wäre Deiner Meinung nach ein analoges Auslesen eines digitalen Signals (außer Anwendung als Oszi) sinnvoll?

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

uwefed

Auch mir kommen keine Gründe in den Sinn wieso man ein digitales Signal analog abtasten soll.
Grüße Uwe

agmue

Tausche fünf digitale Eingänge gegen einen analogen und 80 µs. Ich habe halt mit einem ATtiny angefangen :)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Tommy56

Tausche fünf digitale Eingänge gegen einen analogen und 80 µs. Ich habe halt mit einem ATtiny angefangen :)
Das verstehe ich jetzt nicht. Die analogen Eingänge des Attiny lassen sich doch auch als digitale Eingänge verwenden.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

agmue

#21
Aug 28, 2017, 05:33 pm Last Edit: Aug 28, 2017, 05:33 pm by agmue
Meine Vorstellung ist so:



Fünf Schalterstellungen benötigen nicht fünf digitale sondern nur einen analogen Eingang.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Tommy56

Ach das meinst Du. Wenn genügend Eingänge frei sind, würde ich trotzdem die 5 digitalen Eingänge vorziehen. Wenn man diese dann noch auf einen Port legt, ergibt das eine schnelle Lösung.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

agmue

Ich stimme Dir vollkommen zu, wollte das absolute Wort "iimmer" ja auch nur durch das empfehlende "vorzugsweise" ersetzt haben.

Diese Formulierung von einem Schüler hätte ich überlesen, aber Uwe kennt den sprachlichen Unterschied in der Bedeutung, weshalb ich Absicht vermute. Außerdem hat die Aussage eines Brattain Member besonderes Gewicht, da bin ich dann möglicherweise etwas zu pingelig.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Tommy56

Dein Signal aus #21 ist aber letztendlich ein analoges Signal durch die Widerstandskette.

Ich kann mir immer noch keine sinnvolle Lösung vorstellen, bei der es besser wäre, ein rein binäres Signal analog einlesen zu wollen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

uwefed

#25
Aug 28, 2017, 08:10 pm Last Edit: Aug 28, 2017, 08:22 pm by uwefed
Tausche fünf digitale Eingänge gegen einen analogen und 80 µs. Ich habe halt mit einem ATtiny angefangen :)
In Diesem Fall hast Du kein digitales Signal sondern machst Du mit einem Spannungsteiler mit mehreren Widerständen und mehreren Schaltern ein analoges Signal. Da braucht es einen analogen Eingang (oder theoretisch gesprochen weil praktisch diskret aufgebaut zu aufwändig einen weiteren Spannungsteiler und viele Komparatoren, was dann aber ein einfacher AD/Wandler ist).
In dem von Dir beschriebenen Fall gebe ich dir recht, es brauchst einen analogen Eingang für ein analoges Signal (Signal mit mehreren diskreten Spannungspegeln).

Ich verstehe unter digitalem Signal ein Signal das 2 Zustände hat (HIGH und LOW).
Grüße Uwe

Deltaflyer

#26
Aug 28, 2017, 10:44 pm Last Edit: Aug 28, 2017, 11:28 pm by Deltaflyer
Hallo Micha,
hab da was gebastelt. Versuche es mal damit und gib mir bescheid, wo es noch hakt.
Deine Taster musst du an folgende Digital-Pins anschliessen:
"Links"   = Digi PIN 3
"Stop"    = Digi PIN 4
"Rechts" = Digi PIN 5
Ich habe nur 2 Schalterstellungen mit aktiven Funktionen belegt.
1. Die Stellung 1 macht ein Lauflicht bei dem drei LED's (blau , grün rot) je nach Richtungstaste, entweder von links nach rechts oder umgekehrt laufen.
2. die Stellung 5 zeigt Dein (ruhendes) Lichtband auch jeweils Abhängig von der Richtungstaste links oder rechts von der Mitte.
Ich habe das ganze so gelöst, wie Du wolltest: Richtungstaste drücken, Drehschalter wird eingelesen und der Lichteffekt gestartet. Wen du die Richtungstaste nochmals drückst (egal ob links oder rechts) stoppt der Lichteffekt und der Strip wird gelöscht.
Drückst Du nun wieder eine der Richtungstasten wird wieder der Drehschalter gelesen und der entsprechende Effekt gestartet.
drückst Du auf "Stop" wird ein laufender Lichteffekt sofort gestoppt, und dann das rote 'Stop'-Band angezeigt.

Sorry, ich musste den Code als  Anhang beifügen.

Ich hoffe, Du kanns was damit anfangen.
Ich weiss, der Code ist sicher nicht die eleganteste Lösung, und vele hier könnten das 100 x besser programmieren. aber falls es Dir hilft und stabil läuft, ist ja schon mal ne gewisse Basis da.

LG Stefan

Tommy56

Warum stellst Du den Code nicht für alle lesbar hier in Codetags ein (</> oben links das kannst Du bei Edit auch noch ändern)

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Deltaflyer


Warum stellst Du den Code nicht für alle lesbar hier in Codetags ein (</> oben links das kannst Du bei Edit auch noch ändern)

Gruß Tommy

Oh wie dumm von mir!

Ah, jetzt weiss ich es wieder : The message exceeds the maximum allowed length (9000 characters).

LG Stefan

Deltaflyer

#29
Aug 28, 2017, 11:08 pm Last Edit: Aug 28, 2017, 11:24 pm by Deltaflyer
OK. ich Teile den Code auf 2 Teile auf.
Teil 1 - >
Code: [Select]

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(36, PIN, NEO_GRB + NEO_KHZ800);

const int dsIPin[5] = {8,9,10,11,12}; // drehschalterInputPins
byte lichtEffekt = 0;                 // kein Lichteffekt gewählt
byte Dir = 0;                         // Dir = die Bewegungsrichtung des Lauflichts. (-1 = links; 0 = stop; +1 = rechts)
byte Step = 1;                        // Schrittweite, zeigt an um wieviele pixel das Lauflicht in einem Schritt wandert               
bool Init = true;                     // Init aktiviert die initialisierung des jeweiligen Lichteffektes
bool keyRelease = true;               // ist true,wenn Taste wieder losgelassen wurde
bool llichtRun = false;               // wird benutzt um zu unterscheiden ob Richtungstaste das Erste oder Zweite mal gderueckt
int Interval = 0;                     /* Verzögerung beim Lauflicht in Millisekunden Von einem Pixel zum nächsten.
                                         (0=kein lauflicht) je kleiner der Wert, desto schneller läuft das Lauflicht. */
unsigned long IntervalStart; 
                                   
void setup() {
 IntervalStart = millis();
  strip.begin();
  strip.show();

  pinMode(3,INPUT_PULLUP);          // Taste LINKS, mit internem pullup Widerstand
  pinMode(4,INPUT_PULLUP);          // Taste STOP,  mit internem pullup Widerstand
  pinMode(5,INPUT_PULLUP);          // Taste RECHTS, mit internem pullup Widerstand
  for (int i=0; i<5; i++){
    pinMode(dsIPin[i],INPUT_PULLUP);   // Pins an denen der Drehschalter hängt auf Input und Pullup-Widerstand einschalten
  }
}

void loop() {
  if(readButton(3)) {
    if (llichtRun == false && keyRelease == true) {         // Taste das erste mal gedrückt
        lichtEffekt = readDSwitch();  // lichtEffekt erhält die Position des Drehschalters. (1-5)
        Init = true;                  // bei 'true' wird der Lichteffekt Initialisiert und gestartet.
        Dir = 1;                      // "Links"
        callLichtEffekt(lichtEffekt); // Lichteffekt ausführen
        llichtRun = true;             // merken dass lichteffekt gestartet
        keyRelease = false;           // Taste noch nicht wieder losgelassen
    }
    else if (llichtRun == true && keyRelease == true) {      // Taste das 2. mal gedrückt
      Interval = 0;                   // Interval aussschalten , Lauflicht anhalten
      Dir = 0;                        // Richtung auf 0 ( keine Laufrichtung)
      clearStrip();                   // Strip löschen
      lichtEffekt = 0;                // Kein LichtEffekt gewählt
      llichtRun = false;              // Taste für erneuten start vorbereiten
    }
  }
 
  if(readButton(4) && keyRelease == true) {   // "Stop" - Taste gedrückt
    Interval = 0;                     // Interval aussschalten , Lauflicht anhalten
    Dir = 0;                          // Richtung auf 0 ( keine Laufrichtung)
    stop();                           // 'Stopp'-Band anzeigen
    keyRelease = false;               // Taste noch nicht wieder losgelassen
    llichtRun = false;                // Richtungstasten für erneuten Start vorbereiten
    lichtEffekt = 0;                  // Kein LichtEffekt gewählt
  }
 
  if(readButton(5)) {
    if (llichtRun == false && keyRelease == true) {         // Taste das erste mal gedrückt
        lichtEffekt = readDSwitch();   // lichtEffekt erhält die Position des Drehschalters. (1-5)
        Init = true;                   // bei 'true' wird der Lichteffekt Initialisiert und gestartet.
        Dir = -1;                      // "Links"
        callLichtEffekt(lichtEffekt);  // Lichteffekt ausführen
        llichtRun = true;              // merken dass lichteffekt gestartet
        keyRelease = false;            // Taste noch nicht wieder losgelassen
    }
    else if (llichtRun == true && keyRelease == true) {      // Taste das 2. mal gedrückt
      Interval = 0;                    // Interval aussschalten , Lauflicht anhalten
      Dir = 0;                         // Richtung auf 0 ( keine Laufrichtung)
      clearStrip();                    // Strip löschen
      lichtEffekt = 0;                 // Kein LichtEffekt gewählt
      llichtRun = false;               // Taste für erneuten start vorbereiten
    }
  }

  if ((readButton(3) + readButton(4) + readButton(5) == 0) && keyRelease == false) keyRelease = true; /* gedrückte Taste
                                                                                                        wurde losgelassen */
 
  if (Interval && (millis() - IntervalStart >= Interval)) callLichtEffekt(lichtEffekt);     /* bei laufenden Lichtern
                                                                                              nächsten Schritt ausführen */
}
//Ende der Schleife (loop)

//
byte readDSwitch() {                       // Fragt den Drehschalter ab
  byte dsp=0;                              // hilfsvariable DrehSchalterPosition
  for(int n=0; n<5; n++) {
    if(digitalRead(dsIPin[n]) == LOW) {    // DrehSchalterInputs nacheinander abfragen, wenn LOW, Schalterposition gefunden
      dsp = n+1;                           // dsp bekommt nun den Positionswert (1-5) 
      break;                               // Schleife verlassen, weil Pos gefunden
    }
  }
  return dsp;                              //Positionswert zurückgeben
}

//
int readButton(int pin) {        // Taste einlesen
  if(digitalRead(pin) == LOW) {  // Analog Eingang abfragen
    delay(150);                  // Wartezeit zum erneut abfragen
    if(digitalRead(pin) == LOW)  // Analog Eingang erneut abfragen
      return 1;                  // war gedrückt
  }
      return 0;                  // war nicht gedrückt
}


// Strip löschen (all LED's off)
void clearStrip() {
   for(int i=0; i<strip.numPixels(); i++) {        // Schleife in der Länge des NeoPixel-Strip
    strip.setPixelColor(i,strip.Color(0,0,0));     // Pixel Ausschalten
    strip.show();
   } 
}
//

// Funktion STOP
// zuerst alle Pixel aus, dann die mittleren 6 auf Rot
void stop() {
  clearStrip();                     // Habe das löschen des Strip's in eine eigene Funktion gepackt, da mehrfach benötigt.
 
  for(int i=0; i<6; i++) {
    strip.setPixelColor(15+i,strip.Color(150,0,0));
    strip.show();
   }
}

void callLichtEffekt(byte LiEf) {    // LiEf enthält die Nummer der auszuführenden Funktion
  switch(LiEf){
    case 1:
    run3Points();
    break;

    case 2:
    // Lichteffekt 2 ausführen
    lichtEffekt2();
    break;

    case 3:
    // Lichteffekt 3 ausführen
    lichtEffekt3();
    break;

    case 4:
    // Lichteffekt 4 ausführen
    lichtEffekt4();
    break;

    case 5:
    richtung();
    break;
  }
  IntervalStart = millis();
}
//

-> ende Teil 1

Go Up