AlkoholSensor / Peak

Mahlzeit...

Ich bastel grad ein altes Wahlscheiben Telefon zu einem Alkoholtester um.
Der Sensor befindet sich im Hörer an der Stelle des Mic´s.
Sketch habe ich Teils aus dem Netz...läuft soweit auch ganz gut...die Stellen der Anzeige sollen noch mittig, aber das mache ich später.
Derweil bin ich aber an einer Sache die nicht ganz gut klappt.
Ich möchte den Analogwert als höchsten Peak halten..ohne den ganzen sketch nur das AnalogRead geht das auch, aber ich bekomme ihn nicht in den Alkoholtester Sketch rein :confused:

Hier der Sketch in dem es geht:

int maxval = 0;
void setup() {
  
  Serial.begin(9600);
}


void loop() {
  
  
  Serial.println(maxval);
  int reading = analogRead(A0);
  if ( reading > maxval ) {maxval = reading;}
  
  delay(1);        
}

Hier der Alkoholsketch

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
int TIME_UNTIL_WARMUP = 10;
unsigned long time;


int analogPin = 0;
int val = 0;
Adafruit_SSD1306 display(OLED_RESET);


void setup()   {                

 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 display.clearDisplay();
}


void loop() {  
  
  
  delay(100);

  val = readAlcohol();
  printTitle();
  printWarming();

  time = millis()/1000;
  
  if(time<=TIME_UNTIL_WARMUP)
  {
    time = map(time, 0, TIME_UNTIL_WARMUP, 0, 100);
    display.drawRect(10, 50, 110, 10, WHITE); //Empty Bar
    display.fillRect(10, 50, time,10,WHITE);
  }else
  {
     printTitle();
     printAlcohol(val);
     printAlcoholLevel(val); 
  //display.drawPixel(0, 0, WHITE);
  //display.drawPixel(127, 0, WHITE);
  //display.drawPixel(0, 63, WHITE);
  //display.drawPixel(127, 63, WHITE); 
  }
  display.display();

}


void printTitle()
{
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20,0);
  display.println("Telefon Leitung");
}

void printWarming()
{
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(6,14);
  display.println("Verbindung");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20,35);
  display.println("wird hergetellt");
}

void printAlcohol(int value)
{
  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(17,17); //1. Wert vor Zurück 2. Hochrunter
  display.println(val);
}

void printAlcoholLevel(int value)
{
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(10,56);
  
  if(value<200)
  {
      display.println("  Trink mal was.");
  }
  if (value>=200 && value<280)
  {
      display.println("   Nur ein Bier ?");
  }
  if (value>=280 && value<350)
  {
      display.println(" Ohh es wird besser");
  }
  if (value>=350 && value <450)
  {
      display.println("    Schnappes?");
  }
  if(value>450)
  {
     display.println("  Du bist Voll !");
  }
 }
 
 int readAlcohol()
 {
  int val = 0000;
  int val1;
  int val2;
  int val3; 


  display.clearDisplay();
  val1 = analogRead(analogPin); 
  delay(10);
  val2 = analogRead(analogPin); 
  delay(10);
  val3 = analogRead(analogPin);
  
  val = (val1+val2+val3)/3;
  return val;
 }

Ich habe ihn schon überall reingemogelt aber das resultat is nicht der Peak

Ganz ehrlich versteh ich auch nicht den readAlcohol teil :blush:

Vielleicht mag jemand helfen

Lg Lisa

Hallo,

Schau Dir nochmal das Sketch in Ruhe an, hier zb:

void printAlcohol(int value) // value
{
  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(17,17); //1. Wert vor Zurück 2. Hochrunter
  display.println(val); // val, muss value sein
}

value und val.

Was funktioniert eigentlich nicht? Das ganze Display oder nur die Werte bzw. die Ausgaben der Werte? Welches Display verwendest Du?

Grüße,
Donny

Hi

Das Display ist ein SSD 1306 I2C...aber dad klappt alles wunderbar...hat zwar bissl gedauert..und ich glaube ich habe auch zwei "gehimmelt" *g..aber das geht alles..

Das Problem ist:
Der Wert der über AnalogRead reinkommt wird auf dem Display angezeigt...verschwindet der Alkohol am Sensor fällt er wieder ab..er soll aber den höchsten Wert weiterhin im Display beibehalten...gelöscht / auf 0 gesetzt wird das ganze dann wenn man den Hörer wieder auflegt...

