hiro yamamoto works

マイコンハード、ソフトを作ったりしています。
お家や現場のお困りごと解決に!
内容利用は自己責任でお願いします。

CANバスモジュールを使ってデータ送受信する。(RP2040 受信)

2023-07-15 14:27:40 | CAN通信

受信側スケッチです。改善の余地あり(ちょっと直しました。)
ChatGPT先生にいっぱいヒントを頂きました。
参考:コンパイル途中に次のようなメッセージ表示されていました。
警告:ライブラリAdafruit_CANはアーキテクチャsamdに対応したものであり、
アーキテクチャrp2040で動作するこのボードとは互換性がないかもしれません。
AdafruitのMCP2515ライブラリからのメッセージと思われます。

/*   Adafruit MCP2515_CAN_Receiver_Exampleを改変しています。
一部省略 転記ミスや表示されてない記号があるかも <は半角に直して */
#include<Adafruit_MCP2515.h>
#define CS_PIN    20
// Set CAN bus baud rate
#define CAN_BAUDRATE (250000)
Adafruit_MCP2515 mcp(CS_PIN);
byte receivedData[8];
uint32_t id1_value = 0;
uint32_t id2_value = 0;
uint32_t id3_value = 0;
void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);
  Serial.println("MCP2515 Receiver test!");
  if (!mcp.begin(CAN_BAUDRATE)) {
    Serial.println("Error initializing MCP2515.");
    while (1) delay(10);
  }
  Serial.println("MCP2515 chip found");
}
void loop() {
// try to parse packet
//このスケッチは受信側Receiver(read)
int packetSize = mcp.parsePacket();
if (packetSize) {
if (mcp.packetId() == 0x11) {
Serial.print(mcp.packetId(), HEX); Serial.print(" ");
id1_value = 0;
while (mcp.available()) { //8byte固定 このスケッチは受信側Receiver(read)
for (int i = 0; i <= 7; i++) {
          receivedData[i] = mcp.read();
        }
/*receivedData[0] = mcp.read();
receivedData[1] = mcp.read();
receivedData[2] = mcp.read();
receivedData[3] = mcp.read();
receivedData[4] = mcp.read();
receivedData[5] = mcp.read();
receivedData[6] = mcp.read();
receivedData[7] = mcp.read();*/
}
for (int i = 0; i <= 7; i++) {
id1_value |= (uint32_t)(receivedData[i] << (7 * i));
}
Serial.print("timeValue0 "); Serial.println(id1_value);
}else if (mcp.packetId() == 0x12) {
Serial.print(mcp.packetId(), HEX); Serial.print(" ");
id2_value = 0;
while (mcp.available()) {
for (int i = 0; i <= 7; i++) {
          receivedData[i] = mcp.read();
        }/*
receivedData[0] = mcp.read();
receivedData[1] = mcp.read();
receivedData[2] = mcp.read();
receivedData[3] = mcp.read();
receivedData[4] = mcp.read();
receivedData[5] = mcp.read();
receivedData[6] = mcp.read();
receivedData[7] = mcp.read();*/
}
for (int i = 0; i <= 7; i++) {
id2_value |= (uint32_t)(receivedData[i] << (7 * i));
}
Serial.print("timeValue1 ");
Serial.println(id2_value);
}else if (mcp.packetId() == 0x13) {
Serial.print(mcp.packetId(), HEX); Serial.print(" ");
id3_value = 0;
while (mcp.available()) {
for (int i = 0; i <= 7; i++) {
          receivedData[i] = mcp.read();
        }/*receivedData[0] = mcp.read();
receivedData[1] = mcp.read();
receivedData[2] = mcp.read();
receivedData[3] = mcp.read();
receivedData[4] = mcp.read();
receivedData[5] = mcp.read();
receivedData[6] = mcp.read();
receivedData[7] = mcp.read();*/
}
for (int i = 0; i <= 7; i++) {
id3_value |= (uint32_t)(receivedData[i] << (7 * i));
}
Serial.print("timeValue2 ");
Serial.println(id3_value);
}
}
}


CANバスモジュールを使ってデータ送受信する。(RP2040 送信)

2023-07-15 09:32:20 | CAN通信

数台の機器からデータを送って、受信したデータをまとめて保存するようなものを作るため、
スケッチを書いてテストしています。続編
SPI接続CANバスモジュール(コントローラ:MCP2515、トランシーバ:TJA1050)と
送信AE-RP2040、受信AE-RP2040、送信Arduino-UNO 1台
millis()をそのまま送ってAE-RP2040で受信しています。

