Squama Ethernet でSPI通信とUDP送信 (Arduino)


始めに

SeedなどでSquama Ethernetが販売されています。
この記事ではSquama EthernetでSPI通信にてセンサの情報を受け取り、UDPにてその情報を送信してみたいと思います。

Squama Ethernetとは

端的に言えば、EthernetケーブルがささるArduino、ということになるでしょうか。
個人的にはPoE付のオプションがとても良いですね。
電源回りがシンプルになると、IoT等に利用するにもスッキリしますからね。

また、Arduino IDEで使用するための準備はこちら

外観

ピン配置

ハードウェア要点

Ethernet IC W5500

Squama Ethernetに実装されているチップはArduino Ethernet Shield v2 シールドに実装されているICと同じW5500です。
よって、ArduinoライブラリはEthernet2ライブラリがそのまま使用できます。

外部センサ

今回はテストのため温度センサ(アナログ・デバイセズ社のADT7310)を使用します。
秋月電子でも販売しています。こちら

Squama Ethernetとの接続はSPI通信ピンに接続してください。電源は3.3Vです。
(CS信号は後述します)

ソフトウェア要点

SPI通信のCS信号

今回は、温度センサとEthernet(W5500)を使用するためにSPI通信を使用します。
そのため、CS信号の設定が必要となります。

まず、温度センサ用CS信号はPin7を使用することにします。

次に、W5500用のCS信号ですが、結論から言えばPin10のようです。
Squama Ethernetの回路図的にはMCUのPin27に接続されているようで、こちらがソフト的にPin10に割り当てられているようです。
(例えばソースコード上でPin9に設定したらUDP通信の受信ができなくなりました)

ちなみに、例えばArduino Ethernet Shield v2ですとPin10に固定されていますし、
Arduino MKR Eth ShieldですとPin5ですね。

ソースコード

#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>


// ------Ethernet-------
byte mac[] = {
  0xA8, 0x61, 0x0A, 0xAE, 0x66, 0xC7
};

IPAddress ip(192, 168, 0, 11);   // 自身のIPアドレス
unsigned int localPort = 10000;

IPAddress destIP (192, 168, 0, 1);  //相手のPCのIPアドレス
int destPort = 20001;  //send側ポート

EthernetUDP Udp;


// ------温度センサ-------
int tempSSPin = 7; // Pin7をSS


void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);

  // ------Ethernet-------
  Ethernet.init(10);  // CS信号設定. Most Arduino shields

  Ethernet.begin(mac, ip);
  Udp.begin(localPort);


  // ------温度センサ-------
  pinMode(tempSSPin, OUTPUT);
  SPI.setBitOrder(MSBFIRST);  //最上位ビット(MSB)から送信
  SPI.setClockDivider(SPI_CLOCK_DIV128); //通信速度を遅く設定
  SPI.setDataMode(SPI_MODE0); //CPOL(クロック極性):0 CPHA(クロックフェーズ):0

  SPI.begin();

  digitalWrite(tempSSPin, LOW);

  //ソフトウェアリセット
  SPI.transfer(0xFF);
  SPI.transfer(0xFF);
  SPI.transfer(0xFF);
  SPI.transfer(0xFF);

  SPI.transfer(0x54);    // 測定開始(continuously read)

  Serial.println("Setup End");

  delay(500);
}



void loop() {
  // put your main code here, to run repeatedly:

  sendUDP(getTemp());

  delay(1000);
}

float getTemp() {
  uint16_t uiVal;
  int iVal;

  digitalWrite(tempSSPin, LOW);
  uiVal = (uint16_t)SPI.transfer(0) << 8;  // AD変換値 上位
  uiVal |= SPI.transfer(0);                // AD変換値 下位

  digitalWrite(tempSSPin, HIGH);
  uiVal >>= 3;                          // シフトで13bit化
  //uiVal = 0x1fff; //確認テスト用

  if (uiVal & 0x1000) {              // 13ビットで符号判定
    iVal = uiVal - 0x2000;         // マイナスの時 (10進数で8192)
  }
  else {
    iVal = uiVal;                 //プラスの時
  }

  float fVal = (float)iVal / 16.0;           // 温度換算(摂氏)
  return fVal;
}

void sendUDP(float val) {
  // UDP SEND
  Udp.beginPacket(destIP, destPort);
  Udp.print(val);
  Udp.write(",");
  Udp.print(millis() / 1000, DEC);
  Udp.write("\n");
  Udp.endPacket();
}

結果

UDPの受信結果はこちらになります。こちらはUnityで受信しています。
温度と基板が起動してからのタイムをカンマ区切りで送信しています。

終わりに

Squama Ethernetを使用してSPI通信で外部センサの情報を受けてUDPで送信しました。
Squama Ethernetは最近発売されたようで(私がググって発見したのは2021年4月)、あまり情報がありません。
(CS信号は何ピン?と思ったのがこの記事を書こうと思った発端です)

また、最近はESP32等のお手軽にWiFiが使用できる基板がメジャーでしょうか。
わざわざLANケーブルを接続する必要がなくなっているのもSquama Ethernetの情報が少ない要因かもしれません。

まだまだ有線接続にてネットワーク通信をしたい方の参考になれば幸いです。