Hallo Lisa,

 int readAlcohol()
 {
  int val = 0000;
  int val1;
  int val2;
  int val3;


  display.clearDisplay();
  val1 = analogRead(analogPin);
  delay(10);
  val2 = analogRead(analogPin);
  delay(10);
  val3 = analogRead(analogPin);
 
  val = (val1+val2+val3)/3;
  return val;
 }

in der function readAlcohol() wird der analogWert eingelesen. Es werden 3 Messungen gemacht und daraus der Mittelwert gebildet.

die function liefert den Intereg Wert val zurück

return val;

Wenn Du den peek wert haben willst must du das wie bei deinem anderen Beispiel hier einsetzen. Das Ergebniss legst du wieder in der variablen val ab. Dann sollte das klappen.

Heinz

Hi

Hiermit merkst Du Dir den Max-Wert in Deinem Test-Sketch:

if ( reading > maxval ) {maxval = reading;}

In Deinem Produktiv-Sketch sehe ich nur:

val = readAlcohol();

Wenn Du dort

static int16_t val=0;
val=max(val,readAlcohol());

rein schreibst, könnte Da ein Maximal-Wert bei heraus kommen.

Kleiner Nachteil: Der Arduino muß dafür für jede Messung neu gestartet werden, da 'static' den Variable-Wert 'fest hält' und eben nur beim ersten Durchgang =0 setzt.

Wenn der Arduino aber eh erst bestromt wird, wenn der Höhrer abgehoben wird, sollte Das schon halbwegs passen.

MfG

PS: Warum eigentlich INT?? Erwartest Du negative Werte vom Sensor?

Hallo

Im Rheinland muss der Wert auch negativ sein können wird in der Fastenzeit, nach Karneval benötigt.

Heinz

Guten Mörgäähhn

Danke für die schnelle Hilfe.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
int TIME_UNTIL_WARMUP = 10;
unsigned long time;


int analogPin = 0;
int val = 0;
Adafruit_SSD1306 display(OLED_RESET);


void setup()   {               

 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 display.clearDisplay();
}


void loop() { 
 
 
  delay(100);

  val = readAlcohol();
  printTitle();
  printWarming();

  time = millis()/1000;
 
  if(time<=TIME_UNTIL_WARMUP)
  {
    time = map(time, 0, TIME_UNTIL_WARMUP, 0, 100);
    display.drawRect(10, 50, 110, 10, WHITE); //Empty Bar
    display.fillRect(10, 50, time,10,WHITE);
  }else
  {
     printTitle();
     printAlcohol(val);
     printAlcoholLevel(val);
  //display.drawPixel(0, 0, WHITE);
  //display.drawPixel(127, 0, WHITE);
  //display.drawPixel(0, 63, WHITE);
  //display.drawPixel(127, 63, WHITE);
  }
  display.display();

}


void printTitle()
{
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20,0);
  display.println("Telefon Leitung");
}

void printWarming()
{
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(6,14);
  display.println("Verbindung");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20,35);
  display.println("wird hergetellt");
}

void printAlcohol(int value)
{
  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(17,17); //1. Wert vor Zurück 2. Hochrunter
  display.println(val);
}

void printAlcoholLevel(int value)
{
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(10,56);
 
  if(value<200)
  {
      display.println("  Trink mal was.");
  }
  if (value>=200 && value<280)
  {
      display.println("   Nur ein Bier ?");
  }
  if (value>=280 && value<350)
  {
      display.println(" Ohh es wird besser");
  }
  if (value>=350 && value <450)
  {
      display.println("    Schnappes?");
  }
  if(value>450)
  {
     display.println("  Du bist Voll !");
  }
 }
 
 int readAlcohol()
 {
  int val = 0;
  int maxval = 0;
  val = analogRead(analogPin);
  if (val > maxval ) {maxval = val ;}
 
  
  return val;
 }

Habe heute Morgen mal schnell den Code wie beschrieben reingemogelt ...aber das war es auch nicht..oder ich mache noch etwas falsch.

Warum INT ?!
Ich weiß es nicht besser...Nein negativ wird mir der Wert nie werden ...demnach sollte ich besser ein unsigned int nehmen ? :blush:

