【问题标题】:Send and read the button state via CAN bus using Arduino使用 Arduino 通过 CAN 总线发送和读取按钮状态
【发布时间】:2023-01-24 16:22:27
【问题描述】:

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

使用 digitalRead(pin) 的原始代码通过单个 Arduino 读取和稍后写入按钮的状态。

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(&canMsg7) == MCP2515::ERROR_OK) { //read CAN increament button massage
    if (canMsg1.can_id==0xAA) {
      up = canMsg1.data[0];
      if (up == LOW) {
        pos++;
      } else {}
    }      
  }

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

【问题讨论】:

    标签: button arduino interrupt can-bus


    【解决方案1】:

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

    你可以试试这个:

    • 摆脱 :

      结构 can_frame canMsg1; // 这些只是占用全局内存,没有实际用途。 结构 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 是什么。也不是为什么您需要全局内存中的多个消息结构来一次接收一个 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      相关资源
      最近更新 更多