Semua Tentang Belajar Teknologi Digital Dalam Kehidupan Sehari - Hari

Selasa, 09 Juni 2020

[Praktek Gampang] Jam di TV dengan Arduino - Part 3 - Esp8266-01 Kirim NTP via I2C



Kegemaran saya mengoprek jam kalender dan TV dimulai sejak  membaca tulisan mengenai steve wozniak dan steve jobs tentang bagaimana mereka bekerjasama membuat hardware video game "breakout" di Atari, hingga akhirnya menciptakan komputer apple yang legendaris itu. Dulu saat penulis kuliah sempat mendapat praktikum interfacing monitor VGA tapi hanya selintas aja dan menyesal juga kenapa gak sedari dulu bisa mengerti walau nilai praktikum dapat A (nyontek teman yg pinter sihhh). Dari dua latar belakang tersebut dan ketika microcontroller semakin murah dan mudah didapatkan menjadi tantangan tersendiri bermain micro di TV dan terlihat seperti main-main dan menghabiskan waktu, memang itu benar tapi asyik lhoo!  Tapi jangan berkecil hati karena penulis juga dapat banyak ilmu terutama mengenai pemrograman script yang lebih efisien. Salah satunya adalah ketika tantangan komunikasi arduino ke ESP agar tidak mengganggu timer Atmega328 untuk scanning TV. Jika menggunakan Serial baik Hardware atau emulasi software tetap aja akan menimbulkan interfrensi timer. Untuk itu digunakan komunikasi dengan timer  yg independen yaitu I2C. Dari hasil googling didapat bahwa ESP8266 bisa juga dimanfaatkan sebagai I2C master dan Arduino sebagai Slave nya. 




Komunikasi I2C sudah tersedia librarinya dalam instalasi default sketch,  yaitu dengan library " wire.h ". Untuk arduino uno / mini / micro yg berbasis ATmega328 pin SDA = A4 pin SCL =A5 . Dengan menggunakan I2C maka master dapat mengirim data atau meminta data ke slave. Tiap komponen yg diakses memiliki address masing-masing. Untuk ESP8266-01 memiliki 2 output GPIO yang bukan berfungsi sebagai I2C secara spesifik, sehingga perlu dilakukan inisialisasi port sendiri mana yg berfungsi sebagai SDA atau SCL. 

Menyambung tulisan mengenai jam di TV dan esp8266 , maka sebelum melanjutkan ke bahasan dibawah ada baiknya paca dulu PART1 dan PART2


- Praktek Testing I2C

Kita akan mencoba menghubungkan ESP sebagai master, terhubung secara I2C ke Arduino sebagai Slave dan tujuannya adalah mengirimkan data kalender secara periodik. Slave kemudian akan menuliskan hasil data yg diperoleh ke Serial port.

Script Master ( ESP8266-01)

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "TimeLib.h"
//library I2c
#include <Wire.h>
//library NTP , unduh jika blom ada
#include <NTPClient.h>

const char *ssid     = "Nama Wifi";
const char *password = "Password";
//Offset WIB +7 , sesuaikan
const long utcOffsetInSeconds = 25200;

long previousMillis = 0;   
long interval = 10000; //tiap 10 detik
//Array kalender
char tanggalan[] ="20,1,1,23,59,0" ;

// NTP lokal, ubah jika perlu
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp.bmkg.go.id", utcOffsetInSeconds);

void setup(){
  Serial.begin(9600); //monitor
  Wire.begin(0, 2); 
/* Koneksi i2c  SDA=0 and SCL=2  pada ESP-01 */

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  timeClient.begin();
}

void loop() {

  unsigned long currentMillis = millis(); 

  if(currentMillis - previousMillis > interval) {

  previousMillis = currentMillis;
  timeClient.update();
  unsigned long epoch ;
  epoch = timeClient.getEpochTime();
  
//output ke array
  sprintf(tanggalan,"%2d,%02d,%02d,%02d,%02d,%02d", year(epoch)-2000, month(epoch), day(epoch), hour(epoch), minute(epoch), second(epoch));

  Wire.beginTransmission(8); /* address 8 */
  Wire.write(tanggalan);  /* kirim Kalender */
  Wire.endTransmission();    /* stop */
  Serial.print("tanggal : ");
  Serial.println(tanggalan);

  }
}



Script Slave (Arduino)

#include <Wire.h>


void setup()
{
Serial.begin(9600);
Wire.begin(8);
//rutin event receive i2c
Wire.onReceive(espWifiReceiveEvent);

}

void loop()
{
delay(1);
}

//Kirim ke serial saat ada data i2c masuk

void espWifiReceiveEvent(int count)
{
Serial.print("Received[");
while (Wire.available())
{
char c = Wire.read();
Serial.print(c);
}
Serial.println("]");

}


Nah jika dilihat output pada serial monitor / putty disisi arduino/slave seperti berikut:




