A. Kompetensi
3.1 Menguraikan
konsep dasar komunikasi data serial dan protokol CAN (Controller Area Network).
3.2
Mengidentifikasi jenis-jenis perangkat keras dan perangkat lunak yang digunakan
dalam komunikasi CAN.
3.3 Menguraikan
proses konfigurasi modul CAN (MCP2515) pada Arduino.
4.1 Memasang dan
mengonfigurasi modul CAN (MCP2515) pada Arduino Nano.
4.2 Mengoperasikan
komunikasi data serial menggunakan protokol CAN pada Arduino.
4.3 Mengembangkan
program Arduino untuk mengirim dan menerima data melalui jaringan CAN.
B. Dasar Teori
Arduino
Nano
Arduino Nano
adalah mikrokomputer kecil yang berbasis pada mikrokontroler ATmega328P.
Ukurannya yang kecil membuatnya ideal untuk proyek-proyek dengan ruang
terbatas. Arduino Nano memiliki sejumlah pin digital dan analog yang dapat
digunakan untuk menghubungkan sensor, modul, dan perangkat lainnya.
Mikrokomputer ini juga dapat diprogram menggunakan bahasa pemrograman C++
melalui Arduino IDE.
MCP2515 CAN Module
MCP2515 adalah modul CAN controller yang digunakan untuk mengimplementasikan komunikasi CAN bus pada perangkat mikrokontroler yang tidak memiliki fitur CAN bawaan. Modul ini menggunakan SPI (Serial Peripheral Interface) untuk berkomunikasi dengan Arduino Nano.
Cara Kerja: MCP2515 menerima
data dari Arduino Nano melalui SPI, kemudian data tersebut dikirimkan ke bus
CAN melalui transceiver TJA1050. Modul ini juga dapat menerima data dari bus
CAN dan mengirimkannya kembali ke Arduino untuk diproses.
Relay Module
Relay Module adalah perangkat elektromekanis
yang berfungsi sebagai saklar yang dikendalikan oleh sinyal elektronik. Relay
dapat digunakan untuk mengendalikan perangkat bertegangan tinggi menggunakan
sinyal dari Arduino Nano yang bertegangan rendah. Setiap relay pada modul dapat
digunakan untuk mengontrol perangkat seperti lampu, motor, atau perangkat
elektronik lainnya.
Cara Kerja: Arduino Nano mengirimkan sinyal digital ke relay module. Ketika sinyal tersebut diterima, relay akan mengaktifkan atau menonaktifkan sirkuit yang terhubung. Dengan menggunakan relay, kita dapat mengontrol perangkat eksternal yang membutuhkan arus atau tegangan yang lebih tinggi dari yang dapat ditangani langsung oleh Arduino.
C.
Alat dan Bahan:
·
Laptop
·
Arduino Nano
·
Software Arduino IDE
·
MCP2515 CAN Module
·
Relay Module
·
Kabel Jumper
·
Push Button
·
Breadboard
· Baterai/Power Supply 12V
D. Rangkaian
E. Program
Board 1 :
#include <mcp_can.h>
#include <SPI.h>
#include <math.h>
MCP_CAN CAN0(10);
const int relayPins[4] = {3, 5, 6, 9};
const int buttonPins[4] = {A3, 4, 7, 8};
const int ntcPin =
A2;
const int loadPin =
A6;
const int INTPin = 2;
// variable ntc
int Vo;
float R1 = 10000;
float logR2, R2, T, Tc, Tf;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
// button variabel
byte data_btn[4] = {1, 1, 1, 1};
byte prev_data_btn[4] = {1, 1, 1, 1};
// Variable kirim data
byte data_tx[6] = {1, 1, 1, 1, 0, 0};
byte prev_data_tx[6] = {1, 1, 1, 1, 0, 0};
// Variabel terima data
byte data_rx[6];
byte prev_data_rx[6];
long unsigned int rxId;
unsigned char len;
unsigned char rxBuf[6];
unsigned long curMill = 0;
unsigned long prevMill = 0;
unsigned long interval1 = 300;
unsigned long interval2 = 600;
void btnHandler() {
for (int i = 0; i < 4; i++) {
data_btn[i] = digitalRead(buttonPins[i]);
}
}
void prevBtnHandler() {
for (int i = 0; i < 4; i++) {
prev_data_btn[i] = data_btn[i];
}
data_tx[4] = ntcHandler();
data_tx[5] = loadHandler();
}
void btnToSwt() {
// Tombol 1
if (prev_data_btn[0] == 1 and data_btn[0] == 0) {
if (data_tx[0] == 1) {
data_tx[0] = 0;
}
else {
data_tx[0] = 1;
}
}
// Tombol 2
if (prev_data_btn[1] == 1 and data_btn[1] == 0) {
if (data_tx[1] == 1) {
data_tx[1] = 0;
}
else {
data_tx[1] = 1;
}
}
// Tombol 3
if (prev_data_btn[2] == 1 and data_btn[2] == 0) {
if (data_tx[2] == 1) {
data_tx[1] = 0;
data_tx[2] = 0;
}
else {
data_tx[2] = 1;
}
if (data_tx[3] == 0){
data_tx[3] = 1;
}
}
// Tombol 4
if (prev_data_btn[3] == 1 and data_btn[3] == 0) {
if (data_tx[1] == 0 and data_tx[2] == 0) {
data_tx[2] = 1;
data_tx[3] = 0;
}
else if (data_tx[3] == 1) {
data_tx[3] = 0;
}
else {
data_tx[3] = 1;
}
}
}
void prevInputHandler() {
for (int i = 0; i < 6; i++) {
prev_data_tx[i] = data_tx[i];
}
}
bool cekInputChange() {
bool inpObs = false;
for (int i = 0; i < 6; i++) {
if (data_tx[i] != prev_data_tx[i]) {
inpObs = true;
}
}
return inpObs;
}
float ntcHandler() {
int ntcValue = analogRead(ntcPin);
float resistance = (1023.0 / ntcValue - 1.0) * 10000; // NTC 10K
Ohm thermistor
float temperature = 1.0 / (log(resistance
/ 10000) / 3950 + 1.0 / 298.15) - 273.15; // Convert to temperature
return temperature;
}
float loadHandler() {
int dataAna = analogRead(loadPin);
float V = map(dataAna, 0, 1023, 0, 5);
float I = V / 0.22;
return I;
}
void inputHandler() {
data_tx[0] = digitalRead(buttonPins[0]);
data_tx[1] = digitalRead(buttonPins[1]);
data_tx[2] = digitalRead(buttonPins[2]);
data_tx[3] = digitalRead(buttonPins[3]);
data_tx[4] = ntcHandler();
data_tx[5] = loadHandler();
}
void outputHandler() {
for (int i = 0; i < 4; i++) {
if (data_rx[i] != prev_data_rx[i]) {
digitalWrite(relayPins[i], data_rx[i]);
}
}
}
void prevRelayHandler() {
for (int i = 0; i < 4; i++) {
prev_data_rx[i] = data_rx[i];
}
}
void kirimData() {
byte sndStat = CAN0.sendMsgBuf(0x110, 0, 6, data_tx);
if (sndStat == CAN_OK) {
Serial.print("\t
Berhasil terkirim!");
}
else {
Serial.print("\t
Gagal terkirim!");
}
// delay(50);
}
void terimaData() {
if (!digitalRead(INTPin)) {
CAN0.readMsgBuf(&rxId, &len, rxBuf);
for (int i = 0; i < 6; i++) {
data_rx[i] = (rxBuf[i]);
}
Serial.print("\t
Menerima data");
}
// delay(50);
}
void tampilData() {
Serial.print("\nData:
");
for (int i = 0; i < 6; i++) {
Serial.print(data_tx[i]);
Serial.print("
");
}
Serial.print(" |
");
for (int i = 0; i < 6; i++) {
Serial.print(data_rx[i]);
Serial.print("
");
}
}
void setup() {
Serial.begin(9600);
if (CAN0.begin(MCP_ANY, CAN_500KBPS,
MCP_16MHZ) == CAN_OK) {
Serial.println("Sukses
melakukan inisialisasi MCP2515!");
}
else {
Serial.println("Gagal
melakukan inisialisasi MCP2515 :(");
}
CAN0.setMode(MCP_NORMAL);
pinMode(ntcPin, INPUT);
pinMode(loadPin, INPUT);
pinMode(INTPin, INPUT);
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], 1);
}
for (int i = 0; i < 4; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
}
void loop() {
curMill = millis();
if (curMill - prevMill < interval1) {
tampilData();
btnHandler();
btnToSwt();
prevBtnHandler();
if (cekInputChange()) {
kirimData();
}
else {
terimaData();
}
prevInputHandler();
}
else if (curMill -
prevMill < interval2) {
outputHandler();
prevRelayHandler();
}
else {
prevMill = curMill;
}
}
Board 2 :
#include <mcp_can.h>
#include <SPI.h>
#include <math.h>
MCP_CAN CAN0(10);
const int relayPins[4] = {3, 5, 6, 9};
const int buttonPins[4] = {A3, 4, 7, 8};
const int ntcPin =
A2;
const int loadPin =
A6;
const int INTPin = 2;
// variable ntc
int Vo;
float R1 = 10000;
float logR2, R2, T, Tc, Tf;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
// button variabel
byte data_btn[4] = {1, 1, 1, 1};
byte prev_data_btn[4] = {1, 1, 1, 1};
// Variable kirim data
byte data_tx[6] = {1, 1, 1, 1, 0, 0};
byte prev_data_tx[6] = {1, 1, 1, 1, 0, 0};
// Variabel terima data
byte data_rx[6];
byte prev_data_rx[6];
long unsigned int rxId;
unsigned char len;
unsigned char rxBuf[6];
unsigned long curMill = 0;
unsigned long prevMill = 0;
unsigned long interval1 = 300;
unsigned long interval2 = 600;
void btnHandler() {
for (int i = 0; i < 4; i++) {
data_btn[i] = digitalRead(buttonPins[i]);
}
}
void prevBtnHandler() {
for (int i = 0; i < 4; i++) {
prev_data_btn[i] = data_btn[i];
}
data_tx[4] = ntcHandler();
data_tx[5] = loadHandler();
}
void btnToSwt() {
// Tombol 1
if (prev_data_btn[0] == 1 and data_btn[0] == 0) {
if (data_tx[0] == 0 and data_tx[1] == 0){
data_tx[1] = 1;
}
else if (data_tx[0] == 1) {
data_tx[0] = 0;
data_tx[1] = 1;
}
else {
data_tx[0] = 1;
}
}
// Tombol 2
if (prev_data_btn[1] == 1 and data_btn[1] == 0) {
if (data_tx[0] == 0 and data_tx[1] == 0){
data_tx[0] = 1;
}
else if (data_tx[1] == 1) {
data_tx[1] = 0;
data_tx[0] = 1;
}
else {
data_tx[1] = 1;
}
}
// Tombol 3
if (prev_data_btn[2] == 1 and data_btn[2] == 0) {
if (data_tx[0] == 0 and data_tx[1] == 0) {
data_tx[0] = 1;
data_tx[1] = 1;
}
else {
data_tx[0] = 0;
data_tx[1] = 0;
}
}
// Tombol 4
data_tx[2] = data_btn[3];
}
void prevInputHandler() {
for (int i = 0; i < 6; i++) {
prev_data_tx[i] = data_tx[i];
}
}
bool cekInputChange() {
bool inpObs = false;
for (int i = 0; i < 6; i++) {
if (data_tx[i] != prev_data_tx[i]) {
inpObs = true;
}
}
return inpObs;
}
float ntcHandler() {
int ntcValue = analogRead(ntcPin);
float resistance = (1023.0 / ntcValue - 1.0) * 10000; // NTC 10K
Ohm thermistor
float temperature = 1.0 / (log(resistance
/ 10000) / 3950 + 1.0 / 298.15) - 273.15; // Convert to temperature
return temperature;
}
float loadHandler() {
int dataAna = analogRead(loadPin);
float V = map(dataAna, 0, 1023, 0, 5);
float I = V / 0.22;
return I;
}
void inputHandler() {
data_tx[0] = digitalRead(buttonPins[0]);
data_tx[1] = digitalRead(buttonPins[1]);
data_tx[2] = digitalRead(buttonPins[2]);
data_tx[3] = digitalRead(buttonPins[3]);
data_tx[4] = ntcHandler();
data_tx[5] = loadHandler();
}
void outputHandler() {
for (int i = 0; i < 4; i++) {
if (data_rx[i] != prev_data_rx[i]) {
digitalWrite(relayPins[i], data_rx[i]);
}
}
}
void prevRelayHandler() {
for (int i = 0; i < 4; i++) {
prev_data_rx[i] = data_rx[i];
}
}
void kirimData() {
byte sndStat = CAN0.sendMsgBuf(0x110, 0, 6, data_tx);
if (sndStat == CAN_OK) {
Serial.print("\t
Berhasil terkirim!");
}
else {
Serial.print("\t
Gagal terkirim!");
}
// delay(50);
}
void terimaData() {
if (!digitalRead(INTPin)) {
CAN0.readMsgBuf(&rxId, &len, rxBuf);
for (int i = 0; i < 6; i++) {
data_rx[i] = (rxBuf[i]);
}
Serial.print("\t
Menerima data");
}
// delay(50);
}
void tampilData() {
Serial.print("\nData:
");
for (int i = 0; i < 6; i++) {
Serial.print(data_tx[i]);
Serial.print("
");
}
Serial.print(" |
");
for (int i = 0; i < 6; i++) {
Serial.print(data_rx[i]);
Serial.print("
");
}
}
void setup() {
Serial.begin(9600);
if (CAN0.begin(MCP_ANY, CAN_500KBPS,
MCP_16MHZ) == CAN_OK) {
Serial.println("Sukses
melakukan inisialisasi MCP2515!");
}
else {
Serial.println("Gagal
melakukan inisialisasi MCP2515 :(");
}
CAN0.setMode(MCP_NORMAL);
pinMode(ntcPin, INPUT);
pinMode(loadPin, INPUT);
pinMode(INTPin, INPUT);
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], 1);
}
for (int i = 0; i < 4; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
}
void loop() {
curMill = millis();
if (curMill - prevMill < interval1) {
tampilData();
btnHandler();
btnToSwt();
prevBtnHandler();
if (cekInputChange()) {
kirimData();
}
else {
terimaData();
}
prevInputHandler();
}
else if (curMill -
prevMill < interval2) {
outputHandler();
prevRelayHandler();
}
else {
prevMill = curMill;
}
}
F. Langkah-langkah:
1.
Gunakan dua papan PCB Arduino Nano yang telah disediakan.
2.
Sambungkan modul MCP2515 CAN ke pin header yang telah disediakan
di masing-masing papan PCB Arduino Nano.
·
Hubungkan pin VCC dari MCP2515 ke pin 5V di Arduino Nano.
·
Hubungkan pin GND dari MCP2515 ke pin GND di Arduino Nano.
·
Hubungkan pin CS dari MCP2515 ke pin D10 di Arduino Nano.
·
Hubungkan pin SO dari MCP2515 ke pin D12 di Arduino Nano.
·
Hubungkan pin SI dari MCP2515 ke pin D11 di Arduino Nano.
·
Hubungkan pin SCK dari MCP2515 ke pin D13 di Arduino Nano.
·
Hubungkan pin INT dari MCP2515 ke pin D2 di Arduino Nano.
3. Sambungkan push button ke pin
header yang telah disediakan di papan PCB Arduino Nano sebagai input pada
masing-masing Arduino Nano.
·
Untuk Board 1, gunakan konfigurasi pin sebagai berikut:
·
Push Button 1 ke pin D3 untuk menghidupkan Relay 1 (Fog Lamp).
·
Push Button 2 ke pin D5 untuk menghidupkan Relay 2 (Lampu Kota).
·
Push Button 3 ke pin D6 untuk menghidupkan Relay 3 (Lampu Dekat).
·
Push Button 4 ke pin D9 untuk menghidupkan Relay 4 (Lampu Jauh).
·
Untuk Board 2, gunakan konfigurasi pin sebagai berikut:
·
Push Button 1 ke pin A3 untuk menghidupkan Relay 1 (Lampu Sein
Kiri).
·
Push Button 2 ke pin D4 untuk menghidupkan Relay 2 (Lampu Sein
Kanan).
·
Push Button 3 ke pin D7 untuk menghidupkan Relay 1 dan Relay 2
(Lampu Hazard).
·
Push Button 8 ke pin D8 untuk menghidupkan Relay 7 (Lampu Rem).
·
Sambungkan satu sisi dari masing-masing tombol ke pin input yang
sesuai di Arduino Nano.
·
Sambungkan sisi lainnya dari masing-masing tombol ke ground (GND)
di Arduino Nano.
4.
Sambungkan relay module ke pin header yang telah disediakan di
papan PCB Arduino Nano sebagai output pada masing-masing Arduino Nano.
·
Untuk Board 1, gunakan konfigurasi pin sebagai berikut:
·
Relay 1 (Fog Lamp) ke pin D3.
·
Relay 2 (Lampu Kota) ke pin D5.
·
Relay 3 (Lampu Dekat) ke pin D6.
·
Relay 4 (Lampu Jauh) ke pin D9.
·
Untuk Board 2, gunakan konfigurasi pin sebagai berikut:
·
Relay 1 (Lampu Sein Kiri) ke pin A3.
·
Relay 2 (Lampu Sein Kanan) ke pin D4.
·
Relay 1 dan Relay 2 (Lampu Hazard) ke pin D7.
·
Relay 7 (Lampu Rem) ke pin D8.
·
Sambungkan pin IN dari masing-masing relay module ke pin output
yang sesuai di Arduino Nano.
·
Sambungkan pin VCC dari relay module ke pin 5V di Arduino Nano.
·
Sambungkan pin GND dari relay module ke pin GND di Arduino Nano.
5.
Berikan input tegangan 12V pada pad input yang telah disediakan.**
·
Sambungkan sumber daya 12V ke pad input 12V pada PCB.
·
Pastikan polaritas (+) dan (-) dari sumber daya 12V sesuai dengan
pad input di PCB.
·
Tegangan 12V ini akan di-step down menjadi 5V menggunakan
regulator tegangan yang ada di PCB.
· Tegangan 5V ini akan digunakan untuk menghidupkan relay module dan sebagai input daya untuk modul MCP2515 CAN.
G. Tugas
1.
Jelaskan bagaimana cara kerja rangkaian ini?
2.
Selanjutnya paste program yang memungkinkan dua board Arduino saling berkomunikasi. Pada board
pertama, tombol push button digunakan untuk menghidupkan relay pada board
kedua. Sebaliknya, pada board kedua, tombol push button digunakan untuk
menghidupkan relay pada board pertama.
Jika program eror bisa gunakan link Drive
3.
Buatlah
laporan praktikum dan dikumpulkan!
No comments:
Post a Comment