Mengirim data detektor kebakaran dari arduino ke internet dengan antarmuka code igniter

Data sensor arduino

Sensor adalah instrumen atau komponen yang mampu mendeteksi perubahan kondisi objek dalam jangkauannya. Pengukuran besaran perubahan tersebut harus diubah dahulu menjadi bentuk digital sehingga dapat diproses oleh perangkat digital lainnya.

Data variabel ini bisa dimonitoring secara lokal melalui layar monitor maupun global melalui internet.

Hal yang mendukung keandalan sistem monitoring :

  1. realtime, yaitu data yang ditampilkan merupakan kondisi masa yang singkat, misalnya di perbarui setiap 1 detik.
  2. Data memiliki identitas seperti lokasi, waktu.
  3. Data yang diterima memiliki mekanisme penyaringan sehingga data yang ditampilkan terjamin.

Sensor detektor kebakaran

Terdapat beberapa Indikasi kebakaran yaitu :

  1. Api dideteksi dengan sensor flame
  2. Suhu dibaca dengan sensor suhu
  3. Asap dibaca dengan sensor asap (smoke detector)

Dalam hal pencegahan kebakaran, ketiga variabel ini terus menerus dimonitoring secara lokal.

Monitoring detektor kebakaran ini secara global juga diperlukan untuk memberikan informasi kepada pihak terkait.

Dalam contoh ini ketiga (modul) sensor ini digunakan bersama arduino dan akan dikirimkan ke mysql server.

Akses informasi sensor dengan codeIgniter

Informasi data saat ini dapat dengan mudah diakses dimanapun, namun dengan menggunakan codeIgniter diperoleh beberapa keuntungan yaitu :

  1. Pengembangan lebih mudah dengan baris program yang dapat disederhanakan.
  2. Aksesibilitas dapat dengan mudah dikontrol.
  3. Perlindungan terhadap server terutama server data lebih terjamin.

Skema Monitoring detektor kebakaran dengan codeIgniter

Komponen yang digunakan :

  1. Arduino Uno
  2. ESP8266
  3. Flame detector
  4. Sensor asap MQ7
  5. Sensor suhu dht11
  6. Relay
  7. Buzzer

Sketch / koding monitoring detektor kebakaran esp8266 – WebServer.

#include "WiFiEsp.h"
#include <SoftwareSerial.h>
#include "DHT.h"
 
char ssid[] = "****";        // Isi dengan nama profil Wifi
char pass[] = "********";            // password wifi
char server[] = "x.x.x.x";

long waktuMintaData = 1000; //minta data setiap 1000ms

#define pinFlame    A0
#define pinMQ       A1
#define pinDHT      A2
#define pinBuzzer   8
#define pinRelay    9

float setSuhu = 31.0;

String Respon = "";
long waktuMulai;
bool responDariServer = false;
bool prosesKirimDataKeServer = false;
 
WiFiEspClient client;
int status = WL_IDLE_STATUS;

SoftwareSerial wifi(2,3);
DHT dht(pinDHT, DHT11);
 
void setup()
{
  pinMode(pinFlame, INPUT_PULLUP);
  pinMode(pinMQ, INPUT_PULLUP);
  pinMode(pinDHT, INPUT_PULLUP);
  pinMode(pinBuzzer, OUTPUT);
  digitalWrite(pinRelay, HIGH);
  pinMode(pinRelay, OUTPUT);

  Serial.begin(115200);
 
  wifi.begin(115200);
  WiFi.init(&wifi);
 
  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }
 
  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
 
  // you're connected now, so print out the data
  Serial.println("You're connected to the network");
   
  printWifiStatus();
  dht.begin();
  waktuMulai = millis();
}
 
