pdf-icon

Arduino入門

2. デバイス&サンプル

6. アプリケーション

Module CC1101 Arduino 使用チュートリアル

1. 準備作業

  • 環境設定: Arduino IDE クイックスタートを参照して IDE をインストールし、実際に使用する開発ボードに対応するボードマネージャーと必要なドライバライブラリをインストールしてください。

  • 使用するドライバライブラリ:

  • 使用するハードウェア製品:

2. 注意事項

ピン互換性
各ホスト機のピン構成は異なるため、使用前に製品ドキュメント内のピン互換表を参照し、実際のピン接続に応じてサンプルプログラムを修正してください。

3. サンプルプログラム

  • 本チュートリアルでは、CoreS3 と Module CC1101 を組み合わせて無線通信を実現します。使用前に下図を参考にして、ピンのディップスイッチを指定位置に切り替えてください。

3.1 ピンディップスイッチ

Module CC1101 は SPI 通信方式を採用しています。実際の回路接続に応じて、プログラム内のピン定義を修正してください。デバイス接続後、対応する SPI IO は G5 (CSN)G37 (MOSI)G35 (MISO)G36 (SCK) です。割り込み IO は G7 (GD00)G10 (GD02) です。実物は以下の図のとおりです。

3.2 パラメータ設定

Module CC1101 は多様なパラメータ設定をサポートしています。使用前に以下の内容を参考に設定してください。各パラメータの意味や詳細情報についてはデータシートを参照し、用途に応じてサンプルプログラム内のパラメータ設定を調整してください。送信側と受信側のパラメータを一致させることを必ず確認してください

    1. 周波数 (CC1101_FREQ)
      本モジュールは 855 ~ 925 MHz の周波数帯をサポートしています。
    1. ビットレート (CC1101_BIT_RATE)
    • 計算式:
      ビットレート (kbps) = ((256 + DRATE_M) × 2^DRATE_E × f_xosc) / 2^28
      DRATE_E:範囲 0-15、データレートの指数値
      DRATE_M:範囲 0-255、データレートの仮数
      f_xosc:水晶発振周波数、本モジュールでは 26 MHz
    • ビットレートの範囲は 0.6 ~ 500 kbps の近似離散値です。
      推奨設定は 2.4 kbps (2400 bits/s)。高ビットレートはデータ転送効率を向上させますが、通信距離が短くなり、耐干渉性が低下し、誤り率が増加します。
    1. 周波数偏移 (CC1101_FREQ_OFFSET)
    • 計算式:
      周波数偏移 (kHz) = (8 + DEVIATION_M) × 2^DEVIATION_E × (f_xosc / 2^17)
      DEVIATION_E:範囲 0-7、周波数偏移の指数値
      DEVIATION_M:範囲 0-7、周波数偏移の仮数
      f_xosc:水晶発振周波数、本モジュールでは 26 MHz
    • 周波数偏移の範囲は 1.587 ~ 380.8 kHz の近似離散値です。
      数値が大きいほど識別度が高く、信号の耐干渉性が強くなりますが、帯域幅の占有が増加します。
    1. 帯域幅 (CC1101_BW)
    • Carson帯域幅計算式:
      帯域幅 (kHz) = 2 × 周波数偏移 + ビットレート
    • 受信フィルタ帯域幅は信号占有帯域幅以上である必要があります。上記式で計算された帯域幅は設定した受信フィルタ帯域幅以下でなければならず、それ以外では信号が受信できません。20%-30% の余裕を確保することを推奨します。
      CC1101 が設定可能な受信フィルタ帯域幅は 16 種類:58、68、81、102、116、135、162、203、232、270、325、406、541、650、812 (単位:kHz)。
    1. 送信出力 (CC1101_TX_POWER)
    • 選択可能値:-30, -20, -15, -10, 0, 5, 7, 10 (単位:dBm)
    • 数値が大きいほど送信出力が高く、通信距離が長くなりますが、消費電力も増加します。
注意:
1. 安定した電源を使用できない場合(例:CoreS3 バッテリーベースを使用する場合)、低出力値を設定してください。そうしないと、モジュールが正常に動作しません。
2. このパラメータは受信側には実質的な意味がなく、ソフトウェアを正常にコンパイルするためだけに使用されます。
    1. プリアンブル長 (CC1101_PREAMBLE_LEN)
    • 選択可能値:16、24、32、48、64、96、128、192(単位:bit)
    • プリアンブルは受信側が信号開始を検出するために使用され、値が大きいほど耐干渉性が強くなりますが、パケット長が増加し、転送効率が低下します。
説明
以下のコードでは CSNGD00GD02 の3本のピンのみを設定していますが、実際には RadioLib ライブラリが使用しているメインコントローラデバイスに応じて残りの SPI ピン (MOSIMISOSCK) を自動でマッピングします。つまり、M5Unified ライブラリで初期化されたデバイスごとにデフォルトで定義されているピンを使用し、CoreS3 ではそれぞれ G37 (MOSI)G35 (MISO)G36 (SCK) が使用されるため、手動で指定する必要はありません。

3.3 サンプルコード

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
#include <M5Unified.h>
#include <RadioLib.h>

