Arduino MKR WAN 1310 Getting Started
準備
Arduinoをインストール
brew install arduino --cask
Arduino SAMD Boardsをインストール
Lチカ
兎にも角にもLチカ。
ドキュメントはここにまとまっている。
ピンアウトはこんな感じ。
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があるのでこれを使えそうだ。
やるべきこととしてはいくつかある。
- スリープ時
- Arduinoをスリープさせる。
- Murataの通信モジュールの電源を落とす。
- センサーの電源を落とす。
- スリープ解除時
- その逆。
1, 2はソフトウェアで解決できそうだが3はMOSFETなどを活用する必要が出てきそうだ。
温度センサーが必要としている電流が少ないならdigitalOutで電源を供給してしまってもいいかもしれない。(行儀は悪い。)
DS18B20の消費電力は待機時でも750nAなので1mAhあるだけでも1333時間 = 2ヶ月弱 は持つ。特に気にしなくていいかもしれない。
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();
}
USBのSerialではなくて、TX/RXピンでSerial通信するにはどうしたらいいのか。
このページが参考になった。
int count = 0;
void setup() {
Serial1.begin(9600);
}
void loop() {
Serial1.println(count);
delay(500);
count++;
}