void loop()
{
  float suhu = dht.readTemperature();
//print status
  Serial.println();
  Serial.print("Api = ");
  Serial.println(digitalRead(pinFlame));
  Serial.print("Asap = ");
  Serial.println(digitalRead(pinMQ));
  Serial.print("suhu = ");
  Serial.println(suhu);
  
  if(!digitalRead(pinFlame) && !digitalRead(pinMQ) && (suhu < setSuhu))
  {
    digitalWrite(pinRelay, HIGH);
    digitalWrite(pinBuzzer, LOW);
    
  }
  if(digitalRead(pinFlame))
  {
    digitalWrite(pinRelay, LOW);
    digitalWrite(pinBuzzer, HIGH);
  }
  if(digitalRead(pinMQ))
  {
    digitalWrite(pinRelay, LOW);
    digitalWrite(pinBuzzer, HIGH);
  }
  if(suhu >= setSuhu)
  {
    digitalWrite(pinBuzzer, HIGH);
  }
  //kirim data
  if(waktuMintaData < millis() - waktuMulai)
  {
    waktuMulai = millis();
    prosesKirimDataKeServer = kirimDataKeServer();
  }

  while (client.available()) 
  {
    char c = client.read();
    Respon += c;
  }

  Serial.print("prosesKirimDataKeServer = ");
  Serial.println(prosesKirimDataKeServer);

  if (!client.connected() && prosesKirimDataKeServer) {
    Serial.println("Disconnecting from server...");
    client.stop();
    responDariServer = true;
    prosesKirimDataKeServer = false;
  }

  // penanganan data yang diterima dari server
  if(responDariServer)
  {
    responDariServer = false;
    Serial.println(Respon);
    int posisiData = Respon.indexOf("\r\n\r\n");
    String Data = Respon.substring(posisiData+4);
    Data.trim();
 
    String variabel;
    String nilai;
 
    Serial.println("Data dari server");
    posisiData = Data.indexOf('=');
    if(posisiData > 0)
    {
      variabel = Data.substring(0,posisiData);
      nilai = Data.substring(posisiData+1);
   
      //===========Penanganan respon disini
      if(variabel == "setSuhu")
      {
        setSuhu = nilai.toFloat();
      }
//      Serial.print(variabel);
//      Serial.print(" = ");
//      Serial.println(nilai);
    }
    Respon = "";
  }
}

bool kirimDataKeServer()
{
  Serial.println();
  Serial.println("Starting connection to server...");
  // if you get a connection, report back via serial
  if (client.connect(server, 80)) {
    Serial.println("Connected to server");
    // Make a HTTP request
 
    client.print("GET /index.php/databaseArduino/dariArduino");
    client.print("?Api=");
    client.print(digitalRead(pinFlame));
     
    client.print("&Asap=");
    client.print(digitalRead(pinMQ));

    client.print("&Suhu=");
    client.print(dht.readTemperature());
     
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    return true;
  }
  return false;
}
 
void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
 
  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
 
  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
 
  IPAddress gateway = WiFi.gatewayIP();
  Serial.print("gateway:");
  Serial.print(gateway);
  Serial.println(" ");
}

program codeIgniter untuk monitoring data sensor arduino:

databaseArduino.php

<?php
class databaseArduino extends CI_Controller {
  public function __construct() {
    parent::__construct();
  }

  public function dariBrowser() {
    $this->load->model('Model_databaseArduino');
    $this->Model_databaseArduino->salinDataDariBrowser();
    $data['dataSensor'] = $this->Model_databaseArduino->ambilDataDariArduino();
    $data['dataParameter'] = $this->Model_databaseArduino->ambilDataDariBrowser();

    $this->load->view("data_sensor", $data);
  }

    public function dariArduino() {
    $this->load->model('Model_databaseArduino');
    $this->Model_databaseArduino->salinDataDariArduino();
    $data['dataParameter'] = $this->Model_databaseArduino->ambilDataDariBrowser();

    $this->load->view("data_parameter", $data);
  }
}
?>

Model_databaseArduino.php

<?php
class Model_databaseArduino extends CI_Model {

  public $title;
  public $content;
  public $date;

  public function ambilDataDariArduino()
  {
    $this->load->database();
    $query = $this->db->query("SELECT * FROM (
    SELECT * FROM `data_sensor` ORDER BY `nomor` DESC LIMIT 10
    ) sub
    ORDER BY `nomor` ASC");
    $this->db->close();  
    return $query->result();
  }

  public function salinDataDariArduino()
  {
    date_default_timezone_set('Asia/Jakarta'); # add your city to set local time zone
    $now = date('Y-m-d H:i:s');

    $this->load->database();
    $this->db->set('waktu', $now);
    $this->db->set('api', $this->input->get('Api'));
    $this->db->set('asap', $this->input->get('Asap'));
    $this->db->set('suhu', $this->input->get('Suhu'));
    $this->db->insert('data_sensor');
    $this->db->close();
  }

