---
description: >-
  ใช้บอร์ด IOXESP32 + IOXESP32 CAN Bus shield ต่อเข้ากับ Arduino Uno + MCP2515
  รับ-ส่งข้อมูลเบื้องต้น
---

# การสื่อสารระหว่าง ESP32 กับ Arduino Uno ผ่าน CAN bus เบื้องต้น

## รับ-ส่งข้อความ Hello ผ่าน CAN bus

หัวข้อนี้ทดลองใช้ Arduino Uno สื่อสารกับ ESP32 ผ่าน CAN bus แต่เนื่องจากบอร์ด Arduino Uno ไม่รองรับการสื่อสารผ่าน CAN จึงจำเป็นต้องใช้[โมดูล MCP2515](https://www.ioxhop.com/product/1134/mcp2515-spi-can-bus-controller-and-driver-module) มาเป็นตัวกลาง ส่วนฝั่งบอร์ด IOXESP32 ใช้ [IOXESP32 CAN Bus shield](https://www.ioxhop.com/product/1145/ioxesp32-can-bus-shield) เป็นตัวกลาง

ให้ต่อวงจรดังนี้

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTPpa-Yyd3jRTxm8Sr2%2F-MTQ8u-edjiFDEZmS760%2FESP32_Arduin_CAN_1.png?alt=media\&token=35b65534-588b-4b80-bc30-e5395c085e72)

ให้ติดตั้งไลบารี่ MCP2515 โดยเข้าไปที่ [https://github.com/autowp/arduino-mcp2515](https://github.com/autowp/arduino-mcp2515) กดปุ่ม Code เลือก Download ZIP

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTPpa-Yyd3jRTxm8Sr2%2F-MTQLjwMy_waaBlgHc5b%2F2021-02-13_19-21-53.png?alt=media\&token=ab1a2f37-1b30-41e7-a872-28b16086e5f8)

จะได้ไฟล์ไลบารี่นามสกุล .zip มา ให้กด Sketch > Include Library เลือก Add .ZIP Library...

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTPpa-Yyd3jRTxm8Sr2%2F-MTQLrwGa-hYyIvWLuvq%2F2021-02-13_19-22-40.png?alt=media\&token=9d2cf979-e883-4888-9f84-97c8014f4a5c)

เลือกไฟล์ไลบารี่ได้ที่ได้ดาวน์โหลดมา แล้วกด Open

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTPpa-Yyd3jRTxm8Sr2%2F-MTQM22e1lkpacu5USfM%2F2021-02-13_19-23-32.png?alt=media\&token=81713e19-22ce-4cf1-91d9-9e0a24f2c414)

เมื่อติดตั้งเสร็จแล้ว โปรแกรม ArduinoIDE แจ้งเตือนดังรูป

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTPpa-Yyd3jRTxm8Sr2%2F-MTQMGGToNlY3PFmxc89%2F2021-02-13_19-25-08.png?alt=media\&token=89f2ba8f-d15e-4cd1-be3d-b75d52418fde)

ให้อัพโหลดโค้ดโปรแกรมต่อไปนี้ลงบอร์ด Arduino

```cpp
#include <SPI.h>
#include <mcp2515.h>
 
MCP2515 mcp2515(10);

void setup() {
  Serial.begin(115200);
 
  mcp2515.reset();
  mcp2515.setBitrate(CAN_125KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
}
 
void loop() {
  char *text = "Hello!";
  
  struct can_frame frame;
  frame.can_id = 0x7FF;
  frame.can_dlc = strlen(text);
  strcpy(frame.data, text);

  mcp2515.sendMessage(&frame);

  Serial.print("Send '");
  Serial.print(text);
  Serial.println("' via CAN bus");
  delay(500);
}
```

และอัพโหลดโค้ดโปรแกรมต่อไปนี้ลงบอร์ด ESP32

```cpp
#include "driver/gpio.h"
#include "driver/can.h"

void setup() {
  Serial.begin(115200);

  //Initialize configuration structures
  can_general_config_t g_config =  {
    .mode = CAN_MODE_NORMAL,
    .tx_io = GPIO_NUM_26,
    .rx_io = GPIO_NUM_27,
    .clkout_io = (gpio_num_t)CAN_IO_UNUSED,
    .bus_off_io = (gpio_num_t)CAN_IO_UNUSED,
    .tx_queue_len = 5,
    .rx_queue_len = 5,
    .alerts_enabled = CAN_ALERT_NONE,
    .clkout_divider = 0
  };

  can_timing_config_t t_config = CAN_TIMING_CONFIG_125KBITS();
  can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL();

  //Install CAN driver
  if (can_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    printf("Driver installed\n");
  } else {
    printf("Failed to install driver\n");
    return;
  }

  //Start CAN driver
  if (can_start() == ESP_OK) {
    printf("Driver started\n");
  } else {
    printf("Failed to start driver\n");
    return;
  }
}

void loop() {
  //Wait for message to be received
  can_message_t message;
  if (can_receive(&message, pdMS_TO_TICKS(10000)) == ESP_OK) {
    printf("Message received\n");
  } else {
    printf("Failed to receive message\n");
    return;
  }

  char text[8];
  memset(text, 0, 8);
  memcpy(text, message.data, message.data_length_code);
  Serial.print(">>> ");
  Serial.println(text);
}
```

