Author Topic: DigiSpark Pro powered Door Chime  (Read 7432 times)

tozz88

  • Newbie
  • *
  • Posts: 15
DigiSpark Pro powered Door Chime
« on: May 03, 2015, 11:50:15 pm »
I bought a Digispark Pro on kickstarter to use to rebuild my defective 1940's door chime. Well, the project is finally done. Here is a video of the door chime in action:

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

As you can see, there are LEDs for doorbell press (red), LEDs for each chime (green) and then the power LED on the digispark and finally the programmable digispark LED lights up for the duration of the song.

I have a power switch on the board to turn off power so I can upload sketches if required. This was needed as the Digispark Pro doesn't have a reset button. Here is the sketch for anybody who is interested. I'm sure there is plenty of room for improvements but it serves my purposes. Thanks Digitump!

tozz88

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Door Chime. Uses Digispark Pro
//
// Pinout:
// DigitalOut00 - Chime 0
// DigitalOut01 - LED::Doorbell Pressed detected
// DigitalIn02  - Doorbell
// DigitalIn06  - Serial Rx
// DigitalOut07 - Serial Tx
// DigitalOut08 - Chime  1
// DigitalOut09 - Chime  2
// DigitalOut10 - Chime  3
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define PIN_CHIME0      0
#define PIN_CHIME1      8
#define PIN_CHIME2      9
#define PIN_CHIME3     10
#define PIN_BELL        2
#define PIN_LED         1

#define MAX_NUM_CHIME    4



// The Chime class controls one chime on the doorbell.
class Chime {
  private:
    int pin;                           // GPIO to control chime solenoid
    static const int duration = 100;   // ms
   
  public:
    void Init(int wire)
   {
     pin = wire;
     pinMode(pin, OUTPUT);
     digitalWrite(pin, LOW);
     Serial.print("Chime");
     Serial.print(pin);
     Serial.println(" initialized");

   }
   
    // play one note on the chime.
    void Play(void)
    {
      Serial.print("Chime");
      Serial.print(pin);
      Serial.print(" start...");
      digitalWrite(pin, HIGH);      // turn on solenoid
      delay(Chime::duration);
      digitalWrite(pin, LOW);       // turn off solenoid
      Serial.println("done");
    }
   
} c[MAX_NUM_CHIME];    //  one Chime object for each chime in doorbell.


// This controls the doorbell. It's main job is to detect when doorbell is pressed.
// It assumes doorbell is open-circuit with pull-down resistor as normal (i.e. logic LOW).
// When doorbell is pressed, circuit is closed and goes HIGH.
class Bell {
 
  private:
    int pin;        // GPIO for doorbell.
    int pressed;    // state counter used to debounce doorbell and detect when it has been pressed long enough.
    static const int pressed_level     = HIGH;
    static const int pressed_duration  = 100;
   
  public:
 
    void Restart(void)
    {
      pressed = 0;
    }
   
    void Init(int wire)
    {
      pin = wire;
      pinMode(pin, INPUT);
      Restart();
    }
   
    // Pressed is true if a given duration of pressed_level is detected.
    // this is a simple way to debounce a mechnical switch.
    int IsPressed(void)
    {
      if (digitalRead(pin) == Bell::pressed_level) {
        pressed++;
        //Serial.print("pressed=");
        //Serial.println(pressed);
      }
      else
        pressed--;
      if (pressed < 0) pressed = 0;
      return (int) (pressed > Bell::pressed_duration);
    }
   
} db;


// The song is a list of notes. Each note is a chime and a duration.
// If you want to get fancy you could have several songs .

struct song_note_s {
  unsigned short chime_id;
  unsigned short duration;
};

struct song_note_s melody[] = {
  {0, 500},
  {2, 500},
  {1, 500},
  {3, 1000},
  {3, 500},
  {1, 500},
  {0, 500},
  {2, 500},
  {0, 0}
};

void Play_Song(struct song_note_s *s)
{
  //struct song_note_s *s = melody;
  if (s) {
    digitalWrite(PIN_LED, HIGH);
    while (s->duration) {
      c[s->chime_id].Play();
      delay(s->duration);
      s++;
    }
    digitalWrite(PIN_LED, LOW);
  }
}


// the setup routine runs once when you press reset:
void setup() {               
  Serial.begin(9600);//open diagnostic connection.
  // there is a header on PCB to connect up FTDI serial cable if dianostics are required.

  // The programmable LED will be on during sone.
  pinMode(PIN_LED, OUTPUT); //on board LED
 
  // set up doorbell
  db.Init(PIN_BELL);
 
  // set up chime control
  c[0].Init(PIN_CHIME0);
  c[1].Init(PIN_CHIME1);
  c[2].Init(PIN_CHIME2);
  c[3].Init(PIN_CHIME3);
 
  Serial.println("Doorchime up and running");
}

// the loop routine runs over and over again forever:
void loop() {
  if (db.IsPressed()) {
    Play_Song(melody);
    db.Restart();
  }
}



defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiSpark Pro powered Door Chime
« Reply #1 on: May 07, 2015, 12:04:48 am »
Cool - that is a Pro - and the Pro does have a reset button - opposite corner of the LED on the USB end.

tozz88

  • Newbie
  • *
  • Posts: 15
Re: DigiSpark Pro powered Door Chime
« Reply #2 on: May 13, 2015, 10:11:11 pm »
yes but its not actually hooked up to a reset circuit or software. see http://digistump.com/board/index.php/topic,1587.0.html. If you have any update besides this I'd love to hear it.

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: DigiSpark Pro powered Door Chime
« Reply #3 on: May 14, 2015, 10:39:01 pm »
This is the PRO board:

http://digispark.s3.amazonaws.com/DigisparkProDiagram2.png

The is the board I have called the PRO and the button labeled as Reset works for my purposes as a Reset to the device.

The original Digispark device with the USB plug tab did not have a reset button.