  public function ambilDataDariBrowser()
  {
    $this->load->database();
    $query = $this->db->query("SELECT * FROM `data_parameter` ORDER BY `nomor` DESC LIMIT 1");
    $this->db->close();  
    return $query->row();
  }

  public function salinDataDariBrowser()
  {
    date_default_timezone_set('Asia/Jakarta'); # add your city to set local time zone
    $now = date('Y-m-d H:i:s');

    $this->load->database();
    $this->db->set('waktu', $now);
    $this->db->set('setSuhu', $this->input->post('setSuhu'));
    $this->db->insert('data_parameter');
    $this->db->close();  
  }
}
?>

data_sensor.php

<?php
  defined('BASEPATH') OR exit('No direct script access allowed');

  if(isset($dataParameter))
  {
    echo "setSuhu=";
    echo $dataParameter->setSuhu;
  }
?>

data_parameter.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Welcome to CodeIgniter</title>

  <style type="text/css">

  ::selection { background-color: #E13300; color: white; }
  ::-moz-selection { background-color: #E13300; color: white; }

  body {
    background-color: #fff;
    margin: 40px;
    font: 13px/20px normal Helvetica, Arial, sans-serif;
    color: #4F5155;
  }

  a {
    color: #003399;
    background-color: transparent;
    font-weight: normal;
  }

  h1 {
    color: #444;
    background-color: transparent;
    border-bottom: 1px solid #D0D0D0;
    font-size: 19px;
    font-weight: normal;
    margin: 0 0 14px 0;
    padding: 14px 15px 10px 15px;
  }

  code {
    font-family: Consolas, Monaco, Courier New, Courier, monospace;
    font-size: 12px;
    background-color: #f9f9f9;
    border: 1px solid #D0D0D0;
    color: #002166;
    display: block;
    margin: 14px 0 14px 0;
    padding: 12px 10px 12px 10px;
  }

  #body {
    margin: 0 15px 0 15px;
  }

  p.footer {
    text-align: right;
    font-size: 11px;
    border-top: 1px solid #D0D0D0;
    line-height: 32px;
    padding: 0 10px 0 10px;
    margin: 20px 0 0 0;
  }

  #container {
    margin: 10px;
    border: 1px solid #D0D0D0;
    box-shadow: 0 0 8px #D0D0D0;
  }
  </style>
</head>
<body>



<!--
<form action="/form/data_submitted" method="get">
User Name: <input type="text" name="u_name" placeholder="Please Enter User Name" class="input_box">
<br>
User email: <input type="text" name="u_email" placeholder="Please Enter Email Address" class="input_box">
<input type="submit" value="Submit" class="submit">
</form>
-->

<?php

// echo $this->input->post('setSuhu');

echo form_open('databaseArduino/dariBrowser');
if(isset($dataParameter->setSuhu))
{
  echo form_input('setSuhu', $dataParameter->setSuhu);
}
else
{
  echo form_input('setSuhu', '30.0');
}
echo form_submit('suhuSubmit', 'Set Temperatur');
echo form_close();

echo "<br>";
echo "<strong>Data pembacaan sensor</strong>";
echo "<br>";
echo "<table>";

  echo "<tr>";
  echo "<td width='50'>Nomor</td>";
  echo "<td width='200'>Waktu</td>";
  echo "<td width='50'>Api</td>";
  echo "<td width='50'>Asap</td>";
  echo "<td width='50'>Suhu</td>";
  echo "</tr>";

  foreach ($dataSensor as $row)
{
  echo "<tr>";
  echo "<td>".$row->nomor."</td>";
  echo "<td>".$row->waktu."</td>";
  echo "<td>".$row->api."</td>";
  echo "<td>".$row->asap."</td>";
  echo "<td>".$row->suhu."</td>";
  echo "</tr>";
}
echo "</table>";
?>
</body>
</html>

file server : htdocs.zip

Pengunci nilai batas (Bandgap interlock) pada arduino

