Introduction: Kookoo Kitchen Ikea

My project is to create a modern version of the cuckoo clock and occupy the space lost above the kitchen hood. I am not trying to have a perfect time display because there are several clocks in the kitchen (on the ovens in particular) but what interests me is to trigger the cuckoo clock - except at night! - and to use the clock to light a digital frame and the lighting of the window (cabinet of curiosities). And finally to have fun with the Arduino !

Special thanks to all those who share their resources which allowed me to carry out my project.

There is no point in reproducing this project exactly, but in being inspired by it to make your own cuckoo clock.

You can follow this simple project to begin with Arduino.

Step 1: STEP 1 : Materials

  1. Arduino Uno (or other model)
  2. Prototype shields not mandatory
  3. Led + resistor
  4. Beeper + resistor
  5. Clock DS3231 module
  6. Relay module (JQC 3FF S Z or other)
  7. Servomotor basic
  8. Resistor 200 Ohms
  9. Resistor 100 Ohms
  10. LED
  11. Dupont (!) wire
  12. Dupont and Dupond famous cartoon characters from Hergé (tm)
  13. Acrylic glass
  14. Cardboard
  15. Glue for glue gun
  16. Wood for the structure

most purchased on the Aliepxress site but can be found elsewhere on the web or in your favorite electronics store.

Step 2: STEP 2 : Assembly

You just have to follow the scheme...

Step 3: STEP 2 : Coding

All informations is in the code with comments.

Note that you need

  • #include "simpleRTC.h" // automatic summer time (in France)
  • #include "lagamme.h" // all the notes to play music

You can download kookoo_source.txt : the code

SimpleRTC.zip : https://forum.arduino.cc/index.php?action=dlattach...

lagamme.h must be in the same folder of your sketch and library added with the IDE Arduino.

You need to use the sketch to initialize time, you can find this sketch in the samples when the library has been added to the Arduino IDE.

#include "simpleRTC.h" // automatic summer time (in France)
#include 
#include "lagamme.h"

#include 
#include 
 
// les PINS
const byte PINLED1 = 9;
const byte PINS1 = 10;
const byte PINS2 = 11;
const byte PINR = 12;
const byte PINHP = 13;

// autres constantes
const int TEMPOSONCOUCOU = 500; // durée entre chaque son du Coucou
const int TEMPOCOUCOU = 500; // durée enctre chaque apparition du Coucou
const byte DEBSON = 9; // heure à partir de laquelle on peut sonner - time begin to ring not à night
const byte FINSON = 22; // fin - no more sound
const byte DEBCADRE = 19; // heure de début affichage cadre - time begin digital frame
const byte FINCADRE = 21; // heure de fin affichage cadre - time end
const unsigned long ACTUALISE = 20000; // temporisation dans la boucle principale (exemple : toutes les 30 secondes) - main loop timeout

// création servomoteurs - servo motor
Servo Servo1;
Servo Servo2;
// Mélodie à jouer pour sonner chaque heure
int melodie[] = {
  // Cannon in D - Pachelbel
  // Score available at https://musescore.com/user/4710311/scores/1975521
  // C F
  //NOTE_AS5,8, NOTE_A5,8, NOTE_G5,8, NOTE_F6,2, NOTE_C6,4,  
  NOTE_F6,2, NOTE_C6,4,  
};
// change this to make the song slower or faster
int tempo = 100;
int notes = sizeof(melodie) / sizeof(melodie[0]) / 2;
// this calculates the duration of a whole note in ms
int wholenote = (60000 * 4) / tempo;
int divider = 0, noteDuration = 0;

// variables
unsigned int MemoHeure;
unsigned int MemoMinute;
byte CadreOn;

void setup()
{
  // la liaison série
  Serial.begin(9600);
  // LED HP Relai
  pinMode(PINR,OUTPUT);  
  pinMode(PINHP,OUTPUT);  
  pinMode(PINLED1,OUTPUT);  

  // on déclare l'entrée des servos
  Servo1.attach(PINS1);
  Servo1.write(100); // rentrée du coucou
  Servo2.attach(PINS2);
  Wire.begin();

  RTC.actualiser();
  afficherRTC();
  MemoHeure = RTC.heure();
  MemoMinute = RTC.minute();
  CadreOn = false;
  digitalWrite(PINR, HIGH);
}

