Go Down

Topic: Problem beim nachbau Tea Timer "gelöst" (Read 380 times) previous topic - next topic

michael_x

Der erste Ansatz war, das ohne Interrupt zu machen, Stefan.
Da hast du nun vergebliche Mühe reingesteckt.

Dass bevorzugt Leute die was zusammengefrickelt haben und stolz sind, dass es trotzdem geht, das im Internet veröffentlichen, ist ein wesentlicher Bestandteil des Internets. Wer da was findet, der hat es an der Backe.

Jetzt zu deinen vorigen Details:

Mit byte clock[8] = {0,14,21,23,17,14,0,0};
sollte man eigentlich keine Schwierigkeiten haben ...
wird einmal definiert und einmal verwendet:
lcd.createChar(2, clock);

Dass clock (wie z.B. jede Variable namens status) rot dargestellt wird, nun ja: keine Ahnung warum die Arduino-IDE so beliebt ist. :)

Quote
Das bedeutet den Code den du gepostest hast ist unvollständig
... oder die Funktion heißt checkButton statt checkbutton  oder es schwirrt gar noch ein ckeckButton herum...
aber so weit waren wir auch schon.

Stimmt schon, in C++ kann man Fehler machen, die man in Basic nicht hinkriegt.
Das ist allerdings eine OT Diskussion.

Zumindest probe-übersetzen sollte man schon etwas, bevor man es postet, wenn der Compilerfehler nicht der Inhalt des Threads ist. Da bekenne ich mich schuldig!  
Daher hier nochmal eine kompilierende Version (auch wenn es nicht mehr interessiert):

Code: [Select]
#include <LiquidCrystal.h>
#include <Servo.h>

//state identifiers:
#define MENU 0
#define INPROCESS 1
#define DONE 2

const char* welcomeMessage = ("Willkomen!");
const char* doneMessage = ("Fertig! ");

const int buttonPin = 2;
const int servoPin = 7;
const int buzzerPin = 8;
const int backlightPin = 9;
const int potPin = A0; // selection potentiometer
const int servoHighPosition = 150;
const int servoLowPosition = 70;
const int servoSpeedDelay = 20; // decrease this value to increase the servo speed

unsigned long steepingTime;
unsigned long startTime;
long timeLeft;

int state;

LiquidCrystal lcd(14, 16, 6, 5, 4, 3);
Servo servo;

//custom LCD characters:
byte leftArrow[8] = {0,0,4,12,28,12,4,0};
byte rightArrow[8] = {0,0,4,6,7,6,4,0};
static byte clock[8] = {0,14,21,23,17,14,0,0};
byte sandTimer[8] = {31,17,10,4,10,31,31,0};
byte teaCup[8] = {10,5,0,31,25,9,15,0};

void setup() {

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT);
  pinMode(backlightPin, OUTPUT);
 
  servo.attach(servoPin);
  
  digitalWrite(backlightPin, HIGH);
 
  lcd.createChar(0, leftArrow);
  lcd.createChar(1, rightArrow);
  lcd.createChar(2, clock);
  lcd.createChar(3, sandTimer);
  lcd.createChar(4, teaCup);
 
  state = MENU;
 
  lcd.begin(16, 2);
  lcd.print(welcomeMessage);
}

void checkButton() {
  static bool btnState;
  if (digitalRead(buttonPin) != btnState ) { btnState = ! btnState; buttonISR(); }
}

void loop() {
 
 checkButton();
 switch(state){
 
   case MENU:      
          moveServoTo(servoHighPosition);
          lcd.clear();
                    
          lcd.setCursor(11,1);
          lcd.print("start");
                  
          lcd.setCursor(8,1);
          lcd.write(byte(0));  //display selection arrows
          lcd.write(byte(1));
                  
          lcd.setCursor(1,0);
          lcd.write(byte(2));  //display clock symbol
                                                                      
          while(state == MENU){
                      checkButton();                                          
                      steepingTime = 30000 * map(analogRead(potPin),0,1023,1,20);
                      lcd.setCursor(3,0);
                      lcd.print(millisToTime(steepingTime));
                      delay(200);                                            
          }
          break;
  
   case INPROCESS:  moveServoTo(servoLowPosition);
          startTime = millis();
            
          lcd.clear();
                  
          lcd.setCursor(12,1);
          lcd.print("stop");
              
          lcd.setCursor(1,0);
          lcd.write(byte(3));  //display sand timer symbol            
        
          while(state == INPROCESS){
                       checkButton();                                          
          
                      timeLeft = steepingTime - (millis() - startTime);
                    
                      if(timeLeft > 0){                  
                      
                          lcd.setCursor(3,0);
                          lcd.print(millisToTime(timeLeft));
                      }
                      else state = DONE;  
                    
                      delay(500);                  
           }            
           break;
    
   case DONE:
          lcd.clear();
          lcd.setCursor(1,0);
          lcd.print(doneMessage);
                  
          lcd.write(byte(4));  //display tea cup symbol
                                        
          moveServoTo(servoHighPosition);
                                      
          doneBeep();
                  
          lcd.setCursor(12,1);
          lcd.print("menu");
                  
          while(state == DONE) checkButton();                                      
              
          break;
 }
}


