Sunday, September 29, 2024

Pengendalian Relay dengan Menggunakan Komunikasi CAN Bus pada Arduino Nano

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.

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]);
    }
  }
  //  digitalWrite(relayPins[0], data_rx[0]);
  //  digitalWrite(relayPins[1], data_rx[1]);
  //  digitalWrite(relayPins[2], data_rx[2]);
  //  digitalWrite(relayPins[3], data_rx[3]);
}

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;
  }
}

Jika program eror bisa gunakan link Drive

3.      Buatlah laporan praktikum dan dikumpulkan!

 

 

 

 

 

  

No comments:

Post a Comment

Ujian Klaster UKK 2025

 25 Maret 2025 Silahkan Upload hasil Pekerjaan Anda Di Link Berikut Disini atau https://forms.gle/264GGHp3368Q65Jw7