เปิด Serial Monitor ขึ้นมา จะพบว่าบอร์ด Arduino Uno สามารถส่งข้อมูลไปยังบอร์ด ESP32 ผ่าน CAN bus ได้แล้ว

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTPpa-Yyd3jRTxm8Sr2%2F-MTQNab7JvGEROB7JXVq%2F2021-02-13_19-33-59.png?alt=media\&token=22495139-999a-440f-abe1-a5d2d78c2dea)

## รับ-ส่งค่าแอนะล็อกผ่าน CAN bus

หัวข้อนี้ใช้ Arduino Uno อ่านค่าแอนะล็อกจากวอลุ่ม จากนั้นส่งค่าแอนะล็อกที่อ่านได้ให้ ESP32 แล้วแสดงผลใน Serial Monitor เป็นตัวอย่างการใช้บอร์ด Arduino Uno ช่วยขยายขาต่อใช้งานให้ ESP32

ให้ต่อวงจรดังนี้

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTQPT4HFhtISzGMe3PJ%2F-MTQY8SakXhrJv4qVTJm%2FPicture1987.png?alt=media\&token=51910426-2f3e-4a0e-93a4-25cdbc41c22b)

ที่ฝั่ง Arduino Uno ให้อัพโหลดโค้ดโปรแกรมต่อไปนี้

```cpp
#include <SPI.h>
#include <mcp2515.h>
 
MCP2515 mcp2515(10);
 
void setup() {
  Serial.begin(115200);
 
  mcp2515.reset();
  mcp2515.setBitrate(CAN_125KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();

  Serial.println("------- CAN ----------");
}
 
void loop() {
  uint16_t adc = analogRead(A0);
  
  struct can_frame frame;
  frame.can_id = 0x7FF;
  frame.can_dlc = 2;
  frame.data[0] = adc >> 8;
  frame.data[1] = adc & 0xFF;

  mcp2515.sendMessage(&frame);
  delay(50);
}
```

ที่ฝั่งบอร์ด ESP32 ให้อัพโหลดโปรแกรมต่อไปนี้

```cpp
#include "driver/gpio.h"
#include "driver/can.h"

void setup() {
  Serial.begin(115200);

  //Initialize configuration structures
  can_general_config_t g_config =  {
    .mode = CAN_MODE_NORMAL,
    .tx_io = GPIO_NUM_26,
    .rx_io = GPIO_NUM_27,
    .clkout_io = (gpio_num_t)CAN_IO_UNUSED,
    .bus_off_io = (gpio_num_t)CAN_IO_UNUSED,
    .tx_queue_len = 5,
    .rx_queue_len = 5,
    .alerts_enabled = CAN_ALERT_NONE,
    .clkout_divider = 0
  };

  can_timing_config_t t_config = CAN_TIMING_CONFIG_125KBITS();
  can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL();

  //Install CAN driver
  if (can_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    printf("Driver installed\n");
  } else {
    printf("Failed to install driver\n");
    return;
  }

  //Start CAN driver
  if (can_start() == ESP_OK) {
    printf("Driver started\n");
  } else {
    printf("Failed to start driver\n");
    return;
  }
}

void loop() {
  //Wait for message to be received
  can_message_t message;
  if (can_receive(&message, pdMS_TO_TICKS(10000)) == ESP_OK) {
    printf("Message received\n");
  } else {
    printf("Failed to receive message\n");
    return;
  }

  uint16_t adc = (message.data[0] << 8) | message.data[1];
  Serial.println(adc);
}
```

เปิด Serial Monitor ฝั่ง ESP32 ขึ้นมา จะพบว่าฝั่ง ESP32 สามารถรับค่าแอนะล็อกที่ส่งผ่าน CAN bus มาได้แล้ว

![](https://1080526838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8K8I5jcjPFVEdsdGO2%2F-MTQPT4HFhtISzGMe3PJ%2F-MTQZaLiVDaiiDcvsK0Q%2F2021-02-13_20-24-38.png?alt=media\&token=c3106ba3-57a5-4b70-bc32-6c1b7684b6f8)

แก้ไขโค้ดโปรแกรมเล็กน้อย ให้ IOXESP32 แสดงผลค่าที่อ่านได้บน 4-Digit shield  ได้ผลตามวีดีโอด้านล่างนี้

{% embed url="https://youtu.be/UwQGHAaaERo" %}

