Help us understand the problem. What is going on with this article?

CayenneLPP( Cayenne Low Power Payload) について調べてみた

調べた背景

LoraのGatewayやEndDevice(ノード)をRaspberryPiとDragino GPA-HATで作っています.
GPSデータをTTN(TheThingsNetwork)に送信してマップ表示させてみたりしたいと思っているのですがその中でGPSデータを送信するのに色々試してみたののひとつがCayenneLPPです.ちなにみCayenneはカイエンと読むみたいですがどこかの高級外車の名前のようです...

アプリケーションのデータ形式(ペイロードフォーマット)でTTNのコンソールにCayenneLPPを選ぶところがあり調べて作ってみました.

CayenneLPP(カイエンLPP)のメリット

  1. データサイズが小さい.GPSの緯度、経度、高度のデータを11バイトで送れます.
  2. 一通りのアプリケーションのフォーマットが規定されているのでデバイスとサーバ間で互換性をとりやすい.TTNが対応しているというのもあります.

  3. 楽チン.自分で一から考えなくてよいし、先人のライブラリが利用できる.

    あと、特徴として複数のセンサデータをまとめて送れるとかノードのいろいろな設定ができたりします.(ノードが対応している必要がありますが)

技術的内容

基本の3つの構成要素があります.チャンネル(Channel)とデータタイプ(Data Type)とデータそのもの(Data)です.

LoraWANの場合は基本のデータ形式ではフレームポート(FPort)を1で使いますが2以上の値を使って高度な使い方もできます.
(参考までにLoraWANではFPort=0のペイロードはMacコマンドになります.
アプリケーションは1から223(0xdf)までを使います.)
ここでは便宜上FPort=1のデータ形式を基本データ形式、FPort>=2のデータ形式を拡張データ形式を呼ぶことにします.
(LoraWAN以外の通信規格でもFPortがあるかも知れませんが分かっていません.)
また、サーバからEndDeviceに対してアプリ的な指令(LoraWANのMacコマンド以外という意味)を送ることができます.

Channel

1バイトでセンサーやアクチュエータの個別の名前に対応させて0から64(63?)までの値を割り当てます.
複数のセンサー、アクチュエータでは独立した値にして区別します.

DataTypeとData

Data Typeは1バイトでセンサーやアクチュエータの種別を表します.
DataはData Type毎にフォーマットが規定されています.

基本データ形式

種別 Data Type 値 データサイズ(バイト) 精度
デジタル入力 0x0 1 1
デジタル出力 0x1 1 1
アナログ入力 0x2 1 0.01
アナログ出力 0x3 1 0.01
照度計 0x65 2 1 lux
presence? 0x66 1 1
温度計 0x67 2 0.1 °C
湿度計 0x68 1 0.5 %
加速度計 0x71 6 0.001 G
気圧計 0x73 6 0.1 hPa
ジャイロ計 0x86 6 各軸 0.01 °/s
GPS 0x88 9 緯度、経度 0.0001 °、高度 0.01m

他にも押しボタン(0x93)やブザー(0x8a)、キャラクタディスプレイ(0x8d)などいろいろあるようです.
presenceの意味が良く分からないのですが存在センサー?でしょうか?

GPSデータの例:

1 byte 1 byte 3 bytes 3 bytes 3 bytes
0x1 0x88 0x5,0x5f,0xa4 0x00,0xfe 0x5,0xc1,0x70
Channel 1 GPS 緯度=35.2164 経度=138.4364 高度=3772.00m

ここでたとえば0x5c170=377200で0,01mが単位なので3772.00mと変換されます.
なお、GPSとカイエンの両方のライブラリを使えばこのあたりのことは知らなくてもデータを渡すだけでやってくれます.

複数のセンサーデータを組み合わせて一度に送ったり、フレームごとに送るセンサ(チャンネル)を変えることもできます.
複数センサーの例:

1 byte 1 byte 2 bytes 1 byte 1 byte 2 bytes ...
0x01 0x67 0x01,0x10 0x02 0x67 0xff,0xd7 ...
センサ1 温度 0110=272=27.2°C センサ2 温度 ffd7=-41=-4.1°C ...

フレーム毎に変える例:
Frame N

1 byte 1 byte 2 bytes
0x01 0x67 0x01,0x10
センサ1 温度 0110=272=27.2°C

Frame N+1

1 byte 1 byte 1 bytes
0x02 0x68 0x82
センサ2 湿度 0x82=130=75%

拡張データ形式

パックドデータ

固定のチャンネル値を省略し、基本データ形式のセンサデータを連結した形式です.
通信するごとにチャンネル値は0から64まで増加していきます.
この形式ではセンサーデータの順は不変でないと通信できません.

1byte N Bytes 1byte N byte ...
Data1 Type Data1 Data Type2 Data2 ...

