CAT LoRa Starter Kit ตอนที่ 2 การรับและส่งข้อมูลไปยัง LoRa IoT by CAT (with AcSIP S76S Commands)

Choonewza
Choonewza
Dec 4, 2019 · 5 min read

ในบทความนี้เราจะมาดูวิธีการส่งข้อมูลขึ้นไปยัง CAT LoRaWAN กันครับ โดยบอร์ดตัวนี้จะใช้ชิป AcSIP S76S เราสามารถควบคุมได้โดยการส่งคำสั่งผ่าน UART (Universal Asynchronous Receiver Transmitter) ที่เป็นการสื่อสารอนุกรมแบบ Asynchronous ทำให้สามารถรับและส่งข้อมูลได้ในเวลาเดียวกันแบบ Full Duplex โดยที่คำสั่งทั้งหมดที่เราสามารถใช้งานได้สามารถดาวน์โหลดได้ตามลิ้งด้านล่างนี้เลยครับ

จะเห็นได้ว่ามีคำสั่งมากมายให้เราเลือกใช้งาน แต่ในที่นี้เราจะใช้คำสั่งที่จำเป็นต้องใช้เท่านั้นนะครับ โดยคำสั่งที่ใช้งานมีดังนี้

  1. mac set_ch_freq
  2. mac set_rx2
  3. mac save
  4. mac set_class
  5. mac join abp
  6. mac set_deveui
  7. mac set_devaddr
  8. mac set_nwkskey
  9. mac set_appskey

เราจะทำอะไร ?

ในที่นี้เราจะเขียนโปรแกรมส่งข้อมูลขึ้น CAT LoRaWAN โดยส่ง “0123456789ABCDEF” ขึ้นสู่ Network Server โดยโค๊ดทั้งหมดมีดังนี้

#include "Arduino.h"
#include "wiring_private.h"
#include <Wire.h>
Uart Serial2(&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2);unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 20000;
//LoRa Configuration;
String DEV_EUI = "????????????????";
String DEV_ADDR = "????????";
String NWKS_KEY = "????????????????????????????????";
String APPS_KEY = "????????????????????????????????";
//LoRa Send Data
uint8_t port = 1;
String payload = "0123456789ABCDEF";
void SERCOM1_Handler(void){
Serial2.IrqHandler();
}
void Serial2_String_Write(const char *s){
while (*s)
{
Serial2.write(*s++);
}
}
void Set_LoraConfig(void){
String str1 = "";
//********************
Serial2_String_Write("mac set_ch_freq 0 923200000");//0
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 0");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 1 923400000");//1
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 1");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 2 922000000");//2
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 2");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 3 922200000");//3
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 3");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 4 922400000");//4
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 4");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 5 922600000");//5
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 5");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 6 922800000");//6
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 6");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 7 923000000");//7
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 7");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_rx2 2 923200000");//8
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_rx2 2");
Serial.println(str1);
//********************
Serial2_String_Write("mac save");//8
str1 = "";
delay(3000);
str1 = Serial2.readString();
Serial.print("mac save");
Serial.println(str1);
}
void Set_LoraConfigABP_A(void){
String str1 = "";
String cmdTemp = "";
//********************
Serial2_String_Write("mac set_class A");
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_class A");
Serial.println(str1);
//********************
cmdTemp = String("mac set_deveui ") + DEV_EUI;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_deveui");
Serial.println(str1);
//********************
cmdTemp = String("mac set_devaddr ") + DEV_ADDR;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_devaddr");
Serial.println(str1);
//********************
cmdTemp = String("mac set_nwkskey ") + NWKS_KEY;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_nwkskey");
Serial.println(str1);
//********************
cmdTemp = String("mac set_appskey ") + APPS_KEY;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_appskey");
Serial.println(str1);
//********************
Serial2_String_Write("mac save");
str1 = "";
delay(3000);
str1 = Serial2.readString();
Serial.print("mac save");
Serial.println(str1);
//********************
Serial2_String_Write("mac join abp");
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("mac join abp");
Serial.println(str1);
}
void setup() {
Serial.begin(115200);
Serial2.begin(115200);
pinPeripheral(10, PIO_SERCOM);
pinPeripheral(11, PIO_SERCOM);
delay(5000);
if (Serial2.available()){
Serial.print(Serial2.readString());
}
delay(1000);
Set_LoraConfig();
Set_LoraConfigABP_A(); delay(250);
Wire.begin();
String str1 = "";
str1 = Serial2.readString();
Serial.println(str1);
startMillis = millis();
delay(1000);
Serial.println("LoRa Starter Kit GRAVITECH");
}
void loop() {
String str4 = "";
currentMillis = millis();
// SEND INTERVAL 20 SECOND --> EDIT PARAMETER preiod TO CHANGE TIME INTERVAL LINE 185
if (currentMillis - startMillis >= period){
// SEND UPLINK DATA
String commandSender = String("mac tx ucnf ") + String(port) + String(" ") + payload;
Serial2_String_Write(commandSender.c_str());
startMillis = currentMillis;
}
// COUNT FOR SEND UPLINK
if ((currentMillis - startMillis) / 1000 > 0) {
str4 = Serial2.readString();
if (str4 != "") {
Serial.println(str4);
}
}
}