#define CC1101_FREQ         868.0f  // carrier frequency in MHz (float). Must match receiver
#define CC1101_BIT_RATE     2.4f    // bit rate in kbps (float). Recommend 2.4 = 2400 bits/s
#define CC1101_FREQ_OFFSET  25.4f   // frequency offset in kHz (float). FSK deviation
#define CC1101_BW           58.0    // receiver filter bandwidth in kHz (float). Must be >= signal occupied BW
#define CC1101_TX_POWER     10      // output power in dBm (must be one of allowed values: -30,-20,-15,-10,0,5,7,10)
#define CC1101_PREAMBLE_LEN 16      // preamble length in bits (supported values: 16--2 Bytes, 24--3 Bytes, 32--4 Bytes, 48--6 Bytes, 64--8 Bytes, 96--12 Bytes, 128--16 Bytes, 192--24 Bytes).

//        CC1101 PIN          CSN,       GD00,    RST(unused),    GD02 
CC1101 radio = new Module(GPIO_NUM_5, GPIO_NUM_7, RADIOLIB_NC, GPIO_NUM_10);

// Tracks the result of the last transmission attempt (error code from RadioLib)
int transmissionState = RADIOLIB_ERR_NONE;
// Packet sent flag
volatile bool transmittedFlag = false;

// Special attribute for ESP8266/ESP32 to place ISR in RAM (faster interrupt response)
#if defined(ESP8266) || defined(ESP32)
ICACHE_RAM_ATTR
#endif
// This function is called when a complete packet is transmitted by the module
// IMPORTANT: this function MUST be 'void' type and MUST NOT have any arguments!
void setFlag(void)
{
    // we sent a packet, set the flag
    transmittedFlag = true;
}

void setup() {
    M5.begin();
    Serial.begin(115200);
    M5.Display.setFont(&fonts::FreeMonoBold9pt7b);

    Serial.print(F("[CC1101] Initializing ... "));
    int state = radio.begin(CC1101_FREQ, CC1101_BIT_RATE, CC1101_FREQ_OFFSET, CC1101_BW, CC1101_RX_POWER, CC1101_PREAMBLE_LEN);
    if (state == RADIOLIB_ERR_NONE) {
      Serial.println(F("Init success!"));
    } else {
      Serial.print(F("Init failed, code "));
      Serial.println(state);
      while (true) { delay(10); }
    }

    // Register callback function after sending packet successfully
    radio.setPacketSentAction(setFlag);

    // Send first packet to enable flag
    Serial.print(F("[CC1101] Sending first packet ... "));

    // you can transmit C-string or Arduino string up to
    // 255 characters long
    transmissionState = radio.startTransmit("Transmitter Ready");
    M5.Display.setCursor(5,0);
    M5.Display.printf("Transmitter Ready\n");
}

// Counter to keep track of transmitted packets
int count = 0;

void loop() {
    // check if the previous transmission finished
    if(transmittedFlag) {
        // reset flag
        transmittedFlag = false;

        if (transmissionState == RADIOLIB_ERR_NONE) {
          // packet was successfully sent
          Serial.println(F("Transmission finished!"));
          M5.Display.println("Send sucessfully!");

          // NOTE: when using interrupt-driven transmit method,
          //       it is not possible to automatically measure
          //       transmission data rate using getDataRate()

        } else {
          Serial.print(F("Send failed, code: "));
          Serial.println(transmissionState);
          M5.Display.print("\nSend failed\ncode:");
          M5.Display.println(transmissionState);
        }

        // clean up after transmission is finished
        // this will ensure transmitter is disabled,
        // RF switch is powered down etc.
        radio.finishTransmit();

        // wait a second before transmitting again
        delay(1000);

        Serial.printf("[CC1101] Sending #%d packet ... ", count);
        // you can transmit C-string or Arduino string up to 255 characters long
        String str = "Module CC1101 #" + String(count);
        transmissionState = radio.startTransmit(str);
        M5.Display.clear();
        M5.Display.setCursor(0,5);
        M5.Display.printf("[CC1101]\nSending #%d packet......\n", count++);

        // you can also transmit byte array up to 255 bytes long with limitations https://github.com/jgromes/RadioLib/discussions/1138
        /*
          byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
                            0x89, 0xAB, 0xCD, 0xEF};
          int state = radio.startTransmit(byteArr, 8);
        */
    }
}

3.4 コードのアップロード

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
#include <M5Unified.h>
#include <RadioLib.h>

#define CC1101_FREQ         868.0f  // carrier frequency in MHz (float). Must match transmitter
#define CC1101_BIT_RATE     2.4f    // bit rate in kbps (float). Recommend 2.4 = 2400 bits/s
#define CC1101_FREQ_OFFSET  25.4f   // frequency offset in kHz (float). FSK deviation
#define CC1101_BW           58.0    // receiver filter bandwidth in kHz (float). Must beyond signal occupied BW
#define CC1101_PREAMBLE_LEN 16      // preamble length in bits (supported values: 16--2 Bytes, 24--3 Bytes, 32--4 Bytes, 48--6 Bytes, 64--8 Bytes, 96--12 Bytes, 128--16 Bytes, 192--24 Bytes).  

M5Canvas canvas(&M5.Lcd);

//        CC1101 PIN          CSN,       GD00,    RST(unused),    GD02 
CC1101 radio = new Module(GPIO_NUM_5, GPIO_NUM_7, RADIOLIB_NC, GPIO_NUM_10);

// Packet received flag
volatile bool receivedFlag = false;

// Special attribute for ESP8266/ESP32 to place ISR in RAM (faster interrupt response)
#if defined(ESP8266) || defined(ESP32)
  ICACHE_RAM_ATTR
#endif
// This function is called when a complete packet is received by the module
// IMPORTANT: this function MUST be 'void' type and MUST NOT have any arguments!
void setFlag(void) {
    // we got a packet, set the flag
    receivedFlag = true;
}

void setup() {
    M5.begin();
    Serial.begin(115200);
    canvas.createSprite(320, 240);
    canvas.setFont(&fonts::FreeMonoBold9pt7b);

    Serial.print(F("[CC1101] Initializing ... "));
    int state = radio.begin(CC1101_FREQ, CC1101_BIT_RATE, CC1101_FREQ_OFFSET, CC1101_BW, CC1101_RX_POWER, CC1101_PREAMBLE_LEN);
    if (state == RADIOLIB_ERR_NONE) {
      Serial.println(F("success!"));
    } else {
      Serial.print(F("failed, code "));
      Serial.println(state);
      while (true) { delay(10); }
    }

    // Register callback function after receiving packet successfully
    radio.setPacketReceivedAction(setFlag);

    // Start listening for packets
    Serial.print(F("[CC1101] Starting to listen ... "));
    state = radio.startReceive();
    if (state == RADIOLIB_ERR_NONE) {
      Serial.println(F("success!"));
    } else {
      Serial.print(F("failed, code "));
      Serial.println(state);
      while (true) { delay(10); }
    }

    // if needed, 'listen' mode can be disabled by calling
    // any of the following methods:
    //
    // radio.standby()
    // radio.sleep()
    // radio.transmit();
    // radio.receive();
    // radio.readData();
}

void loop() {
    // check if the flag is set
    if(receivedFlag) {
        // reset flag
        receivedFlag = false;

        // you can read received data as an Arduino String
        String str;
        int length = radio.getPacketLength();
        int state = radio.readData(str, length);

        // you can also read received data as byte array
        /*
          byte byteArr[8];
          int numBytes = radio.getPacketLength();
          int state = radio.readData(byteArr, numBytes);
        */

        if (state == RADIOLIB_ERR_NONE) {
          // Packet was successfully received
          Serial.println(F("[CC1101] Received packet:"));
          canvas.clear();
          canvas.setCursor(0,5);
          canvas.printf("[CC1101]\nReceived packet:\n");

          // Data of the packet
          Serial.print(F("[CC1101] Data:\t\t"));
          Serial.println(str);
          canvas.printf("Data: %s\n", str.c_str());

          // RSSI (Received Signal Strength Indicator)
          Serial.print(F("[CC1101] RSSI:\t\t"));
          Serial.print(radio.getRSSI());
          Serial.println(F(" dBm"));
          canvas.printf("RSSI: %0.2f dBm\n", radio.getRSSI());

          // LQI (Link Quality Indicator), lower is better
          Serial.print(F("[CC1101] LQI:\t\t"));
          Serial.println(radio.getLQI());
          canvas.printf("LQI:  %d\n", radio.getLQI());
          canvas.pushSprite(0, 0);

          radio.finishReceive();

        } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
          // Packet was received, but is malformed
          Serial.println(F("CRC error!"));
        } else {
          Serial.print(F("failed, code "));
          Serial.println(state);
        }
        // Put module back to listen mode
        radio.startReceive();
    }
}

4. コンパイルとアップロード

  • ダウンロードモード:異なるデバイスでプログラムを書き込む前にダウンロードモードへ入る必要があります。主制御デバイスによって手順が異なる場合があります。詳細はArduino IDE クイックスタートページ下部のデバイス別プログラムダウンロードチュートリアル一覧を参照し、具体的な操作方法を確認してください。
  • CoreS3 のリセットボタンを長押し(約 2 秒)し、内部の緑色 LED が点灯したらボタンを離してください。この時点でデバイスはダウンロードモードに入り、書き込みを待機しています。
  • デバイスのポートを選択し、Arduino IDE 左上のコンパイル&アップロードボタンをクリックします。プログラムがコンパイルされ、デバイスにアップロードされるのを待ちます。

5. 情報送受信の効果表示

上述の例では、送信側が 1 秒ごとにカウンタ付きの文字列を送信し、受信側は受信した文字列を表示し、RSSI などの情報を出力します。

  • 送信側シリアル出力情報:
    [CC1101] Sending #199 packet ... Transmission finished!
  • 受信側シリアル出力情報:
    [CC1101] Received packet:
    [CC1101] Data:            Module CC1101 #199
    [CC1101] RSSI:            -61.00 dBm
    [CC1101] LQI:             2
On This Page