ライブラリがRP2040非対応か
ArduinoUNO、ESP32で動いていたライブラリがRP2040で動かない
Arduino IDEのライブラリマネージャでMCP2515を検索しAdafruit MCP2515をインストール
こちらは対応している(?)ようです。

送信データの1バイトに入る数値に制限がある?
0x00〜0xFF(B11111111)のはずが、最上位bitが使えず0x00〜0x7F(B1111111)となっています。
使い方に間違いがあるかもしれません。
送信8バイトをフルに使うことはないのでこれでも目的は
達成できそうです。

ChatGPT先生にいっぱいヒントを頂きました。


動作概要
複数のデータそれぞれにID番号を割り当てて
送信側:数値をばらしてバイト配列に入れて送る。
受信側:バイト配列を組み立ててもとの数値へ戻す。
準備できたら送信、受信スケッチを紹介したいと思います。

送信側スケッチ
変化する送信データサンプルとしてmillis()を読んで使っています。
3つのID(0x11,0x12,0x13)を使っています。
(0x14は使えなかった。0x21〜0x23使えた。)
ID毎に1つのデータを送っています。

/*Adafruit MCP2515_CAN_Sender Exampleを改変しています。
一部省略 転記ミスや表示されてない記号があるかも <は半角に直して*/
#include<Adafruit_MCP2515.h>
#define CS_PIN    20
// Set CAN bus baud rate
#define CAN_BAUDRATE (250000)
Adafruit_MCP2515 mcp(CS_PIN);

byte time0[8];
byte time1[8];
byte time2[8];
byte packetId0 = 0x11;
byte packetId1 = 0x12;
byte packetId2 = 0x13;//0x14は使えなかった
void setup() {
  Serial.begin(115200);
  while (!Serial);
  delay(10);
  Serial.println("MCP2515 Sender test!");
  if (!mcp.begin(CAN_BAUDRATE)) {
    Serial.println("Error initializing MCP2515.");
    while (1);
    delay(10);
  }
  Serial.println("MCP2515 chip found");
}

//送信側Sender(write)
void loop() {
  // send packet: id is 11 bits, packet can contain up to 8 bytes of data
  // パケットを送信:IDは11ビット、パケットには最大8バイトのデータを含むことができる
   //Serial.print("Sending packet ... ");
   uint32_t timeValue0 = millis();
   uint32_t timeValue1 = millis();
   uint32_t timeValue2 = millis();
   Serial.print(packetId0 , HEX);
   Serial.print(" send data ");
   Serial.println(timeValue0);
   Serial.print(packetId1, HEX);
   Serial.print(" send data ");
   Serial.println(timeValue1);
   Serial.print(packetId2, HEX);
   Serial.print(" send data ");
   Serial.println(timeValue2);
   mcp.beginPacket(packetId0);//送信側Sender(write)
  for (int i = 0; i <= 7; i++) {//最上位bit使えない0x7F B1111111を超えるとNG
     time0[i] = (byte)(timeValue0 >> (i * 7)) & 0x7F;
     //time0[i] = (byte)(timeValue0 >> (i * 8)) & 0xFF;//最上位bitまで使える時
     //sendData
     mcp.write(time0[i]);
  }
   mcp.endPacket();
//送信側Sender(write)
mcp.beginPacket(packetId1);
for (int i = 0; i <= 7; i++) {//最上位bit使えない0x7F B1111111までOK
     time1[i] = (byte)(timeValue1 >> (i * 7)) & 0x7F;//最上位bit使えないとき
     //time1[i] = (byte)(timeValue1 >> (i * 8)) & 0xFF;//最上位bit使えるとき
     //sendData
     mcp.write(time1[i]);//送信側Sender(write)
   }
   mcp.endPacket();//送信側Sender(write)
    //送信側Sender(write)
mcp.beginPacket(packetId2);
for (int i = 0; i <= 7; i++) {//最上位bit使えない0x7F B1111111までOK
     time2[i] = (byte)(timeValue2 >> (i * 7)) & 0x7F;//最上位bit使えないとき
     //time2[i] = (byte)(timeValue2 >> (i * 8)) & 0xFF;//最上位bit使えるとき
     //sendData
     mcp.write(time2[i]);//送信側Sender(write)
   }
   mcp.endPacket();//送信側Sender(write)
   delay(1000);
}