อธิบายโค๊ด

การติดต่อกับ CAT LoRaWAN

เปิดการใช้งาน Uart เพื่อเชื่อมต่อกับชิป AcSIP S76S

Uart Serial2(&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2);//และเรียกใช้โดย Serial2.begin(115200); ใน setup function

ตั้งค่าความถึ่และ Chanel ที่ใช้สำหรับการเชื่อมต่อกับ CAT LoRaWAN

void Set_LoraConfig(void){
String str1 = "";
//********************
Serial2_String_Write("mac set_ch_freq 0 923200000");//0
str1 = "";
delay(100);
str1 = Serial2.readString();
Serial.print("set_ch_freq 0");
Serial.println(str1);
//********************
Serial2_String_Write("mac set_ch_freq 1 923400000");//1
...
//********************
Serial2_String_Write("mac set_ch_freq 2 922000000");//2
...
//********************
Serial2_String_Write("mac set_ch_freq 3 922200000");//3
...
//********************
Serial2_String_Write("mac set_ch_freq 4 922400000");//4
...
//********************
Serial2_String_Write("mac set_ch_freq 5 922600000");//5
...
//********************
Serial2_String_Write("mac set_ch_freq 6 922800000");//6
...
//********************
Serial2_String_Write("mac set_ch_freq 7 923000000");//7
...
//********************
Serial2_String_Write("mac set_rx2 2 923200000");
...
//********************
Serial2_String_Write("mac save");
...
}
//และเรียกใช้โดย Set_LoraConfig(); ใน setup function

กำหนดวิธีเชื่อมต่อเป็น ABP แบบ Class A โดยระบุข้อมูลที่ CAT ออกให้เพื่อใช้ในการเชื่อมต่อมี 4 อย่างดังนี้
3.1 Device EUI (deveui)
3.2 Device Address (devaddr)
3.3 Network Security Key (nwkskey)
3.4 Application Security Key (appskey)

//LoRa Configuration;
String DEV_EUI = "????????????????";
String DEV_ADDR = "????????";
String NWKS_KEY = "????????????????????????????????";
String APPS_KEY = "????????????????????????????????";
void Set_LoraConfigABP_A(void)
{
String str1 = "";
String cmdTemp = "";
//********************
Serial2_String_Write("mac set_class A");
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_class A");
Serial.println(str1);
//********************
cmdTemp = String("mac set_deveui ") + DEV_EUI;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_deveui");
Serial.println(str1);
//********************
cmdTemp = String("mac set_devaddr ") + DEV_ADDR;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_devaddr");
Serial.println(str1);
//********************
cmdTemp = String("mac set_nwkskey ") + NWKS_KEY;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_nwkskey");
Serial.println(str1);
//********************
cmdTemp = String("mac set_appskey ") + APPS_KEY;
Serial2_String_Write(cmdTemp.c_str());
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("set_appskey");
Serial.println(str1);
//********************
Serial2_String_Write("mac save");
str1 = "";
delay(3000);
str1 = Serial2.readString();
Serial.print("mac save");
Serial.println(str1);
//********************
Serial2_String_Write("mac join abp");
str1 = "";
delay(250);
str1 = Serial2.readString();
Serial.print("mac join abp");
Serial.println(str1);
}