Bin jetzt im Büro...

Bye

Hallo,

HouseLisa:
Das Display ist ein SSD 1306 I2C...

I2C!! Was macht die SPI lib in Deinem Sketch? erste Zeile raus.

if(time<=TIME_UNTIL_WARMUP)

TIME_UNTIL_WARMUP ist nirgends definiert, ich geh mal stark davon aus das es ein #define ist. Also folgendes in die erste Zeile:

#define TIME_UNTIL_WARMUP 500

wobei 500 eine aus der Luft gegriffene Zahl ist. Jetzt meckert der Compiler fast nicht mehr. Er warnt noch bei Zeile 75, das hab ich bereits in #1 gesagt.

Warum INT ?!
Ich weiß es nicht besser...Nein negativ wird mir der Wert nie werden ...demnach sollte ich besser ein unsigned int nehmen ?

Ja genau. Du kannst das ganze auch mit uint16_t abkürzen. Bei den Pins kannst Du const byte verwenden. Braucht weniger Speicher.

Grüße,
Donny

Danke Donny...das sind ja gleich mehrer Dinge :-/

Werde es ändern..

#define OLED_RESET 4
int TIME_UNTIL_WARMUP = 10;
unsigned long time;

gilt das TIME_UNTIL_WARMUP mit dem "int" nicht als definiert?

lG Lisa

Hi

Jupp - aber auch hier die Frage: Erwartest Du negative WarmUp-Zeiten?
10 würde auch in ein Byte passen.
Wenn sich der Wert NIE ändert, würde ein CONST vor das int/byte/uint16_t wohl den Speicherplatzverbrauch auf NULL reduzieren, da der Wert fest im Code eingebaut werden kann und keine Variable dafür nötig ist (also RAM gespart und wohl auch einige Byte an Flash, da das Programm die Variable auch nicht vorher aus dem Speicher auslesen muß, sondern hier der feste Wert eingebunden werden kann).

Man kann 'int' durchaus sinnvoll benutzen - wenn man aber überall int benutzt, lässt Das auf unwissenheit/unaufmerksamkeit schließen.
Pin-Nummern z.B. werden wohl auch nie negativ werden und sind zumeist auch noch fest (=const, wodurch der Datentyp wieder vernachlässigbar wird, da eh feste Zahlen im Code landen).

MfG

:grinning:
..es ist natürlich unwissenheit ...!

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
const int TIME_UNTIL_WARMUP = 0; //Aufwärmphase
unsigned long time;


const byte analogPin = 0;
uint16_t Read = 0 ;
uint16_t val = 0;
Adafruit_SSD1306 display(OLED_RESET);


void setup()   {                

 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 display.clearDisplay();
}


void loop() {  
  
  
  delay(100);

  val = readAlcohol();
  printTitle();
  printWarming();

  time = millis()/1000;
  
  if(time<=TIME_UNTIL_WARMUP)
  {
    time = map(time, 0, TIME_UNTIL_WARMUP, 0, 100);
    display.drawRect(10, 50, 110, 10, WHITE); // Bar Anzeige
    display.fillRect(10, 50, time,10,WHITE);
  }else
  {
     printTitle();
     printAlcohol(val);
     printAlcoholLevel(val); 
  
  }
  display.display();

}


void printTitle()
{
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20,0);
  display.println("Telefon Leitung");
}

void printWarming()
{
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(6,14);
  display.println("Verbindung");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(20,35);
  display.println("wird hergetellt");
}

void printAlcohol(int value)
{
  display.setTextSize(4);
  display.setTextColor(WHITE);
 if (val < 10) { display.setCursor(53,17);} //1. Wert vor Zurück 2. Hochrunter
 if (val > 9 && val < 100) { display.setCursor(40,17);}
 if (val > 99 && val < 1000) { display.setCursor(27,17);}
 if (val > 999 && val < 1024) { display.setCursor(17,17);}
  display.println(val);
}

void printAlcoholLevel(int value)
{
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(10,56);
  
  if(value<200)
  {
      display.println("  Trink mal was.");
  }
  if (value>=200 && value<280)
  {
      display.println("   Nur ein Bier ?");
  }
  if (value>=280 && value<350)
  {
      display.println(" Ohh es wird besser");
  }
  if (value>=350 && value <450)
  {
      display.println("    Schnappes?");
  }
  if(value>450)
  {
     display.println("  Du bist Voll !");
  }
 }
 
 int readAlcohol()
 {
 Read = analogRead ( analogPin ) ;
 if ( Read > val ) { val = Read ; }
  
  
 
  return val;
 }

