繁体   English   中英

使用 Arduino 通过 CAN 总线发送和读取按钮 state

[英]Send and read the button state via CAN bus using Arduino

我打算使用通过 CAN 总线(MP2515)连接的 2 个独立的 Arduino 读取按钮输入的变化。 发射器将连接到带有内部下拉电阻的按钮,该引脚将用作外部中断。 我的参考来自这里 通过不为数据帧分配任何值(下面代码中的 canMsg1 和 canMsg2),是否足以让接收器理解输入引脚 state?

源代码使用digitalRead(pin)通过单个Arduino读写按钮的state。

CAN按摩发射器

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg1;
struct can_frame canMsg2;

MCP2515 mcp2515(10);

int incPin(2);
int decPin(3);
unsigned long current_time = 0;
unsigned long previous_time = 0;

void setup() {
  Serial.begin(9600);
  SPI.begin();

  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
  
  canMsg1.can_id = 0xAA;
  canMsg1.can_dlc = 1;
  canMsg2.can_id = 0xBB
  canMsg2.can_dlc = 1;

  pinMode(incPin, INPUT_PULLUP);
  pinMode(decnPin, INPUT_PULLUP);

  attachInterrupt(incpPin, inc, FALLING);
  attachInterrupt(decPin, dec, FALLING);              
}

void loop() {}

void inc() {
  current_time = millis();
  if (current_time - previous_time > 200) { //debouncing for 0.2s
    mcp2515.sendMessage(&canMsg1);
  }
  previous_time = current_time;
}

void dec() {
  current_time = millis();
  if (current_time - previous_time > 200) { //debouncing for 0.2s
    mcp2515.sendMessage(&canMsg2);
  }
  previous_time = current_time;
}

CAN消息的接收器/阅读器

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg1;
struct can_frame canMsg2;

MCP2515 mcp2515(10);

int pos = 0;
int up;
int down;

void setup() {
  Serial.begin(9600);
  SPI.begin();

  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();      
}

void loop() {
  if (mcp2515.readMessage(&canMsg1) == MCP2515::ERROR_OK) { //read CAN increment button message
    if (canMsg1.can_id==0xAA) {
      up = canMsg1.data[0];
      if (up == LOW) {
        pos++;
      } else {}
    }      
  }

  if (mcp2515.readMessage(&canMsg2) == MCP2515::ERROR_OK) { //read CAN decrement button message
    if (canMsg2.can_id==0xBB) {
      down = canMsg2.data[0];
      if (down == LOW) {
        pos--;
      } else {}
    }      
  }
}

你是对的,你的 CAN 事件不需要任何数据。 但是,为什么要将 can_dlc 设置为 1? 没有数据是 0 字节。

你可以试试这个:

  • 摆脱:

    结构 can_frame canMsg1; // 这些只是 hog global memory 没有实际用途。 结构 can_frame canMsg2;

将中断例程更改为:

void inc() {
  current_time = millis();
  if (current_time - previous_time > 200) { //debouncing for 0.2s
    mcp2515.beginPacket(0xAA);
    mcp2515.endPacket();
  }
  previous_time = current_time;
}

void dec() {
  current_time = millis();
  if (current_time - previous_time > 200) { //debouncing for 0.2s
    mcp2515.beginPacket(0xBB);
    mcp2515.endPacket();
  }
  previous_time = current_time;
}

我不知道 canMsg7 和 canMsg8 是什么。 也不是为什么你需要全局 memory 中的多个消息结构一次接收一个 CAN 消息......我真的认为没有必要。 由于您的数据包没有数据,因此接收也得到简化:

int loop() {
    if (mcp2515.parsePacket() != 0) {  // != 0 => we have fully received a packet.
        switch (mcp2515.packetId()) {
           case 0xAA:
               // inc switch was pressed
               // ...
               break;

           case 0xBB:
               // dec switch was pressed
               // ...
               break;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM