Bel sekolah dengan pengaturan melalui tombol

Bel sekolah merupakan pengingat waktu terjadwal yang menandai pergantian antar waktu pelajaran di sekolah. Ber sekolah juga memiliki penjawalan mingguan dan bulanan.

Perangkat bel sekolah otomatis bisa diaplikasikan menggunakan arduino sebagai unit prosesornya, tidak seperti bel sekolah digital berbasis komputer yang menyimpan jadwal dalam harddisk, bel sekolah digital arduino menyimpan data jadwal pelajaran didalam EEPROM. Data Jadwal disimpan dalam format/struktur berikut :

  • Aktif
  • Jam
  • Menit

Guna mengatur data jadwal tersebut, perangkat bel sekolah ini dilengkapi dengan tombol-tombol dengan fungsi [menu], [tambah], [kurang] dan [ok].

serta penggunaan LCD sebagai tampilan waktu sekarang dan tampilan jadwal apabila waktunya telah tepat.

skema bel sekolah dengan pengaturan melalui tombol/button:

komponen yang digunakan :

  1. Arduino uno
  2. RTC DS3231
  3. LCD i2C
  4. push button 4x

sketch/koding bel sekolah arduino :

#define pinTombolMenu       5
#define pinTombolTambah     4
#define pinTombolKurang     3
#define pinTombolOk         2

#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include "RTC.h"

LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
RTC_DS3231 rtc;
char namaHari[][7] = {"Minggu", "Senin", "Selasa", " Rabu", "Kamis", "Jum'at", "Sabtu"};
char textMenuUtama[][17] = {
  "Bel masuk +pel 1",
  "Ganti pel 2     ",
  "Bel istirahat   ",
  "Bel masuk +pel 3",
  "Ganti pel 4     ",
  "Bel pulang      ",
  "Set Jam         ",
};
char textAktif[][6] = {"Mati ", "Aktif"};

char bufWaktu[40];

struct Jadwal
{
  bool aktif;
  byte jam;
  byte menit;
};

Jadwal jadwal[6] = {{0, 7, 0}, {0, 7, 0}, {0, 7, 0}, {0, 7, 0}, {0, 7, 0}, {0, 7, 0},} ;
Jadwal jadwalSet;