Sketch läuft...das mit dem Peak war heute Morgen falsch...is mir später aber noch klar geworden..

Ich habe eingige Zuordnungen geändert..sind die denn jetzt richtig?

Hallo,

wenn Du keine Fehlermeldungen oder Warnungen bekommst hast Du alles richtig gemacht. Wenn dann auch noch alles so läuft wie Du es haben willst !! bravo gut gemacht.

Allerdings kann es Sinn machen bei Messwerten Spitzen raus zu filtern, es könnte sich ja um einen falschen Messwert handeln. Desswegen nimmt man gerne einen Mittelwert. Oft wird in der Praxis dann auch ein gleitender Mittelwert verwendet.

ich hab jetzt nicht den ganzen Sketch angesehen, wird denn irgendwann die Messung beendet, oder wird kontinuierlich gemessen. Dann geht natürlich der Messwert irgendwann wieder runter wenn man nicht mehr auf den Sensor bläst, vermutlich bist Du aus dem Grund auf die Idee mit dem peek wert gekommen.

Heinz

Hallo,

Du kannst in der Arduino IDE unter Einstellungen alle Compiler Meldungen anzeigen lassen. Vielleicht stellst Du das mal ein.

Man kann auch mittels #define "etwas" vordefinieren. Das muss nicht zwingend eine Zahl sein, kann auch eine Funktion oder sonst was sein. Viele schreiben solche #define's in Großbuchstaben. Der große Unterschied, #define WAS_AUCH_IMMER wird im Sketch vor dem kompilieren ersetzt.

#define TIME_UNTIL_WARMUP 10 // sollte ziemlich am Anfang stehen

edit: Hier ist etwas Text verloren gegangen:
Aus Übersichtsgründen schreiben viele #define GROßBUCHSTABEN 10,deshalb bin ich eigentlich davon ausgegangen, dass es sich um ein #define und nicht um eine Variable handelt.
Nichts desto trotz, man kann diese Aufwärmzeit natürlich auch in einer Variable speichern. Aber dann auch richtig. :wink:

const byte TIME_UNTIL_WARMUP = 10; //oder
//unsigned int TIME_UNTIL_WARMUP = 10; //oder: uint16_t

Sonst warnt der Compiler!

Aso... der Fehler aus #1 ist immer noch drinnen.

void printAlcohol(int value) //<- value auf val setzen oder alle val('s) auf value!!!
{
  display.setTextSize(4);
  display.setTextColor(WHITE);
 if (val < 10) { display.setCursor(53,17);} //1. Wert vor Zurück 2. Hochrunter
 if (val > 9 && val < 100) { display.setCursor(40,17);}
 if (val > 99 && val < 1000) { display.setCursor(27,17);}
 if (val > 999 && val < 1024) { display.setCursor(17,17);}
  display.println(val);
}

Aus irgendeinen Grund muss ich das Sketch zweimal compilieren, beim ersten mal werd ich mit Warnungen regelrecht überschüttet (sind allerdings nur Warnungen), beim zweiten mal funktioniert alles einwandfrei. :confused: Die Warnungen haben etwas mit der lib zu tun.

Also:

const int ... // wird:
const unsigned int TIME_UNTIL_WARMUP = 10; // und
void printAlcohol(int value) // wird
void printAlcohol(int val) // dann ist der Compiler glücklich!

Grüße,
Donny
PS: Die Zeilennummer kann man sich auch in der IDE anzeigen lassen.

Huhuu...

Hardware läuft prima und Software is mir fast gelungen...
Ich habe im Moment ein Problem oder ein Verhalten welches ich nicht nachvollziehen kann.
Vielleicht kann mir einer einen Schubs geben:

Folgender Sketch arbeitet einwandfrei
Ich Taste .. LED geht an und nach der Intervall Zeit geht sie wieder aus... nichts aufregendes.

const int button = 3;
const int ledPin = 6;
int buttonState = 0; 
int ledState = LOW;             
unsigned long previousMillis = 0;       
const long interval = 5000;          

