hiro yamamoto works

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

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

2023-07-15 14:27:40 | マイコンソフトウェア

受信側スケッチです。改善の余地あり(ちょっと直しました。)
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 | マイコンソフトウェア

数台の機器からデータを送って、受信したデータをまとめて保存するようなものを作るため、
スケッチを書いてテストしています。続編
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);
}


RP2040でスケッチ書き込み後にRaspberry Pi Picoシリアルポートが消える

2023-05-27 20:11:08 | マイコンソフトウェア

今回経験したこの現象の原因はスケッチの書き方ミスによるものです。
Arduino IDEで書いた LiquidCrystal_PCF8574.hを使ったスケッチで
lcd.setBacklight(255);
lcd.begin(16, 2);

と記述順が違っていたためという単純ミスです。
なぜかコンパイルは通るんです。そしてこのスケッチは、間違えているんですが
以前ATMEGA Arduinoでは動いていた(?)ように記憶しています。
シリアルポートが消えてしまったら、
USBケーブルを抜いてBOOTスイッチを押しながらUSBケーブルを挿せば、
シリアルポートにUF2 Boardが出てくるので、選んで書き込めば元に戻ります。
同様の現象でお困りの方の参考になればと投稿しました。
コンパイルが通るから大丈夫ではないことがわかった貴重な体験でした。笑笑


XIAO SAMD21でポートA全体を読み込む方法をchatGPTに聞いてみると

2023-04-22 20:06:52 | マイコンソフトウェア

教えてくれました
そして動きました。
uint32_t port_data;
port_data = PORT->Group[0].IN.reg;

助かりました。こんな簡単なcodeだったんですがwiring_digital.cの中に記述されている
digitalRead( uint32_t ulPin )を調べたり、ネット検索してもピッタリの答えにたどりつけず2時間弱・・・
早く聞いてみればよかった。
XIAO SAMD21は
CPU ARM Cortex-M0+ CPU(SAMD21G18)
Size 20x17.5x3.5mm


SDWebServerスケッチでクライアントのダウンロード完了を検出する

2022-10-30 20:55:13 | マイコンソフトウェア

行番号104〜106を改変する
if (server.streamFile(dataFile, dataType) != dataFile.size()) {
    //"送信データが予想より少ない!"メッセージを出力する
DBG_OUTPUT_PORT.println("Sent less data than expected!");
}

改変後
if (server.streamFile(dataFile, dataType) != dataFile.size()) {
DBG_OUTPUT_PORT.println("Sent less data than expected!");
//送信済データサイズとファイルデータサイズが同じで リクエストパラメータ名が
//"download"の時にファイルのダウンロードが正常終了したと判断する
} else if (server.hasArg("download")) {
//ここに/実行したい処理を書く
}