Arduino와 Atom matrix 간의 CAN 통신

27037 단어 Arduinom5stackcantech
표시된 내용이 있으니 적어 두세요.

1. 연결도



[전송 측면]
・Arduino Uno
· MCP2515CAN 버스 모듈
https://www.amazon.co.jp/gp/product/B07F68GHBJ/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
[수신자]
・Atom matrix
• M5 Stack용 CAN-BUS 유닛

2. 동작하는 모습


보시다시피 보드의 버튼을 눌러 RGB의 색상 정보를 보냅니다.
동시에 를 눌러 색상을 작성할 수 있습니다.

3. 프로그램 해설


[전송 측면]
연결 버튼의 GPIO 단자를 모두 내부 위로 설정합니다.
pinMode(red_button, INPUT_PULLUP);
pinMode(green_button, INPUT_PULLUP);
pinMode(blue_button, INPUT_PULLUP);
판의 케이블 연결이 간단해졌습니다.
포트가 LOW로 떨어지는 것을 트리거하여 상태를 변경합니다.
byte rgb[] = {0x00,0x00,0x00}
이 배열은 왼쪽부터 R, G, B의 배열이다
빨간색 버튼을 누르면 {0xFF, 0x00, 0x00}
녹색 버튼을 누르면 {0x00, 0xFF, 0x00}
파란색 버튼을 누르면 {0x00, 0x00, 0xFF}
.
빨간색과 녹색을 동시에 누르면 {0xFF, 0xFF, 0x00}이 노랗게 변합니다.
그렇다면 MCP 2515를 사용할 때 먼저 이쪽 기사를 참고해 프로그램 라이브러리에 넣었다.
https://qiita.com/covao/items/d30fa5e36470bbee3be7
이번 범례도 이쪽 코드를 개조했다.
다음 그림은 이 글의 코드를 그대로 이동시켜 작은 백으로 파형을 감시하는 그림이다.

CH1은 CAN입니다.H, CH2는 CANL, 빨간색은 CH1과 CH2의 차이입니다.
실제로 이 빨간색 파형으로 신호를 식별한다.
소음이 잘 취소되었다.
이 파형은 MCP2515 모듈의 점프선을 단축시켜 120Ω의 단말기 저항을 유효하게 한다.
수신 측면의 CAN-BUS 유닛에도 단말기 저항을 설치하는 게 좋을 것 같았는데 켜보니 전압이 반으로 바뀌어 켜지지 않았다.그래서 통신이 성공했다.
어느 쪽이 전압 레벨에 적합한지 아직 알아내지 못했는데..
[수신자]
M5.dis.drawpix(j,CRGB(rx_frame.data.u8[0],rx_frame.data.u8[1],rx_frame.data.u8[2]))
이 부분에 LED가 표시되고 CRGB(X, X, X)의 부분은 왼쪽부터 R, G, B의 값으로 들어갑니다.
이전 for (intj=0; j<25; j++) {에서 0에서 24번째 픽셀 순서로 표시됩니다.
CAN-ID: 10 수신 시 LED가 켜지지만 수신 시 Disp가 켜집니다.clear () 함수로 닫습니다.
이 코드는 M5 Atom의 견본 코드를 개조한 것이다.
Arduino IDE를 통해 파일 → 스케치 예 → M5 Atom → Unit → CAN 코드를 표시할 수 있습니다.
여기 기사도 참고했어.
https://knt60345blog.com/can-bus/
CAN의 통신 속도는 송신 측과 수신 측이 일치해야 한다.

4. 코드


송신 측면
#include <mcp_can.h> 
#include <SPI.h>

unsigned long rxId;
byte len;
byte rgb[] = {0x00,0x00,0x00};

MCP_CAN CAN0(10);// CAN0 CS: pin 10

int red_button = 7;
int green_button = 6;
int blue_button = 5;
int red_buttonState = 0;
int green_buttonState = 0;
int blue_buttonState = 0;

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

  // init CAN0 bus, baudrate: 500kbps@8MHz
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK){
    Serial.println("CAN0: Init OK!");
    CAN0.setMode(MCP_NORMAL);
  } else{ 
    Serial.println("CAN0: Init Fail!");
  }

  //pinMode(ledPin, OUTPUT);      
  pinMode(red_button, INPUT_PULLUP);
  pinMode(green_button, INPUT_PULLUP);
  pinMode(blue_button, INPUT_PULLUP);
}

void loop(){
  
  red_buttonState = digitalRead(red_button);
  green_buttonState = digitalRead(green_button);
  blue_buttonState = digitalRead(blue_button);
  
  if (red_buttonState == LOW) {
    rgb[0]={0xFF};
  } 
  else{
    rgb[0]={0x00};
  }

    if (green_buttonState == LOW) {
    rgb[1]={0xFF};
  } 
  else{
    rgb[1]={0x00};
  }

    if (blue_buttonState == LOW) {
    rgb[2]={0xFF};
  } 
  else{
    rgb[2]={0x00};
  }

  CAN0.sendMsgBuf(0x100, 0, 8, rgb);
  Serial.print(rgb[0],HEX);
  Serial.print(rgb[1],HEX);
  Serial.print(rgb[2],HEX);
  Serial.println();
    
  delay(200); //ここの時間変更でボタン押下のチャタリング対策できる
}
수신 측면
#include <M5Atom.h>
#include "ESP32CAN.h"
#include "CAN_config.h"

#define TX GPIO_NUM_26
#define RX GPIO_NUM_32

CAN_device_t CAN_cfg;

int i,j = 0;

void disp_clear(){
  for(int j=0; j<25; j++){
    M5.dis.drawpix(j, 0x000000); //black
  }
}
void setup() {
  M5.begin(true, false, true);
  Serial.println("CAN Unit Send&Received");

  CAN_cfg.speed = CAN_SPEED_500KBPS;  //Set the Can speed
  CAN_cfg.tx_pin_id = TX; //Set the Pin foot
  CAN_cfg.rx_pin_id = RX;

  CAN_cfg.rx_queue = xQueueCreate(10,sizeof(CAN_frame_t));
  ESP32Can.CANInit(); // Init CAN Module
}

void loop() {
  CAN_frame_t rx_frame;

  if(xQueueReceive(CAN_cfg.rx_queue,&rx_frame, 3*portTICK_PERIOD_MS)==pdTRUE){

    Serial.print(millis());   // 受信時間
    Serial.print(",");
    Serial.print(rx_frame.MsgID,HEX);   // Msg ID
    Serial.print(",");
    Serial.print(rx_frame.FIR.B.DLC);   // DLC
    Serial.println(",");

    for(int i = 0; i < 3; i++){
      Serial.print(rx_frame.data.u8[i],HEX);   // CANデータ
    }
    Serial.println();
    
    if(rx_frame.MsgID==256){ //CAN-ID:0x100が10進で256なので。IDは何でもいい。
      Serial.println("received");
      for(int j=0; j<25; j++){
        M5.dis.drawpix(j,CRGB(rx_frame.data.u8[0],rx_frame.data.u8[1],rx_frame.data.u8[2]));
      }
    }
  }
  else {
    disp_clear();
  }

  M5.update();
  delay(200);

}
그게 다야.

좋은 웹페이지 즐겨찾기