void setup() 
{
 
  pinMode(ledPin, OUTPUT);
  pinMode(button,INPUT_PULLUP);
}

void loop() {
 
 buttonState = digitalRead(button); 
 unsigned long currentMillis = millis();

if  (buttonState == LOW) { ledState = HIGH; }
  
if ((ledState == HIGH) && (currentMillis - previousMillis >= interval)) { previousMillis = currentMillis;ledState = LOW; }
      
digitalWrite(ledPin, ledState);

}

Bau ich den Code in meinen TelefonCode ein stimmt irgendwas nicht.

Nach der WarmUp Phase springt er im Display gleich in den PartyMode.
Versteh aber nicht warum..
Die If Bedingung ist doch garnicht erfüllt::!?

  #include <Wire.h>
  #include <Adafruit_GFX.h>
  #include <Adafruit_SSD1306.h>
  #define OLED_RESET 4
  const uint16_t TIME_UNTIL_WARMUP = 10; //Aufwärmphase
  unsigned long time;
  unsigned long previousMillis = 0;       
  const long interval = 5000; 
  const int Gabel = 3;
  const int Party = 2;
  int       GabelState = 0;
  int       PartyState = 0;
  int       PartyCount = 0;
  const byte analogPin = 0;
  uint16_t        Read = 0;
  uint16_t         val = 0;
  const int Klingel = 5;
  const int blauPin = 9;
  const int rotPin = 10;     
  const int gruenPin = 11;    
  
  Adafruit_SSD1306 display(OLED_RESET);
  
  
  void setup()   
  {                
   pinMode(Gabel,INPUT_PULLUP);
   pinMode(Party,INPUT_PULLUP);
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.clearDisplay();
   Serial.begin(9600);
  }
  
  
  void loop() 
  {  
   GabelState = digitalRead(Gabel);
   PartyState = digitalRead(Party);
   pinMode(rotPin, OUTPUT);        
   pinMode(gruenPin, OUTPUT);      
   pinMode(blauPin, OUTPUT);
   pinMode(Klingel, OUTPUT);  
    
    val = readAlcohol();
    //printTitle();
    printWarming();
  
    time = millis()/1000;
    unsigned long currentMillis = millis();
    
    if(time<=TIME_UNTIL_WARMUP)  
    {
      time = map(time, 0, TIME_UNTIL_WARMUP, 0, 100);
      display.drawRect(10, 50, 110, 10, WHITE); // Bar Anzeige
      display.fillRect(10, 50, time,10,WHITE);
      analogWrite(rotPin, 255);
    }
    else
    {
      if (GabelState == HIGH)
      {
       analogWrite(blauPin, 0);
       analogWrite(rotPin, 0);
       analogWrite(gruenPin, 255);
       display.clearDisplay();
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(18,0);
       display.println("Das Alkoholofon");
       display.setTextSize(3);
       display.setTextColor(WHITE);
       display.setCursor(1,19);                     // Wenn die Gabel unten ist
       display.println("L I S A");
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(1,56);
       display.println("-------------------");  
       display.drawLine (3,15,122,15,WHITE);
       display.drawLine (1,16,123,16,WHITE);
       display.drawLine (1,42,123,42,WHITE);        // Linien
       display.drawLine (3,43,122,43,WHITE);
       display.fillCircle(27,30,3 , WHITE);
       display.fillCircle(60,30,3 , WHITE);         // Punkte
       display.fillCircle(98,30,3 , WHITE);
      }
    else

    if ( val == 0 )
    {
       analogWrite(blauPin, 255);
       analogWrite(rotPin, 0);
       analogWrite(gruenPin, 0);
       display.clearDisplay();
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(18,0);
       display.println("Das Alkoholofon");
       display.setTextSize(3);
       display.setTextColor(WHITE);
       display.setCursor(13,20);                     
       display.println("Bereit");
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(27,56);                     
       display.println("Bitte blasen");
    }
    else
    {
      
      analogWrite(blauPin, 255);
      printTitle();
      printAlcohol(val);       //Gabel abgenommen
      printAlcoholLevel(val); 
    }
    
    
    if ((GabelState == HIGH) && ( PartyState == LOW ))
    {
      PartyCount++;
      
      delay(250);
    }
      
       
   if ((PartyCount==1) && (currentMillis - previousMillis >= interval)) { previousMillis = currentMillis;PartyCount =0; }  
     {
       analogWrite(Klingel, 255);
       display.clearDisplay();
       display.setTextSize(3);                    // PARTY MODE
       display.setTextColor(WHITE);
       display.setCursor(13,20);
       display.println("----------");
      }

       if ((PartyCount==2) |! (GabelState == HIGH))
          { PartyCount =0;}
    
    
    }

    
    Serial.println(PartyCount);
    display.display();
    }
  

   
  void printTitle()
  {
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);               //Oberste Zeile
    display.setCursor(2,0);
    display.println("Ihre aktuelle Nummer:");
  }
  
  void printWarming()
  {
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(6,5);
    display.println("Verbindung");               // Aufwärmphase Text
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(20,30);
    display.println("wird hergetellt");
  }
  
  void printAlcohol(int value)
  {
   display.setTextSize(4);
   display.setTextColor(WHITE);
   if (val < 10)                  {display.setCursor(53,17);} 
   if (val >   9 && val <  100)   {display.setCursor(40,17);}    // Anzeige MQ-3 Wert
   if (val >  99 && val < 1000)   {display.setCursor(27,17);}    // 1. Wert Vor/Zurück
   if (val > 999 && val < 1024)   {display.setCursor(17,17);}    // 2. Hoch/Runter
   display.println(val);
  }
  
  void printAlcoholLevel(int value)           // Zuordnug und Anzeige je nach erreichtem Wert
  {
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(10,56);
    
    if(value<200)
    {
        display.println("  Lisa ist bereit");
    }
    if (value>=200 && value<280)
    {
        display.println("  Nur ein Bier ?");
    }
    if (value>=280 && value<350)
    {
        display.println("Ohh es wird besser");
    }
    if (value>=350 && value <450)
    {
        display.println("    Schnappes?");
    }
    if(value>450)
    {
       display.println("  Du bist Voll !");
    }
   }
   
   int readAlcohol()                   // AnalogRead MQ-3 Sensor
   {
   Read = analogRead ( analogPin ) ;
   if ( Read > val ) { val = Read ; }  // Höchstwert Anzeige
   if (Read < 200 ) { val = 0 ; } // Alle Werte unter 200 sind gleich 0  
   
   return val;
   }

