Der TeaBoy hebt nach Ablauf der eingestellten Zeit den Teebeutel aus der Tasse.

Bedienung:

  1. Teebeutel am Arm einhängen und über der Tasse mit heißem Wasser positionieren
  2. Timer minutengenau einstellen
  3. Der Arm mit dem Teebeutel senkt sich in den Tee
  4. Nach Ablauf der Zeit hebt sich der Arm automatisch und eine Melodie informiert, dass der Tee fertig ist

Schaltplan

Bauteile

Bauteile  Menge   Preis   Lieferant   Summe 
Coffee Pads Dose 1 1,29 Mömax 1,29
Modelcraft Standard-Servo RS 2 1 5,95 Conrad 5,95
Batterie 9V 1 1,30 Reichelt 1,30
Batterieclip 1 0,13 Reichelt 0,13
Taster, Printmontage, Kappe blau 4 0,81 Reichelt 3,24
7-Segment Anzeige blau 2 1,18 Reichelt 2,36
74HC595 2 0,32 Reichelt 0,64
Arduino UNO (Atmel ATmega328) 1 4,50 Watterott 4,50
Piezo Schallwandler 1 0,63 Reichelt 0,63
Standardquarz 16 MHz 1 0,15 Reichelt 0,15
Spannungsregler 7805 1 0,24 Reichelt 0,24
Kondensator 100µF 2 0,04 Reichelt 0,08
Kondensator 22pF 2 0,05 Reichelt 0,10
Kondensator 100nF 2 0,05 Reichelt 0,10
Transistor PNP MPSA64 1 0,06 Reichelt 0,06
Transistor NPN BC547C 1 0,06 Reichelt 0,06
Widerstand 10 KΩ 3 0,03 Reichelt 0,09
Widerstand 10 Ω 1 0,03 Reichelt 0,03
Widerstand 4,7 KΩ 1 0,03 Reichelt 0,03
Widerstand 1 KΩ 1 0,03 Reichelt 0,03
Widerstand 75 Ω 15 0,03 Reichelt 0,45
IC-Sockel 28-Pin 1 0,35 Reichelt 0,35
Stiftleiste 1 0,10 Reichelt 0,10
Buchsenleiste 10-Pin 2 0,24 Reichelt 0,48
Streifenraterplatine 50x100 2 0,49 Reichelt 0,98
Lochrasterplatine 50x100 1 0,37 Reichelt 0,37
Pfostenbuchse 10-polig 2 0,08 Reichelt 0,16
Wannen-Steckerleiste 10-polig 2 0,41 Reichelt 0,82
        24,22

Platinen

Streifenrasterplatine

 

 

 

 

Leiterplatten

  

 

 

 

  

 

Bilder

      

Prototyp

    

Sourcecode

include <Servo.h>
include <Bounce.h>
include <MsTimer2.h>
Servo myservo; // Servo Object

const int buttonUp = 10; // Button Up const int buttonDown = 8; // Button Down const int buttonStart = 3; // Button Start Timer const int speakerOut = 4; // Speaker const int latchPin = 6; // Pin connected to ST_CP of 74HC595 const int clockPin = 7; // Pin connected to SH_CP of 74HC595 const int dataPin = 5; // Pin connected to DS of 74HC595 const int powerPin = 2; // Power Pin const int servo = 9; // Servo

// Servo degrees

define WINKELOBEN 45
define WINKELUNTEN 70
define WINKELPARK 175
// Config Sound

define c1 3830
define d1 3400
define e1 3038
define f1 2864
define g1 2550
define a1 2272
define b1 2028
define C1 1912
define R1 0
int melody[] = { C1, c1, g1, a1, C1, C1, b1, g1, C1, b1, e1, R1}; int beats[] = { 16, 16, 16, 8, 8, 16, 16, 16, 8, 8, 16, 32};

// Config Buttons Bounce bouncerUp = Bounce(buttonUp, 10); Bounce bouncerDown = Bounce(buttonDown, 10); Bounce bouncerStart = Bounce(buttonStart, 10); int buttonUpvalue = HIGH; int buttonDownvalue = HIGH; int buttonStartvalue = HIGH;

int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping. long tempo = 10000; // Set overall tempo int pause = 1000; // Set length of pause between notes // Loop variable to increase Rest length int rest_count = 100; //<-BLETCHEROUS HACK // Initialize core variables int tone_ = 0; int beat = 0; long duration = 0;

// right display const byte LED_CHAR_SET1[12] = {

B11111010, B01100000, B11011100, 
B11110100, B01100110, B10110110, 
B10111110, B11100000, B11111110, 
B11110110, B00000001, B00000000
};

// left display const byte LED_CHAR_SET2[12] = {

B11111010, B01100000, B11011100, 
B11110100, B01100110, B10110110, 
B10111110, B11100000, B11111110, 
B11110110, B00000001, B00000000
};

// Init variables

