Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: Making a Cuckoo-Clock with Teensy

  1. #1

    Making a Cuckoo-Clock with Teensy

    Making a Cockoo-Clock with teensy.

    Hi, perhaps this is an idea for a project of some other people. At least I had some fun with it…

    A cockoo clock is a clock hanging at a wall. It has a small window which opens every full hour. A little bird comes out of the window and calls "Kuckuck". These clocks have a great tradition in the Blackforest in South Germany. I live some 150km from this region. When I saw such clocks at a tourist shop there some weeks ago, I thought this would be fun.
    Normally everything is done by mechanics which would be a very big task. But with microcontrollers everything is much simpler at least when you can reuse a lot of the work of others - many thanks to all!

    So the goal was to make a clock (shows time), which mechanicly opens a small window every full hour, shows a bird and lets the bird sing. And closes the window shutter again.

    I was very happy, when I discovered that you can buy rings with 12 multicolour Neopixels from adafruit. These give a nice display. I think this has more style than a digital text display and it is much simpler than a mechanical clock face.

    The bird normally moves with a linear movement on a kind of sled. This was simplified to circular movement. A small platform has the shutter of the window fixed to it and carries the bird. It is directly fixed to a rc-servo axle. So the swing of the servo opens the shutter and brings the bird forward at the same time.

    Of course the bird must sing at full hours, so you need a possibility to output sound, which is done using *.wav files together with the DAC of the teensy and with the sound library.

    Function Hardware Library Comment (The following lines should be a table)

    Time: Built-In Timer TimeLib

    Set time accurately: Receiver for time broadcast DCF77 (Pollin) DCF77 Library hat to be modified slightly because of different interrupts. Because of automatic time setting, no user buttons are needed.

    LED (13) for indication of reception
    LED blinks 3 times, if the last correct reception was within last hour
    2 times if it was within one day and
    1 time per signal (signal is copied to LED) if the reception was not yet correct or if it was longer ago than one day.


    Open/Close Shutter: show bird Rc-servo, high quality for low noise PWMservo
    The servo brings noise into the audio output. To minimise this, the pwm signal is shut down after movement (make pin input). In addition a RC filter of 47 Ohms and 470µF is used at the 5V supply of the LM386.

    Clock face: Adafruit Neopixel Ring, WS2812Serial Small addition to deal with 4 LEDs per pixel. See function "setPixel".
    The LEDs are very bright, so they are used only with 1/255 (White) and 10/255 (others) of their power.
    Red indicates hours.
    Green indicates minutes in steps of 5.
    Blue shows at 5 seconds intervals.
    White shows the 12 positions of the face constantly.

    Let bird sing: SD-card to hold wav- Files, See example WAV player There are nice WAV files on the internet. To convert them to 16bit, 44.1kHz you can use Audacity. So the bird is not allways a cockoo…. https://www.vogelstimmen.info/Vogels...en_GRATIS.html
    DAC 12-bit
    Small amp with LM386 and small loud speaker The amp is as included in the datasheet of LM386.

    Multitasking TeensyThreads Simplifies programming a lot and is easy to use! There are 4 tasks:
    1. Check DCF77 reception and indicate its status
    2. Set the clock if new broadcast available
    3. Display the time
    4. Normal loop: Show bird and start to play WAV

    I took some time to consider, which controller would be best to use. (Original Arduino, Arduino with BASCOM, Arduino M0, Raspi, Parallax Propeller, Teensy 3.2, 3.5)
    I choose Teensy 3.5 mainly because of the audio library, the DAC and the SD-card, DCF77-library for Arduino. Fallback would have been the audio shield. With a raspi I would have used internet time with wlan instead of DCF77. Of course Teensy 3.5 needs only about 7% of its memory and you could solder a SD-card to 3.2….
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	20180722_154243.jpg 
Views:	88 
Size:	60.7 KB 
ID:	14880  
    Attached Files Attached Files

  2. #2
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,901
    Das ist ja mal ne witzige Idee

  3. #3
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,579

  4. #4
    Member
    Join Date
    Sep 2014
    Location
    South Dundas, Ontario, Canada
    Posts
    41
    Quote Originally Posted by Theremingenieur View Post
    I still have one of those clocks.

  5. #5
    ... tried to correct orientation of the image....

  6. #6
    Hi,
    Thanks to pjrc and the guys who have made all the libraries. I just want to say, that the clock works completely stable for some months now 7/24.
    😊 Christof

  7. #7
    Administrator Robin's Avatar
    Join Date
    Oct 2012
    Location
    PJRC Global Headquarters
    Posts
    319
    I would like to feature this project on our blog. Do you have any more pictures of it?

  8. #8
    Click image for larger version. 