例:

1 byte N bytes 1 byte N bytes
0x67 0x01,0x10 0x67 0x00,0xfe
Temp 27.2°C Temp 25.4°C
0x110=272 0xfe=254

Channelはデータを送るたびに1->2->3と増えていきます.

(あくまで個人の感想です)
個人的にはあまり使わないほうがよさげな気がします.
解釈で複数センサーデータとの区別が面倒くさそうな気がするのと
一度にたくさん送るのは送信データサイズの制限に引っかかりやすいです.
LoraチップSX1276のFIFOサイズは送受共用256バイトで単純に使えば半々の128バイトずつです.試したところSF7で送受できるペイロードの最大サイズは115バイトでした.
ペイロードサイズは送信側、受信側、両方の制限を受けるので小さめにしておくのがよさげかと思います.

フルスケールGPSデータ

この形式では基本GPSデータと異なる形式で高精度の高度データを送れるらしいが詳細は不明...

時系列データ

あるチャンネルのデータを時系列にまとめて送る形式.
チャンネルはFPort値で通知します.
$$ Frame Port = Data Channel + 100 $$
時刻差Deltaはフレーム送信時txtimeからの差を秒単位で2バイトで表します.

1 byte 2 bytes N byte(s) 2 bytes N byte(s) ...
Data Type Delta1 Data(txtime-Delta1) Delta2 Data(txtime-Delta2) ...

アクチュエータコマンド

デジタルのON/OFF、HIGH,LOWやアナログの値.デジタルとアナログで同じ形式でDataTypeがありません.
デジタルのHIGHはアナログの1.00と同じ値になります.
100=0x0064

1 byte 2 bytes 1 byte
Channel Value 0xFF

デバイス設定

デバイスの次の設定をします.
1.UNIX時刻秒
2.送信の時間間隔秒
3.センサーデータ取得の間隔秒.

Config Mask Setting Size Definition
0b00000001 UTC Time 4 Unix timestamp 秒
0b00000010 TX Period 4 センサーデータの送信フレームの時間間隔秒
0b00000100 Reading Period 2

例えばセンサーは60秒毎に読み取り、データの送信は5分毎にといった設定ができます.
複数の設定を同時に組み合わせて行うことができます.
この場合、下位ビットのUTC Timeから順に解釈していきます.
例:

1byte 4 bytes 4 bytes 2 bytes
0x07 0x5d,0x7e,0xe4,0xf8,0x59 0x00,0x00,0x01,0x2c 0x00,0x3c
0b00000111 0x5d7ee4f8 =1568597240 0x0000012c=300 0x003c=60
3つある UTC時刻 2019/9/16 10:27:20 送信間隔 300秒 センサー読取間隔 60秒

センサー読み取り間隔設定

センサーごとで(チャンネルごとで)読み取り間隔を個別に設定できます.

1 byte 2 bytes
チャンネル 時間間隔秒

センサー許可/禁止設定

データをあげるセンサ(チャンネル)を個々に許可、禁止できます.
8バイトで個々のビットにセンサ(チャンネル)を割り当てて設定します.
最下位ビットがチャンネル1に対応します.
最大64個のセンサーに対応ということになります.
ちなみに許可=1、禁止=0

8 bytes(64 bit channel mask)
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 全チャネル許可
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 チャンネル1は許可、他は禁止

(あくまで個人の感想です)
他の8バイトのデータフォーマットと重複しないか心配です.

C言語での例

ArduinoやmbedのC++での例はいくつかあるようですがC言語のはあまりないようです.GithubにCayenne-LPPというC言語のプログラムがありましたのでそれを使ってみました.

    /// GPS version ////
    loc_t gps_data;
    gps_location(&gps_data);
    //// Cayenne_lpp format ////
    cayenne_lpp_t lpp;
    uint8_t channel=1;      // set application channel
    cayenne_lpp_reset( &lpp);
    cayenne_lpp_add_gps( &lpp, channel, gps_data.latitude, gps_data.longitude, gps_data.altitude);
    memcpy(telegram, lpp.buffer, lpp.cursor);

こんな感じで数行で使えます.最後の行のtelegram は送信されるペイロードです.Cayenne-LPPにサンプルコードがあります.
RaspberryPiで簡単にGPSデータをTTNに送れました!

最後に

CayenneLPPはIPSO Alliance Smart Objects Guidelinesから引っ張ってきて
さらにこれはLightweight M2Mから引っ張ってきているそうです.
まだオリジナルに当たれていないので理解不足とかあるかもしれないです.

参考

https://community.mydevices.com/t/cayenne-lpp-2-0/7510
https://developers.mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload-examples-device-with-gps
https://github.com/aabadie/cayenne-lpp

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした