0% found this document useful (0 votes)
22 views

JWS ESP8266

Uploaded by

santiazzura
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

JWS ESP8266

Uploaded by

santiazzura
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 21

/*

* JADWAL WAKTU SHOLAT MENGGUNAKAN NODEMCU ESP8266, LED P10, RTC DS3231, BUZZER
* FITUR : JADWAL SHOLAT 5 WAKTU DAN TANBIH IMSAK, JAM BESAR, TANGGAL, SUHU,
ALARAM ADZAN DAN TANBIH IMSAK,
* DAN HITUNG MUNDUR IQOMAH DAN UBAH WAKTU LEWAT WIFI DENGAN BROWSER.
*

Pin on DMD P10 GPIO NODEMCU Pin on DS3231 NODEMCU


Pin on Buzzer NODEMCU
2 A GPIO16 D0 SCL D1 (GPIO 5)
+ RX (GPIO 3)
4 B GPIO12 D6 SDA D2 (GPIO 4)
- GND
8 CLK GPIO14 D5 VCC 3V
10 SCK GPIO0 D3 GND GND
12 R GPIO13 D7
1 NOE GPIO15 D8
3 GND GND GND

*/

#include <Wire.h>
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);

#include <HJS589.h>

#include <fonts/ElektronMart5x6.h>
#include <fonts/ElektronMart6x8.h>
#include <fonts/ElektronMart6x12.h>
#include <fonts/ElektronMart6x16.h>
#include <fonts/ElektronMartArabic5x6.h>
#include <fonts/ElektronMartArabic6x16.h>

#include <fonts/bmz6x16.h>
#include <fonts/bmz5x7.h>
#include <fonts/bmz6x7.h>
#include <fonts/bmz4x6.h>

#include <PrayerTimes.h>

//----------------------------
// SETUP DMD HJS589

#define DISPLAYS_WIDE 2
#define DISPLAYS_HIGH 1
HJS589 Disp(DISPLAYS_WIDE, DISPLAYS_HIGH); // Jumlah Panel P10 yang digunakan
(KOLOM,BARIS)

//----------------------------------------------------------------------
// HJS589 P10 FUNGSI TAMBAHAN UNTUK NODEMCU ESP8266

void ICACHE_RAM_ATTR refresh() {

Disp.refresh();
timer0_write(ESP.getCycleCount() + 80000);

void Disp_init() {

Disp.start();
noInterrupts();
timer0_isr_init();
timer0_attachInterrupt(refresh);
interrupts();
Disp.clear();

//SETUP RTC
//year, month, date, hour, min, sec and week-day(Senin 0 sampai Ahad 6)
//DateTime dt(2018, 12, 20, 16, 30, 0, 3);
RtcDateTime now;
char weekDay[][7] = {"AHAD", "SENIN", "SELASA", "RABU", "KAMIS", "JUM'AT", "SABTU",
"AHAD"}; // array hari, dihitung mulai dari senin, hari senin angka nya =0,
char monthYear[][4] = { "DES", "JAN", "FEB", "MAR", "APR", "MEI", "JUN", "JUL",
"AGU", "SEP", "OKT", "NOV", "DES" };

// PrayerTimes
double times[sizeof(TimeName)/sizeof(char*)];
int ihti = 2;

int detikiqmh;
int menitiqmh;

// BUZZER
const int buzzer = 3; // Pin GPIO Buzzer - RX

//----------------------------------------------------------------------
// SETUP

void setup() {

Serial.begin(9600);

//Buzzer
pinMode(buzzer, OUTPUT);
digitalWrite(buzzer, LOW);
delay(50);

//RTC D3231

int rtn = I2C_ClearBus(); // clear the I2C bus first before calling Wire.begin()
if (rtn != 0) {
Serial.println(F("I2C bus error. Could not clear"));
if (rtn == 1) {
Serial.println(F("SCL clock line held low"));
} else if (rtn == 2) {
Serial.println(F("SCL clock line held low by slave clock stretch"));
} else if (rtn == 3) {
Serial.println(F("SDA data line held low"));
}
} else { // bus clear, re-enable Wire, now can start Wire Arduino master
Wire.begin();
}

Rtc.Begin();

if (!Rtc.GetIsRunning()) {

Rtc.SetIsRunning(true);

Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);

//Rtc.SetDateTime(RtcDateTime(2019, 10, 11, 22, 20, 50));

Serial.println("Setup RTC selesai");

//DMD
Disp_init();

Disp.setBrightness(20);

//----------------------------------------------------------------------
// LOOP

uint8_t tmputama;

void loop() {

switch(tmputama) {

case 0 :
tampiljws();
break;

case 1 :
iqomah();
break;

uint8_t tmpjws;
void tampiljws() {

switch(tmpjws) {

case 0 :
animLogoX();
AlarmSholat();
break;

case 1 :
JamBesar(1);
tampilinfo();
AlarmSholat();
break;

case 2 :
TeksBerjalanKananKiri();
AlarmSholat();
break;

uint8_t tmpinfo;

void tampilinfo() {

switch(tmpinfo) {

case 0 :
TampilTanggal();
break;

case 1 :
TampilSuhu();
break;

case 2 :
TampilJadwalSholat();
break;

//----------------------------------------------------------------------
// ALARM SHOLAT BERJALAN SAAT MASUK WAKTU SHOLAT

void AlarmSholat() {

RtcDateTime now = Rtc.GetDateTime();

int Hari = now.DayOfWeek();


int Hor = now.Hour();
int Min = now.Minute();
int Sec = now.Second();
int durasiadzan = 3 * 60000;

JadwalSholat();

int hours, minutes, seconds;

// Tanbih Imsak
get_float_time_parts(times[0], hours, minutes);
minutes = minutes + ihti;

if (minutes < 10) {

minutes = 60 - minutes;
hours --;

} else {

minutes = minutes - 10 ;

if (Hor == hours && Min == minutes) {

BuzzerPendek();
Disp.clear();
Disp.setFont(bmz4x6);
textCenter(0, "TANBIH");
textCenter(8, "IMSAK");
delay(durasiadzan);
Disp.clear();

// Subuh
get_float_time_parts(times[0], hours, minutes);
minutes = minutes + ihti;

if (minutes >= 60) {

minutes = minutes - 60;


hours ++;

if (Hor == hours && Min == minutes) {

BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "SUBUH");
delay(durasiadzan);
menitiqmh = 12;
tmputama = 1;
Disp.clear();
}

// Dzuhur
get_float_time_parts(times[2], hours, minutes);
minutes = minutes + ihti;

if (minutes >= 60) {

minutes = minutes - 60;


hours ++;

if (Hor == hours && Min == minutes && Hari != 5) {

BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "DZUHUR");
delay(durasiadzan);
Disp.clear();
menitiqmh = 7;
tmputama = 1;

} else if (Hor == hours && Min == minutes && Hari == 5) {

BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "JUM'AT");
delay(durasiadzan);

// Ashar
get_float_time_parts(times[3], hours, minutes);
minutes = minutes + ihti;

if (minutes >= 60) {

minutes = minutes - 60;


hours ++;

if (Hor == hours && Min == minutes) {

BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "ASHAR");
delay(durasiadzan);
Disp.clear();
menitiqmh = 5;
tmputama = 1;

// Maghrib
get_float_time_parts(times[5], hours, minutes);
minutes = minutes + ihti;

if (minutes >= 60) {

minutes = minutes - 60;


hours ++;

if (Hor == hours && Min == minutes) {

BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "MAGHRIB");
delay(durasiadzan);
Disp.clear();
menitiqmh = 5;
tmputama = 1;

// Isya'
get_float_time_parts(times[6], hours, minutes);
minutes = minutes + ihti;

if (minutes >= 60) {

minutes = minutes - 60;


hours ++;

if (Hor == hours && Min == minutes) {

BuzzerPendek();
Disp.clear();
Disp.setFont(ElektronMart6x8);
textCenter(0, "ADZAN");
textCenter(8, "ISYA'");
delay(durasiadzan);
Disp.clear();
menitiqmh = 5;
tmputama = 1;

//----------------------------------------------------------------------
// FORMAT TEKS

void textCenter(int y,String Msg) {

int center = int((Disp.width()-Disp.textWidth(Msg)) / 2);


Disp.drawText(center,y,Msg);

void textCenter1PKanan(int y,String Msg) {

int center = ((Disp.width()-Disp.textWidth(Msg)) / 2) + (Disp.width() / 4);


Disp.drawText(center,y,Msg);

//----------------------------------------------------------------------
//TAMPILKAN RUNNING TEKS

static String nama1 = (" Belajar Membuat JWS ESP8266 Wifi ");
static String nama2 = (" Membuat JWS Running Teks ");

void TeksBerjalanKananKiri() {
RtcDateTime now = Rtc.GetDateTime();

char jam[3];
char menit[3];
char detik[3];
sprintf(jam, "%02d", now.Hour());
sprintf(menit, "%02d", now.Minute());
sprintf(detik, "%02d", now.Second());

static uint32_t pM;


uint32_t cM = millis();
static uint8_t Kecepatan = 50;
static uint32_t x;

int width = Disp.width();


int fullScroll = Disp.textWidth(nama1) + width;

Disp.setFont(bmz6x7);
Disp.drawText(8,-1,jam);
Disp.drawText(22,-1,":");
Disp.drawText(25,-1,menit);
Disp.drawText(39,-1,":");
Disp.drawText(42,-1,detik);

if(cM - pM > Kecepatan) {

pM = cM;

if (x < fullScroll) {

++x;

} else {
x = 0;
Disp.clear();
tmpjws = 0;

Disp.setFont(bmz5x7);
Disp.drawText(width - x, 9, nama1);

void TeksBerjalanKiriKanan() {

static uint32_t pM;


uint32_t cM = millis();
static uint8_t Kecepatan = 50;
static uint32_t x;

int width = Disp.width();


int fullScroll = Disp.textWidth(nama2) + width;

Disp.setFont(ElektronMart6x8);

if(cM - pM > Kecepatan) {

pM = cM;

if (x < fullScroll) {

++x;

} else {

x = 0;

Disp.drawText(x - fullScroll + width, 8, nama2);

//----------------------------------------------------------------------
//TAMPILKAN LOGO

//----------------------------------------------------------------------
// ANIMASI LOGO

void animLogoX() {

static uint8_t x;
static uint8_t s; // 0=in, 1=out
static uint32_t pM;
uint32_t cM = millis();

JamBesar2(16);

if (cM - pM > 35) {

if (s == 0 and x < 16) {

pM = cM;
x++;

if (s == 1 and x > 0) {

pM = cM;
x--;

if (cM - pM > 10000 and x == 16) {

s = 1;

if (x == 0 and s == 1) {

Disp.clear();
s = 0;
tmpjws = 1;

LogoA(Disp.width() - x);
LogoM(x - 16);

void LogoA(uint32_t x) {

static const uint8_t LogoA[] PROGMEM = {

16, 16,

0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00, 0x7e, 0x66, 0x7e, 0x66, 0x06,
0x66, 0x06, 0x66, 0x7e, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f,
0xfe, 0x7f, 0xfe, 0x00, 0x00

};

Disp.drawBitmap(x, 0, LogoA);
}
void LogoM(uint32_t x) {

static const uint8_t LogoM[] PROGMEM = {

16, 16,

0x00, 0x00, 0x66, 0x7e, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x7e,
0x7e, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x7e, 0x7e, 0x7e, 0x66, 0x06, 0x66, 0x06, 0x7f,
0xfe, 0x7f, 0xfe, 0x00, 0x00

};

Disp.drawBitmap(x, 0, LogoM);
}

//----------------------------------------------------------------------
//TAMPILKAN JADWAL SHOLAT

void JadwalSholat() {

/*
CALCULATION METHOD
------------------
Jafari, // Ithna Ashari
Karachi, // University of Islamic Sciences, Karachi
ISNA, // Islamic Society of North America (ISNA)
MWL, // Muslim World League (MWL)
Makkah, // Umm al-Qura, Makkah
Egypt, // Egyptian General Authority of Survey
Custom, // Custom Setting

JURISTIC
--------
Shafii, // Shafii (standard)
Hanafi, // Hanafi

ADJUSTING METHOD
----------------
None, // No adjustment
MidNight, // middle of night
OneSeventh, // 1/7th of night
AngleBased, // angle/60th of night

TIME IDS
--------
Fajr,
Sunrise,
Dhuhr,
Asr,
Sunset,
Maghrib,
Isha

*/

RtcDateTime now = Rtc.GetDateTime();


int tahun = now.Year();
int bulan = now.Month();
int tanggal = now.Day();
float latitude = -7.78;
float longitude = 110.39;
int zonawaktu = 7;

set_calc_method(Karachi);
set_asr_method(Shafii);
set_high_lats_adjust_method(AngleBased);
set_fajr_angle(20);
set_isha_angle(18);

get_prayer_times(tahun, bulan, tanggal, latitude, longitude, zonawaktu, times);

void TampilJadwalSholat() {

JadwalSholat();

static uint8_t i;
static uint32_t pM;
uint32_t cM = millis();

char sholat[7];
char jam[5];
char TimeName[][8] = {"SUBUH","TERBIT","DZUHUR","ASHAR","TRBNM","MAGRIB","ISYA"};
int hours, minutes;

if (cM - pM >= 3000) {

pM = cM;
Disp.drawRect(31,0,64,15,0,0);

if (i == 1) {i = 2;} // Abaikan Terbit


if (i == 4) {i = 5;} // Abaikan Terbenam

get_float_time_parts(times[i], hours, minutes);

minutes = minutes + ihti;

if (minutes >= 60) {


minutes = minutes - 60;
hours ++;
}

String sholat = TimeName[i];


sprintf(jam,"%02d:%02d", hours, minutes);

Disp.setFont(bmz4x6);
textCenter1PKanan(-1, sholat);
Disp.drawLine(32,7,64,7,1);
Disp.setFont(bmz6x7);
textCenter1PKanan(8, jam);

i++;
if (i > 7) {
get_float_time_parts(times[0], hours, minutes);
minutes = minutes + ihti;
if (minutes < 11) {
minutes = 60 - minutes;
hours --;
} else {
minutes = minutes - 10 ;
}
sprintf(jam,"%02d:%02d", hours, minutes);
Disp.drawRect(31,0,64,15,0,0);
Disp.setFont(bmz4x6);
textCenter1PKanan(-1, "TANBIH");
Disp.drawLine(32,7,64,7,1);
Disp.setFont(bmz6x7);
textCenter1PKanan(8, jam);

if (i > 8) {
i = 0;
Disp.drawRect(0,0,64,15,0,0);
tmpinfo = 0;
tmpjws = 2;
}

//----------------------------------------------------------------------
// HITUNG MUNDUR WAKTU SETELAH ADZAN SAMPAI MULAI IQOMAH

void iqomah() {

static uint32_t pM;


uint32_t cM = millis();
static char hitungmundur[6];

Disp.setFont(ElektronMart5x6);
textCenter(0, "IQOMAH");

if (detikiqmh == 60) {
detikiqmh = 0;
}

if (cM - pM >= 100) {


pM = cM;
detikiqmh--;

if (menitiqmh == 0 && detikiqmh == 0) {


Disp.clear();
Disp.setFont(ElektronMart5x6);
textCenter(0, "LURUSKAN DAN");
textCenter(8, "RAPATKAN SHAF");
BuzzerPanjang();
detikiqmh = 59;
Disp.clear();
tmputama = 1;
}

if (detikiqmh < 0) {
detikiqmh = 59;
menitiqmh--;
}

sprintf(hitungmundur, "%02d:%02d", menitiqmh, detikiqmh);


Disp.setFont(ElektronMart6x8);
textCenter(8, hitungmundur);

//----------------------------------------------------------------------
//TAMPILKAN TANGGAL

void TampilTanggal() {

RtcDateTime now = Rtc.GetDateTime();

char hari[8];
char tanggal[7]; // 21 SEP

static uint32_t pM;


uint32_t cM = millis();

static uint8_t flag;

if(cM - pM > 3000) {

pM = cM;
flag++;

sprintf(hari, "%s", weekDay[now.DayOfWeek()]);


sprintf(tanggal, "%02d %s", now.Day(), monthYear[now.Month()]);

Disp.setFont(bmz4x6);
textCenter1PKanan(0, hari);
textCenter1PKanan(8, tanggal);

if (flag >= 2) {
flag = 0;
Disp.drawRect(32,0,64,15,0,0);
tmpinfo = 1;

//----------------------------------------------------------------------
// TAMPILKAN SUHU

void TampilSuhu() {

RtcTemperature temp = Rtc.GetTemperature();


int celsius = temp.AsFloatDegC();

char suhu[3];
int koreksisuhu = 2; // Perkiraan selisih suhu mesin dengan suhu ruangan

static uint32_t pM;


uint32_t cM = millis();

static uint8_t flag;

if(cM - pM > 3000) {

pM = cM;
flag++;

sprintf(suhu, "%02d", celsius - koreksisuhu);

Disp.setFont(bmz4x6);
textCenter1PKanan(0, "SUHU");
Disp.setFont(bmz5x7);
Disp.drawText(36,8, suhu);
Disp.drawCircle(49,9,1);
Disp.drawText(53,8, "C");

if (flag >= 2) {
flag = 0;
Disp.drawRect(32,0,64,15,0,0);
tmpinfo = 2;

//----------------------------------------------------------------------
// TAMPILKAN JAM

void JamBesar(uint16_t x) {

RtcDateTime now = Rtc.GetDateTime();

char jam[3];
char menit[3];
char detik[3];

sprintf(jam, "%02d", now.Hour());


sprintf(menit, "%02d", now.Minute());
sprintf(detik, "%02d", now.Second());

static boolean huruf;


static uint8_t y;
static uint8_t d;
static uint32_t pM;
uint32_t cM = millis();

static uint32_t pMPulse;


static uint8_t pulse;

if (cM - pMPulse >= 100) {


pMPulse = cM;
pulse++;
}

if (pulse > 8) {
pulse=0;
}

if(cM - pM > 35) {


if(d == 0 and y < 20) {
pM=cM;
y++;
}
if(d == 1 and y > 0) {
pM=cM;
y--;
}
}

if(cM - pM > 10000 and y == 20) {


d=1;
}

if(y == 20) {
Disp.drawRect(x+13,3+pulse,x+16,11-pulse,0,1);
}

if(y < 20) {


Disp.drawRect(x+13,3,x+16,11,0,0);
}

if(y == 0 and d == 1) {
d=0;
huruf = !huruf;
}

//JAM
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+0, y - 20, jam);

//MENIT
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+17, y - 20, menit);

//DETIK

void JamBesar2(uint16_t x) {

RtcDateTime now = Rtc.GetDateTime();

char jam[3];
char menit[3];

sprintf(jam, "%02d", now.Hour());


sprintf(menit, "%02d", now.Minute());

static boolean huruf;

static uint8_t y;
static uint8_t d;
static uint32_t pM;
uint32_t cM = millis();

static uint32_t pMPulse;


static uint8_t pulse;

if (cM - pMPulse >= 100) {

pMPulse = cM;
pulse++;

if (pulse > 8) {
pulse=0;
}

if(cM - pM > 35) {

if(d == 0 and y < 20) {


pM = cM;
y++;
}

if(d == 1 and y > 0) {


pM = cM;
y--;
}

if(cM - pM > 10000 and y == 20) {


d=1;
}

if(y == 20) {
Disp.drawRect(x+14,3+pulse,x+17,11-pulse,0,1);
}

if(y < 20) {


Disp.drawRect(x+14,3,x+18,17,0,0);
}

if(y == 0 and d == 1) {
d=0;
huruf = !huruf;
}

//JAM
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+1, y - 20, jam);

//MENIT
if (huruf) {
Disp.setFont(bmz6x16);
} else {
Disp.setFont(bmz6x16);
}
Disp.drawText(x+18, y - 20, menit);

void TampilJamKecil() {

static uint32_t pMJam;


uint32_t cM = millis();

RtcDateTime now = Rtc.GetDateTime();


char jam[9];

if (cM - pMJam >= 1000) {

pMJam = cM;

//JAM
sprintf(jam,"%02d:%02d:%02d", now.Hour(), now.Minute(), now.Second());
Disp.setFont(bmz5x7);
Disp.drawText(20,7, jam);

//----------------------------------------------------------------------
// BUNYIKAN BEEP BUZZER
void BuzzerPanjang() {

digitalWrite(buzzer, HIGH);
delay(1000);
digitalWrite(buzzer, LOW);
delay(1000);
digitalWrite(buzzer, HIGH);
delay(1000);
digitalWrite(buzzer, LOW);
delay(3000);

void BuzzerPendek() {

digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(100);
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(3000);

void BunyiBeep() {

static uint32_t pMBuz;


uint32_t cM = millis();
static boolean beep;

if (cM - pMBuz >= 200) {

pMBuz = cM;

beep = !beep;

if (beep) {

digitalWrite(buzzer, HIGH);

} else {

digitalWrite(buzzer, LOW);

//----------------------------------------------------------------------
// I2C_ClearBus menghindari gagal baca RTC (nilai 00 atau 165)

int I2C_ClearBus() {
#if defined(TWCR) && defined(TWEN)
TWCR &= ~(_BV(TWEN)); //Disable the Atmel 2-Wire interface so we can control the
SDA and SCL pins directly
#endif

pinMode(SDA, INPUT_PULLUP); // Make SDA (data) and SCL (clock) pins Inputs with
pullup.
pinMode(SCL, INPUT_PULLUP);

delay(2500); // Wait 2.5 secs. This is strictly only necessary on the first
power
// up of the DS3231 module to allow it to initialize properly,
// but is also assists in reliable programming of FioV3 boards as it gives the
// IDE a chance to start uploaded the program
// before existing sketch confuses the IDE by sending Serial data.

boolean SCL_LOW = (digitalRead(SCL) == LOW); // Check is SCL is Low.


if (SCL_LOW) { //If it is held low Arduno cannot become the I2C master.
return 1; //I2C bus error. Could not clear SCL clock line held low
}

boolean SDA_LOW = (digitalRead(SDA) == LOW); // vi. Check SDA input.


int clockCount = 20; // > 2x9 clock

while (SDA_LOW && (clockCount > 0)) { // vii. If SDA is Low,


clockCount--;
// Note: I2C bus is open collector so do NOT drive SCL or SDA high.
pinMode(SCL, INPUT); // release SCL pullup so that when made output it will be
LOW
pinMode(SCL, OUTPUT); // then clock SCL Low
delayMicroseconds(10); // for >5uS
pinMode(SCL, INPUT); // release SCL LOW
pinMode(SCL, INPUT_PULLUP); // turn on pullup resistors again
// do not force high as slave may be holding it low for clock stretching.
delayMicroseconds(10); // for >5uS
// The >5uS is so that even the slowest I2C devices are handled.
SCL_LOW = (digitalRead(SCL) == LOW); // Check if SCL is Low.
int counter = 20;
while (SCL_LOW && (counter > 0)) { // loop waiting for SCL to become High
only wait 2sec.
counter--;
delay(100);
SCL_LOW = (digitalRead(SCL) == LOW);
}
if (SCL_LOW) { // still low after 2 sec error
return 2; // I2C bus error. Could not clear. SCL clock line held low by slave
clock stretch for >2sec
}
SDA_LOW = (digitalRead(SDA) == LOW); // and check SDA input again and loop
}
if (SDA_LOW) { // still low
return 3; // I2C bus error. Could not clear. SDA data line held low
}

// else pull SDA line low for Start or Repeated Start


pinMode(SDA, INPUT); // remove pullup.
pinMode(SDA, OUTPUT); // and then make it LOW i.e. send an I2C Start or Repeated
start control.
// When there is only one I2C master a Start or Repeat Start has the same
function as a Stop and clears the bus.
/// A Repeat Start is a Start occurring after a Start with no intervening Stop.
delayMicroseconds(10); // wait >5uS
pinMode(SDA, INPUT); // remove output low
pinMode(SDA, INPUT_PULLUP); // and make SDA high i.e. send I2C STOP control.
delayMicroseconds(10); // x. wait >5uS
pinMode(SDA, INPUT); // and reset pins as tri-state inputs which is the default
state on reset
pinMode(SCL, INPUT);
return 0; // all ok
}

You might also like