- SCRIPT JAM LENGKAP

Terdapat beberapa hal yg menjadi perhatian saat data diterima arduino pada port I2C, dimana timer tetap akan kacau kalau data i2c nya panjang. I2C akan hang itulah yg terjadi saat 17 byte char diterima ,  jadi diakali dengan melakukan penonaktifan I2C setelah data kalender lengkap. Peng-update-an tanggalan dilakukan setiap jam atau sesuai keinginan misalnya tiap jam 3 pagi jika TV mau nyala terus dan gak dipake emak nonton sinetron..hehehehe...ayuk kita kupas satu persatu.


#include <TVout.h>
#include <Wire.h>
#include "fontALL.h"
#include <String.h>

TVout TV;

long previousMillis = 0;    
byte second, minute, hour, dayOfMonth, month, year;
long interval = 200;
int tvx,tvy,tvradius,x2,y2,x3,y3;
char buff[20]="20,08,06,23,58,58";
int buffindex=0;
char incomingByte ;

//status flag
bool ntpkomplit = false;
bool ntpupdate = false;

//function nulis kalender dan jam
void printTime()
{

second++;

if(second >=60){
  minute++;
  second=0;

}

if(minute >=60){
  hour++;
  minute=0;

  //reset flag
  ntpkomplit=false;
  ntpupdate=false;
  
  //restart i2C
   TWCR = 0;
   Wire.begin(8); //address 8
   Wire.onReceive(espWifiReceiveEvent);

}

if(hour >=24){
  hour=0;  
  dayOfMonth++;
}

//jika flag ntp komplit maka update kalender
if( ntpkomplit == true && ntpupdate == false ){
//parsing koma ke kalender
  char* ptr = strtok(buff, ",");
  byte i = 0;
  while (ptr) {
    if( i ==0 )year=atoi(ptr);
    else if( i == 1)month=atoi(ptr);
    else if( i == 2)dayOfMonth=atoi(ptr);
    else if( i == 3)hour=atoi(ptr);
    else if( i == 4)minute=atoi(ptr);
    else if( i == 5)second=atoi(ptr);
    
    ptr = strtok(NULL, ",");
    i++;
  }
  //flag ntp telah terupdate
  ntpupdate = true;
}

//tulis kalender

TV.set_cursor(0,0);
TV.print( char( hour/10 + 0x30) );
TV.print( char( hour%10 + 0x30) );
TV.print(":");
TV.print( char(minute/10 + 0x30));
TV.print( char(minute%10 + 0x30));
TV.print(":");
TV.print(char (second/10+0x30));
TV.print(char (second%10+0x30));


TV.set_cursor(8,9);
TV.print(char(dayOfMonth/10+0x30));
TV.print(char(dayOfMonth%10+0x30));
TV.print("/");
TV.print(char(month/10+0x30));
TV.print(char(month%10+0x30));
TV.set_cursor(10,18);
TV.print("20");
TV.print(char(year/10+0x30));
TV.print(char(year%10+0x30));
  
//status NTP connecting atau OK 

if( ntpupdate == false)
{
  TV.set_cursor(10,38);
  TV.print("con");
}

else{

  TV.set_cursor(10,38);
  TV.print("OK!");
}

//gambar Jam
//courtesy of Giant Metal Robot Blog 
  
TV.draw_circle(tvx,tvy,tvradius-5,BLACK,BLACK);

float angle = second*6 ;
angle=(angle/57.29577951) ; //Convert degrees to radians  
x3=(tvx+(sin(angle)*(tvradius-6)));
y3=(tvy-(cos(angle)*(tvradius-6)));
TV.draw_line(tvx,tvy,x3,y3,WHITE);
angle = minute * 6 ;
angle=(angle/57.29577951) ; //Convert degrees to radians  
x3=(tvx+(sin(angle)*(tvradius-11)));
y3=(tvy-(cos(angle)*(tvradius-11)));
TV.draw_line(tvx,tvy,x3,y3,WHITE);
angle = hour * 30 + int((minute / 12) * 6 )   ;
angle=(angle/57.29577951) ; //Convert degrees to radians  
x3=(tvx+(sin(angle)*(tvradius-15)));
y3=(tvy-(cos(angle)*(tvradius-15)));
TV.draw_line(tvx,tvy,x3,y3,WHITE);

}


void setup()  {
//TV di mode NTSC

TV.begin(_NTSC,150,71);
TV.select_font(font6x8);
TV.clear_screen();

tvx= TV.hres()/2;
tvy=TV.vres()/2;
tvradius=TV.vres()/2 ;
//clock face lingkaran
 TV.draw_circle(tvx,tvy,tvradius,WHITE);
//hour ticks
for( int z=0; z < 360;z= z + 30 ){
  //Begin at 0° and stop at 360°
  float angle = z ;
  angle=(angle/57.29577951) ; //Convert degrees to radians
  x2=(tvx+(sin(angle)*tvradius));
  y2=(tvy-(cos(angle)*tvradius));
  x3=(tvx+(sin(angle)*(tvradius-5)));
  y3=(tvy-(cos(angle)*(tvradius-5)));

  TV.draw_line(x2,y2,x3,y3,WHITE);
}
  
  
  TV.set_cursor(10,30);
  TV.print("NTP");
  TV.set_cursor(0,55);
  TV.print("aisi555");
  TV.set_cursor(3,63);
  TV.print(".com");



//buka serial kalau mau debug
//Serial.begin(9600);
Wire.begin(8); // I2C
Wire.onReceive(espWifiReceiveEvent);

}

void loop() {
  
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {

  previousMillis = currentMillis;
  TV.delay(980); // Sesuaikan antara 950-1000
  printTime();

  }

}


void espWifiReceiveEvent(int count)
{

 //buka blok serial kalau mau debug
//Serial.print("Received[");

//jika i2c terima data dan blum komplit kalendernya
while (Wire.available() && ntpkomplit == false)
{
 char c = Wire.read();
 //Serial.print(c);
 buff[buffindex]=c;
 buffindex++;
}
//Serial.println("]");


//Ntpkomplit = true Jika buffer kalender sampe menit terpenuhi 
if(buffindex >=14) {
  ntpkomplit = true;
  TWCR = 0; //bunuh i2c
  
}

buffindex = 0;

}




HASIL :



Proses update yg saya gunakan adalah tiap JAM atau menit ke 0, jadi memang tidak akan langsung terupdate akibat proses BITBANG tabrak menabrak antar timer vs i2c. Jadi seperti video berikut ini dapat dilihat UPDATE ke waktu NTP terjadi hampir  2 menit kemudian.



Bagaimana ? Sudah Mumet ? Sebaiknya baca dari awal ya PART1 dan PART2 dan juga bagian sebelumnya mengenai TV menggunakan microcontroller yang sudah saya tulis sejak 2012. 

SELAMAT MENCOBA

Share:

5 komentar:

  1. Thank you for sharing. I still failed in the end. No matter it is reading ESP8266 data from RX TX or I2C, the data cannot be updated, and "NTP con" is always displayed. Hope you can share more detailed schematics and codes, thank you!

    BalasHapus
    Balasan
    1. because it wait for the message from bitbang i2c data every top of the hour. so just wait a little bit longer

      Hapus
    2. Thank you so much for your reply! I tested the two modes and the waiting time is relatively long, but there is still no data. Could you please sort out the working schematics and code and share with me? Thank you again!

      Hapus
    3. you know what, TV timing is critical, so it will make the UC bussy all the time ...no luck in using other means of communication rather than i2c..

      Hapus
  2. bang bikin ntpNodeMcu yg pake alarm tanpa pushbuttton

    BalasHapus

Kontak Penulis



12179018.png (60Ɨ60)
+628155737755

Mail : ahocool@gmail.com

Site View

Categories

555 (8) 7 segmen (3) adc (4) amplifier (2) analog (19) android (14) antares (11) arduino (28) artikel (11) attiny (3) attiny2313 (19) audio (5) baterai (5) blog (1) bluetooth (1) chatgpt (2) cmos (2) crypto (2) dasar (46) digital (11) dimmer (5) display (3) esp8266 (26) euro2020 (13) gcc (1) gsm (1) iklan (1) infrared (2) Input Output (3) iot (76) jam (7) jualan (12) kereta api (1) keyboard (1) keypad (3) kios pulsa (2) kit (6) komponen (17) komputer (3) komunikasi (1) kontrol (8) lain-lain (8) lcd (2) led (14) led matrix (6) line tracer (1) lm35 (1) lora (11) lorawan (2) MATV (1) memory (1) metal detector (4) microcontroller (70) micropython (6) mikrokontroler (2) mikrokontroller (14) mikrotik (5) modbus (9) mqtt (3) ninmedia (5) ntp (1) paket belajar (19) palang pintu otomatis (1) parabola (88) pcb (2) power (1) praktek (2) project (33) proyek (1) python (8) radio (28) raspberry pi (9) remote (1) revisi (1) rfid (1) robot (1) rpm (2) rs232 (1) script break down (3) sdcard (3) sensor (2) sharing (3) signage (1) sinyal (1) sms (6) software (18) solar (1) solusi (1) tachometer (2) technology (1) teknologi (2) telegram (2) telepon (9) televisi (167) television (28) telkomiot (5) transistor (2) troubleshoot (3) tulisan (94) tutorial (108) tv digital (6) tvri (2) vu meter (2) vumeter (2) wav player (3) wayang (1) wifi (3) yolo (7)

Arsip Blog

Diskusi


kaskus
Forum Hobby Elektronika