void setup()
{
  pinMode(pinTombolMenu, INPUT_PULLUP);
  pinMode(pinTombolTambah, INPUT_PULLUP);
  pinMode(pinTombolKurang, INPUT_PULLUP);
  pinMode(pinTombolOk, INPUT_PULLUP);

  Serial.begin (9600);

  rtc.begin();

  if (rtc.lostPower())
  {
    Serial.println(F("Waktu RTC di set ulang"));
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  Wire.beginTransmission(0x3F);
  if (Wire.endTransmission())
  {
    lcd = LiquidCrystal_I2C(0x27, 16, 2);
  }
  lcd.begin();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Nama");
  lcd.setCursor(0, 1);
  lcd.print("Judul");

  //  delay(3000);

  if (EEPROM.read(0) != 0x48)
  {
    simpanJadwal();
    EEPROM.write(0, 0x48);
  }
  else
  {
    ambilJadwal();
  }
  Serial.println("Bel sekolah dimulai");
}

byte detikSebelumnya = 60;
byte menitSebelumnya = 60;
byte menuLevel = 0;
byte menuIndex[2];
DateTime setWaktu;

void loop()
{
  DateTime now = rtc.now();
  if (detikSebelumnya != now.detik)
  {
    detikSebelumnya = now.detik;
    if (!menuLevel)
    {
      sprintf(bufWaktu, "Pukul : %02d:%02d:%02d", now.jam, now.menit, now.detik);
      lcd.setCursor(0, 0);
      lcd.print(bufWaktu);
      sprintf(bufWaktu, "%s, %02d/%02d/%02d", namaHari[now.hari - 1], now.tanggal, now.bulan, now.tahun - 2000);
      lcd.setCursor(0, 1);
      lcd.print(bufWaktu);

    }
    if (menitSebelumnya != now.menit)
    {
      menitSebelumnya = now.menit;
      for (byte i = 0; i < 6; i++)
      {
        if (jadwal[i].aktif)
        {
          if ((jadwal[i].jam == now.jam) && (jadwal[i].menit == now.menit))
          {
            lcd.setCursor(0, 0);
            lcd.print("  Bel Sekolah   ");
            lcd.setCursor(0, 1);
            lcd.print(textMenuUtama[i]);
            delay(10000);
          }
        }
      }
    }
  }

  if (!digitalRead(pinTombolMenu))
  {
    delay(100);
    if (!digitalRead(pinTombolMenu))
    {
      if (menuLevel == 0)
      {
        menuLevel = 1;
        menuIndex[0] = 0;
      }
      else
      {
        menuLevel = 0;
        lcd.noBlink();
      }
      tampilanMenu();
      while (!digitalRead(pinTombolMenu));
    }
  }
  if (!digitalRead(pinTombolTambah))
  {
    delay(100);
    if (!digitalRead(pinTombolTambah))
    {
      if (menuLevel == 1)
      {
        menuIndex[0]++;
        if (menuIndex[0] >= sizeof(textMenuUtama) / sizeof(textMenuUtama[0]))
        {
          menuIndex[0] = 0;
        }
        tampilanMenu();
      }
      if (menuLevel == 2)
      {
        if (menuIndex[0] == 6)
        {
          switch (menuIndex[1])
          {
            case 0:
              setWaktu.jam++;
              if (setWaktu.jam >= 24)
              {
                setWaktu.jam = 0;
              }
              break;
            case 1:
              setWaktu.menit++;
              if (setWaktu.menit >= 60)
              {
                setWaktu.menit = 0;
              }
              break;
            case 2:
              setWaktu.detik++;
              if (setWaktu.detik >= 60)
              {
                setWaktu.detik = 0;
              }
              break;
          }
        }
        else
        {
          switch (menuIndex[1])
          {
            case 0:
              jadwalSet.aktif = !jadwalSet.aktif;
              break;
            case 1:
              jadwalSet.jam++;
              if (jadwalSet.jam >= 24)
              {
                jadwalSet.jam = 0;
              }
              break;
            case 2:
              jadwalSet.menit++;
              if (jadwalSet.menit >= 60)
              {
                jadwalSet.menit = 0;
              }
              break;
          }
        }
        tampilanMenu();
      }
      delay(100);
    }
  }
  if (!digitalRead(pinTombolKurang))
  {
    delay(100);
    if (!digitalRead(pinTombolKurang))
    {
      if (menuLevel == 1)
      {
        if (menuIndex[0] == 0)
        {
          menuIndex[0] = sizeof(textMenuUtama) / sizeof(textMenuUtama[0]) - 1;
        }
        else
        {
          menuIndex[0]--;
        }
        tampilanMenu();
      }
      if (menuLevel == 2)
      {
        if (menuIndex[0] == 6)
        {
          switch (menuIndex[1])
          {
            case 0:
              if (setWaktu.jam == 0)
              {
                setWaktu.jam = 23;
              }
              else
              {
                setWaktu.jam--;
              }
              break;
            case 1:
              if (setWaktu.menit == 0)
              {
                setWaktu.menit = 59;
              }
              else
              {
                setWaktu.menit--;
              }
              break;
            case 2:
              if (setWaktu.detik == 0)
              {
                setWaktu.detik = 59;
              }
              else
              {
                setWaktu.detik--;
              }
              break;
          }
        }
        else
        {
          switch (menuIndex[1])
          {
            case 0:
              jadwalSet.aktif = !jadwalSet.aktif;
              break;
            case 1:
              if (jadwalSet.jam == 0)
              {
                jadwalSet.jam = 23;
              }
              else
              {
                jadwalSet.jam--;
              }
              break;
            case 2:
              if (jadwalSet.menit == 0)
              {
                jadwalSet.menit = 59;
              }
              else
              {
                jadwalSet.menit--;
              }
              break;
          }
        }
        tampilanMenu();
      }
      delay(100);
    }
  }
  if (!digitalRead(pinTombolOk))
  {
    delay(100);
    if (!digitalRead(pinTombolOk))
    {
      if (menuLevel == 1)
      {
        menuLevel = 2;
        menuIndex[1] = 0;
        if (menuIndex[0] == 6)
        {
          setWaktu = rtc.now();
          tampilanMenu();
          lcd.setCursor(4, 1);
          lcd.blink();
        }
        else
        {
          jadwalSet.aktif = jadwal[menuIndex[0]].aktif;
          jadwalSet.jam = jadwal[menuIndex[0]].jam;
          jadwalSet.menit = jadwal[menuIndex[0]].menit;
          tampilanMenu();
          lcd.setCursor(2, 1);
          lcd.blink();
        }
      }
      else if (menuLevel == 2)
      {
        menuIndex[1]++;
        if (menuIndex[0] == 6)
        {
          switch (menuIndex[1])
          {
            case 1:
              tampilanMenu();
              lcd.setCursor(7, 1);
              lcd.blink();
              break;
            case 2:
              tampilanMenu();
              lcd.setCursor(10, 1);
              lcd.blink();
              break;
            case 3:
              menuLevel = 1;
              rtc.adjust(setWaktu);
              tampilanMenu();
              lcd.noBlink();
              break;
          }
        }
        else
        {
          switch (menuIndex[1])
          {
            case 1:
              tampilanMenu();
              lcd.setCursor(8, 1);
              lcd.blink();
              break;
            case 2:
              tampilanMenu();
              lcd.setCursor(11, 1);
              lcd.blink();
              break;
            case 3:
              menuLevel = 1;
              jadwal[menuIndex[0]].aktif = jadwalSet.aktif;
              jadwal[menuIndex[0]].jam = jadwalSet.jam;
              jadwal[menuIndex[0]].menit = jadwalSet.menit;
              simpanJadwal();
              lcd.noBlink();
              tampilanMenu();
              break;
          }
        }
        while (!digitalRead(pinTombolOk));
        delay(500);
      }
    }
  }
}
void tampilanMenu()
{
  if (menuLevel == 1)
  {
    lcd.setCursor(0, 0);
    lcd.print("   Menu Utama   ");
    lcd.setCursor(0, 1);
    lcd.print(textMenuUtama[menuIndex[0]]);
  }
  else if (menuLevel == 2)
  {
    if (menuIndex[0] == 6)
    {
      lcd.setCursor(0, 0);
      lcd.print(textMenuUtama[menuIndex[0]]);
      sprintf(bufWaktu, "    %02d:%02d:%02d    ", setWaktu.jam, setWaktu.menit, setWaktu.detik);
      lcd.setCursor(0, 1);
      lcd.print(bufWaktu);
    }
    else
    {
      lcd.setCursor(0, 0);
      lcd.print(textMenuUtama[menuIndex[0]]);
      sprintf(bufWaktu, "  %s %02d:%02d   ", textAktif[jadwalSet.aktif], jadwalSet.jam, jadwalSet.menit);
      lcd.setCursor(0, 1);
      lcd.print(bufWaktu);
    }
  }
}

void ambilJadwal()
{
  byte *alamat = (byte*)jadwal;
  for (byte i = 1; i < sizeof(jadwal) + 1; i++)
  {
    *alamat++ = EEPROM.read(i);
  }
}
void simpanJadwal()
{
  byte *alamat = (byte*)jadwal;
  for (byte i = 1; i < sizeof(jadwal) + 1; i++)
  {
    EEPROM.update(i, *alamat++);
  }
}

library yang digunakan:

Bel sekolah arduino dengan kontrol android 2 (upgrade lcd)

Bel sekolah adalah pengingat waktu yang digunakan di sekolah sebagai penanda pergantian jadwal.

Bel sekolah digital bisa di aplikasikan dalam bentuk:

    1. Aplikasi komputer
      adalah aplikasi yang ditanam dalam komputer dan bisa dijalankan secara otomatis. sistem ini mudah dalam pengaturan, memiliki data jadwal sangat besar,  peringatan admin, backup, update suara mudah, perekan suara, kunci aplikasi dll. Kelemahannya adalah komputer dan aplifier suara harus tetap hidup dan bergantung kepada adanya daya listrik/ups termasuk biaya listrik, pesan sponsor pada aplikasi gratis,  biaya pengadaan dan perawatan komputer.
    2. Aplikasi android
      Aplikasi / apk android memiliki sama dengan aplikasi komputer dan aplikasi android dapat terhubung dengan  sistem tata suara melalui bluetooth dan kabel audio. kekurangannya adalah device android harus selalu berada dekat dengan sistem (selalu standby)
    3. Aplikasi perangkat mandiri
      Sistem bel sekolah otomatis dapat dibangun dengan perangkat mandiri menggunakan microkontroller dengan biaya murah dan bisa dikembangkan untuk keperluan lainnya seperti :

      • bisa menggunakan baterai sebagai daya cadangannya
      • Pendeteksi gempa dan peringatan
      • Notifikasi sms ke pengajar
      • Mekanuisme kunci pagar
      • Panggilan melalui microphone yang tertuju langsung ke kelas tertentu
      • dan lain-lain sesuai kebutuhan

      Kekurangan sistem ini adalah ruang penyimpanan data jadwal dan suara terbatas, pengaturan jadwal yang sulit melalui tombol/keypad.

Dalam proyek ini menggabungkan perangkat mandiri dengan platform arduino yang dikombinasikan dengan aplikasi/apk android sebagai kontrolnya.

Skema bel sekolah otomatis dengan kontrol android:

komponen bel sekolah arduino control android:

  • Arduino Uno
  • Bluetooth HC-05
  • RTC DS3231
  • LCD 1602 + I2C backpack
  • modul Relay 1 channel
  • DF Player mini mp3
  • Speaker

tampilan Aplikasi bel sekolah android :

sketch/aplikasi bel sekolah bluettoth android :

#define namaSekolah   "Nama Sekolah"

#define SQWPin        A3
#define pinRelay      8
#define relayOn       LOW

#include <avr/sleep.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#include "RTC.h"
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define tokenEEPROM 0x83
SoftwareSerial bluetooth(2, 3); // RX, TX
SoftwareSerial mp3Serial(4, 5); // RX, TX
LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

struct Waktu
{
  byte jam;
  byte menit;
};

struct TabelMataPelajaran
{
  byte aktif;
  Waktu waktu;
  byte hariAktif;
  byte mingguAktif;
  byte kegiatan;
};

const char kegiatanText[][17] PROGMEM = {
  "-               ",
  "Jam Pelajaran 1 ",
  "Jam Pelajaran 2 ",
  "Jam Pelajaran 3 ",
  "Jam Pelajaran 4 ",
  "Jam Pelajaran 5 ",
  "Jam Pelajaran 6 ",
  "Jam Pelajaran 7 ",
  "Jam Pelajaran 8 ",
  "Jam Pelajaran 9 ",
  "Jam Pelajaran 10",
  "Jam Pelajaran 11",
  "Jam Pelajaran 12",
  "Jam Pelajaran 13",
  "Jam Pelajaran 14",
  "Jam Pelajaran 15",
  "Masuk           ",
  "Upacara         ",
  "Istirahat       ",
  "Istirahat1      ",
  "Istirahat2      ",
  "Istirahat3      ",
  "Selesai istiraht",
  "Kepramukaan     ",
  "Khusus          ",
  "Pulang          ",
  "Pulang Jum'at   ",
  "Pulang Sabtu    ",
  "Musik 1         ",
  "Musik 2         ",
  "Musik 3         ",
  "Musik 4         ",
  "Musik 5         ",
  "Musik 6         ",
  "Hadits 1        ",
  "Hadits 2        ",
  "Hadits 3        ",
  "Hadits 4        ",
  "Hadits 5        ",
  "Hadits 6        ",
};

enum _kegiatan
{
  TidakAda,
  JamPelajaran1,
  JamPelajaran2,
  JamPelajaran3,
  JamPelajaran4,
  JamPelajaran5,
  JamPelajaran6,
  JamPelajaran7,
  JamPelajaran8,
  JamPelajaran9,
  JamPelajaran10,
  JamPelajaran11,
  JamPelajaran12,
  JamPelajaran13,
  JamPelajaran14,
  JamPelajaran15,
  Masuk,
  Upacara,
  Istirahat,
  Istirahat1,
  Istirahat2,
  Istirahat3,
  SelesaiIstirahat,
  Kepramukaan,
  Khusus,
  Pulang,
  PulangJumat,
  PulangSabtu,
  Musik1,
  Musik2,
  Musik3,
  Musik4,
  Musik5,
  Musik6,
  Hadits1,
  Hadits2,
  Hadits3,
  Hadits4,
  Hadits5,
  Hadits6,
};
enum PengaturanAndroid
{
  cekAses,
  pengaturanJadwal,
  pengaturanWaktu,

};

char karakterMusik[8] = {
  0b00000,
  0b00100,
  0b00110,
  0b00101,
  0b00101,
  0b00100,
  0b11100,
  0b11100
};
byte karakterDetik1[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b00100,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};
byte karakterDetik2[8] = {
  0b00000,
  0b00000,
  0b00100,
  0b01010,
  0b00100,
  0b00000,
  0b00000,
  0b00000
};
byte karakterDetik3[8] = {
  0b00000,
  0b00100,
  0b01010,
  0b10001,
  0b01010,
  0b00100,
  0b00000,
  0b00000
};
byte karakterSetting[8] = {
  0b00100,
  0b00100,
  0b00100,
  0b01110,
  0b00100,
  0b10001,
  0b01010,
  0b00100
};

volatile bool interupsiDetik;
byte indexMataPelajaran;
RTC_DS3231 rtc;
DateTime now;
bool rtcValid;
byte indexPengaturanJadwal = 0;

#define hariAktifSenin 1<<6
#define hariAktifSelasa 1<<5
#define hariAktifRabu 1<<4
#define hariAktifKamis 1<<3
#define hariAktifJumat 1<<2
#define hariAktifSabtu 1<<1
#define hariAktifMinggu 1<<7

char namaHari[][7] = {"Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jum'at", "Sabtu"};
#define _hariAktif(Sen,Sel,Rab,Kam,Jum,Sab,Mgu) (Mgu<<7)|(Sen<<6)|(Sel<<5)|(Rab<<4)|(Kam<<3)|(Jum<<2)|(Sab<<1)
#define _mingguAktif(Mgu1,Mgu2,Mgu3,Mgu4,Mgu5,Mgu6) (Mgu1<<7)|(Mgu2<<6)|(Mgu3<<5)|(Mgu4<<4)|(Mgu5<<3)|(Mgu6<<2)
#define _waktu(Jam, Menit) {Jam, Menit}
#define Aktif 1
#define TidakAktif 0

TabelMataPelajaran jadwalBelajar[40];
Waktu waktu;

char bufWaktu[40];
byte detikSebelumnya = 60;
byte tanggalSebelumnya = 0;
Waktu jadwalBerikutnya;
byte menitBel;
bool statusBel;
bool statusPengingat;

byte jadwalBerikutnyaKegiatan;


void setup() {
  digitalWrite(pinRelay, !relayOn);
  pinMode(pinRelay, OUTPUT);
  
  pinMode(SQWPin, INPUT_PULLUP);

  Serial.begin(9600);
  Serial.println(F("Bel Sekolah Dengan Kontrol Android"));
  Serial.println(F("https://www.project.semesin.com"));
  Serial.println();

  Wire.begin();
  Wire.beginTransmission(0x3F);
  if (Wire.endTransmission())
  {
    lcd = LiquidCrystal_I2C(0x27, 16, 2);
  }
  lcd.begin();

  lcd.command (0x40 | (0 << 3));
  for (byte i = 0; i < 8; i++)
    lcd.write (karakterDetik1[i]);

  lcd.command (0x40 | (1 << 3));
  for (byte i = 0; i < 8; i++)
    lcd.write (karakterDetik2[i]);

  lcd.command (0x40 | (2 << 3));
  for (byte i = 0; i < 8; i++)
    lcd.write (karakterDetik3[i]);

  lcd.command (0x40 | (3 << 3));
  for (byte i = 0; i < 8; i++)
    lcd.write (karakterDetik2[i]);

  lcd.command (0x40 | (4 << 3));
  for (byte i = 0; i < 8; i++)
    lcd.write (karakterMusik[i]);

  lcd.command (0x40 | (5 << 3));
  for (byte i = 0; i < 8; i++)
    lcd.write (karakterSetting[i]);


  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Bel Sekolah");
  lcd.setCursor(0, 1);
  lcd.print(namaSekolah);


  mp3Serial.begin(9600);
  bluetooth.begin (9600);
  bluetooth.listen();

  mp3_set_serial (mp3Serial);
  mp3_set_volume (15);//full volume 0x30

  rtc.begin();

  if (rtc.lostPower()) 
  {
    Serial.println(F("RTC lost power, lets set the time!"));
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  
  rtc.writeSqwPinMode(DS3231_SquareWave1Hz);

  if (EEPROM.read(sizeof(jadwalBelajar)) != tokenEEPROM)
  {
    nilaiAwal();
    EEPROM.write(sizeof(jadwalBelajar), tokenEEPROM);
    Serial.println("setting awal");
  }
  
  EEPROM.get(0, jadwalBelajar);
  cekJadwalHariIni();

  delay(1000);

  lcd.clear();

  Serial.println(F("Sistem bel sekolah dimulai"));

}

void loop() {
  if (digitalRead(SQWPin))
  {
    if (rtcValid)
    {
      rtcValid = false;

      now = rtc.now();

      uint16_t unixJadwalBerikutnya = (jadwalBerikutnya.jam * 60) + jadwalBerikutnya.menit;
      uint16_t unixWaktu = (now.jam * 60) + now.menit;

      if (!now.detik)
      {
        if (jadwalBerikutnyaKegiatan && (jadwalBerikutnya.jam == now.jam) && (jadwalBerikutnya.menit == now.menit))
        {
          lcd.setCursor(6, 1);
          lcd.print((char)4);
          lcd.setCursor(0, 0);
          lcd.print((__FlashStringHelper *)kegiatanText[jadwalBerikutnyaKegiatan]);

          mp3_play (jadwalBerikutnyaKegiatan);
          Serial.println((__FlashStringHelper *)kegiatanText[jadwalBerikutnyaKegiatan]);
          menitBel = jadwalBerikutnya.menit;
          statusBel = true;
          statusPengingat = false;
        }
        else if (jadwalBerikutnyaKegiatan && (unixWaktu == unixJadwalBerikutnya - 1))
        {
          statusPengingat = true;
          digitalWrite(pinRelay, relayOn);
          Serial.println("Pengingat bel masuk 1 menit lagi");
        }
      }

      if (menitBel != now.menit)
      {
        if (statusBel)
        {
          lcd.setCursor(6, 1);
          lcd.print(' ');

          digitalWrite(pinRelay, !relayOn);

          cariJadwal();
          statusBel = false;
          tanggalSebelumnya = 0;
        }
      }

      //tampilan
      if (statusPengingat)
      {
        lcd.setCursor(1, 1);
        if (now.detik % 2)
        {
          sprintf(bufWaktu, "%02d:%02d", jadwalBerikutnya.jam, jadwalBerikutnya.menit);
          lcd.print(bufWaktu);
        }
        else
        {
          lcd.print("     ");
        }
      }

      if (detikSebelumnya != now.detik)
      {
        sprintf(bufWaktu, "%02d:%02d:%02d", now.jam, now.menit, now.detik);
        lcd.setCursor(8, 1);
        lcd.print(bufWaktu);
        lcd.setCursor(0, 1);
        lcd.print((char)(now.detik % 4));

        sprintf(bufWaktu, "%02d:%02d:%02d %s, %02d/%02d/%02d", now.jam, now.menit, now.detik, namaHari[now.hari - 1], now.tanggal, now.bulan, now.tahun - 2000);
        Serial.println(bufWaktu);
      }

      if (tanggalSebelumnya != now.tanggal)
      {
        tanggalSebelumnya = now.tanggal;
        lcd.clear();
        lcd.print(namaHari[now.hari - 1]);
        lcd.print(',');
        sprintf(bufWaktu, "%02d/%02d/%02d", now.tanggal, now.bulan, now.tahun - 2000);
        lcd.setCursor(8, 0);
        lcd.print(bufWaktu);

        cariJadwal();
      }
    }
  }
  else
  {
    rtcValid = true;
  }
  cekBluetooth();
}

void cekBluetooth()
{
  uint8_t tokenMulai;
  uint8_t perintah;
  uint8_t parameter;
  uint8_t panjang1;
  uint8_t panjang2;
  char c;
  uint8_t i, j;
  uint8_t tokenSelesai;
  byte bufferSerial[100];
  byte *alamat;

  if (bluetooth.available())
  {
    tokenMulai = bluetoothRead();
    if (tokenMulai == 0xFD)
    {
      panjang1 = bluetoothRead();
      panjang2 = bluetoothRead();

      if (panjang2 == 254 - panjang1)
      {
        if (panjang1 >= sizeof(bufferSerial))
        {
          panjang1 = sizeof(bufferSerial);
        }

        uint16_t timeOut = 0xFFF;
        i = 0;
        do
        {
          if (bluetooth.available())
          {
            c = bluetoothRead();
            bufferSerial[i++] = c;
          }
        } while ((i < panjang1 + 3) && (timeOut--));

        perintah = bufferSerial[0];
        parameter = bufferSerial[1];

        tokenSelesai = bufferSerial[i - 1];
        if (tokenSelesai == 0x00)
        {
          delay(10);
          bluetooth.write(254);
          switch (perintah)
          {
            case cekAses:
              bluetooth.write(1);
              bluetooth.write(254);
              break;
            case pengaturanJadwal:
              lcd.setCursor(6, 1);
              lcd.print((char)5);

              memcpy((byte*)&jadwalBelajar[parameter], bufferSerial + 2, sizeof(TabelMataPelajaran));
              if (parameter == (sizeof(jadwalBelajar) / sizeof(TabelMataPelajaran)) - 1)
              {
                EEPROM.put(0, jadwalBelajar);
                Serial.println("Jadwal diterima");

                lcd.setCursor(6, 1);
                lcd.print(' ');

                tanggalSebelumnya = 0;
              }
              break;
            case pengaturanWaktu:
              memcpy((byte*)&now, bufferSerial + 2, sizeof(DateTime));
              rtc.adjust(now);
              tanggalSebelumnya = 0;
              Serial.println("Setting waktu diterima");
              break;
          }
        }
        else
        {
          bluetooth.write(252);//data tidak benar
        }
      }
    }
  }
}
byte bluetoothRead()
{
  uint16_t timeOut = 0xFFF;
  while (!bluetooth.available() && timeOut--);
  return bluetooth.read();
}



void nilaiAwal()
{
  byte i = 0;
  jadwalBelajar[i++] = {Aktif, _waktu(  6, 45 ), hariAktifSenin                 , _mingguAktif(1, 0, 0, 0, 0, 0), Upacara};
  jadwalBelajar[i++] = {Aktif, _waktu(  6, 45 ), hariAktifSenin                 , _mingguAktif(0, 1, 1, 1, 1, 1), JamPelajaran1};
  jadwalBelajar[i++] = {Aktif, _waktu(  6, 45 ), _hariAktif(0, 1, 1, 1, 1, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran1};

  jadwalBelajar[i++] = {Aktif, _waktu(  7, 30 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran2};
  jadwalBelajar[i++] = {Aktif, _waktu(  8, 15 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran3};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 0  ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran4};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 45 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), Istirahat};
  jadwalBelajar[i++] = {Aktif, _waktu( 10, 15 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran5};
  jadwalBelajar[i++] = {Aktif, _waktu( 11, 0  ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran6};
  jadwalBelajar[i++] = {Aktif, _waktu( 11, 45 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), Istirahat};
  jadwalBelajar[i++] = {Aktif, _waktu( 12, 30 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran7};
  jadwalBelajar[i++] = {Aktif, _waktu( 13, 15 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran8};

  jadwalBelajar[i++] = {Aktif, _waktu( 14, 0  ), _hariAktif(1, 1, 1, 0, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran9};
  jadwalBelajar[i++] = {Aktif, _waktu( 14, 45 ), _hariAktif(1, 1, 1, 0, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran10};

  jadwalBelajar[i++] = {Aktif, _waktu( 14, 0  ), hariAktifKamis,            _mingguAktif(1, 1, 1, 1, 1, 1), Kepramukaan};
  jadwalBelajar[i++] = {Aktif, _waktu( 14, 45 ), hariAktifKamis,            _mingguAktif(1, 1, 1, 1, 1, 1), Khusus};

  jadwalBelajar[i++] = {Aktif, _waktu( 15, 30 ), _hariAktif(1, 1, 1, 1, 0, 0, 0), _mingguAktif(1, 1, 1, 1, 1, 1), Pulang};

  jadwalBelajar[i++] = {Aktif, _waktu(  7, 25 ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran2};
  jadwalBelajar[i++] = {Aktif, _waktu(  8, 5  ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran3};
  jadwalBelajar[i++] = {Aktif, _waktu(  8, 45 ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran4};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 25 ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), Istirahat};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 55 ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran5};
  jadwalBelajar[i++] = {Aktif, _waktu( 10, 35 ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), JamPelajaran6};
  jadwalBelajar[i++] = {Aktif, _waktu( 11, 15 ), hariAktifJumat,            _mingguAktif(1, 1, 1, 1, 1, 1), PulangJumat};

  EEPROM.put(0, jadwalBelajar);
}

void cekJadwalHariIni()
{
  Serial.println("Jadwal hari ini");
  for (byte i = 0; i < sizeof(jadwalBelajar) / sizeof(TabelMataPelajaran) ; i++)
  {
    Serial.print(jadwalBelajar[i].aktif);
    Serial.print('\t');
    Serial.print(jadwalBelajar[i].waktu.jam);
    Serial.print('\t');
    Serial.print(jadwalBelajar[i].waktu.menit);
    Serial.print('\t');
    Serial.print(jadwalBelajar[i].hariAktif, HEX);
    Serial.print('\t');
    Serial.print(jadwalBelajar[i].mingguAktif, HEX);
    Serial.print('\t');
    Serial.print(jadwalBelajar[i].kegiatan);
    Serial.print('\t');
    char buf[20];
    memcpy_P(buf, kegiatanText[jadwalBelajar[i].kegiatan], sizeof(kegiatanText[0]));
    Serial.print(buf);
    Serial.println();
  }

}

void cariJadwal()
{
  uint16_t unixWaktu = (now.jam * 60) + now.menit;
  byte hariKeDiTanggal1 = ((now.hari + 7  - (now.tanggal % 7)) % 7) + 1;
  byte SeninKe = ((now.tanggal + ((hariKeDiTanggal1 + 4) % 7)) / 7); //senin pertama
  byte mingguKe = ((now.tanggal + hariKeDiTanggal1 + 6 - 1) / 7);

  Serial.print("SeninKe = ");
  Serial.println(SeninKe);
  Serial.print("mingguKe = ");
  Serial.println(mingguKe);


  uint16_t unixTerkecil = UINT16_MAX;
  jadwalBerikutnyaKegiatan = 0;
  Waktu waktuTerkecil;

  for (byte i = 0; i < sizeof(jadwalBelajar) / sizeof(TabelMataPelajaran); i++)
  {
    if (
      (jadwalBelajar[i].aktif) &&
      (jadwalBelajar[i].hariAktif & (1 << (8 - now.hari))) &&
      (jadwalBelajar[i].mingguAktif & (1 << (8 - mingguKe)))
    )
    {
      uint16_t unixJadwal = (jadwalBelajar[i].waktu.jam * 60) + jadwalBelajar[i].waktu.menit;
      if (unixWaktu < unixJadwal)
      {
        if (unixTerkecil > unixJadwal)
        {
          unixTerkecil = unixJadwal;
          jadwalBerikutnya.jam = jadwalBelajar[i].waktu.jam;
          jadwalBerikutnya.menit = jadwalBelajar[i].waktu.menit;
          jadwalBerikutnyaKegiatan = jadwalBelajar[i].kegiatan;
        }
      }
    }
  }
  if (jadwalBerikutnyaKegiatan)
  {
    Serial.print("Bel berikutnya : ");
    Serial.print((__FlashStringHelper *)kegiatanText[jadwalBerikutnyaKegiatan]);
    Serial.print(" ");
    Serial.print(jadwalBerikutnya.jam);
    Serial.print(":");
    Serial.println(jadwalBerikutnya.menit);

    lcd.setCursor(1, 1);
    sprintf(bufWaktu, "%02d:%02d", jadwalBerikutnya.jam, jadwalBerikutnya.menit);
    lcd.print(bufWaktu);
  }
  else
  {
    lcd.setCursor(1, 1);
    lcd.print("--:--");
  }


}

library arduino bel sekolah dengan bluetooth dan aplikasi android yang digunakan :

Suara mp3 bel sekolah arduino dengan bluetooth:

mp3.zip

aplikasi apk android untuk bel sekolah arduino (evaluasi):

Bel_sekolah_v1_Evaluasi.apk

cara penggunaan :

  1. Buat rangkaian arduino seperti skema dan upload sketch yang diberikan.
  2. Masukkan file suara dalam kartu memori/SD card (file mp3 dan folder mp3).
  3. install aplikasi bel sekolah v1 evaluasi di android (evaluasi = 10 jadwal yang aktif).

Membaca file txt dari SDCard/kartu memori kedalam struct menggunakan Arduino (Aplikasi Bel Sekolah)

SDCard/microSD/kartu memori merupakan media penyimpanan yang banyak digunakan pada perangkat-perangkat elektronik untuk menyimpan foto, video, data dll. Dalam aplikasi arduino SDCard bisa dibaca/ditulis dalam protokol SPI, format yang didukung adalah FAT.

Dalam perancangan ini saya menggunakan file .txt yang tersusun sebagai database (contoh database jadwal bel sekolah), dan dibaca dengan arduino untuk kemudian dimasukkan kedalam tabel “jadwalBelajar”.

format yang digunakan adalah

Aktif | Waktu | Hari aktif | Minggu aktif | Kegiatan

Aktif
Sebagai status item/baris jadwal diaktifkan atau tidak(diabaikan)
isiannya Aktif, Tidak Aktif

Waktu
Format waktu jam:menit

Hari aktif
hari dimana item jadwal diaktifkan
isiannya: Senin, Selasa, Rabu, Kamis, Jum’at, Sabtu, Minggu atau kombinasinya dalam bentuk array didalam tanda ‘{‘ dan ‘}’

minggu aktif
isiannya kombinasi minggu bentuk array didalam tanda ‘{‘ dan ‘}’

Kegiatan
text Kegiatan

Skema:

sketch/program:

#include <avr/pgmspace.h>
#include <SPI.h>
#include <SD.h>

struct Waktu
{ 
  byte jam; 
  byte menit; 
};

struct TabelMataPelajaran
{
  byte aktif;
  Waktu waktu;
  byte hariAktif;
  byte mingguAktif;
  byte kegiatan;
};

const PROGMEM char kegiatan[][21] = 
{
  "Jam Pelajaran 1\0    ",
  "Jam Pelajaran 2\0    ",
  "Jam Pelajaran 3\0    ",
  "Jam Pelajaran 4\0    ",
  "Jam Pelajaran 5\0    ",
  "Jam Pelajaran 6\0    ",
  "Jam Pelajaran 7\0    ",
  "Jam Pelajaran 8\0    ",
  "Jam Pelajaran 9\0    ",
  "Jam Pelajaran 10\0   ",
  "Jam Pelajaran 11\0   ",
  "Jam Pelajaran 12\0   ",
  "Jam Pelajaran 13\0   ",
  "Jam Pelajaran 14\0   ",
  "Jam Pelajaran 15\0   ",
  "Masuk\0              ",
  "Upacara\0            ",
  "Istirahat\0          ",
  "Selesai Istirahat\0  ",
  "Kepramukaan\0        ",
  "Khusus\0             ",
  "Pulang\0             ",
  "Pulang Jumat\0       ",
  "Pulang Sabtu\0       "
};

const char namaHari[][7] PROGMEM = 
{
  "Minggu",
  "Senin\0",
  "Selasa",
  "Rabu\0 ",
  "Kamis\0",
  "Jum'at",
  "Sabtu\0"
};

const char Aktifasi[][12] PROGMEM = 
{
  "Aktif\0     ",
  "Tidak aktif"
};

#define hariAktifSenin 1<<6
#define hariAktifSelasa 1<<5
#define hariAktifRabu 1<<4
#define hariAktifKamis 1<<3
#define hariAktifJumat 1<<2
#define hariAktifSabtu 1<<1
#define hariAktifMinggu 1<<7


#define _hariAktif(Sen,Sel,Rab,Kam,Jum,Sab,Mgu) (Mgu<<7)|(Sen<<6)|(Sel<<5)|(Rab<<4)|(Kam<<3)|(Jum<<2)|(Sab<<1)
#define _mingguAktif(Mgu1,Mgu2,Mgu3,Mgu4,Mgu5) (Mgu1<<7)|(Mgu2<<6)|(Mgu3<<5)|(Mgu4<<4)|(Mgu5<<3)
#define _waktu(Jam, Menit) {Jam, Menit}
#define Aktif 1
#define TidakAktif 0

TabelMataPelajaran jadwalBelajar[150];
Waktu waktu;
File fileJadwal;
char buffer[21];

void setup() {
  Serial.begin(9600);
  Serial.println("Membaca file txt dari SDCard/kartu memori kedalam struct menggunakan Arduino");
  Serial.println("(Aplikasi Bel Sekolah)");
  Serial.println("https://www.project.semesin.com");
}

void loop() {
  if (!SD.begin(53)) 
  {
    Serial.println("Gagal memulai kartu memori!");
  }
  else
  {  
    if (!SD.exists("Jadwal.txt")) 
    {
      Serial.println("file Jadwal.txt tidak ditemukan");
    } 
    else 
    {
      char c;
      byte index;
      String str;
      fileJadwal = SD.open("Jadwal.txt", FILE_READ);
      while(1)
      {
        c = fileJadwal.peek();
        if(c == -1)
        {
          break;
        }
        else if(c == '/')
        {
          while(fileJadwal.read() != '\n');
          continue;
        }
        else if((c == '\r') || (c == '\n') || (c == '\t') || (c == ' '))
        {
          fileJadwal.read();
          continue;
        }
        jadwalBelajar[index].aktif = ambilCSVAktif(fileJadwal);
        ambilCSVWaktu(&jadwalBelajar[index].waktu.jam,&jadwalBelajar[index].waktu.menit, fileJadwal);
        jadwalBelajar[index].hariAktif = ambilCSVHari(fileJadwal);
        jadwalBelajar[index].mingguAktif = ambilCSVMinggu(fileJadwal);
        jadwalBelajar[index].kegiatan = ambilCSVKegiatan(fileJadwal);

        copyFlashString(buffer, &Aktifasi[jadwalBelajar[index].aktif][0]);
        Serial.print(buffer);
        Serial.print('\t');
        if(jadwalBelajar[index].waktu.jam < 10) Serial.print('0');
        Serial.print(jadwalBelajar[index].waktu.jam);
        Serial.print(':');
        if(jadwalBelajar[index].waktu.menit < 10) Serial.print('0');
        Serial.print(jadwalBelajar[index].waktu.menit);
        Serial.print('\t');
        Serial.print(jadwalBelajar[index].hariAktif,HEX);
        Serial.print('\t');
        Serial.print(jadwalBelajar[index].mingguAktif,HEX);
        Serial.print('\t');
        copyFlashString(buffer, &kegiatan[jadwalBelajar[index].kegiatan][0]);
        Serial.println(buffer);
      }
      fileJadwal.close();
    }
  }

  while(1);//***
}
byte ambilCSVAktif(File file)
{
  String str = ambilCSVDariFile(file);

  for(byte i=0;i<sizeof(Aktifasi)/sizeof(Aktifasi[0]);i++)
  {
    copyFlashString(buffer, &Aktifasi[i][0]);
    if(str.equalsIgnoreCase((String)buffer))
    {
      return i;
    }
  }
}
void ambilCSVWaktu(byte* jam, byte* menit, File file)
{
  String str = ambilCSVDariFile(file);
  byte pos1 = str.indexOf(':');
  *jam = str.substring(0,pos1).toInt();
  *menit = str.substring(pos1+1).toInt();
}
byte ambilCSVHari(File file)
{
  String str = ambilCSVDariFile(file);
  for(byte i=0;i<sizeof(namaHari)/sizeof(namaHari[0]);i++)
  {
    copyFlashString(buffer, &namaHari[i][0]);
    if(str.equalsIgnoreCase((String)buffer))
    {
      return 1<<(7-i);
    }
  }
  byte dataHari = 0;
  byte shift = 0x80;
  byte hari[7];

  ambilCSVDariString(hari, str);
  for(byte i=0;i<sizeof(hari);i++)
  {
    if(hari[i])
    {
      dataHari += shift;
    }
    shift >>= 1;
    
  }
  return dataHari;
}

byte ambilCSVMinggu(File file)
{
  byte dataMinggu = 0;
  byte shift = 0x80;
  byte minggu[5];
  String str = ambilCSVDariFile(file);

  ambilCSVDariString(minggu, str);
  for(byte i=0;i<sizeof(minggu);i++)
  {
    if(minggu[i])
    {
      dataMinggu += shift;
    }
    shift >>= 1;
  }
  return dataMinggu;
}

byte ambilCSVKegiatan(File file)
{
  String str = ambilCSVDariFile(file);
  for(byte i=0;i<sizeof(kegiatan)/sizeof(kegiatan[0]);i++)
  {
    copyFlashString(buffer, &kegiatan[i][0]);
    if(str.equalsIgnoreCase((String)buffer))
    {
      return i;
    }
  }
}
String ambilCSVDariFile(File file)
{
  String str = "";
  char terminator = ',';

  while(1)
  {
    char c = file.peek();
    if(c == '{')
    {
      terminator = '}';
      file.read();
    }
    else if(((c != terminator) && (c != '\r')))
    {
      str += (char)file.read();
    }
    else
    {
      file.read();
      if(terminator == '}')
      {
        terminator = ',';
      }
      else if((terminator == ',') || (c == '\r'))
      {
        break;
      }
    }
  }
  str.trim();
  return str;
}
void copyFlashString(char* buf, const char* alamat)
{
  char c;
  while(c = pgm_read_byte(alamat++))
  {
    *buf++ = c;
  }
  *buf = 0;
}
void ambilCSVDariString(byte *minggu, String str)
{
  while(1)
  {
    int pos = str.indexOf(',');
    *minggu++ = str.substring(0,pos).toInt();
    if(pos == -1)
    {
      break;
    }
    str = str.substring(pos+1);
  }
}

contok keluaran serial monitor:

Contoh file jadwal.txt:
Jadwal.txt

Bel sekolah bluetooth dengan kontrol android : disini

Bel Sekolah menggunakan tabel database fleksibel berbasis Arduino

Bel sekolah digital dimanfaatkan untuk menentukan waktu pertukaran kegiatan di sekolah-sekolah. Jadwal untuk sebuah sekolah berbeda dengan sekolah lainnya, baik perbedaan tingkat sekolah maupun zona waktunya. Selain itu terdapat juga perbedaan jadwal untuk masing masing hari, seperti senin pertama setiap bulan untuk upacara dan hari lainnya yang mempunyai kekhususan waktu. Bel sekolah digital berbasis arduino atau mikrokontroller lain memiliki kemampuan penjadwalan jam pelajaran tersebut. selain itu bel sekolah digital arduino juga mudah dalam pengembangan nantinya.

Dalam perancangan bel sekolah arduino ini dibatasi hanya sampai pengaplikasian tabel database arduino fleksibel yang bisa disesuaikan dengan kebutuhan. Bel sekolah berbasis arduino ini hanya berupa penerapan dasar saja yang bisa dikombinasikan dengan aplikasi Bel Sekolah fungsional lainnya.

Untuk pengembangannya bisa saja perangkat bel sekolah otomatis berbasis arduino ini ditambahkan sistem entri data dari bluetooth, wifi, PC dll. juga bisa ditambahkan sistem output multimedia seperti alarm, suara, running text, DMD dan lain-lain.

Kelebihan perancangan ini adalah:

  1. Tabel database jadwal fleksibel
  2. Pembacaan RTC dengan interupsi sehingga menghemat resource
  3. Pemanfaatan sleep mode

Komponen yang digunakan:

  1. Arduino Uno
  2. RTC DS3231

berikut skema / rangkaian bel sekolah dengan arduino:

dan program/sketch Arduino:

#include <DS3232RTC.h>
#include <avr/sleep.h>

#define SQWPin 12

struct Waktu
{ 
  byte jam; 
  byte menit; 
};

struct TabelMataPelajaran
{
  byte aktif;
  Waktu waktu;
  byte hariAktif;
  byte mingguAktif;
  byte kegiatan;
};

enum _kegiatan
{
  JamPelajaran1,
  JamPelajaran2,
  JamPelajaran3,
  JamPelajaran4,
  JamPelajaran5,
  JamPelajaran6,
  JamPelajaran7,
  JamPelajaran8,
  JamPelajaran9,
  JamPelajaran10,
  JamPelajaran11,
  JamPelajaran12,
  JamPelajaran13,
  JamPelajaran14,
  JamPelajaran15,
  Masuk,
  Upacara,
  Istirahat,
  SelesaiIstirahat,
  Kepramukaan,
  Khusus,
  Pulang,
  PulangJumat,
  PulangSabtu
};

volatile bool interupsiDetik;
byte indexMataPelajaran;

#define hariAktifSenin 1<<6
#define hariAktifSelasa 1<<5
#define hariAktifRabu 1<<4
#define hariAktifKamis 1<<3
#define hariAktifJumat 1<<2
#define hariAktifSabtu 1<<1
#define hariAktifMinggu 1<<7

String namaHari[] = {"Minggu","Senin","Selasa","Rabu","Kamis","Jum;at","Sabtu"};
#define _hariAktif(Sen,Sel,Rab,Kam,Jum,Sab,Mgu) (Mgu<<7)|(Sen<<6)|(Sel<<5)|(Rab<<4)|(Kam<<3)|(Jum<<2)|(Sab<<1)
#define _mingguAktif(Mgu1,Mgu2,Mgu3,Mgu4,Mgu5) (Mgu1<<7)|(Mgu2<<6)|(Mgu3<<5)|(Mgu4<<4)|(Mgu5<<3)
#define _waktu(Jam, Menit) {Jam, Menit}
#define Aktif 1
#define TidakAktif 0



TabelMataPelajaran jadwalBelajar[35];
Waktu waktu;
tmElements_t tm;

void setup() {
  byte i = 0;

  //Senin
  jadwalBelajar[i++] = {Aktif, _waktu(  6, 45 ), hariAktifSenin,            _mingguAktif(1,0,0,0,0), Upacara};
  jadwalBelajar[i++] = {Aktif, _waktu(  6, 45 ), hariAktifSenin,            _mingguAktif(0,1,1,1,1), JamPelajaran1};
  jadwalBelajar[i++] = {Aktif, _waktu(  6, 45 ), _hariAktif(0,1,1,1,1,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran1};
  
  jadwalBelajar[i++] = {Aktif, _waktu(  7, 30 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran2};
  jadwalBelajar[i++] = {Aktif, _waktu(  8, 15 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran3};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 0  ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran4};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 45 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), Istirahat};
  jadwalBelajar[i++] = {Aktif, _waktu( 10, 15 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran5};
  jadwalBelajar[i++] = {Aktif, _waktu( 11, 0  ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran6};
  jadwalBelajar[i++] = {Aktif, _waktu( 11, 45 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), Istirahat};
  jadwalBelajar[i++] = {Aktif, _waktu( 12, 30 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran7};
  jadwalBelajar[i++] = {Aktif, _waktu( 13, 15 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran8};

  jadwalBelajar[i++] = {Aktif, _waktu( 14, 0  ), _hariAktif(1,1,1,0,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran9};
  jadwalBelajar[i++] = {Aktif, _waktu( 14, 45 ), _hariAktif(1,1,1,0,0,0,0), _mingguAktif(1,1,1,1,1), JamPelajaran10};

  jadwalBelajar[i++] = {Aktif, _waktu( 14, 0  ), hariAktifKamis,            _mingguAktif(1,1,1,1,1), Kepramukaan};
  jadwalBelajar[i++] = {Aktif, _waktu( 14, 45 ), hariAktifKamis,            _mingguAktif(1,1,1,1,1), Khusus};

  jadwalBelajar[i++] = {Aktif, _waktu( 15, 30 ), _hariAktif(1,1,1,1,0,0,0), _mingguAktif(1,1,1,1,1), Pulang};

  jadwalBelajar[i++] = {Aktif, _waktu(  7, 25 ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), JamPelajaran2};
  jadwalBelajar[i++] = {Aktif, _waktu(  8, 5  ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), JamPelajaran3};
  jadwalBelajar[i++] = {Aktif, _waktu(  8, 45 ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), JamPelajaran4};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 25 ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), Istirahat};
  jadwalBelajar[i++] = {Aktif, _waktu(  9, 55 ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), JamPelajaran5};
  jadwalBelajar[i++] = {Aktif, _waktu( 10, 35 ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), JamPelajaran6};
  jadwalBelajar[i++] = {Aktif, _waktu( 11, 15 ), hariAktifJumat,            _mingguAktif(1,1,1,1,1), PulangJumat};

  indexMataPelajaran = i;

  Serial.begin(9600);
  Serial.println("Bel Sekolah menggunakan tabel database flexibel berbaasis Arduino");
  Serial.println("Bisa ditambahkan input bluetooth, wifi, PC, komputer dll");
  Serial.println("Bisa ditambahkan output multimedia seperti suara, alarm, running text, dmd dll");
  Serial.println("https://www.project.semesin.com");
  
  byte ControlRegister;
  RTC.readRTC(0x0E,&ControlRegister,1);
  ControlRegister &= ~(0x07<<2);
  RTC.writeRTC(0x0E, &ControlRegister,1);

  *digitalPinToPCMSK(SQWPin) |= bit (digitalPinToPCMSKbit(SQWPin));
  PCIFR  |= bit (digitalPinToPCICRbit(SQWPin));
  PCICR  |= bit (digitalPinToPCICRbit(SQWPin));
 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

////Set waktu sekali saja
//  tm.Day = 1;
//  tm.Month = 4;
//  tm.Year = CalendarYrToTm(2018);
//  tm.Hour = 15;
//  tm.Minute = 24;
//  tm.Second = 00;
//
//  time_t t = makeTime(tm);
//  tm.Wday = dayOfWeek(t);
//  RTC.write(tm);
//  TampilkanWaktu();
}

ISR (PCINT0_vect)
{
  if(digitalRead(SQWPin))
  {
    interupsiDetik = true;
  }
}  

void loop() {
  
  
  if(interupsiDetik)
  {
    interupsiDetik = false;
    RTC.read(tm);
    
    if(tm.Second == 0)
    {
      TampilkanWaktu();//***
      
      byte hariKeDiTanggal1 = (((tm.Wday + 8)  - (tm.Day % 7)) % 7);
      byte SeninKe = ((tm.Day + 7 - hariKeDiTanggal1) / 7);
      byte mingguKe = ((tm.Day + 8 - hariKeDiTanggal1) / 7) + 1;
      
      for(byte i=0; i<indexMataPelajaran ;i++)
      {
        if(jadwalBelajar[i].aktif)
        {
          if((jadwalBelajar[i].waktu.jam == tm.Hour) && 
          (jadwalBelajar[i].waktu.menit == tm.Minute) && 
          (jadwalBelajar[i].hariAktif & (1<<(8-tm.Wday))) &&
          (jadwalBelajar[i].mingguAktif & (1<<(8-SeninKe))))
          {
            TampilkanWaktu();
            //Bisa ditambahkan sistem output
            switch(jadwalBelajar[i].kegiatan)
            {
              case JamPelajaran1:
                Serial.println("Jam Pelajaran 1");
                break;
              case JamPelajaran2:
                Serial.println("Jam Pelajaran 2");
                break;
              case JamPelajaran3:
                Serial.println("Jam Pelajaran 3");
                break;
              case JamPelajaran4:
                Serial.println("Jam Pelajaran 4");
                break;
              case JamPelajaran5:
                Serial.println("Jam Pelajaran 5");
                break;
              case JamPelajaran6:
                Serial.println("Jam Pelajaran 6");
                break;
              case JamPelajaran7:
                Serial.println("Jam Pelajaran 7");
                break;
              case JamPelajaran8:
                Serial.println("Jam Pelajaran 8");
                break;
              case JamPelajaran9:
                Serial.println("Jam Pelajaran 9");
                break;
              case JamPelajaran10:
                Serial.println("Jam Pelajaran 10");
                break;
              case JamPelajaran11:
                Serial.println("Jam Pelajaran 11");
                break;
              case JamPelajaran12:
                Serial.println("Jam Pelajaran 12");
                break;
              case JamPelajaran13:
                Serial.println("Jam Pelajaran 13");
                break;
              case JamPelajaran14:
                Serial.println("Jam Pelajaran 14");
                break;
              case JamPelajaran15:
                Serial.println("Jam Pelajaran 15");
                break;
              case Masuk:
                Serial.println("Masuk");
                break;
              case Upacara:
                Serial.println("Upacara");
                break;
              case Istirahat:
                Serial.println("Istirahat");
                break;
              case SelesaiIstirahat:
                Serial.println("Selesai istirahat");
                break;
              case Kepramukaan:
                Serial.println("Kepramukaan");
                break;
              case Khusus:
                Serial.println("Khusus");
                break;
              case Pulang:
                Serial.println("Jam pelajaran telah selesai, sampai jumpa esok hari");
                break;
              case PulangJumat:
                Serial.println("Jam pelajaran telah selesai, sampai jumpa minggu depan");
                break;
              case PulangSabtu:
                Serial.println("Jam pelajaran telah selesai, sampai jumpa minggu depan");
                break;
              default:
                Serial.println("Lainnya");
                break;
            }
          }
        }
      }
    }
  }
  delay(100);//Selesaikan Serial nge print, hapus saja jika tidak diperlukan
  sleep_mode();
}
void TampilkanWaktu()
{
  Serial.print("Waktu = ");
  print2digits(tm.Hour);
  Serial.write(':');
  print2digits(tm.Minute);
  Serial.write(':');
  print2digits(tm.Second);
  Serial.print(", Tanggal = ");
  Serial.print(namaHari[tm.Wday-1]);
  Serial.write(' ');
  Serial.print(tm.Day);
  Serial.write('/');
  Serial.print(tm.Month);
  Serial.write('/');
  Serial.print(tmYearToCalendar(tm.Year));
  Serial.println();
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

contoh Bel Sekolah Arduino Uno dengan output modul mini MP3 DFPlayer (library DFPlayer_Mini_Mp3.h) dan software serial : Bel_Sekolah_tanpa_interupsi.ino

Bel sekolah bluetooth dengan kontrol android : disini