Hallo,

Ok, warum hast Du die pinMode's in der loop, verschieb das mal ins Setup.
So wie ich das sehe, fragst Du hier 2 Taster ab? Wenn ja, die gehören entprellt. Dadurch das Du INPUT_PULLUP verwendest, ist ein Tastendruck LOW. Du fragst allerdings nach HIGH.

else
  {
    if (GabelState == HIGH) // if(GabelState == LOW)

Die letzte Funktion im "Hauptcode": if(Read > val) ist immer wahr! (val = 0).

val = readAlcohol(); // Funktionsaufruf in der loop

int readAlcohol()                   // AnalogRead MQ-3 Sensor
{
  Read = analogRead ( analogPin ) ;
  if ( Read > val ) { // val ist 0, also _immer_ true
    val = Read ;  // Höchstwert Anzeige
  }

Grüße,
Donny
Nachtrag: In #1 hab ich Dich bereits (damals) auf die value und val aufmerksam gemacht, der Fehler ist noch immer drinnen. Ja es funktioniert, da val eine Globale Variable ist, wenn das so sein soll brauchst du kein value und keine Variable übergeben. Wenn Du ne Variable übergibst solltest Du diese auch verwenden. ( printAlcohol(int value) )

  }
  else

  if ( val == 0 )
  {

Das ergibt else if und bringt Dein ganzes if / else Konstrukt durcheinander, ich denke das hier der eigentliche Fehler liegt.

He Yo

Das mit dem HIGH is richtig in der Abfrage..Wenn der Hörer drauf liegt is der Schalter offen...demnach is der Eingang HIGH erst wenn ich den Hörer Abnehem schließt er und geht auf LOW..das ist so gewollt und funktioniert auch.

Und das mit dem Read Val is auch richtig..funktionert..Es wir nur der Peak angezeigt wenn der "Echte" Analoge Wert im Hintergrund wieder runtergeht springt es unter 200 wieder auf null...bzw auf "Bereit"

Anbei der Sketch der richtig ist und auch funktioniert...sobald ich die Sache mit den Millis einfüge gehts nicht mehr. Er springt halt gleich in den PartyMode ...

  #include <Wire.h>
  #include <Adafruit_GFX.h>
  #include <Adafruit_SSD1306.h>
  #define OLED_RESET 4
  const uint16_t TIME_UNTIL_WARMUP = 10; //Aufwärmphase
  unsigned long time;
  const int Gabel = 3;
  const int Party = 2;
  int       GabelState = 0;
  int       PartyState = 0;
  int       PartyCount = 0;
  const byte analogPin = 0;
  uint16_t        Read = 0;
  uint16_t         val = 0;
  const int Klingel = 5;
  const int blauPin = 9;
  const int rotPin = 10;     
  const int gruenPin = 11;    
  
  Adafruit_SSD1306 display(OLED_RESET);
  
  
  void setup()   
  {                
   pinMode(Gabel,INPUT_PULLUP);
   pinMode(Party,INPUT_PULLUP);
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.clearDisplay();
   Serial.begin(9600);
  }
  
  
  void loop() 
  {  
   GabelState = digitalRead(Gabel);
   PartyState = digitalRead(Party);
   pinMode(rotPin, OUTPUT);        
   pinMode(gruenPin, OUTPUT);      
   pinMode(blauPin, OUTPUT);
   pinMode(Klingel, OUTPUT);  
    
    val = readAlcohol();
    //printTitle();
    printWarming();
  
    time = millis()/1000;
    
    if(time<=TIME_UNTIL_WARMUP)  
    {
      time = map(time, 0, TIME_UNTIL_WARMUP, 0, 100);
      display.drawRect(10, 50, 110, 10, WHITE); // Bar Anzeige
      display.fillRect(10, 50, time,10,WHITE);
      analogWrite(rotPin, 255);
    }
    else
    {
      if (GabelState == HIGH)
      {
       analogWrite(blauPin, 0);
       analogWrite(rotPin, 0);
       analogWrite(gruenPin, 255);
       display.clearDisplay();
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(18,0);
       display.println("Das Alkoholofon");
       display.setTextSize(3);
       display.setTextColor(WHITE);
       display.setCursor(1,19);                     // Wenn die Gabel unten ist
       display.println("L I S A");
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(1,56);
       display.println("Stadtwerke Lemgo GmbH");  
       display.drawLine (3,15,122,15,WHITE);
       display.drawLine (1,16,123,16,WHITE);
       display.drawLine (1,42,123,42,WHITE);        // Linien
       display.drawLine (3,43,122,43,WHITE);
       display.fillCircle(27,30,3 , WHITE);
       display.fillCircle(60,30,3 , WHITE);         // Punkte
       display.fillCircle(98,30,3 , WHITE);
      }
    else

    if ( val == 0 )
    {
       analogWrite(blauPin, 255);
       analogWrite(rotPin, 0);
       analogWrite(gruenPin, 0);
       display.clearDisplay();
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(18,0);
       display.println("Das Alkoholofon");
       display.setTextSize(3);
       display.setTextColor(WHITE);
       display.setCursor(13,20);                     
       display.println("Bereit");
       display.setTextSize(1);
       display.setTextColor(WHITE);
       display.setCursor(27,56);                     
       display.println("Bitte blasen");
    }
    else
    {
      
      analogWrite(blauPin, 255);
      printTitle();
      printAlcohol(val);       //Gabel abgenommen
      printAlcoholLevel(val); 
    }
    
    
    if ((GabelState == HIGH) && ( PartyState == LOW ))
    {
      PartyCount++;
      
      delay(250);
    }
      
       
     if (PartyCount==1)
     {
       analogWrite(Klingel, 255);
       display.clearDisplay();
       display.setTextSize(3);
       display.setTextColor(WHITE);    //PartyMode
       display.setCursor(13,20);
       display.println("Saufen");
      }

       if ((PartyCount==2) |! (GabelState == HIGH))
          { PartyCount =0;}
    
    
    }

    
    Serial.println(Read);
    display.display();
    }
  

   
  void printTitle()
  {
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);               //Oberste Zeile
    display.setCursor(2,0);
    display.println("Ihre aktuelle Nummer:");
  }
  
  void printWarming()
  {
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(6,5);
    display.println("Verbindung");               // Aufwärmphase Text
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(20,30);
    display.println("wird hergetellt");
  }
  
  void printAlcohol(int value)
  {
   display.setTextSize(4);
   display.setTextColor(WHITE);
   if (val < 10)                  {display.setCursor(53,17);} 
   if (val >   9 && val <  100)   {display.setCursor(40,17);}    // Anzeige MQ-3 Wert
   if (val >  99 && val < 1000)   {display.setCursor(27,17);}    // 1. Wert Vor/Zurück
   if (val > 999 && val < 1024)   {display.setCursor(17,17);}    // 2. Hoch/Runter
   display.println(val);
  }
  
  void printAlcoholLevel(int value)           // Zuordnug und Anzeige je nach erreichtem Wert
  {
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(10,56);
    
    if(value<200)
    {
        display.println("  Lisa ist bereit");
    }
    if (value>=200 && value<280)
    {
        display.println("  Nur ein Bier ?");
    }
    if (value>=280 && value<350)
    {
        display.println("Ohh es wird besser");
    }
    if (value>=350 && value <450)
    {
        display.println("    Schnappes?");
    }
    if(value>450)
    {
       display.println("  Du bist Voll !");
    }
   }
   
   int readAlcohol()                   // AnalogRead MQ-3 Sensor
   {
   Read = analogRead ( analogPin ) ;
   if ( Read > val ) { val = Read ; }  // Höchstwert Anzeige
   if (Read < 200 ) { val = 0 ; } // Alle Werte unter 200 sind gleich 0  
   
   return val;
   }

Hey,

Ja natürlich, Du hast ja ein Telefon... :slight_smile: Das Mit HIGH und LOW stimmt und ja, um den Peak zu erhalten stimmt das auch, ich hätte es etwas anders geschrieben aber das macht ja nicht. :slight_smile:

Schau mal:

if ((PartyCount==1) && (currentMillis - previousMillis >= interval)) { previousMillis = currentMillis;PartyCount =0; } 
// Hier ist die if Abfrage bereits abgearbeitet <- { } 
Der Party Modus wird dann einfach ausgeführt.
     {
       analogWrite(Klingel, 255);
       display.clearDisplay();
       display.setTextSize(3);                    // PARTY MODE
       display.setTextColor(WHITE);
       display.setCursor(13,20);
       display.println("----------");
      }

Grüße,
Donny

Oh Damn...natürlich...jetzt hab ich es gecheckt...

:blush:

Hab es so gemacht:

if ((GabelState == HIGH) && ( PartyState == LOW ))
    {
      PartyCount++;
      
      delay(250);
    }
      
       
   if (PartyCount==1)   
     {
       analogWrite(Klingel, 255);
       display.clearDisplay();
       display.setTextSize(3);
       display.setTextColor(WHITE);
       display.setCursor(13,20);
       display.println("Saufen");
       currentMillis = millis();
       
      }
       if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis;PartyCount =0; } 
       if ((PartyCount==2) |! (GabelState == HIGH))
          { PartyCount =0;}

