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

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

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

หัวข้อนี้ทดลองใช้ Arduino Uno สื่อสารกับ ESP32 ผ่าน CAN bus แต่เนื่องจากบอร์ด Arduino Uno ไม่รองรับการสื่อสารผ่าน CAN จึงจำเป็นต้องใช้โมดูล MCP2515 มาเป็นตัวกลาง ส่วนฝั่งบอร์ด IOXESP32 ใช้ IOXESP32 CAN Bus shield เป็นตัวกลาง

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

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

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

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

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

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

#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

#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 ได้แล้ว

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

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

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

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

#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 ให้อัพโหลดโปรแกรมต่อไปนี้

#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 มาได้แล้ว

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

Last updated