//และเรียกใช้โดย Set_LoraConfig(); ใน setup function

ถ้าไม่มีอะไรผิดพลาด เมื่อเรา upload และ run โปรแกรม เราจะพบข้อความใน Terminal แสดงดังนี้

  1. ในตอน Setup function จะปรากฏข้อความดังภาพ
public setup(){
...
}

2. ในตอน Loop Function จะแสดงข้อความดังภาพ เนื่องจากเราวนลูปให้ส่งข้อความไป LoraWAN ทุก ๆ 20 วินาที

public loop(){
...
}

3. ทดลองส่งข้อมูลมายัง Node ผ่านเว็บของ CATTELECOM

  • port = 9
  • payload = 090807060504030201

จากผลของ Terminal จะเห็นข้อความ

>> Ok คือการตอบกลับเมื่อส่งคำสั่งไปยัง AcSIP S76S สำเร็จ

>> tx_ok คือการตอบกลับเมื่อส่งคำสั่ง mac tx ucnf FFFF ไปยัง AcSIP S76S

>> mac rx คือการรับข้อมูลที่ส่งมาจาก Network Server

จากที่กล่าวมาข้อมูลอยู่ในรูปที่เราไม่สามารถนำมาใช้ได้เลยทันที เราจำเป็นต้องทำการตัดเอาเฉพาะข้อมูลที่ต้องการมาใช้เท่านั้นก่อน

การส่งข้อมูลไปยัง Network Server

ในการส่งข้อมูลนั้นเราต้องการ 2 สิ่งคือ

  1. Port ที่จะส่ง — เลขจำนวนเต็มแบบไม่มีเครื่องหมาย
  2. ข้อมูลที่จะส่ง — โดยข้อมูลที่จะส่งต้องอยู่ในรูปแบบของเลขฐาน 16 (0–9,A-F) และเป็นจำนวนคู่ เท่านั้น
uint8_t port = 1;
String payload = "0123456789ABCDEF";

โดยการส่งข้อมูลจะทำการส่งแบบอนุกรม เขียนไปยัง Serial2 ในรูปแบบคำสั่งของชิบ AcSIP S76S

// ประกอบเป็นคำสั่งสำหรับส่งข้อมูลในรูปแบบ "mac tx ucnf 1 0123456789ABCDEF"
String commandSender = String("mac tx ucnf ") + String(port) + String(" ") + payload;
//เขียนข้อมูลไปยัง Serial2
Serial2_String_Write(commandSender.c_str());

และใน LoraWAN มีกฏห้ามส่งข้อมูลต่อเนื่องติด ๆ กัน ต้องส่งห่างกันอย่างน้อย 20 วินาที เราจึงต้องเขียนควบคุมเวลาการส่งให้ส่งออกทุก ๆ 20 วินาทีด้วย

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 20000; //ตัวแปรกำหนดไว้ที่ 20 วินาที
///////////////////////////////////
public loop(){
...
currentMillis = millis();
if (currentMillis - startMillis >= period){

// SEND UPLINK DATA
...
startMillis = currentMillis;
}

...
}

การรับข้อมูลจาก Network Server

เราจะเขียนรับข้อมูลไว้ในฟังก์ชั่น loop() โดยจะหน่วงเวลาไว้ที่ 1 วินาที ใช้ฟังก์ชั่น readString() ของ Serial2 แล้วแสดงออกมาทาง Terminal

public loop(){
...
if ((currentMillis - startMillis) / 1000 > 0) {
str4 = Serial2.readString();
if (str4 != "") {
Serial.println(str4);
}
}
...
}

ในบทความนี้ก็ขอจบไว้เพียงเท่านี้ครับ บทความหน้าเราจะมาเปลี่ยนให้มันเป็น Library พร้อมใช้งานกัน ชีวิตจะง่ายขึ้นเยอะ สวัสดีครับ

Choonewza

Written by

Choonewza

More From Medium

Related reads

Related reads

Decision Tree

161

Related reads

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade