5. Penampil LCD + Serial

Apabila di Aplikasi 4 (Penampil LCD), Outseal Nano dijadikan Master, dan Arduino Nano dijadikan Slave, di mana Arduino Nano ini difungsikan untuk membantu Outseal Nano agar dapat membaca data Sensor dan kemudian menampilkan data tersebut di LCD dan di Serial Monitor, maka di Aplikasi 5 ini, peran keduanya dibalik, yaitu Outseal Nano dijadikan Slave, dan Arduino Nano dijadikan Master. 

Mengapa dibalik, apa tujuannya? Tujuannya agar Pengguna atau Operator tidak hanya membaca data dan menampillkannya di LCD dan Serial Monitor saja, tetapi juga dapat mengubah data di Outseal Nano melalui Komunikasi Serial. Jadi Aplikasi 5 ini sebenarnya menggabungkan Aplikasi 3 (Kirim Terima Serial) dengan Aplikasi 4 (Penampil LCD), dengan tujuan agar dapat melakukan kesepuluh hal berikut ini:
  1. Meminta data Coil Outseal dari Serial Monitor
  2. Meminta data Input Diskrit Outseal dari Serial Monitor
  3. Meminta data Input Register Outseal dari Serial Monitor
  4. Meminta data Holding Register Outseal dari Serial Monitor
  5. Mengubah data Coil Outseal dari Serial Monitor
  6. Mengubah data Holding Register Outseal dari Serial Monitor
  7. Menampilkan data Coil di LCD
  8. Menampilkan data Input Diskrit di LCD
  9. Menampilkan data Input Register di LCD
  10. Menampilkan data Holding Register di LCD
Catatan: Agar lebih bervariasi, di Aplikasi 5 ini, sengaja Arduino Nano yang dijadikan Master, diganti dengan Arduino Uno, sedangkan Arduino Nano untuk Outseal Nano tetap menggunakan Arduino Nano. Jadi di Aplikasi 5 ini, Arduino Uno sebagai Master, dan Arduino Nano sebagai Slave. 

Untuk bisa melakukan kesepuluh hal di atas, berikut ini langkah-langkahnya:

1. Buka Proteus, dan buat rangkaian Outseal Nano dengan komponen ATmega328, atau rangkaian Outseal Mega dengan komponen ATmega128 seperti berikut ini:

Gambar 1(a). Rangkaian Outseal Nano dengan Alat Input Output Digital dan Analog di Proteus (File Proteus ini dapat diunduh di bagian akhir tulisan ini, dengan nama file Outseal_Nano.pdsprj)

Gambar 1(b). Rangkaian Outseal Mega dengan Alat Input Output Digital dan Analog di Proteus (File Proteus ini dapat diunduh di bagian akhir tulisan ini, dengan nama file Outseal_Mega.pdsprj)

2. Buat Ladder Diagram di Outseal Studio seperti berikut ini. Ladder Diagram yang pertama untuk Outseal Nano, dan Ladder Diagram yang kedua untuk Outseal Mega.

Gambar 2(a). Ladder Diagram untuk Outseal Nano

Gambar 2(b). Ladder Diagram untuk Outseal Mega

Catatan: Pada dasarnya kedua Ladder Diagram di atas sama, hanya Ladder Diagram untuk Outseal Mega memiliki kontak dan coil yang lebih banyak, yaitu 2 kali lipat dari Ladder Diagram Outseal Nano.

3. Berikutnya, dari rangkaian Gambar 1(a) dan Gambar 1(b) di atas, tambahkan LCD I2C dan Arduino Uno, serta Virtual Terminal dan COMPIM, seperti ditunjukkan gambar berikut ini:

Gambar 3(a). Rangkaian Outseal Nano dengan penambahan LCD I2C dan Arduino Uno (File Proteus ini dapat diunduh di bagian akhir tulisan ini, dengan nama file Outseal_Nano_Uno.pdsprj)

Catatan: Arduino Uno dan Arduino Nano memiliki mikrokontroler yang sama, yaitu ATmega328P. Untuk itu di Proteus, keduanya ditampilkan dalam bentuk komponen ATmega328P. Hanya saja, Arduino Uno tidak memunculkan kaki ADC6 dan kaki ADC7, yang mana kedua kaki tersebut diperlukan sebagai kaki Input Analog A.1 dan A.2 di Outseal. Untuk itu, hanya Arduino Nano yang bisa dijadikan Outseal, karena kaki ADC6 dan kaki ADC7 dimunculkan di papan rangkaiannya.

Gambar 3(b). Rangkaian Outseal Mega dengan penambahan LCD I2C dan Arduino Uno (File Proteus ini dapat diunduh di bagian akhir tulisan ini, dengan nama file Outseal_Mega_Uno.pdsprj)

4. Gunakan program berikut ini untuk Arduino Uno, baik di rangkaian Gambar 3(a) maupun di rangkaian Gambar 3(b).

KodeProgram_ArduinoUno
  1. #include <ModbusRTU.h>
  2. #include <Wire.h>
  3. #include <LiquidCrystal_I2C.h>
  4. #include <SoftwareSerial.h>
  5. SoftwareSerial S(3, 2);
  6. LiquidCrystal_I2C lcd(0x27, 16, 2);
  7. ModbusRTU mb;
  8. String inputString = "";
  9. bool stringComplete = false;
  10. bool case1 = false;
  11. bool case2 = false;
  12. bool case3 = false;
  13. bool case4 = false;
  14. bool case5 = false;
  15. bool case6 = false;
  16. bool coil[20];
  17. bool idis[20];
  18. uint16_t hreg[10];
  19. uint16_t ireg[10];
  20. uint16_t cacah;
  21. unsigned long skr = 0;
  22. void setup() {
  23.   Serial.begin(9600);
  24.   lcd.init();
  25.   lcd.backlight();
  26.   S.begin(9600);
  27.   mb.begin(&S);
  28.   mb.master();
  29.   mb.readIsts(1, 0, idis, 16);  //hanya untuk trigger
  30.   while (mb.slave()) {
  31.     mb.task();
  32.     delay(10);
  33.   }
  34.   delay(1000);
  35.   Serial.println("Silahkan kirim data");
  36. }
  37. void loop() {
  38.   if (stringComplete) {
  39.     Serial.print("> ");
  40.     Serial.print(inputString);
  41.     lcd.setCursor(0, 0);
  42.     lcd.print(">               ");
  43.     lcd.setCursor(1, 0);
  44.     lcd.print(inputString);
  45.     String d1 = getValue(inputString, ',', 0);
  46.     String d2 = getValue(inputString, ',', 1);
  47.     String d3 = getValue(inputString, ',', 2);
  48.     String d4 = getValue(inputString, ',', 3);
  49.     uint8_t id = d1.toInt();
  50.     uint8_t kode = d2.toInt();
  51.     uint16_t alamat = d3.toInt();
  52.     uint16_t nilai = d4.toInt();
  53.     switch (kode) {
  54.       case 1:
  55.         mb.readCoil(id, alamat, coil, nilai);
  56.         case1 = true;
  57.         break;
  58.       case 2:
  59.         mb.readIsts(id, alamat, idis, nilai);
  60.         case2 = true;
  61.         break;
  62.       case 3:
  63.         mb.readHreg(id, alamat, hreg, nilai);
  64.         case3 = true;
  65.         break;
  66.       case 4:
  67.         mb.readIreg(id, alamat, ireg, nilai);
  68.         case4 = true;
  69.         break;
  70.       case 5:
  71.         mb.writeCoil(id, alamat, nilai < 1);
  72.         case5 = true;
  73.         break;
  74.       case 6:
  75.         mb.writeHreg(id, alamat, nilai);
  76.         case6 = true;
  77.         break;
  78.     }
  79.     while (mb.slave()) {
  80.       mb.task();
  81.       delay(10);
  82.     }
  83.     if (case1) {
  84.       Serial.print(" = ");
  85.       lcd.setCursor(0, 1);
  86.       lcd.print("=               ");
  87.       lcd.setCursor(1, 1);
  88.       for (int i = 0; i < nilai; i++) {
  89.         Serial.print(coil[i] ? "0" : "1");
  90.         lcd.print(coil[i] ? "0" : "1");
  91.       }
  92.       Serial.println();
  93.       case1 = false;
  94.     }
  95.     if (case2) {
  96.       Serial.print(" = ");
  97.       lcd.setCursor(0, 1);
  98.       lcd.print("=               ");
  99.       lcd.setCursor(1, 1);
  100.       for (int i = 0; i < nilai; i++) {
  101.         Serial.print(idis[i] ? "0" : "1");
  102.         lcd.print(idis[i] ? "0" : "1");
  103.       }
  104.       Serial.println();
  105.       case2 = false;
  106.     }
  107.     if (case3) {
  108.       Serial.print(" = ");
  109.       lcd.setCursor(0, 1);
  110.       lcd.print("=               ");
  111.       lcd.setCursor(1, 1);
  112.       for (int i = 0; i < (nilai - 1); i++) {
  113.         Serial.print(hreg[i]);
  114.         Serial.print(',');
  115.         lcd.print(hreg[i]);
  116.         lcd.print(',');
  117.       }
  118.       Serial.println(hreg[nilai - 1]);
  119.       lcd.print(hreg[nilai - 1]);
  120.       case3 = false;
  121.     }
  122.     if (case4) {
  123.       Serial.print(" = ");
  124.       lcd.setCursor(0, 1);
  125.       lcd.print("=               ");
  126.       lcd.setCursor(1, 1);
  127.       for (int i = 0; i < (nilai - 1); i++) {
  128.         Serial.print(ireg[i]);
  129.         Serial.print(',');
  130.         lcd.print(ireg[i]);
  131.         lcd.print(',');
  132.       }
  133.       Serial.println(ireg[nilai - 1]);
  134.       lcd.print(ireg[nilai - 1]);
  135.       case4 = false;
  136.     }
  137.     if (case5) {
  138.       mb.readCoil(id, alamat, coil, 1);
  139.       while (mb.slave()) {
  140.         mb.task();
  141.         delay(10);
  142.       }
  143.       Serial.print(" = ");
  144.       Serial.println(coil[0] ? "0" : "1");
  145.       lcd.setCursor(0, 1);
  146.       lcd.print("=               ");
  147.       lcd.setCursor(1, 1);
  148.       lcd.print(coil[0] ? "0" : "1");
  149.       case5 = false;
  150.     }
  151.     if (case6) {
  152.       mb.readHreg(id, alamat, hreg, 1);
  153.       while (mb.slave()) {
  154.         mb.task();
  155.         delay(10);
  156.       }
  157.       Serial.print(" = ");
  158.       Serial.println(hreg[0]);
  159.       lcd.setCursor(0, 1);
  160.       lcd.print("=               ");
  161.       lcd.setCursor(1, 1);
  162.       lcd.print(hreg[0]);
  163.       case6 = false;
  164.     }
  165.     inputString = "";
  166.     stringComplete = false;
  167.   }
  168.   if (millis() - skr > 1000) {
  169.     skr = millis();
  170.     tampilLCD();
  171.     cacah++;
  172.     if (cacah > 5) cacah = 0;
  173.   }
  174. }
  175. void serialEvent() {
  176.   while (Serial.available()) {
  177.     char inChar = (char)Serial.read();
  178.     inputString += inChar;
  179.     if (inChar == 13) {
  180.       stringComplete = true;
  181.       skr = millis();
  182.     }
  183.   }
  184. }
  185. String getValue(String data, char separator, int index) {
  186.   int found = 0;
  187.   int strIndex[] = { 0, -1 };
  188.   int maxIndex = data.length() - 1;
  189.   for (int i = 0; i <= maxIndex && found <= index; i++) {
  190.     if (data.charAt(i) == separator || i == maxIndex) {
  191.       found++;
  192.       strIndex[0] = strIndex[1] + 1;
  193.       strIndex[1] = (i == maxIndex) ? i + 1 : i;
  194.     }
  195.   }
  196.   return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
  197. }
  198. void tampilLCD() {
  199.   switch (cacah) {
  200.     case 0:
  201.       inputString = "1,2,0,8";
  202.       stringComplete = true;
  203.       break;
  204.     case 1:
  205.       inputString = "1,2,8,8";
  206.       stringComplete = true;
  207.       break;
  208.     case 2:
  209.       inputString = "1,1,0,8";
  210.       stringComplete = true;
  211.       break;
  212.     case 3:
  213.       inputString = "1,1,8,8";
  214.       stringComplete = true;
  215.       break;
  216.     case 4:
  217.       inputString = "1,4,0,2";
  218.       stringComplete = true;
  219.       break;
  220.     case 5:
  221.       inputString = "1,3,0,2";
  222.       stringComplete = true;
  223.       break;
  224.   }
  225. }

Keterangan program:
  • File program di atas dapat diunduh di bagian akhir tulisan ini, dengan judul nama file: KodeProgram_ArduinoUno.ino.
  • Program di atas akan menampilkan kondisi Input Digital (Switch), kondisi Output Digital (LED/Relay), kondisi Input Analog (Potensio) dan kondisi Output Analog PWM (LED) setiap detik, baik di Serial Monitor (Virtual Terminal) maupun di tampilan LCD I2C. Apabila terlalu cepat, periode waktunya bisa diubah, sebagai contoh, diubah menjadi 5 detik, maka di baris 168, ubah angka 1000 (1 detik) menjadi 5000 (5 detik). 
  • Program di atas akan menerima pengubahan data melalui komunikasi serial, dengan format data = "id, fungsi, alamat, nilai", dengan contoh seperti ditunjukkan dalam Tabel berikut:
Untuk Outseal Nano:

ID

Fungsi

Alamat

Nilai

Keterangan

1

5

136

0

Memadamkan LED di R.1

1

5

143

1

Menyalakan LED di R.8

1

6

0

1000

Memberikan duty cycle pwm 1000 ke LED di R.7

1

6

0

800

Memberikan duty cycle pwm 800 ke LED di R.7

1

4

0

2

Membaca input Analog di A.1 dan A.2

1

2

0

8

Membaca input Switch di S.1 – S.8

1

1

0

8

Membaca output Relay di R.1 – R.8

1

3

0

1

Membaca duty cycle pwm di R.7


Untuk Outseal Mega: 

ID

Fungsi

Alamat

Nilai

Keterangan

1

5

144

0

Memadamkan LED di R.1

1

5

159

1

Menyalakan LED di R.16

1

6

0

1000

Memberikan duty cycle pwm 1000 ke LED di R.7

1

6

1

800

Memberikan duty cycle pwm 800 ke LED di R.8

1

4

0

2

Membaca input Analog di A.1 dan A.2

1

2

0

16

Membaca input Switch di S.1 – S.16

1

1

0

16

Membaca output Relay di R.1 – R.16

1

3

0

2

Membaca duty cycle pwm di R.7 dan R.8

 
  • Program di atas bisa digunakan untuk menampilkan data Outseal Nano dan Outseal Mega yang lebih dari 1 (yang terhubung dengan sambungan RS-485), dengan cara mengatur ID sesuai alamat Modbus Slave, yang diisikan pada Settings di Outseal Studio. 
  • Silahkan memperbanyak Case pada void tampilLCD() di baris program 198 - 225, sehingga dapat menampilkan data Modbus yang terdiri dari Coil, Input Diskrit, Input Register, dan Holding Register untuk setiap Outseal yang dihubungkan, yang ditampilkan secara berurutan, mulai dari Case1 ke Case berikutnya. Jumlah Case ini diatur dalam variabel cacah, yang di-nol-kan lagi setelah mencapai maksimum (lihat baris 172).

5. Jalankan simulasi Proteus dan buka Serial Monitor Arduino. Namun sebelumnya, atur dulu COMPIM. Isi di kolom Physical Port dengan COM yang berpasangan dengan Port COM di Arduino IDE. Atur semua baud rate ke 9600, seperti ditunjukkan pada gambar berikut:

Gambar 4. Sebelum simulasi Proteus dijalankan, atur baudrate COMPIM ke 9600, dan isi Physical port dengan COM yang berpasangan dengan Port COM di Arduino IDE

6. Jalankan simulasi Proteus dan buka Serial Monitor di Arduino IDE, kemudian perhatikan tampilan LCD I2C dan juga Serial Monitor. Seharusnya terlihat data 

Gambar 5(a). Simulasi rangkaian Outseal Nano di Proteus: data Modbus dapat ditampilkan di LCD I2C dan juga di Serial Monitor, serta data Coil dan Holding Register dapat diubah dari Serial Monitor

Gambar 5(b). Simulasi rangkaian Outseal Mega di Proteus: data Modbus dapat ditampilkan di LCD I2C dan juga di Serial Monitor, serta data Coil dan Holding Register dapat diubah dari Serial Monitor


7. Untuk penerapan secara riil, berhubung stok Outseal Nano saya habis (sudah terpasang semua di kontrol pemanas oven), maka di sini saya menunjukkan simulasinya dengan hardware Arduino Nano. Berikut ini gambar pengawatan rangkaian dengan Arduino Nano sebagai Outseal Nano, yang dirangkai dengan sebuah Dip Switch 8 jalur, 2 buah Potensio, sebuah Modul Relay 8 Channel, sebuah Arduino Uno, dan sebuah LCD I2C:

Gambar 6. Pengawatan rangkaian Penampil LCD I2C + Serial untuk Outseal Nano

8. Gambar berikut ini menunjukkan hasil implementasi dari aplikasi Penampil LCD + Serial sesuai langkah-langkah di atas:

Gambar 7. Rangkaian hardware riil dengan penampil LCD I2C dan baca tulis datanya dengan Serial Monitor

Gambar 8. Rangkaian hardware riil dengan penampil LCD I2C dan baca tulis datanya dengan Serial Bluetooth Terminal

Gambar 9. Rangkaian simulasi Outseal Nano di Proteus dengan penampil LCD dan baca tulis datanya dengan Serial Monitor

Gambar 10. Rangkaian simulasi Outseal Mega di Proteus dengan penampil LCD dan baca tulis datanya dengan Serial Monitor

9. Sampai di sini langkah-langkah implementasi Penampil LCD + Serial untuk Outseal Nano dan Outseal Mega. Untuk memudahkan rekan-rekan dalam mempelajari materi di halaman ini, rekan-rekan bisa mengunduh semua file yang diperlukan dalam pembuatan aplikasi di halaman ini di link berikut ini: https://drive.google.com/file/d/1k7DjA1dQhI0XXA9SSIkQ3FUzBKF1MHHH/view?usp=sharing

10. Agar lebih jelas, berikut ini video pembuatan Penampil LCD + Serial yang dibuat mengikuti materi di halaman ini. 

Video pembuatan aplikasi Penampil Data Modbus Outseal di LCD I2C dan Serial Monitor



No comments:

Post a Comment