Sistem interlock pada pemograman digunakan untuk mengunci suatu blok program agar dijalankan hanya satu kali. Penguncian dapat dilakukan dengan flag/bendera, jadi sebelum masuk suatu blok program nilai flag penguncinya diuji dan hanya bisa dilewati jika nilainya cocok. pada arduino algoritma flag arduino (pengunci nilai arduino / interlock arduino) biasanya dideklarasikan sebagai boolean/bool yang bernilai true dan false.

Contoh sketch berikut ini menggunakan sensor analog (bisa dikembangkan untuk sensor dengan basis komunikasi) sebagai input. Sedangkan alarm/buzzer berlaku sebagai output. Tombol berfungsi sebagai konfirmasi bahwa alarm telah disetujui.

Komponen yang digunakan :

  1. Arduino uno
  2. Sensor analog (potensio, LM35, water level, flex, dll)
  3. Buzzer
  4. Tombol push on

Skema pengujian sistem kunci arduino:

Sketch / koding contoh penggunaan flag pada arduino:
Fungsi utama:

  1. Alarm hanya hidup jika nilai diluar batas dan belum dikonfirmasi
  2. Alarm mati jika tombol konfirmasi sudah ditekan
  3. Sistem alarm dapat kembali berfungsi jika nilai sudah dalam batas
//Pin
#define pinSensor           A0
#define pinTombolKonfirmasi 2
#define pinAlarm            13

#define batasAtas 600
#define batasBawah 400

bool sistemNormal = true;

void setup() {
  pinMode(pinTombolKonfirmasi, INPUT_PULLUP);
  pinMode(pinAlarm, OUTPUT);

  Serial.begin(9600);
  Serial.println("Alarm pengunci nilai batas (Bandgap interlock) pada arduino");
  Serial.println("http://www.semesin.com/project/");
}

void loop() {
  int nilaiSensor = analogRead(pinSensor);
  Serial.print("Nilai pembacaan sensor : ");
  Serial.println(nilaiSensor);

  if((nilaiSensor <= batasBawah) || (nilaiSensor >= batasAtas))//Pembacaan diluar batas
  {
    if(sistemNormal)//alarm belum dikonfirmasi
    {
      Serial.println("Pembacaan sensor diluar batas.");
      digitalWrite(pinAlarm, HIGH);
      sistemNormal = false;
    }
  }
  else //Pembacaan dalam batas
  {
    sistemNormal = true;
  }

  if(!digitalRead(pinTombolKonfirmasi))
  {
    Serial.println("Alarm dikonfirmasi.");
    digitalWrite(pinAlarm, LOW);
  }

  delay(1000);
}

dalam bentuk lain:

//Pin
#define pinSensor           A0
#define pinTombolKonfirmasi 2
#define pinAlarm            13

#define batasAtas 600
#define batasBawah 400

bool Alarm;
bool telahKonfirmasi;
bool Konfirmasi;

void setup() {
  pinMode(pinTombolKonfirmasi, INPUT_PULLUP);
  pinMode(pinAlarm, OUTPUT);

  Serial.begin(9600);
  Serial.println("Alarm pengunci nilai batas (Bandgap interlock) pada arduino");
  Serial.println("http://www.semesin.com/project/");
}

void loop() {

  int nilaiSensor = analogRead(pinSensor);
  Serial.print("Nilai pembacaan sensor : ");
  Serial.println(nilaiSensor);

  bool sistemNormal = ((nilaiSensor >= batasBawah) && (nilaiSensor <= batasAtas));
  if(!telahKonfirmasi)
  {
    Konfirmasi = !digitalRead(pinTombolKonfirmasi);
  }

  if(sistemNormal && (!Alarm || (Alarm && Konfirmasi)))
  {
    Alarm = false;
    telahKonfirmasi = false;
    Serial.println("Status : Sistem normal");
  }
  else if(sistemNormal && Alarm)
  {
    Serial.println("Status : Sistem normal, belum dikonfirmasi");
  }
  else if(!sistemNormal && Konfirmasi)
  {
    Alarm = false;
    telahKonfirmasi = true;
    Serial.println("Status : Sistem tidak normal, telah dikonfirmasi");
  }
  else if(!sistemNormal && !telahKonfirmasi)
  {
    Alarm = true;
    Serial.println("Status : Sistem tidak normal");
  }
  digitalWrite(pinAlarm, Alarm);

  delay(1000);
}

Pengaturan alarm dengan arduino dan RTC DS1307 melalui 4 tombol