Name:	IMG_20190705_072022-600x800.jpg 
Views:	24 
Size:	73.6 KB 
ID:	16915
    Click image for larger version. 

Name:	IMG_20190705_072301-600x800.jpg 
Views:	24 
Size:	76.8 KB 
ID:	16916

    Hi, perhaps this works?
    Best regards Christof

  9. #9
    I was inspired by this project to make something to appeal to my grandson. Thanks for all the hard work that made my job easy!

    https://www.youtube.com/watch?v=fK1i3N29YwI

    Code:
    #include <TimeLib.h>
    
    #define BROWNTOUCH  0         //not yet
    #define BLUETOUCH   33       //touchpads -- color wire attached to pad/pin #
    #define PURPLETOUCH 25      //hours
    #define GRAYTOUCH   30      //???attached or miscounted???
    #define WHITETOUCH  32
    #define YELLOWTOUCH 17
    #define GREENTOUCH  16      //minutes
    #define ORANGETOUCH 15       //not yet
    
    #include <PWMServo.h>  
      PWMServo myservo;
      int pos;
    #define SERVO_PIN  21
    
    #include <WS2812Serial.h>
    const int numled = 60;
    const int led_pin = 10;       //Pin to connect LED ring data in
    byte drawingMemory[numled*3];         //  3 bytes per LED
    DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED
    
    WS2812Serial ring(numled, displayMemory, drawingMemory, led_pin, WS2812_RGB);
    
    
    
    #define  HR_COLOR  0x000018       //RGB::Blue
    #define  MIN_COLOR 0x180000      //RGB::Green
    #define  SEC_COLOR 0x001800       //RGB::Red
    #define  BLACK     0x000000
    //Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_RGB + NEO_KHZ800);
    
    #include <SPI.h>
    #include <SD.h>
    #include <Audio.h>
    #include <SerialFlash.h>
    // https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib
    #include <play_sd_aac.h>
    
    
    // GUItool: begin automatically generated code
    //AudioPlaySdWav           playSdWav1;     //xy=154,422
    AudioPlaySdAac           playAac1; //xy=154,422
    AudioMixer4              mixer1;         //xy=327,432
    AudioOutputAnalog        dac1;           //xy=502,412
    AudioConnection          patchCord1(playAac1, 0, mixer1, 0);
    AudioConnection          patchCord2(playAac1, 1, mixer1, 1);
    AudioConnection          patchCord3(mixer1, dac1);
    // GUItool: end automatically generated code
    
    
    #define PROP_AMP_ENABLE    5
    #define FLASH_CHIP_SELECT  6
    
      int h = 0;
      int m = 1;
      int s = 2;
      int hADD = 0; 
      int mADD = 0;
      int state = 0;
      
    void setup()  {
      // set the Time library to use Teensy 3.0's RTC to keep time
      setSyncProvider(getTeensy3Time);
      ring.begin();
      ring.show(); // Initialize all pixels to 'off'
      //ring.setBrightness(32);
      AudioMemory(8); //4
      delay(2000);
    
      // Start SerialFlash
      if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1) {
          Serial.println ("Cannot access SPI Flash chip");
          delay (1000);
        }
      }
      //Set Volume
      mixer1.gain(0, 0.1);     //volume very low for testing
      mixer1.gain(1, 0.1);
    
      //Start Amplifier
      pinMode(PROP_AMP_ENABLE, OUTPUT);
      digitalWrite(PROP_AMP_ENABLE, HIGH);    // Enable Amplifier
    
      myservo.write(90);
      pos = 90;
      myservo.attach(SERVO_PIN);  // attaches the servo on pin 35 to the servo object 
      delay(1000);
      
      
     Serial.begin(9600);
      //while (!Serial);  // Wait for Arduino Serial Monitor to open
    
    #ifdef TeensyView
      delay(100);
      oled.begin();    // Initialize the OLED
      oled.clear(ALL); // Clear the display's internal memory
     //oled.display();  // Display what's in the buffer (splashscreen)
     //delay(1000);     // Delay 1000 ms
      oled.clear(PAGE); // Clear the buffer.
      oled.setFontType(1);  // Set font to type 1
      oled.setCursor(5, 0); // move cursor
    
      
      if (timeStatus()!= timeSet) {
        oled.print("Unable to sync with the RTC");
      } else {
        oled.print("RTC has set the system time");
      }
    
      oled.display(); 
      delay(1000);
    
      oled.clear(PAGE);
    #endif //TeensyView
    
     //Teensy3_setSystemClock(Teensy3Clock.get());   //teensy4
    }    //end setup()
    
    void loop() {
     
      if (Serial.available()) {
        time_t t = processSyncMessage();
        if (t != 0) {
          Teensy3Clock.set(t); // set the RTC
          setTime(t);
        }
      }
     Serial.print( touchRead(PURPLETOUCH) ); Serial.print("  ");  Serial.print( touchRead(BLUETOUCH) ); Serial.print("  "); Serial.print( touchRead(GRAYTOUCH) ); Serial.print("  ");Serial.print("  "); 
       Serial.print( touchRead(YELLOWTOUCH) ); Serial.print("  ");   Serial.print( touchRead(ORANGETOUCH) ); Serial.print("  ");Serial.print( touchRead(WHITETOUCH) ); Serial.println("  ");
    
    
      if (touchRead(PURPLETOUCH) >3000) { 
        hADD++; Serial.println("hour button"); delay(200);} 
         
      if (touchRead(GREENTOUCH) >3000){
        mADD++; Serial.println("minute button"); delay(200);}
        
      if (touchRead(BLUETOUCH)  > 3000) { state = 1; Serial.println("Touched Blue"); }
      if (touchRead(YELLOWTOUCH)  > 3000) { state = 3; Serial.println("Touched Yellow"); }
      if (touchRead(WHITETOUCH)  > 3000) { state = 2; Serial.println("Touched White");}
      
      if (touchRead(ORANGETOUCH)  > 3000) { state = 4; Serial.println("Touched Orange");}
      
      if (touchRead(GRAYTOUCH)  > 3000) { state = 5;Serial.println("Touched Gray"); }
      if (touchRead(BROWNTOUCH)  > 3000) { state = 6;Serial.println("Touched Brown"); }
      
    
      if (state == 0) {
          digitalClockDisplay();
        delay(200);
      }
      if (state == 1) {
          rainbowSpin1();
      }
      if (state == 2) {
          rainbowSpin2();
        }
        if (state == 3) {
          rainbowSpin3();
        }
        if (state == 4) {
          elvisRockClock();     //ORANGE
        }
        if (state == 5) {
          elvisCutTheCake();   //gray
        }
        if (state == 6) {
          elvisList();
        }
      
    }
    
    long getPixelColor(int pix){      //read the value of a neopixel. This is included in Adafruit_Neopixel. 
      int k=pix*3;                    //I suspect the code is slightly different if you have GRB, BRG, RGB, RBG, BFG. RBG is the best!
      return((drawingMemory[k]) | (drawingMemory[k+2]<<16) | (drawingMemory[k+1]<<8) );
    }
    
    void digitalClockDisplay() {       //  digital clock display of the time
      Serial.print(hour());
      printDigits(minute());
      printDigits(second());
      Serial.print(" ");
      Serial.print(day());
      Serial.print(" ");
      Serial.print(month());
      Serial.print(" ");
      Serial.print(year()); 
      Serial.println(); 
      
      
    
      ring.setPixel(h, BLACK);  //blank old time
      ring.setPixel(m, BLACK);  //blank old time
      ring.setPixel(s, BLACK);  //blank old time
    
      h =30+ 5*(hADD+hour());       //30+ because pixel 0 is at 6 o'clock on ring.
      while (h>59) {h -= 60;}
      m = 30+ minute() + mADD;
      while (m > 59) {m -= 60;}
      s = 30+ second();
      while (s > 59) {s -= 60;}
      ring.setPixel(h, HR_COLOR);
      uint32_t color = getPixelColor(m);
      ring.setPixel(m, color|MIN_COLOR);
      color = getPixelColor(s);
      ring.setPixel(s, color|SEC_COLOR);
      ring.show();
    }
    
    time_t getTeensy3Time() {
      return Teensy3Clock.get();
    }
    
    
    /*void Teensy3_setSystemClock(unsigned long t)               //teensy 4 teensyduino beta 4/5/2020 doesn't set the system clock
    {
       // stop the RTC
       SNVS_HPCR &= ~(SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS);
       while (SNVS_HPCR & SNVS_HPCR_RTC_EN); // wait
       // stop the SRTC
       SNVS_LPCR &= ~SNVS_LPCR_SRTC_ENV;
       while (SNVS_LPCR & SNVS_LPCR_SRTC_ENV); // wait
       // set the SRTC
       SNVS_LPSRTCLR = t << 15;
       SNVS_LPSRTCMR = t >> 17;
       // start the SRTC
       SNVS_LPCR |= SNVS_LPCR_SRTC_ENV;
       while (!(SNVS_LPCR & SNVS_LPCR_SRTC_ENV)); // wait
       // start the RTC and sync it to the SRTC
       SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS;
    }
    */
    
    /*  code to process time sync messages from the serial port   */
    #define TIME_HEADER  "T"   // Header tag for serial time sync message
    
    unsigned long processSyncMessage() {
      unsigned long pctime = 0L;
      const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 
    
      if(Serial.find(TIME_HEADER)) {
         pctime = Serial.parseInt();
         return pctime;
         if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
           pctime = 0L; // return 0 to indicate that the time is not valid
         }
      }
      return pctime;
    }
    
    void printDigits(int digits){
      // utility function for digital clock display: prints preceding colon and leading 0
      Serial.print(":");
      if(digits < 10)
        Serial.print('0');
      Serial.print(digits);
    }
    
    
    static const uint8_t PROGMEM _NeoPixelGammaTable[256] = {
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
        3,  3,  4,  4,  4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  7,
        7,  7,  8,  8,  8,  9,  9,  9, 10, 10, 10, 11, 11, 11, 12, 12,
       13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
       20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
       30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
       42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
       58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
       76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
       97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
      122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
      150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
      182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
      218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255};
      
    static uint8_t    gamma8(uint8_t x) {
        return pgm_read_byte(&_NeoPixelGammaTable[x]); // 0-255 in, 0-255 out
      }
    // A 24-bit variant of gamma8() that applies the same function
    // to all components of a packed RBG.
    uint32_t gamma32(uint32_t x) {
      uint8_t *y = (uint8_t *)&x;
      for(uint8_t i=0; i<3; i++) y[i] = gamma8(y[i]);
      return x; // Packed 32-bit return
    }
    
    uint32_t colorHSV(uint16_t hue) {
    
      uint8_t r, g, b, sat=255, val=100;  //if val is too high, power draw makes it hang.
    
      // Remap 0-65535 to 0-1529. Pure red is CENTERED on the 64K rollover;
      // 0 is not the start of pure red, but the midpoint...a few values above
      // zero and a few below 65536 all yield pure red (similarly, 32768 is the
      // midpoint, not start, of pure cyan). The 8-bit RGB hexcone (256 values
      // each for red, green, blue) really only allows for 1530 distinct hues
      // (not 1536, more on that below), but the full unsigned 16-bit type was
      // chosen for hue so that one's code can easily handle a contiguous color
      // wheel by allowing hue to roll over in either direction.
      hue = (hue * 1530L + 32768) / 65536;
      // Because red is centered on the rollover point (the +32768 above,
      // essentially a fixed-point +0.5), the above actually yields 0 to 1530,
      // where 0 and 1530 would yield the same thing. Rather than apply a
      // costly modulo operator, 1530 is handled as a special case below.
    
      // So you'd think that the color "hexcone" (the thing that ramps from
      // pure red, to pure yellow, to pure green and so forth back to red,
      // yielding six slices), and with each color component having 256
      // possible values (0-255), might have 1536 possible items (6*256),
      // but in reality there's 1530. This is because the last element in
      // each 256-element slice is equal to the first element of the next
      // slice, and keeping those in there this would create small
      // discontinuities in the color wheel. So the last element of each
      // slice is dropped...we regard only elements 0-254, with item 255
      // being picked up as element 0 of the next slice. Like this:
      // Red to not-quite-pure-yellow is:        255,   0, 0 to 255, 254,   0
      // Pure yellow to not-quite-pure-green is: 255, 255, 0 to   1, 255,   0
      // Pure green to not-quite-pure-cyan is:     0, 255, 0 to   0, 255, 254
      // and so forth. Hence, 1530 distinct hues (0 to 1529), and hence why
      // the constants below are not the multiples of 256 you might expect.
    
      // Convert hue to R,G,B (nested ifs faster than divide+mod+switch):
      if(hue < 510) {         // Red to Green-1
        b = 0;
        if(hue < 255) {       //   Red to Yellow-1
          r = 255;
          g = hue;            //     g = 0 to 254
        } else {              //   Yellow to Green-1
          r = 510 - hue;      //     r = 255 to 1
          g = 255;
        }
      } else if(hue < 1020) { // Green to Blue-1
        r = 0;
        if(hue <  765) {      //   Green to Cyan-1
          g = 255;
          b = hue - 510;      //     b = 0 to 254
        } else {              //   Cyan to Blue-1
          g = 1020 - hue;     //     g = 255 to 1
          b = 255;
        }
      } else if(hue < 1530) { // Blue to Red-1
        g = 0;
        if(hue < 1275) {      //   Blue to Magenta-1
          r = hue - 1020;     //     r = 0 to 254
          b = 255;
        } else {              //   Magenta to Red-1
          r = 255;
          b = 1530 - hue;     //     b = 255 to 1
        }
      } else {                // Last 0.5 Red (quicker than % operator)
        r = 255;
        g = b = 0;
      }
    
      // Apply saturation and value to R,G,B, pack into 32-bit result:
      uint32_t v1 =   1 + val; // 1 to 256; allows >>8 instead of /255
      uint16_t s1 =   1 + sat; // 1 to 256; same reason
      uint8_t  s2 = 255 - sat; // 255 to 0
      return ((((((r * s1) >> 8) + s2) * v1) & 0xff00) << 8) |
              (((((g * s1) >> 8) + s2) * v1) & 0xff00)       |
             ( ((((b * s1) >> 8) + s2) * v1)           >> 8);
    }
    
    void rainbowSpin1() {
    // Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
    
      // Hue of first pixel runs 5 complete loops through the color wheel.
      // Color wheel has a range of 65536 but it's OK if we roll over, so
      // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
      // means we'll make 5*65536/256 = 1280 passes through this outer loop:
      for(uint32_t firstPixelHue = 0; firstPixelHue < 1*65536; firstPixelHue += 256) {
        Serial.print("firstPixelHue = "); Serial.println(firstPixelHue);
        for(int i=0; i<numled; i++) { // For each pixel in strip...
          // Offset pixel hue by an amount to make one full revolution of the
          // color wheel (range of 65536) along the length of the strip
          // (strip.numPixels() steps):
          long pixelHue = firstPixelHue + (i * 65536L / numled);
          // Here we're using just the single-argument hue variant. The result
          // is passed through strip.gamma32() to provide 'truer' colors
          // before assigning to each pixel:
         // Serial.print(i); Serial.print("  "); Serial.print(pixelHue); Serial.print("  ");Serial.print(colorHSV(pixelHue)); Serial.println();
          ring.setPixelColor(i, gamma32(colorHSV(pixelHue)  ));
          
        }
        ring.show(); // Update strip with new contents
        delay(10);  // Pause for a moment
      }
      state = 0;     //back to clock
      ring.clear();
    }
    
    
    // Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
    void rainbowSpin2() {
      int firstPixelHue = 0;     // First pixel starts at red (hue 0)
      for(int a=0; a<10; a++) {  // Repeat 30 times...
        for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
          ring.clear();         //   Set all pixels in RAM to 0 (off)
          // 'c' counts up from 'b' to end of strip in increments of 3...
          for(int c=b; c<numled; c += 3) {
            // hue of pixel 'c' is offset by an amount to make one full
            // revolution of the color wheel (range 65536) along the length
            // of the strip (strip.numPixels() steps):
            long      hue   = firstPixelHue + c * 65536L / numled;
            uint32_t color = gamma32(colorHSV(hue)); // hue -> RGB
            ring.setPixelColor(c, color ); // Set pixel 'c' to value 'color'
          }
          ring.show();                // Update strip with new contents
          delay(70);                 // Pause for a moment
          firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
        }
      }
      state = 0;     //back to clock
      ring.clear();
    }
    
    
    void rainbowSpin3() {
      uint32_t color = random(65535);  
      for(int a=0; a<9; a++) {  // Repeat 10 times...
        for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
          ring.clear();         //   Set all pixels in RAM to 0 (off)
          // 'c' counts up from 'b' to end of strip in steps of 3...
          for(int c=b; c<numled; c += 3) {
            ring.setPixelColor(c,gamma32(colorHSV(color)) ); // Set pixel 'c' to value 'color'
          }
          ring.show(); // Update strip with new contents
          delay(100);  // Pause for a moment
        }
      }
      state = 0;     //back to clock
      ring.clear();
    }
    
    void playFile(const char *filename) {
     // Serial.println(); Serial.println("in playFile");
      SerialFlashFile ff = SerialFlash.open(filename);
      Serial.print("Playing file: ");
      Serial.println(filename);
    
      uint32_t sz = ff.size();
      uint32_t pos = ff.getFlashAddress();
    
      // Start playing the file.  This sketch continues to
      // run while the file plays.
      playAac1.play(pos,sz);
    
      // Simply wait for the file to finish playing.
      while (playAac1.isPlaying()) {
        yield();
      }
    }
    
    void openDoor() {
      int startPos = myservo.read();
      if(startPos == 255) {startPos = 90;}     //255 means undefined
      Serial.print(" OpenDoor startPosition = "); Serial.println(startPos);
      for(pos = startPos; pos <= startPos+88; pos++) {   //may need to adjust range
       // Serial.print(" pos="); Serial.print(pos);
        myservo.write(pos);
        delay(12);
      }
    }
    
    void closeDoor() {
      int startPos = myservo.read();
      if(startPos == 255) {startPos = 90;}     //255 means undefined
      Serial.print(" closeDoor startPosition = "); Serial.println(startPos);
      for (pos = startPos; pos >= startPos-88; pos--) {
        //Serial.print("pos = "); Serial.print(pos);
        myservo.write(pos);
        delay(12);
      }
    }
    void elvisRockClock() {
      openDoor();
      playFile("ROCKCLK.m4a");
      closeDoor();  
      state = 0;     //back to clock
      ring.clear();
    }
    
    void elvisCutTheCake() {
      openDoor();
      playFile("CUTCAKE.m4a");
      closeDoor(); 
      state = 0;     //back to clock
      ring.clear(); 
    }
    
    
    char fileList[6][13] = {"ENGLE.m4a","MARVTOY.m4a","HOTFROGS.m4a","GOZOO.m4a","FRED.m4a","DAYBORN.m4a"};
    int filePointer = 0;
    
    void elvisList() {
      openDoor();
      playFile(fileList[filePointer]);
      filePointer++;
      if(filePointer >= 6) {filePointer = 0;}
      closeDoor();
      state=0;
      ring.clear();
    }

  10. #10
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    329
    It says the video is not available?

  11. #11
    Huh. I can still see it and my son watched it. I'm new to youtube but I thought it was hard to find but public.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •