LoginSignup
27

More than 5 years have passed since last update.

Arduinoで安くてオトクに簡単無線通信(315MHz編)

Last updated at Posted at 2016-12-23

こんな方にオススメなお話

無線通信したいけど、
XBee(*1)さんは¥2,500くらいして安くなったにせよ大量につかうと割高だし、
ESP-WROOM-02さん(*2)は¥1,000以下で安いけどWifiでネットワーク組むほどは...
とよくばりなアナタに。

消費電力おさえめで、ネットワーク組むほど賢いのは不要、
ついでにいうと送信だけとかでもokですよ!って方には恐らくベストな選択肢、
315MHzさんのお話です。

※ あとは通信速度もとめてたり、通信距離求めている場合は微妙かも。

ひつようなもの


Arduino UNO x 2
https://www.switch-science.com/catalog/789/


送信モジュール(315MHz) [RF315-TX5-R]
http://www.aitendo.com/product/4138

VCC 1.8 - 3.6V
動作電流 10mA
外形寸法 11.0 x 16.0 x 5.0mm


受信モジュール(315MHz) [RF315-RXB12]
http://www.aitendo.com/product/2607

VCC 3.3 - 5.0V
動作電流 2.5 - 2.7mA
出力 300 - 500m
外形寸法 30.0 x 8.5 x 5.0mm
バンド幅 200KHz

配線

送信側

15725349_10210964879495655_2123920786_o.jpg

Arduino UNO 送信モジュール側(RF315-TX5-R)
3.3V VCC
D12 DATA
GND GND

 

受信側

15540128_10210964879255649_1344473852_o.jpg

Arduino UNO 受信モジュール(RF315-RXB12)
3.3V VCC
D11 DATA
GND GND

ソース

送受信は、お手軽無線用モジュール VirtualWire をつかいます。
https://www.pjrc.com/teensy/td_libs_VirtualWire.html

送信側

send.ino
/**
 * 315MHz通信モジュール 送信側プログラム
 * 使用デバイス: RF315-TX5-R
 * /
#include <VirtualWire.h>

#define SEND_PIN 12 // D12

void setup() {
  vw_set_tx_pin(SEND_PIN);
  vw_setup(2000);
}

void loop() { 
  int numData = 25;
  char datas[numData];
  for (int i=0;i<numData;i++) {
    datas[i] = i;
  }
  vw_send((uint8_t *)datas, numData);
  vw_wait_tx();
}

送信データが少ない場合(2byteずつ送るとか)、
vw_setupの2000msを6~7000msくらいまで上げると、
送信速度があがるようです。

上の例のように複数バイト送る場合は、2000くらいが安定です。
データ量、主観的評価なので誤差はあると思いますが、
一度に送る送信量は25くらいがmaxで、30とか送ると届かなくなったりした気がします。

受信側

recv.ino
/**
 * 315MHz通信モジュール 受信側プログラム
 * 使用デバイス: RF315-RXB12
 * /
#include <VirtualWire.h>

#define RECV_PIN 11

void setup() {
  delay(1000);
  Serial.begin(9600);
  Serial.println("receiver setup");

  vw_set_rx_pin(RECV_PIN);
  vw_setup(2000);
  vw_rx_start();
}

void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) {
    Serial.print("Got: ");
    for (int i = 0; i < buflen; i++) {
      Serial.print(buf[i], DEC);
      Serial.print(' ');
    }
    Serial.println();
  }
}

おまけ

文字列の送信をしたい方向けのサンプル落ちてたので、ぺたり。
http://www.buildcircuit.com/how-to-use-rf-module-with-arduino/

めでたしめでたし。

[^1] ... https://www.switch-science.com/catalog/996/
[^2] ... https://www.switch-science.com/catalog/2346/

おまけ その2(ちょっっとだけ省電力化)

VDDを送信するときだけ流すようにすることで、
ちょっとだけ省電力化(ってほど変わらなかった気もしますが…)。

ちなみにテストは下記のArduino Pro mini 3.3V 16MHzつかいました。
http://www.tinyosshop.com/index.php?route=product/product&product_id=275

通常時(アイドル時) 送信時
約10mA 約17mA

ソースは下記になります。

send2.ino
/**
 * 315MHzのモジュール簡易送信プログラム
 * VDDに3.3V常時接続ではなく、SEND_EN_PINとVDDつないで通常時はlowにして省電力にするバージョン
 */
#include <VirtualWire.h>

#define MY_ID 90
#define SEND_PIN 2 // DATA <-> D12
#define SEND_EN_PIN 3 // VDD <-> D3

#define PACKET_ID 0
#define PACKET_TYPE 1
#define PACKET_DATA 2

#define SEND_INTERVAL 10000

unsigned long sendTimer;

void setup() {
  pinMode(SEND_EN_PIN, OUTPUT);
  digitalWrite(SEND_EN_PIN, LOW);

  vw_set_tx_pin(SEND_PIN);
  //vw_set_ptt_inverted(true);
  vw_setup(2000); // Bits per sec
}

void loop() {
  if (millis() - sendTimer > SEND_INTERVAL) {
    digitalWrite(SEND_EN_PIN, HIGH);
    delay(50); // wait for wakeup

    for (int j=0;j<10;j++) {
      int numCount = 25; // 25くらいがmax、30とかにすると落ちる
      char counts[numCount];
      counts[PACKET_ID] = MY_ID;
      counts[PACKET_TYPE] = j * 10;
      for (int i=PACKET_DATA;i<numCount;i++) {
        counts[i] = i;
      }
      vw_send((uint8_t *)counts, numCount);
      vw_wait_tx(); // Wait until the whole message is gone
    }

    digitalWrite(SEND_EN_PIN, LOW);

    sendTimer = millis();
  }
}

以下、コメントでご指摘いただいたので追記します(2017.08.01)。
製品自体には問題はありませんが、ちょっとアンテナを工夫するだけで軽く微弱の範囲を超えてくるものです。
電波障害を起した場合、使用者が法的責任を問われる可能性がありますので、ご注意ください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27