void loop() {
RTC.actualiser();
afficherRTC();
int Heure_Actu = RTC.heure();
int Minute_Actu = RTC.minute();
int Lheure = 0;
int Nbh = 0;
Serial.print(Heure_Actu);
Serial.print(" - memorisation : ");
Serial.println(MemoHeure);
if(Heure_Actu != MemoHeure) { // time change
  if(Heure_Actu==0) { Lheure = 12; } // number of kookoo
    else { 
      if(Heure_Actu>12) { Lheure = Heure_Actu - 12; }
      else { Lheure = Heure_Actu; }
      }
  // Coucou déclenchement -----------------------------
  // Allumage des leds
  digitalWrite(PINLED1, HIGH);
  // Cadre numérique via relais - digital frame, relay
  if(Heure_Actu>=DEBCADRE && Heure_Actu<=FINCADRE) {
    if(CadreOn==false) { // On allume une seule fois
      Serial.println("Cadre allumé");
      digitalWrite(PINR, LOW);
      CadreOn=true;
      }
    } else { // on éteint
      if(CadreOn==true) { // On allume une seule fois
      Serial.println("Cadre éteint");
      CadreOn=false;
      digitalWrite(PINR, HIGH);
      }
    }
    // Décompte des heures
    Serial.println(Lheure);
    for(Nbh = 0; Nbh < Lheure; Nbh++) {
      Serial.println(Nbh);
      Servo1.write(30); // sortie du coucou
      Serial.print("je sors ");
      // temporisation - pas de son selon l'heure
      if(Heure_Actu>=DEBSON && Heure_Actu<=FINSON) {
        JoueCoucou();
        delay(TEMPOCOUCOU);
      } else {
        delay(TEMPOCOUCOU);
    }
    Servo1.write(100); // rentrée du coucou
    Serial.println("je rentre");
    delay(TEMPOCOUCOU);  
    }
  // Extinctions leds
  digitalWrite(PINLED1, LOW);
  MemoHeure = Heure_Actu; // heure suivante
  MemoMinute = Minute_Actu;
  }

  // Horloge
  int S2minute = Heure_Actu*60 + Minute_Actu;
  Serial.println(S2minute);
  S2minute= map(S2minute, 0, 1440, 165, 25);
  Servo2.write(S2minute);
  delay(ACTUALISE); // Pas la peine de recommencer toutes les secondes !
}

void Serial_print_nn(uint8_t nombre)
{
  if (nombre < 10) Serial.print('0');
  Serial.print(nombre);
}

void JoueCoucou() {
  // https://dragaosemchama.com/en/2019/02/songs-for-arduino/
  // iterate over the notes of the melody.
  // Remember, the array is twice the number of notes (notes + durations)
  for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {
    // calculates the duration of each note
    divider = melodie[thisNote + 1];
    if (divider > 0) {
      // regular note, just proceed
      noteDuration = (wholenote) / divider;
    } else if (divider < 0) {
      // dotted notes are represented with negative durations!!
      noteDuration = (wholenote) / abs(divider);
      noteDuration *= 1.5; // increases the duration in half for dotted notes
    }
    // we only play the note for 90% of the duration, leaving 10% as a pause
    tone(PINHP, melodie[thisNote], noteDuration * 0.9);
    // Wait for the specief duration before playing the next note.
    delay(noteDuration);
    // stop the waveform generation before the next note.
    noTone(PINHP);
  }
}

void afficherRTC()
{
  afficherJourSemaineJJJ(RTC.jourSemaine());
  Serial.print(' ');
  afficherDateHeureS(RTC.annee(), RTC.mois(), RTC.jour(), RTC.heure(), RTC.minute(), RTC.seconde());
  Serial.print(" heure d'");
  if (RTC.heureEte()) {
    Serial.print("ete");
    } else {
    Serial.print("hiver");
    }
  Serial.print(" (");
  afficherDateHeureS(RTC.anneeUTC(), RTC.moisUTC(), RTC.jourUTC(), RTC.heureUTC(), RTC.minute(), RTC.seconde());
  Serial.println(" UTC)");
}

void afficherJourSemaineJJJ(uint8_t joursem)
{
  switch (joursem) {
    case 0  : Serial.print("Dim");break; // Sunday, monday etc...
    case 1  : Serial.print("Lun");break;
    case 2  : Serial.print("Mar");break;
    case 3  : Serial.print("Mer");break;
    case 4  : Serial.print("Jeu");break;
    case 5  : Serial.print("Ven");break;
    case 6  : Serial.print("Sam");break;
    default : Serial.print("xxx");
  }
}

void afficherDateHeureS(uint8_t annee, uint8_t mois, uint8_t jour, uint8_t heure, uint8_t minute, uint8_t seconde)
{
  afficherDate(annee, mois, jour);
  Serial.print(' ');
  afficherHeure(heure, minute, seconde);
}

void afficherDate(uint8_t annee, uint8_t mois, uint8_t jour)
{
  Serial_print_nn(jour);
  Serial.print('/');
  Serial_print_nn(mois);
  Serial.print("/20"); // What about next century ;-)
  Serial_print_nn(annee);
}

void afficherHeure(uint8_t heure, uint8_t minute, uint8_t seconde)
{
  Serial_print_nn(heure);
  Serial.print(':');
  Serial_print_nn(minute);
  Serial.print(':');
  Serial_print_nn(seconde);
}

Step 4: STEP 4 : Assembly and Result

After having tested the assembly on a breadboard I used a prototyping shield and I welded the elements then I installed the elements on my wooden support painted in black. The led is used to light the cuckoo clock when it rings.