Closed9

Arduino MKR WAN 1310 Getting Started

準備

Arduinoをインストール

brew install arduino --cask

Arduino SAMD Boardsをインストール

Lチカ

兎にも角にもLチカ。
ドキュメントはここにまとまっている。

https://docs.arduino.cc/hardware/mkr-wan-1310

ピンアウトはこんな感じ。

LEDはどこかな?と思ったけど最近は LED_BUILTIN ってのがあるんですね。

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);
}

できた。

センシング

お次に家に転がっている適当な温度センサでセンシングしてみる。今回はDS18B20を使った。
OneWire ライブラリとDallasTemperature ライブラリを入れる。

Library Managerで簡単に入れられます。

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 6
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup(void)
{
  Serial.begin(9600);
  sensors.begin();
}

void loop(void)
{ 
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  Serial.print("Temperature for the device 1 is: ");
  Serial.println(sensors.getTempCByIndex(0));

  delay(500);
}

いい感じにとれました。

LoRaで温度を送ってみる

送信側

LoRaモジュールを使う。

#include <LoRa.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 6
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup(void)
{
  Serial.begin(9600);
  Serial.println("LoRa sender");
  
  if (!LoRa.begin(868E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }

  sensors.begin();
}

void loop(void)
{
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  float temperature = sensors.getTempCByIndex(0);

  // send packet
  LoRa.beginPacket();
  LoRa.print(temperature);
  LoRa.print(" celsius");
  LoRa.endPacket();
  delay(5000);
}

受信側

受け取って、Serialに流すだけ。

#include <SPI.h>
#include <LoRa.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(920E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

結果

いい感じにとれている。

省電力化

電池で動かしたいので省電力化したい。幸いArduino Low Powerがあるのでこれを使えそうだ。

やるべきこととしてはいくつかある。

  • スリープ時
    1. Arduinoをスリープさせる。
    2. Murataの通信モジュールの電源を落とす。
    3. センサーの電源を落とす。
  • スリープ解除時
    • その逆。

1, 2はソフトウェアで解決できそうだが3はMOSFETなどを活用する必要が出てきそうだ。

温度センサーが必要としている電流が少ないならdigitalOutで電源を供給してしまってもいいかもしれない。(行儀は悪い。)

Arduinoをスリープさせる作例があったので紹介。Examplesの中の TimedWakeup より。

#include "ArduinoLowPower.h"

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  // Uncomment this function if you wish to attach function dummy when RTC wakes up the chip
  // LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, dummy, CHANGE);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  // Triggers a 2000 ms sleep (the device will be woken up only by the registered wakeup sources and by internal RTC)
  // The power consumption of the chip will drop consistently
  LowPower.sleep(2000);
}

この後色々試すのだが、setup() の中で attachInterruptWakeup を呼んでいるとsleepから帰ってこないことがあり、結構ハマってしまった。

できた。

LoRa.end() は内部的に LoRa.sleep() を呼び出しており、続けて呼ぶとスタックするっぽいので注意が必要だった。

#include <LoRa.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ArduinoLowPower.h>

#define ONE_WIRE_BUS 6
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

boolean inSleep = false;

void setup(void)
{
  Serial.begin(9600);
  if (!LoRa.begin(920E6)) {
    Serial.println("LoRa init error");
  }
  sensors.begin();
  Serial.println("setup");
}

void loop(void)
{
  if(inSleep)
  {
    wakeup();
    inSleep = false;
  }

  sensors.requestTemperatures();

  float temperature = sensors.getTempCByIndex(0);

  // send packet
  LoRa.beginPacket();
  LoRa.print("{'temp': ");
  LoRa.print(temperature);
  LoRa.print("}");
  LoRa.endPacket();
  
  startSleep();
}

void startSleep()
{
  inSleep = true;
  digitalWrite(LED_BUILTIN, LOW);
  LoRa.end();
  LowPower.sleep(10 * 1000);
}

void wakeup()
{
  Serial.begin(9600);
  if (!LoRa.begin(920E6)) {
    Serial.println("LoRa begin failed");
  }
  sensors.begin();
}
このスクラップは3ヶ月前にクローズされました
ログインするとコメントできます