Alarm berfungsi sebagai pengingat atau pemberitahu baik melalui visual dan suara. Biasanya alarm diaktifkan pada waktu-waktu tertentu sesuai kebutuhan, adakalanya dalam satu hari ada beberapa waktu alarm diaktifkan.

Dalam desain ini saya hanya menggunakan satu entri waktu alarm yang bisa diatur dengan 4 (empat) tombol, fungsi masing-masing tombol adalah:

  1. tombol kiri (M) untuk menu, tekan pertama untuk pengaturan jam, kedua untuk menit, ketiga untuk detik dan ke-empat untuk kembali.
  2. tombol kanan (E) untuk exit/langsung kembali jika sudah dalam menu.
  3. tombol atas untuk tambah
  4. tombol bawah untuk kurang

breadboard:

komponen yang digunakan:

  1. Arduino Uno
  2. LCD matrik 16×2
  3. I2C to LCD PCF8574
  4. RTC DS1307
  5. Buzzer
  6. Tombol 4bh

sketch/program:

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <EEPROM.h>

//pin
byte tombolUp = 9;
byte tombolDn = 10;
byte tombolMinus = 11;
byte tombolPlus = 8;
byte buzzer = 13;

LiquidCrystal_I2C  lcd(0x3F,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified backpack
byte detikTerakhir = 60;

int alarmJamAddr = 0;
int alarmMenitAddr = 1;
int alarmDetikAddr = 2;

byte alarmJam;
byte alarmMenit;
byte alarmDetik;

bool alarmStatus = false;
unsigned long millisMulai;
unsigned long millisAlarmMulai;

bool buzzStatus;

uint16_t jedaBuzzer = 1000;
uint16_t waktuAlarm = 10000;//Alarm 10 detik

byte menu = 0;
byte menuLCDPos = 8;
byte temp;

void setup()
{
  Serial.begin(9600);
  Serial.println("Setting alarm menggunakan Arduino dan RTC1307 melalui 4 push button");
  Serial.println("http://www.semesin.com/project");

  pinMode(buzzer, OUTPUT);
  pinMode(tombolUp, INPUT_PULLUP);
  pinMode(tombolDn, INPUT_PULLUP);
  pinMode(tombolMinus, INPUT_PULLUP);
  pinMode(tombolPlus, INPUT_PULLUP);
  
  lcd.begin (16,2);
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);

  lcd.setCursor (0,0);
  lcd.print("Waktu:    :  :  ");
  lcd.setCursor(0,1);
  lcd.print("Alarm:    :  :  ");

  readEEPROMDataWaktu();

  lcd.setCursor(8,1);
  if(alarmJam < 10)lcd.print('0');
  lcd.print(alarmJam);
  lcd.setCursor(11,1);
  if(alarmMenit < 10)lcd.print('0');
  lcd.print(alarmMenit);
  lcd.setCursor(14,1);
  if(alarmDetik < 10)lcd.print('0');
  lcd.print(alarmDetik);
}

void loop()
{
  tmElements_t tm;

  do
  {
    lcd.setCursor(menuLCDPos, 1);
    switch(bacaTombol())
    {
      case '+':
        temp = EEPROM.read(menu - 1);
        if(((temp >= 23) && (menu == 1)) || ((temp >= 59) && (menu > 1)))
          temp = 0;
        else
          temp++;
        EEPROM.write(menu - 1, temp);
        if(temp < 10)lcd.print('0');
        lcd.print(temp);
        break;
      case '-':
        temp = EEPROM.read(menu - 1);
        if((temp == 0) && (menu == 1))
          temp = 23;
        else if((temp == 0) && (menu > 1))
          temp = 59;
        else
          temp--;
        EEPROM.write(menu - 1, temp);
        if(temp < 10)lcd.print('0');
        lcd.print(temp);
        break;
      case 'M':
        menu++;
        if(menu == 1)
        {
          menuLCDPos = 8;
          temp = alarmJam;
          lcd.blink();
        }
        else if(menu == 2)
        {
          menuLCDPos = 11;
        }
        else if(menu == 3)
        {
          menuLCDPos = 14;
        }
        if(menu == 4)
        {
          menu = 0;
          lcd.noBlink();
          readEEPROMDataWaktu();
        }
        break;
      case 'E':
        menu = 0;
        lcd.noBlink();
        readEEPROMDataWaktu();
        break;
    }
  }
  while (menu);

  if(alarmStatus)
  {
    if(millisMulai + jedaBuzzer < millis())
    {
      buzzStatus = !buzzStatus;
      digitalWrite(buzzer, buzzStatus);
      millisMulai = millis();
    }
    if(millisAlarmMulai + waktuAlarm < millis())
    {
      alarmStatus = false;
      digitalWrite(buzzer, LOW);
    }
  }

  if (RTC.read(tm)) {
    if(tm.Second != detikTerakhir)
    {
      lcd.setCursor(8,0);
      if(tm.Hour < 10)lcd.print('0');
      lcd.print(tm.Hour);
      lcd.setCursor(11,0);
      if(tm.Minute < 10)lcd.print('0');
      lcd.print(tm.Minute);
      lcd.setCursor(14,0);
      if(tm.Second < 10)lcd.print('0');
      lcd.print(tm.Second);

      if((alarmJam == tm.Hour) && (alarmMenit == tm.Minute) && (alarmDetik == tm.Second))
      {
        alarmStatus = true;
        millisMulai = millis();
        millisAlarmMulai = millisMulai;
      }

      detikTerakhir = tm.Second;
    }
  }
}