define TIMER2 1000 // Timer event every second (1000ms)
boolean blinkingDot = true; unsigned long seconds = 0; boolean timeOver = false; boolean timerStart = false; int timeCounter = 0; int shutDown = 0; unsigned long idleTime = 0;

void setup() {

pinMode(powerPin, OUTPUT);
digitalWrite(powerPin, HIGH);
moveServo(WINKELOBEN);
myservo.attach(servo);  		// attaches the servo to the servo object 

//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

pinMode(speakerOut, OUTPUT);

 // buttons to input
 pinMode(buttonUp, INPUT);
 pinMode(buttonDown, INPUT);
 pinMode(buttonStart, INPUT);
 // Enable internal pullup resistors
 digitalWrite(buttonUp, HIGH);
 digitalWrite(buttonDown, HIGH);
 digitalWrite(buttonStart, HIGH);
 display(0, 0);
 
 MsTimer2::set(TIMER2, checkTimer);
 MsTimer2::start();

 delay(500);
}


void loop() {

 bouncerUp.update();
 bouncerDown.update();
 bouncerStart.update();
 if (bouncerUp.read() == LOW) {
   if (buttonUpvalue == HIGH) {
     if (!timerStart) {
       timeCounter++;
       if (timeCounter > 99)
         timeCounter = 0;
       display(timeCounter/10, timeCounter%10);
       idleTime = 0;
     }
   }
 }
 buttonUpvalue = bouncerUp.read();
 if (bouncerDown.read() == LOW) {
   if (buttonDownvalue == HIGH) {
     if (!timerStart) {
       timeCounter--;
       if (timeCounter < 0)
         timeCounter = 0;
       display(timeCounter/10, timeCounter%10);
       idleTime = 0;
     }
   }
 }
 buttonDownvalue = bouncerDown.read();
 if (bouncerStart.read() == LOW) {
   if (buttonStartvalue == HIGH) {
     if ((timeCounter > 0) && !timerStart) {
       timerStart = true;
       moveServo(WINKELUNTEN);
     }
     else if ((timeCounter > 0) && timerStart) {
       timerStart = false;
       timeOver = false;
       timeCounter = 0;
       idleTime = 0;
       display(0, 0);
       moveServo(WINKELOBEN);
     }
     else if (timeCounter == 0) {
       moveServo(WINKELPARK);
       delay(500);
       digitalWrite(powerPin, LOW);
     }
     idleTime = 0;
   }
 }
 buttonStartvalue = bouncerStart.read();
 
 if (timeOver) {
   moveServo(WINKELOBEN);
   playMelodie();
   shutDown++;
 }
 if (shutDown >= 3) {
   timeOver = false;
   digitalWrite(powerPin, LOW);
 }
 
}

void checkTimer() {

 if (timerStart) {
   if (blinkingDot) {
     display(11, 10);
     blinkingDot = false;
   }
   else {
     display(10, 11);
     blinkingDot = true;
   }
   seconds++;
   if (seconds >= timeCounter * 60)
     timeOver = true;
 }
 
 idleTime++;
 if ((idleTime >= 60) && !timerStart) {
   digitalWrite(powerPin, LOW);
 }
}

void moveServo(int degree) {

 int curPos = myservo.read();
 if (curPos >= degree) {
   for (int i=curPos; i>=degree; i--) {
      myservo.write(i);
      delay(15);
    }
 } else {
   for (int i=curPos; i<degree; i++) {
      myservo.write(i);
      delay(15);
    }
 }
}


void playMelodie() {

 for (int i=0; i<MAX_COUNT; i++) {
   tone_ = melody[i];
   beat = beats[i];
   duration = beat * tempo; // Set up timing
   playTone(); 
   // A pause between notes...
   delayMicroseconds(pause);
 }
}


void display(byte seg1, byte seg2){

send(seg2, seg1);
}


void send(byte data1, byte data2){

//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, LED_CHAR_SET2[data2]);
shiftOut(dataPin, clockPin, LSBFIRST, LED_CHAR_SET1[data1]);
//return the latch pin high to signal chip that it no longer needs to listen for information
digitalWrite(latchPin, HIGH);
}


void playTone() {

 long elapsed_time = 0;
 if (tone_ > 0) { // if this isn't a Rest beat, while the tone has 
   //  played less long than 'duration', pulse speaker HIGH and LOW
   while (elapsed_time < duration) {
     digitalWrite(speakerOut,HIGH);
     delayMicroseconds(tone_ / 2);
     // DOWN
     digitalWrite(speakerOut, LOW);
     delayMicroseconds(tone_ / 2);
     // Keep track of how long we pulsed
     elapsed_time += (tone_);
   } 
 }
 else { // Rest beat; loop times delay
   for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
     delayMicroseconds(duration);  
   }                                
 }                                 
}

Bedienungsanleitung

Bedienungsanleitung TeaBoy

Video