void buttonISR(){
 
   static unsigned long lastInterruptTime = 0; //used to debounce button input
   unsigned long interruptTime = millis();
 
   if(interruptTime - lastInterruptTime > 500) { //long time to force a long press
      switch(state){
        case MENU:       state = INPROCESS;   break;
        case INPROCESS:  state = DONE;        break;
        case DONE:       state = MENU;        break;
      }
  }
  lastInterruptTime = interruptTime;
}


void moveServoTo(int finalPosition){ //move the servo slowly to the desired position

  int currentPosition = servo.read();
 
  if(finalPosition > currentPosition){
 
    for(int i = currentPosition; i <= finalPosition; i++){
  
     servo.write(i);
     delay(servoSpeedDelay);
    }
  }
  else if(finalPosition < currentPosition){
 
    for(int i = currentPosition; i >= finalPosition; i--){
  
      servo.write(i);
      delay(servoSpeedDelay);
    }
  }
}

char*  millisToTime(unsigned long milliseconds){
 static char result[]="99:99";
 unsigned int sec = milliseconds/1000;
 byte minutes =  sec / 60;
 byte minutes1 = minutes % 10;
 byte minutes10 = minutes / 10 % 10;
 byte seconds1 =  sec % 10;
 byte seconds10 =  sec % 60 / 10;

 result[0] = '0' + minutes10;
 result[1] = '0' + minutes1;
 result[3] = '0' + seconds10;
 result[4] = '0' + seconds1;
 return result;
}

void doneBeep(){
   tone(buzzerPin, 4000, 700);
}


Eigentlich geht es um die Verwendung der buttonISR ohne Interrupt. Und da scheint was zu gehen...

michael_x

Hab mal LCD und Servo durch Serial Testausgaben ersetzt und das "Poti" fest auf 04:30 eingestellt.

Code: [Select]
//state identifiers:
#define MENU 0
#define INPROCESS 1
#define DONE 2

const char* welcomeMessage = ("Willkomen!");
const char* doneMessage = ("Fertig! ");

const int buttonPin = 2;

unsigned int servoSpeedDelay = 200;
int servoHighPosition = 10;
int servoLowPosition = 1;

unsigned long steepingTime;
unsigned long startTime;
long timeLeft;

int state;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  state = MENU;
 
  Serial.print(welcomeMessage);
}

void checkButton() {
  static bool btnState;
  if (digitalRead(buttonPin) != btnState ) { btnState = ! btnState; buttonISR(); }
}

void loop() {
 
 checkButton();
 switch(state){
 
   case MENU:      
          moveServoTo(servoHighPosition);
          Serial.print("start");
                  
          while(state == MENU){
                      checkButton();                                          
                      steepingTime = 30000 * map(450,0,1023,1,20);  // Voreinstellung 04:30
                      Serial.println(millisToTime(steepingTime));
                      delay(400);                                            
          }
          break;
  
   case INPROCESS:  moveServoTo(servoLowPosition);
          startTime = millis();
          Serial.print("stop");
          while(state == INPROCESS){
                      checkButton();                                          
                      timeLeft = steepingTime - (millis() - startTime);
                      if(timeLeft > 0){                  
                        Serial.println(millisToTime(timeLeft));
                      }
                      else state = DONE;  
                      delay(500);                  
           }            
           break;
    
   case DONE:
          Serial.print(doneMessage);
          moveServoTo(servoHighPosition);
                                      
          doneBeep();
          Serial.print("menu");
                  
          while(state == DONE) checkButton();                                      
              
          break;
 }
}


void buttonISR(){
 
   static unsigned long lastInterruptTime = 0; //used to debounce button input
   unsigned long interruptTime = millis();
 
   if(interruptTime - lastInterruptTime > 500) { //long time to force a long press
      switch(state){
        case MENU:       state = INPROCESS;   break;
        case INPROCESS:  state = DONE;        break;
        case DONE:       state = MENU;        break;
      }
  }
  lastInterruptTime = interruptTime;
}

void moveServoTo(int finalPosition){ //move the servo slowly to the desired position
  static int currentPosition;
  if(finalPosition > currentPosition){
    for(int i = currentPosition; i <= finalPosition; i++){
     Serial.write('+');
     currentPosition++;
     delay(servoSpeedDelay);
    }
  }
  else if(finalPosition < currentPosition){
    for(int i = currentPosition; i >= finalPosition; i--){
      Serial.write('-');
      currentPosition--;
      delay(servoSpeedDelay);
    }
  }
  Serial.println();
}