char bacaTombol()
{
  char tombol = ' ';
  if(!digitalRead(tombolUp))
  {
    tombol = '+';
  }
  else if(!digitalRead(tombolDn))
  {
    tombol = '-';
  }
  else if(!digitalRead(tombolMinus))
  {
    tombol = 'M';
  }
  else if(!digitalRead(tombolPlus))
  {
    tombol = 'E';//exit
  }
  while(!digitalRead(tombolUp));
  while(!digitalRead(tombolDn));
  while(!digitalRead(tombolMinus));
  while(!digitalRead(tombolPlus));
  delay(200);

  return tombol;
}

void readEEPROMDataWaktu()
{
  alarmJam = EEPROM.read(alarmJamAddr);
  alarmMenit = EEPROM.read(alarmMenitAddr);
  alarmDetik = EEPROM.read(alarmDetikAddr);
}

 

I2C scanner

apabila ditemui kesulitan dalam mencari alamat I2C dari PCF8574 (modul I2C ke LCD 16×2) gunakan I2C scanner berikut:

#include <Wire.h>
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      
      byte addressFull = address << 1;
      Serial.print("(");
      if (addressFull<16)
        Serial.print("0");
      Serial.print(addressFull,HEX);
      Serial.println(")");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);
}

alamat tulis I2C yang umum:

  • DS1307 = 0xD0
  • AT24C32 = 0xA0 – oxAE

running text anti flicker (improved DMD) dengan arduino

DMD (dot matrix display) yang dikontrol dengan arduino dengan segala keterbatasannya memiliki permasalahan saat panel DMD disusun dalam lebih dari 4 panel. Flicker terjadi karena proses pengiriman data serial dari arduino harus mengantri sekian lama sehingga pergantian aktifasi baris per baris tertangkap oleh mata seperti berayun (berkedip) dan tentu membuat mata tidak nyaman.

Untuk itu saya melakukan improvisasi terhadap library arduino –DMD2– dengan prinsip kerja satu clock untuk lebih dari satu baris. contohnya untuk ukuran panel 4 kolom 2 baris kelompok DMD dibagi menjadi 2 bagian (baris 1 dan baris 2) dengan entri data yang sama setiap clock-nya.

Kelebihan alat DMD2 arduino:

  1. Sensor DHT11 untuk memantau keadaan suhu dan kelembaban sekitar
  2. Database waktu sholat 5 waktu (statis) dan dilengkapi buzzer yang menandakan waktu sholat telah masuk.

 

Komponen yang dibutuhkan :

  1. 8 Panel P10
  2. Arduino Mega 2560
  3. RTC DS1307
  4. DHT11
  5. Buzzer

DS1307 dapat diganti dengan DS3231 untuk keperluan presisi RTC.

berikut skema-nya :

berserta sketch atau program nya:

 

#include <DMD2.h>
#include <fonts/SystemFont5x7.h>
#include <fonts/Arial14.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include "DHT.h"