Danke Dir für die Hilfe

Freut mich wenn es funktioniert.
In #14 hab ich noch was dazugeschrieben, hoffe Du hast es gesehen. Sollen im Grunde auch nur 2 Tipps sein. (Formatierung)

Grüße,
Donny

Moinsen

Ich steh mit millis() grad schon wieder aufem Schlauch
Ich werte einen Schalter aus. Wenn der wieder losgelassen wird, wird die Zeit gesetzt und LED geht an.
Nach Ablauf Interval geht LED wieder aus.

Funktion ist gegeben.
Aaaaber:

Die LED bleibt nicht immer gleich lang an.

const int button = 3;
const int ledPin = 6;
int buttonState = 0; 
int ledState = LOW;
int Count = 0;             
unsigned long vergangen = 0;       
const long interval = 5000;
         

void setup() 
{
 Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(button,INPUT_PULLUP);
}

void loop() {
 
 Serial.println(Count);
 buttonState = digitalRead(button); 
 unsigned long aktuell = millis(); 

if  (buttonState == LOW) { Count++; }
  
  delay(200);

if ((buttonState == HIGH) && (Count != 0)) { aktuell = millis(); ledState = HIGH; }

if  (aktuell - vergangen >= interval ){ vergangen = aktuell; ledState = LOW; Count = 0; }
      
digitalWrite(ledPin, ledState);

LG Lisa