char*  millisToTime(unsigned long milliseconds){
 static char result[]="99:99";
 unsigned int sec = milliseconds/1000;
 byte minutes =  sec / 60;
 byte minutes1 = minutes % 10;
 byte minutes10 = minutes / 10 % 10;
 byte seconds1 =  sec % 10;
 byte seconds10 =  sec % 60 / 10;

 result[0] = '0' + minutes10;
 result[1] = '0' + minutes1;
 result[3] = '0' + seconds10;
 result[4] = '0' + seconds1;
 return result;
}

void doneBeep(){
  Serial.println("beep");
  delay(200);
}

Was wäre daran noch "geht nicht" ?

StefanL38

Hab mal LCD und Servo durch Serial Testausgaben ersetzt und das "Poti" fest auf 04:30 eingestellt.

Code: [Select]
//state identifiers:
#define MENU 0
#define INPROCESS 1
#define DONE 2

const char* welcomeMessage = ("Willkomen!");
const char* doneMessage = ("Fertig! ");

const int buttonPin = 2;

unsigned int servoSpeedDelay = 200;
int servoHighPosition = 10;
int servoLowPosition = 1;

unsigned long steepingTime;
unsigned long startTime;
long timeLeft;

int state;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  state = MENU;
 
  Serial.print(welcomeMessage);
}

void checkButton() {
  static bool btnState;
  if (digitalRead(buttonPin) != btnState ) { btnState = ! btnState; buttonISR(); }
}

void loop() {
 
 checkButton();
 switch(state){
 
   case MENU:      
          moveServoTo(servoHighPosition);
          Serial.print("start");
                  
          while(state == MENU){
                      checkButton();                                          
                      steepingTime = 30000 * map(450,0,1023,1,20);  // Voreinstellung 04:30
                      Serial.println(millisToTime(steepingTime));
                      delay(400);                                            
          }
          break;
  
   case INPROCESS:  moveServoTo(servoLowPosition);
          startTime = millis();
          Serial.print("stop");
          while(state == INPROCESS){
                      checkButton();                                          
                      timeLeft = steepingTime - (millis() - startTime);
                      if(timeLeft > 0){                  
                        Serial.println(millisToTime(timeLeft));
                      }
                      else state = DONE;  
                      delay(500);                  
           }            
           break;
    
   case DONE:
          Serial.print(doneMessage);
          moveServoTo(servoHighPosition);
                                      
          doneBeep();
          Serial.print("menu");
                  
          while(state == DONE) checkButton();                                      
              
          break;
 }
}


void buttonISR(){
 
   static unsigned long lastInterruptTime = 0; //used to debounce button input
   unsigned long interruptTime = millis();
 
   if(interruptTime - lastInterruptTime > 500) { //long time to force a long press
      switch(state){
        case MENU:       state = INPROCESS;   break;
        case INPROCESS:  state = DONE;        break;
        case DONE:       state = MENU;        break;
      }
  }
  lastInterruptTime = interruptTime;
}

void moveServoTo(int finalPosition){ //move the servo slowly to the desired position
  static int currentPosition;
  if(finalPosition > currentPosition){
    for(int i = currentPosition; i <= finalPosition; i++){
     Serial.write('+');
     currentPosition++;
     delay(servoSpeedDelay);
    }
  }
  else if(finalPosition < currentPosition){
    for(int i = currentPosition; i >= finalPosition; i--){
      Serial.write('-');
      currentPosition--;
      delay(servoSpeedDelay);
    }
  }
  Serial.println();
}

char*  millisToTime(unsigned long milliseconds){
 static char result[]="99:99";
 unsigned int sec = milliseconds/1000;
 byte minutes =  sec / 60;
 byte minutes1 = minutes % 10;
 byte minutes10 = minutes / 10 % 10;
 byte seconds1 =  sec % 10;
 byte seconds10 =  sec % 60 / 10;

 result[0] = '0' + minutes10;
 result[1] = '0' + minutes1;
 result[3] = '0' + seconds10;
 result[4] = '0' + seconds1;
 return result;
}

void doneBeep(){
  Serial.println("beep");
  delay(200);
}

Was wäre daran noch "geht nicht" ?
Die erste CodeVersion die du (micheal_x)  gepostest hast hatte checkButton und checkbutton.
Der Thread-opener hat dann die Schreibweise korrigiert und es irgendwie geschafft dabei die Definition der function checkButton rauszulöschen. Dann geht natürlich noch nix.
viele Grüße 
Stefan

rambrot

#18
May 24, 2020, 01:54 pm Last Edit: May 24, 2020, 01:59 pm by rambrot
vielen dank, hat geklappt.

das war der Fehler

attachInterrupt(1, buttonISR, CHANGE);

ich hatte

attachInterrupt(0, buttonISR, CHANGE);

drin.

vielen dank, an alle.

grüße
rambrot


Go Up