byte DataPins[2] = {33, 35}; //pin jalur out
SoftDMD dmd(4, 2, 23, 25, 27, 31, 29, 2, DataPins); //kolom, baris, OE, A, B, SCK, CLK, jumlah jalur out, pin jalur out
//SoftDMD dmd(4,2,23,25,27,31,29,33); //standard

DMD_TextBox box(dmd, 0, 0, 78, 32);

DHT dht(A0, DHT11);
String namaSholat[] = {"  Subuh", "  Zuhur", "   Asar", " Maghrib", "   Isya"};
byte waktuSholat[][2] = {{5, 12},
                        {12, 32},
                        {15, 45},
                        {18, 35},
                        {19, 44}
};

#define waktunyaSholat 1
#define pesanSMS 2

int n = 123;
byte lastSecond = 60;
byte lastDay = 32;
byte lastH = 60;
byte lastT = 32;
String Sholat;
String pesanDisplay;
byte pesan;
int buzzer = 8;
bool buzz;
byte buzzCounter;

void setup() {
  Serial.begin(9600);
  Serial.println("Running text dengan Arduino bebas kedip");
  Serial.println("http://www.semesin.com/project");
  dht.begin();
  dmd.setBrightness(255);
  dmd.begin();

  pesan = pesanSMS;
  pesanDisplay = "  Selamat\n  datang";
  dmd.selectFont(Arial14);
  box.print(pesanDisplay);
}

void loop()
{
  tmElements_t tm;
  byte h = (byte)dht.readHumidity();
  byte t = (byte)dht.readTemperature();
  RTC.read(tm);

  if (pesan == waktunyaSholat)
  {
    buzzCounter++;
    if (!(buzzCounter % 32))
    {
      buzz = !buzz;
      digitalWrite(buzzer, buzz);
      pinMode(buzzer, OUTPUT);
    }
  }

  if (tm.Second != lastSecond)
  {
    String waktu = "";
    if (tm.Hour < 10)
      waktu += "0";
    waktu += tm.Hour;
    waktu += ":";
    if (tm.Minute < 10)
      waktu += "0";
    waktu += tm.Minute;
    waktu += ":";
    if (tm.Second < 10)
      waktu += "0";
    waktu += tm.Second;
    lastSecond = tm.Second;

    dmd.selectFont(SystemFont5x7);
    dmd.drawString(80, 0, waktu);

    if ((pesan == waktunyaSholat) && (tm.Second >= 58))
    {
      box.clear();
      dmd.selectFont(Arial14);
      box.print(pesanDisplay);
      pesan = pesanSMS;
      digitalWrite(buzzer, LOW);
    }
    else if (tm.Second <= 1)
    {
      for (byte i = 0; i < 5; i++)
      {
        if ((waktuSholat[i][0] == tm.Hour) && (waktuSholat[i][1] == tm.Minute))
        {
          Sholat = namaSholat[i];
          box.clear();
          dmd.selectFont(Arial14);
          box.println("  Sholat");
          box.print(Sholat);
          pesan = waktunyaSholat;
        }
      }
    }
  }
  if (tm.Day != lastDay)
  {
    String tanggal = "";
    if (tm.Day < 10)
      tanggal += "0";
    tanggal += tm.Day;
    tanggal += "/";
    if (tm.Month < 10)
      tanggal += "0";
    tanggal += tm.Month;
    tanggal += "/";
    if (tmYearToCalendar(tm.Year) < 10)
      tanggal += "0";
    tanggal += tmYearToCalendar(tm.Year);
    lastDay = tm.Day;

    dmd.selectFont(SystemFont5x7);
    dmd.drawString(80, 8, tanggal);
  }
  if ((h != lastH) || (t != lastT))
  {
    String suhu = "";
    if (t < 10)
      suhu += "0";
    suhu += t;
    suhu += "'C ";
    if (h < 10)
      suhu += "0";
    suhu += h;
    suhu += "%";

    lastT = t;
    lastH = h;

    dmd.selectFont(SystemFont5x7);
    dmd.drawString(80, 16, suhu);
  }
}

dokumentasi Galeri DMD arduino anti flicker

Library yang sudah dimodifikasi: DMD-GL

Jika menginginkan jadwal sholat yang dinamis (waktu matahari) bisa menggunakan library “PrayerTimes.h”.