โครงการนี้พยายามที่จะทำการทดสอบเทคโนโลยีการส่งสัญญาณ LORA เล็กน้อยเพื่อรวบรวมข้อมูลที่มูลนิธิ CTIC สามารถใช้งานได้ ข้อมูลจะถูกส่งจากอุปกรณ์สุดท้าย (โหนดหรือลูกค้า) ข้อมูลนี้จะถูกรวบรวมโดยอุปกรณ์เกตเวย์และในทางกลับกันจะส่งต่อไปยังเซิร์ฟเวอร์เพื่อจัดเก็บ
LORA เป็นเทคโนโลยีไร้สาย (เช่น WiFi, Bluetooth, LTE, Sigfox หรือ Zigbee) ที่ใช้การปรับความถี่วิทยุประเภทต่าง ๆ ที่จดสิทธิบัตรโดย Semtech
ปัจจุบันเทคโนโลยีดำเนินการโดย Alliance Lora ที่รับรองการผลิตฮาร์ดแวร์ทั้งหมดที่พยายามทำงานกับเทคโนโลยีนี้
LORA มี ความอดทนสูงต่อการรบกวน ความไวสูงในการรับข้อมูล (-168dB) การบริโภคที่ต่ำมาก (อุปกรณ์สามารถใช้งานได้หนึ่งทศวรรษด้วยแบตเตอรี่เดียว) และ ช่วง 10 ถึง 20 กม. (ขึ้นอยู่กับว่าการมองเห็นโดยตรงหรือทอพอโลยีของที่ดินมีอยู่) ในทางกลับกันเราพบ การถ่ายโอนข้อมูลที่ต่ำมาก (สูงสุด 255 ไบ)
ทั้งหมดนี้ทำให้เทคโนโลยีการถ่ายโอนนี้มีประโยชน์สำหรับ ระยะทางไกล หรือเครือข่าย IoT ที่ไม่ต้องการหรือไม่สามารถเข้าถึงกระแสไฟฟ้าได้
LORA ทำงานที่ความถี่ฟรี (นี่คือ 868MHz ในยุโรป 916MHz ในอเมริกาหรือ 433MHz ในเอเชีย) ซึ่งรวมถึงการรวบรวมผู้ที่ไม่จำเป็นต้องมีซัพพลายเออร์เครือข่ายไฟฟ้าและผู้ให้บริการโทรคมนาคม (เราใช้ radiofrequency)
เราสามารถสื่อสารกับอุปกรณ์ผ่าน Loremac (หรือที่รู้จักผ่าน Lora) หรือ Lorawan
LORAMAC : ใช้ในการสื่อสารสองอุปกรณ์ซึ่งกันและกันด้วยจุดหนึ่งไปยังจุดหนึ่งส่งข้อมูลและอื่น ๆ รวบรวม (หรือในทางกลับกัน)
LORAWAN : ใช้ในการสื่อสารเครือข่ายอุปกรณ์ ในวิธีการนี้ตัวเลขของเกตเวย์จะปรากฏขึ้น (อุปกรณ์ที่รวบรวมข้อมูลของอุปกรณ์หนึ่งตัวขึ้นไปและส่งต่อไปยังเซิร์ฟเวอร์) ใน Lorawan ข้อมูลจะต้องถูกกรองเพื่อทราบว่าอุปกรณ์ใดที่คุณควรฟังเกตเวย์และที่จะเพิกเฉย แต่จะเห็นในภายหลัง วิธีการนี้ใช้ทอพอโลยีดาว
ในทางกลับกันใน Lorawan มี อุปกรณ์หรือโหนดขั้นสุดท้ายสามประเภท :
*ในตัวอย่างการสนับสนุนเฉพาะโหนด Class A และ B (รองรับโดยไลบรารีที่ใช้) แต่มีการใช้งานประเภท A เท่านั้น
หากใช้แถบความถี่ฟรีในยุโรป (868MHz) ต้องคำนึงถึงข้อ จำกัด บางประการ:
ในแต่ละแถบความถี่มีหลายช่องทางหรือแถบย่อยในกรณีของยุโรป (868MHz) เราพบ 10 ช่อง สัญญาณตั้งแต่ 0 ถึง 9 แต่ตัวอย่างเช่นในอเมริกา (915MHz) เราสามารถค้นหาได้ถึง 64
การส่งข้อมูลผ่านช่องทางเดียวหรืออื่นเป็นงานที่ห้องสมุดมักจะอำนวยความสะดวกในการใช้งาน
ในบาง พื้นที่ มีความเป็นไปได้ที่จะปรับเปลี่ยน DatArrate หรืออุปกรณ์ กระจาย อุปกรณ์
Datarrate และการแพร่กระจายที่เกี่ยวข้อง: datarrate ของ 0 หมายถึง SF12 และ datarrate 5 หมายถึง SF7 ทั้งหมดที่ความถี่ 125kHz มีข้อยกเว้นดังต่อไปนี้: dataterate 6 หมายถึง SF7 ที่มี 250kHz
อุปกรณ์สองตัว (หนึ่งเครื่องสำหรับโหนดและอีกอันสำหรับเกตเวย์ซึ่งต้องมีการเชื่อมต่อ WiFi) และบัญชีที่เกี่ยวข้องใน TTS ( เครือข่ายสิ่งต่าง ๆ ) หรือ Chirpstack (สามารถใช้เซิร์ฟเวอร์ของตัวเองได้ที่บ้าน) ในตัวอย่างนี้ตัวอย่างทั้ง Loremac และ Lorawan ที่ใช้ประโยชน์จากโหนด Arduino และ Pycom Gateway
ในการเริ่มต้นมันก็เพียงพอที่จะโคลนที่เก็บ:
git clone https://github.com/Javieral95/Getting_Started_With_LoRa.git
จากนั้นอัปโหลดโครงการที่เกี่ยวข้องไปยังอุปกรณ์
ทำไมต้องเป็นสอง ides? Simple, PyMAKR ส่วนขยายแทบจะไม่ทำงานใน Visual Studio Code อย่าลังเลที่จะใช้พื้นที่ทำงานที่สะดวกสบายที่สุด
อุปกรณ์ทั้งสองมี antera lora เชื่อมต่อกับพวกเขา
หมายเหตุ : รหัสสำหรับ ArduinomkR1300 (เตรียมพร้อมสำหรับการใช้งานเช่น Lora End-Device) และรหัสเพื่อใช้ pysense หรือ pytrack เป็น end-evex รวมอยู่ใน repos

ตัวอย่าง Loramac (พบได้ในโฟลเดอร์ Homonym) เป็นการใช้งานการใช้งานอุปกรณ์สุดท้ายของ Arduino และเกตเวย์ Pycom
โหนดจะส่งข้อมูลฮาร์ดโค้ดเท่านั้นและเกตเวย์จะเชื่อมต่อกับ LORA และ WiFi เท่านั้นรับข้อมูล PYCOM และพิมพ์ข้อมูลที่อ่าน (แม้ว่าจะใช้ฟังก์ชันการส่งข้อมูลไปยังเครือข่าย)
การใช้เซิร์ฟเวอร์เครือข่ายนั้นถูกแจกจ่ายด้วย
หากต้องการทราบข้อมูลเพิ่มเติมคุณสามารถเข้าถึงโฟลเดอร์ /Loramac
สำหรับการใช้ตัวอย่างเหล่านี้ (ซึ่งเป็นการใช้งานการใช้งานอุปกรณ์สุดท้ายของ Arduino และเกตเวย์ Pycom) จำเป็นต้องใช้เซิร์ฟเวอร์เพื่อให้เห็นภาพข้อมูล ในตัวอย่างนี้การใช้ เครือข่ายสิ่งต่าง ๆ และ Chirpstack (ก่อนหน้านี้รู้จักกันในชื่อ Loraserver) ได้รับการแก้ไขแล้ว
หากต้องการทราบข้อมูลเพิ่มเติมคุณสามารถเข้าถึงโฟลเดอร์ /Lorawan จากนั้นดำเนินการปรึกษาเอกสารนี้ต่อไป
Lorawan มีสองประเภทใน Lorawan:
*ในตัวอย่างในขณะนี้มีเพียง OTAA เท่านั้น
ดังที่ได้กล่าวไว้ก่อนหน้านี้เราจะต้องมีเซิร์ฟเวอร์ สำหรับตัวอย่างนี้มีการใช้งานเครือข่ายสิ่งต่าง ๆ ฟรีเซิร์ฟเวอร์ Chirpstack ที่ PYCOM เป็นเจ้าของและใช้งานที่บ้านที่บ้านได้ถูกนำมาใช้
เป็นทางเลือกที่น่าเชื่อถือที่สุดปลอดภัยและดีกว่า อย่างไรก็ตามทุกอย่างบ่งชี้ว่ามันจะหยุดเปิด (มีขีด จำกัด 50 โหนดต่อแอปพลิเคชัน)
การสร้างแอปพลิเคชันนั้นง่ายเข้าถึงเมนูและคลิกที่ปุ่ม + เมื่อเราระบุชื่อของแอปพลิเคชันรหัสที่ไม่ซ้ำกันและคำอธิบาย
เมื่อแอปพลิเคชันถูกสร้างขึ้นเราสามารถเพิ่มอุปกรณ์สุดท้าย (โหนด) คลิกที่ปุ่ม +
เกตเวย์เป็นอุปกรณ์ที่รับผิดชอบในการส่งทราฟฟิกที่มาจากอุปกรณ์สุดท้ายหลายเครื่อง (เป็นของแอปพลิเคชันหลายรายการ) และส่งต่อไปยังเซิร์ฟเวอร์ การสร้างเกตเวย์นั้นง่ายมากคลิกที่ปุ่ม + และกรอกแบบฟอร์มให้ความสนใจกับแนวคิดต่อไปนี้:
เพื่อให้สามารถอ่านข้อมูลที่โหนดได้ส่งไปยังเซิร์ฟเวอร์จำเป็นต้องถอดรหัสเพย์โหลดในกรณีของ TTN เราจะทำมันสำหรับแต่ละอุปกรณ์ในแท็บ Payload Formatters เราเลือกวิธี การพิมพ์ตัว เลือก JavaScript และ::
function Decoder(bytes, port) {
// Decode plain text; for testing only
return {
myTestValue: String.fromCharCode.apply(null, bytes)
};
}
arduino_ttn_decoder.js เป็นที่ยอมรับว่าที่อยู่เลขฐานสิบหกของเครือข่ายสิ่งต่าง ๆ อยู่ในนายกเทศมนตรีมันไม่สำคัญเมื่อเขียนโปรแกรมอุปกรณ์ แต่ข้อผิดพลาดได้รับความเดือดร้อนในเวอร์ชันที่ผ่านมา
นี่คือทางเลือกโอเพ่นซอร์สมันยังอยู่ในระหว่างการพัฒนาและเอกสารของมันไม่ดีนัก อย่างไรก็ตามมันใช้งานได้และอนุญาตให้เปิดใช้งานเซิร์ฟเวอร์
PyCom เสนอเซิร์ฟเวอร์ Chirpstack เพื่อเชื่อมต่ออุปกรณ์เกตเวย์ของคุณ
แอปพลิเคชันคล้ายกับรายละเอียดในส่วนของเครือข่ายสิ่งต่าง ๆ
คุณต้องไปที่ โปรไฟล์อุปกรณ์ ของส่วนเซิร์ฟเวอร์หนึ่งครั้งในการเข้าถึงโปรไฟล์ที่สนใจ (OTAA ในกรณีนี้) และแก้ไขเวอร์ชัน:
ในการสร้างเกตเวย์ให้เข้าถึงชื่อเดียวกันและคลิกปุ่ม + กรอกแบบฟอร์มที่ให้ความสนใจเป็นพิเศษกับฟิลด์ Gateway ID (64 บิตในเลขฐานสิบหกที่ระบุเกตเวย์) คุณสามารถทำให้ chirpstack สร้างขึ้นสำหรับคุณ แต่ Mac ของอุปกรณ์มักจะใช้ (ถ้าคุณไม่ทราบในส่วน
คุณสามารถทิ้งค่าเริ่มต้นที่เหลือไว้
ในการอ่านข้อมูลที่โหนดได้ส่งไปยังเซิร์ฟเวอร์จำเป็นต้องถอดรหัสเพย์โหลดในกรณีของ Chirpstack เราจะทำมันสำหรับแต่ละโปรไฟล์อุปกรณ์ในอุปกรณ์ propiles _ เราเข้าถึงโปรไฟล์ที่สนใจเรา (ในกรณีนี้ OTAA) และเราเข้าถึงแท็บ ตัวแปลงสัญญาณ :
เราเลือกใน ฟังก์ชันตัวแปลงสัญญาณ Decipt ที่กำหนดเอง และ::
function Decode(fPort, bytes) {
var tempObj = new Object();
tempObj.data=bytes;
tempObj.decodedData = String.fromCharCode.apply(null, bytes);
tempObj.message = "Informacion recibida del nodo";
return tempObj;
}
arduino_chirpstark_decoder.js เป็นที่ยอมรับว่าที่อยู่ hexadecimal ทั้งหมดของ chirpstack อยู่ในจิ๋วมันไม่สำคัญเมื่อเขียนโปรแกรมอุปกรณ์ แต่ข้อผิดพลาดได้รับความเดือดร้อนในเวอร์ชันที่ผ่านมา
Chirpstack จัดหาทางเลือก OpenSource เพื่อเปิดตัวเซิร์ฟเวอร์ส่วนตัวของเราใน Lorawan และช่วยให้เราสามารถทำมันได้อย่างง่ายและผ่านคอนเทนเนอร์
นั่นคือเหตุผลที่พื้นที่เก็บข้อมูลอื่นที่เป็นเจ้าของโดยผู้ก่อตั้ง Chirpstack (Brocar) ที่อนุญาตให้ดำเนินการนี้: Chirpstack-Docker ถูกโคลนในที่เก็บปัจจุบัน เราพบมันในโฟลเดอร์ chirpstack-docker
Chirpstack มีส่วนประกอบต่าง ๆ ในสถาปัตยกรรมเพื่อให้บริการสามารถใช้งานได้พวกเขามีดังต่อไปนี้:

วิธีการแสดงเซิร์ฟเวอร์ในรูปแบบของคอนเทนเนอร์ช่วยให้เราสามารถนามธรรมส่วนประกอบสถาปัตยกรรมส่วนใหญ่ได้อย่างไรก็ตามมีรายละเอียดด้านล่าง:
ก่อนที่จะปรับใช้พารามิเตอร์ที่จำเป็นทั้งหมดจะต้องได้รับการกำหนดค่าในไฟล์การกำหนดค่าที่เก็บไว้ในบอร์ด การกำหนดค่า
คุณสามารถปรึกษาเอกสารอย่างเป็นทางการต่อไปนี้:
หมายเหตุ: ไฟล์การกำหนดค่ามีความอ่อนไหวต่อช่องว่างหรือบรรทัดที่ว่างเปล่า (พบในเครือข่ายยุง) ตรวจสอบไฟล์และกำจัดเพื่อหลีกเลี่ยงข้อผิดพลาด
ดังที่ได้กล่าวไปแล้วก่อนหน้านี้การปรับใช้ในคอนเทนเนอร์นั้นง่ายและอยู่ในไดเรกทอรี chirpstack-docker
เมื่อมีการกำหนดค่าที่จำเป็นแล้วมันก็เพียงพอที่จะวางไว้ในไดเรกทอรี Chirpstack-Docker และเปิดตัว:
docker-compose up
ด้วยการกำหนดค่าเริ่มต้นคุณสามารถเข้าถึงเซิร์ฟเวอร์ใน ทิศทางท้องถิ่น: 8080 ผู้ใช้จะเป็น ผู้ดูแลระบบ และรหัสผ่าน ผู้ดูแลระบบ
เริ่มเพิ่มการกำหนดค่าพื้นฐาน:
เมื่อเซิร์ฟเวอร์ได้รับการกำหนดค่าแล้วเราจะต้องลงทะเบียนเกตเวย์ของเราและสร้างแอปพลิเคชันเพื่อบันทึกอุปกรณ์สุดท้ายของเรา กระบวนการนี้ดำเนินการแบบอะนาล็อกกับที่อธิบายไว้ในส่วนก่อนหน้าของเอกสารนี้: Chirpstack (Lora Server)
นอกจากนี้ฟังก์ชั่นที่ถอดรหัสและเข้ารหัสข้อมูลที่ได้รับจะต้องระบุมันยังมีการอธิบายในส่วนก่อนหน้า
รหัสที่ใช้ในการเรียกใช้เกตเวย์มีรายละเอียดด้านล่างใน pycom (fipy กับ pytrack) รหัสนี้ตั้งอยู่ใน Lorawan/Lorapycomgateway
ห้องสมุด Nanogateway PY ถูกนำมาใช้เพื่อให้ Gateway เปิดตัวในไม่กี่นาที
Nano-Gateway แปลงอุปกรณ์ PYCOM ให้เป็น เกตเวย์อย่างง่ายที่ฟังช่องสัญญาณความถี่ (monochanal) เพื่อฟังแถบเพิ่มเติมใน PyCOM เป็นไปได้ที่จะต้องใช้เกตเวย์เชิงพาณิชย์
ในไฟล์กำหนดค่าทุกอย่างที่จำเป็นในการปรับแต่งเกตเวย์:
WIFI_MAC = ubinascii.hexlify(machine.unique_id()) #.toUpper() para TTS
SERVER = 'loraserver.pycom.io' #(or url of your server)
GATEWAY_ID = WIFI_MAC[:6] + "ffff" + WIFI_MAC[6:12] #Minusculas: Chirpstack
NTP = "es.pool.ntp.org"
NTP_PERIOD_S = 3600
#WiFi settings (change it)
WLAN_SSID = "MyAwesomeWiFi" #"pycom-wifi"
WLAN_PASS = "CheckOutThisGoodPassword" #"securepassword"
WLAN_TIMEOUT_MS = 180000
### LoRaWAN for EU868 ###
LORA_FREQUENCY = 868500000
#Spreading Factor: (Higher value in SF=More distance but less speed transmision)
LORA_GW_DR = "SF7BW125" # DR_5,Can change in range: SF7 to SF15 (SF7B250 also exists)
LORA_NODE_DR = 5 #5 (6 uses 250Khz) for SF7, 4 for SF6.. all using 125Khz
###
def get_gateway_id():
print("Your gateway_id is: {}".format(GATEWAY_ID)) #The gateway is b'THIS_STRING'
return GATEWAY_ID
หมายเหตุ: หากคุณเชื่อมต่อเกตเวย์ของคุณกับเครือข่ายท้องถิ่นโดยไม่ต้องเชื่อมต่ออินเทอร์เน็ตมันจะส่งคืนข้อผิดพลาดเมื่อซิงโครไนซ์นาฬิกา คุณสามารถ ออกจากขั้นตอน การแสดงความคิดเห็นเกี่ยวกับบรรทัดของรหัสต่อไปนี้ในฟังก์ชั่น เริ่มต้น (ตนเอง) ของไฟล์ nanogateway.py ตามตัวอย่างต่อไปนี้แสดง:
# get a time sync
self._log('Syncing time with {} ...', self.ntp_server)
#self.rtc.ntp_sync(self.ntp_server, update_period=self.ntp_period)
#while not self.rtc.synced():
# utime.sleep_ms(50)
self._log("RTC NTP sync complete")
ไม่ได้ใช้ฟังก์ชั่นไฟล์หลักหลายฟังก์ชั่น แต่จำเป็นต้องเปิดเกตเวย์ดังนี้และจะใช้งานได้แล้ว
def init_loraWAN_gateway():
print("Initializing LoRaWAN nano Gateway")
nanogw = NanoGateway(
id=config.GATEWAY_ID,
frequency=config.LORA_FREQUENCY,
datarate=config.LORA_GW_DR,
ssid=config.WLAN_SSID,
password=config.WLAN_PASS,
server=config.SERVER,
port=config.PORT,
ntp_server=config.NTP,
ntp_period=config.NTP_PERIOD_S
)
print("Ok! Now you have a LoRaWAN Gateway! Lets start it, wait . . .")
pycom.rgbled(0xAA0000)
nanogw.start()
nanogw._log('. . . Yeah! Nano gateway is connected and running, enjoy the log:')
pycom.rgbled(0x000000)
PYCOM จะเก็บแสงสีแดงไว้จนกว่าจะเชื่อมต่อเมื่อฟังอุปกรณ์ของอุปกรณ์จะกะพริบ LED สีเขียว
ต่อไปนี้มีรายละเอียดในการใช้งานโหนดคลาส A โดยใช้ Arduino
ทฤษฎีใช้ช่องทั้งหมดที่มีอยู่ในแถบความถี่หลังจากนั้นจะเห็น วิธี การบังคับเพียงหนึ่งเดียวเท่านั้น (ไม่แนะนำ)
ห้องสมุด MCCI Arduino Lorawan ถูกนำมาใช้ซึ่งช่วยให้คุณสามารถสรุปการสื่อสาร LORA ได้หลายแง่มุม มันได้รับการติดตั้งโดย Manager Platformio Library
โดยพื้นฐานแล้วรหัสที่ใช้สำหรับไคลเอนต์ Arduino คือรหัสที่พบในตัวอย่าง ttn-otaa.ino ของไลบรารียกเว้นการดัดแปลงบางอย่าง
การกำหนดค่าทำในสองไฟล์ที่แตกต่างกัน:
การกำหนดค่าทั้งหมดที่เกี่ยวข้องกับ Lorawan ดังที่ระบุไว้ข้างต้นจะระบุไว้ในไฟล์ lorawan.cpp ที่จุดเริ่มต้นของเอกสารมีรายละเอียดว่าควรระบุข้อมูล: APP_EUI , Dev_EUI และ APP_KEY (มองไปที่รูปแบบที่ระบุไว้ด้านล่าง)
จากนั้นตัวอย่างใน Chirpstack:
static const u1_t PROGMEM APPEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const u1_t PROGMEM DEVEUI[8] = {0x7b, 0x6b, 0xff, 0x2c, 0x7b, 0x2c, 0x19, 0x5a};
static const u1_t PROGMEM APPKEY[16] = {0xbd, 0x21, 0x5a, 0x82, 0xb2, 0xf7, 0x92, 0xf3, 0xc7, 0xcb, 0xb2, 0x88, 0xc7, 0x55, 0x33, 0xe7};
ภายใต้การกำหนดค่าคีย์ทั้งหมดในไฟล์ loraWan.cpp เราสามารถเลือกได้ว่าจะส่งข้อความหรือข้อมูลแบนจากเซ็นเซอร์อุณหภูมิและความชื้น Decomes ตัวเลือกที่ต้องการ:
/******* Send data config *******/
// Use this to send a Hello world in plain text
// static uint8_t mydata[] = "Hello World!";
// Use this to send sensor data
const int neededBytes = 4; // 4 bytes: 2 for temperature and 2 for humidity, can change this value
static byte mydata[neededBytes];
static LoraEncoder encoder(mydata);
จะต้องใช้ข้อมูลที่ส่งหรือฟังก์ชั่นอื่น ๆ ขึ้นอยู่กับข้อมูลที่ระบุไว้ในส่วนของเครือข่ายสิ่งต่าง ๆ และ Chirpstack
ดังที่เคยเห็นก่อนหน้านี้แผ่น Nano-Gateway Pycom สามารถอ่านได้ในช่องทางในขณะที่อุปกรณ์ Arduino Final สามารถออกอากาศในช่องวงดนตรีทั้งหมด (ตัวอย่างเช่นในวงดนตรียุโรปมี 10 ช่องทาง) แม้ว่าจะไม่แนะนำ (กฎ 1%อาจถูกละเมิด) สามารถถูกบังคับให้ใช้เฉพาะช่องและความถี่เท่านั้นเนื่องจากปัญหาการพัฒนาและการทดสอบ
สำหรับสิ่งนี้มีความจำเป็นที่จะต้องแก้ไขรหัสห้องสมุดโดยเฉพาะอย่างยิ่ง lorabase_eu868.h (ในกรณีของการใช้ความถี่ในยุโรป) และบังคับให้ความถี่ที่ต้องการในการออกดังนี้ (สังเกตว่าค่าทั้งหมดได้รับการบันทึกความถี่ 868.MHz):
enum {
EU868_F1 = 868500000, // g1 SF7-12
EU868_F2 = 868500000, // g1 SF7-12 FSK SF7/250
EU868_F3 = 868500000, // g1 SF7-12
EU868_F4 = 868500000, // g2 SF7-12
EU868_F5 = 868500000, // g2 SF7-12
EU868_F6 = 868500000, // g3 SF7-12
EU868_J4 = 868500000, // g2 SF7-12 used during join
EU868_J5 = 868500000, // g2 SF7-12 ditto
EU868_J6 = 868500000, // g2 SF7-12 ditto
};
enum {
EU868_FREQ_MIN = 868500000,
EU868_FREQ_MAX = 868500000
};
ควรเรียกใช้ฟังก์ชันต่อไปนี้ที่จุดเริ่มต้นของ LORA ( LORAWAN_STARTJOB () ฟังก์ชัน:
// Define the single channel and data rate (SF) to use
void disableChannels(int selectedChannel, int dr)
{
// Disable all channels, except for the one defined above.
// ONLY FOR TESTING AND DEVELOPING!
for (int i = 0; i < 9; i++)
{ // For EU; for US use i<71
if (i != selectedChannel)
{
LMIC_disableChannel(i);
}
}
// Set data rate (SF) and transmit power for uplink
LMIC_setDrTxpow(dr, 14);
}
ช่องและ daterate ที่จะกำหนดค่าอยู่ที่จุดเริ่มต้นของไฟล์ในบรรทัด (โดยค่าเริ่มต้น: ช่อง 0 และข้อมูลที่ต้องการของปัจจัยการแพร่กระจาย 7 ซึ่งมีค่า 5):
/******* Channel config (only change if you want to uses a single channel) *******/
const int channel = 0; // Use if you want to use only one Band's Channel.
const int dr = DR_SF7; // Use if you want to use a specific datarate (The spreading factor mark the dr's value).
สิ่งนี้จะทำให้การสูญเสียแพ็คเกจลดลงอย่างมากแม้ว่าจะมีบางอย่างที่เกตเวย์ไม่ได้รับ
เพียงคัดลอกโครงการไปยังจาน Arduino ของคุณ
ร้านหนังสือทำงานโดยกิจกรรมในกรณีนี้สิ่งที่สำคัญที่สุดคือการรับรองความถูกต้อง (เมื่อคุณทำเสร็จคุณจะเห็นกุญแจในคอนโซล) และการจัดส่งข้อมูล
เหตุการณ์ที่ข้อมูลถูกส่งจะเป็น ev_txcomplete ใน ฟังก์ชันโมฆะ onevent (ev_t eV) ของไฟล์ lorawan.cpp สังเกตว่าเหตุการณ์นั้นรวมถึง "หน้าต่าง RX" ซึ่งเป็นเวลาที่อุปกรณ์ฟัง
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen)
{
Serial.print(F("Received "));
Serial.print(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
break;
ฟังก์ชั่นในไฟล์เดียวกันซึ่งจะมีรายละเอียดว่าข้อมูลใดที่ส่งคือ do_send (ความคิดเห็นหรือแยกแยะบรรทัดที่เข้ารหัสข้อมูลหากคุณต้องการส่งข้อความแบน):
void do_send(osjob_t *j)
{
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND)
{
Serial.println(F("OP_TXRXPEND, not sending"));
}
else
{
// Leer datos de sensor y codificar (Libreria LoRa_Serialization).
am2315_readedData data = readAM2315Data();
encoder.writeTemperature(data.temp);
encoder.writeHumidity(data.hum);
// Comentar las dos lineas "encoder" para enviar texto plano
// Send packet
LMIC_setTxData2(1, mydata, sizeof(mydata), 0);
if (isLoopRunning)
{
freq = String(LMIC.freq);
Serial.println("-->Packet queued using freq = " + freq);
// Prepare upstream data transmission at the next possible time.
printSensorInfoInDisplay(data.temp, data.hum);
printLoraSentInDisplay(freq);
}
}
// Next TX is scheduled after TX_COMPLETE event.
}
หมายเหตุ : ข้อผิดพลาดได้รับความเดือดร้อนที่ป้องกันไม่ให้โหนดได้รับแพ็คเกจกลับดังนั้นจึงเป็นไปไม่ได้ที่จะตรวจสอบอุปกรณ์ที่อยู่ด้านหน้าของเซิร์ฟเวอร์ มีการเพิ่มใน การตั้งค่าลูกค้า () (โดยเฉพาะอย่างยิ่งในฟังก์ชัน lorawan_startjob () ของไฟล์ lorawan.cpp ) บรรทัดรหัสต่อไปนี้ที่เพิ่มข้อผิดพลาดนาฬิกาสูงสุด 10%:
LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);
ทั้ง Chirpstack และ Things Network เสนอชุดของการรวมเพื่อส่งข้อมูลที่เซิร์ฟเวอร์ของเราได้รับไปยังบริการอื่น ๆ ตัวอย่างเช่น: เราสามารถส่งข้อมูลไปยังฐานข้อมูลที่มีอิทธิพลได้ใช้ประโยชน์จาก MQTT เชื่อมต่อกับ AWS Services หรือ Azure ...
ในส่วนนี้จะเห็นกรณีที่เป็นประโยชน์ซึ่งเราสามารถใช้การรวม HTTP (webhooks ในเครือข่ายสิ่งต่าง ๆ ) และ MQTT เพื่อส่งข้อมูลที่อุปกรณ์ของเราส่งและเซิร์ฟเวอร์ของเราได้รับแอปพลิเคชันของตัวเอง
เพื่อเข้าถึงการรวม:
ใน กรณี ที่ใช้ Chirpstack เรา สนใจ
ในเซิร์ฟเวอร์ทั้งสองการรวมนี้ทำงานในลักษณะเดียวกัน: เปิดตัวกิจกรรมทุกครั้งที่อุปกรณ์แอปพลิเคชันส่งข้อมูล (ในกรณีของ TTN เราต้องทำเครื่องหมายกล่อง ข้อความอัปลิงค์ ) และด้วยข้อมูลนี้จะมีการเปิดตัวคำขอโพสต์ -ype HTTP ไปยัง URL ที่เราระบุ
หมายเหตุ: แนวทางปฏิบัติที่ดีไม่ว่าจะเป็นการตรวจสอบว่าเหตุการณ์นั้นเปิดตัวอย่างถูกต้องหรือเพื่อให้เห็นภาพรูปแบบข้อมูลคือการเข้าถึงบริการ postbin ซึ่งเราสามารถสร้าง ถังขยะ (URL ชั่วคราวเพื่อรับคำขอ)
หมายเหตุ 2: หากแอปพลิเคชันที่คุณจะเปิดตัวคำร้องจะอยู่ใน LocalHost และเซิร์ฟเวอร์ Chirpstack ด้วย (ในวิธี dokerized ดังที่แสดงในเอกสารนี้) คุณจะต้องระบุ URL ดังนี้:
http://host.docker.internal:PUERTO/uri
เอกสารนี้ครอบคลุมเฉพาะการใช้ Chirpstack และ TTN ไม่ได้บันทึกไว้เพื่อส่งข้อมูล (มีรูปแบบที่แตกต่างกันในคำร้อง)
หากข้อมูลได้รับการถอดรหัสด้วยตัวอย่างของพื้นที่เก็บข้อมูลนี้ (โฟลเดอร์ Decoders-Integrations ) เราจะได้รับร่างกายในคำขอคล้ายกับต่อไปนี้:
{
"applicationID": 0,
"applicationName": "Name",
"deviceName": "DeviceName",
"devEUI": "BYTES_EUI",
"txInfo": [Object object],
"adr": true,
"dr": 5,
"fCnt": 24,
"fPort": 1,
"data": "DATA_WITHOUT_DECODE",
"objectJSON": {
"data":"DATA_WITHOUT_DECODE==",
"decodedData":{
"humidity":37,"temperature":23
},
"message":"Informacion recibida del nodo"
},
"tags": [Object object],
"confirmedUplink": false,
"devAddr": "BYTES_DEV_ADDR"
}
ObjectJson เป็นวัตถุที่ส่งคืนโดยฟังก์ชั่น ตัวถอดรหัส ของเรา
Para leerlo, por ejemplo en una aplicación JavaScript bastaría con hacer algo parecido a lo siguiente (más en el archivo /Decoders-Integrations/arduino_Chirpstack_Http_Integration.js )
const { deviceName, objectJSON, devAddr} = req.body;
var sensorData = JSON.parse(objectJSON);
//devAddr esta codificado!
var temperature = sensorData.decodedData.temperature;
var humidity = sensorData.decodedData.humidity;
Realmente, a no ser que usemos MQTTS (Mqtt con TLS) no será necesario acceder a ninguna integración desde la aplicación web del servidor.
En este ejemplo suscribiremos nuestra aplicación al topico al que nuestro dispositivo final enviará los datos.
Si nuestra aplicación esta lanzada en local y el servidor Chirpstack también (dockerizado como hemos mostrado en esta documentación), el host del broker será la IP de la máquina WSL. Para conocer este dato lanzaremos:
wsl hostname -I
También habrá que realizar algunas configuraciones lanzando los siguientes comandos (1883 es el puerto de Mosquitto, si se usa otro modificarlo):
netsh interface portproxy add v4tov4 listenport=1883 listenaddress=0.0.0.0 connectport=1883 connectaddress=127.0.0.1
Podemos usar MQTT tal y como viene en el ejemplo de docker, con el parametro anonymous con valor true (sin usar ningún tipo de contraseña o lista de usuarios) o podemos configurar un listado de usuarios (cada uno con los topicos que pueden leer o escribir) con sus respectivas contraseñas (como indica la siguiente documentación).
Para ello, lanzaremos los siguientes comandos (podemos lanzarlos desde WSL ), cada uno de ellos nos pedirá que introduzcamos una contraseña para cada usuario (en este ejemplo se ha usado pass para todos):
# Create a password file, with users chirpstack_gw, chirpstack_ns, chirpstack_as, bob and nodeApp
sudo mosquitto_passwd -c /etc/mosquitto/passwd chirpstack_gw
sudo mosquitto_passwd /etc/mosquitto/passwd chirpstack_ns
sudo mosquitto_passwd /etc/mosquitto/passwd chirpstack_as
sudo mosquitto_passwd /etc/mosquitto/passwd bob
sudo mosquitto_passwd /etc/mosquitto/passwd nodeApp
# Optional, Secure the password file
sudo chmod 600 /etc/mosquitto/passwd
Esto nos creará el fichero passwd que contendrá todos los usuarios y contraseñas, ahora podremos configurar un listado de acls en un fichero homónimo como el siguiente:
user chirpstack_gw
topic write gateway/+/event/+
topic read gateway/+/command/+
user chirpstackns
topic read gateway/+/event/+
topic write gateway/+/command/+
user chirpstack_as
topic write application/+/device/+/event/+
topic read application/+/device/+/command/+
user bob
topic read application/123/device/+/event/+
topic write application/123/device/+/command/+
user nodeApp
topic read application/+/device/#
topic write application/+/device/#
Ahora, deberemos modificar la configuración del servidor para utilizar estas credenciales modificando los ficheros albergados en /chirpstack-docker/configuration :
[application_server.integration.mqtt]
server="tcp://mosquitto:1883"
username="chirpstack_as"
password="pass"
[integration.mqtt.auth.generic]
servers=["tcp://mosquitto:1883"]
username="chirpstack_gw"
password="pass"
[network_server.gateway.backend.mqtt]
server="tcp://mosquitto:1883"
username="chirpstack_ns"
password="pass"
listener 1883
password_file /mosquitto/config/passwd
acl_file /mosquitto/config/acls
allow_anonymous false
mosquitto:
image: eclipse-mosquitto:2
ports:
- 1883:1883
volumes:
- ./configuration/eclipse-mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
- ./configuration/eclipse-mosquitto/passwd:/mosquitto/config/passwd
- ./configuration/eclipse-mosquitto/acls:/mosquitto/config/acls
En este ejemplo usaremos una aplicación NodeJS para conectarnos a nuestro servidor local Chirpstack dockerizado. Todo el código podemos encontrarlo en el archivo /Decoders-Integrations/arduino_Chirpstack_mqtt_Integration.js .
Lo primero, tendremos que instalar el paquete mqtt
npm install mqtt --save
Con él, ya podremos conectarnos al broker:
var mqtt = require('mqtt')
const host = 'WSL_IP'
const port = '1883' //or your port
const clientId = 'mqtt_NodeApp_' + Math.random().toString(16).slice(3)
const connectUrl = 'mqtt://' + host + ':' + port;
const client = mqtt.connect(connectUrl, {
clientId,
clean: true,
//username: "nodeApp", //Descomentar si usamos contraseñas y acls
//password: "pass", //Colocar el usuario y contraseña correspondiente
connectTimeout: 4000,
reconnectPeriod: 1000,
debug: true
})
Y suscribirnos al topico deseado (el caracter # es un wildcard multinivel, significa que leemos cualquier subtopico, mientras que el caracter + es un wildcard de un solo nivel).
const chirpstackApplicationID = 1; //Check url, for example: http://localhost:8080/#/organizations/1/applications. /1/ is the ID
const chirpstackDeviceID = "DEV_EUI";
const chirpstackReadAppTopic = "application/" + chirpstackApplicationID + "/device/#";
const chirpstackWriteAppTopic = "application/" + chirpstackApplicationID + "/device/"+chirpstackDeviceID+"/EXAMPLE";
Usaremos los siguientes eventos para ello:
//Evento al conectarse
client.on('connect', function () {
console.log("Connected")
client.subscribe(chirpstackReadAppTopic, function (err) {
if (!err) {
console.log("Subscribed to topic: "+chirpstackReadAppTopic)
//client.publish(chirpstackWriteAppTopic, 'Hello mqtt') //Podemso enviar un mensaje para debugear
}
else {
console.log("Error in connection:")
console.log(err)
}
})
})
//Evento al recibir un mensaje
client.on('message', function (topic, message) {
// El mensaje es un buffer, convertimos a String.
var stringMsg = message.toString();
console.log(topic + " - " + stringMsg)
insertSensorEntry_Mqtt(topic, stringMsg); //Funcion que lee el mensaje e inserta en base de datos
})
En ambos servidores (Chirpstack y The Things Network) la integración tiene por nombre MQTT , eso sí, antes de realizar ninguna integración debemos configurar los certificados.
A continuación se documentará como realizar la integración con MQTT en un servidor local de Chirpstack (para más info revisar el apartado ChirpStack privado en local de esta documentación).
Antes de generar los certificados, debemos tener instalado CFSSL & CFSSLJSON. Tras ello, clonaremos el siguiente repositorio propiedad del creador de Chirpstack y seguiremos los pasos de su documentación: Chirpstack-Certificates.
NOTA: Si se usa Windows, instalar los pre-requisitos en la máquina WSL pues se necesitará hacer uso del comando make .
Colocamos la carpeta certs generada con el proyecto Chirpstack-Certificates en nuestro proyecto Chirpstack-Docker . Después modificados el archivo docker-compose.yml para añadir a cada contenedor el volumen que contendrá los certificados correspondientes.
Seguimos siguiendo la documentación del proyecto Chirpstack-Certificates para realizar todas las modificaciones pertinentes en la configuración del servidor:
Como hemos visto anteriormente, el evento que se lanza al recibir un mensaje llama a una función que lee el mensaje recibido y lo descodifica.
El formato del mensaje recibido (si hemos usado los descodificadores del ejemplo) es una cadena de texto con el siguiente contenido:
{"applicationID":"1","applicationName":"APP_NAME","deviceName":"DEV_NAME","devEUI":"DEV_ADDRESS", "txInfo":{"frequency":868500000,"dr":5},"adr":true,"fCnt":2, "fPort":1,"data":"DATA","object":{"data":"DATA","decodedData":{"humidity":0,"temperature":-327},"message":"Informacion recibida del nodo"}}
Y es lo que buscamos leer en la siguiente función:
function insertSensorEntry_Mqtt(topic, msg){
console.log("INSERTAMOS DATO DE SENSOR RECIBIDO POR MQTT EN TOPICO: "+topic);
const parseMsg = JSON.parse(msg); //Recordar haber hecho un ToString al buffer antes!
var deviceName = parseMsg.deviceName;
var devAddr = parseMsg.devEUI; //No codificado
var temperature = parseMsg.object.decodedData.temperature;
var humidity = parseMsg.object.decodedData.humidity;
var success = true;
}
object es el objeto retornado por nuestra función Decoder .
Como bien se sabe, la tasa de transferencia de LoRA es muy baja, lo que provoca una gran perdida de paquetes y una enorme latencia cuando se envía información:
Algunos expertos indican que es necesario cierta distancia entre los dispositivos (30m y preferiblemente algún obstaculo entre ellos) para que la comunicación sea más fluida. No ha sido probado y solo se ha lanzado con las dos tarjetas en un extremo cada una de un piso.
Por otro lado se hace uso de versiones antiguas de LoRaWAN (1.0.2 y 1.0.3) que tienen problemas de seguridad que se solventan en parte en las siguientes versiones (1.0.4 y 1.1.0, esta última también implementa re-conectividad en caso de desconectarse de la red LoRaWAN), pero no se dispone de librerias para trabajar con ellas.
Esto no quita que esta técnología pueda ser muy interesante y útil en el futuro debido a no depender de proveedores externos (de comunicaciones y electricidad), siendo una opción ecónomica y muy llamativa para utilizar en proyectos IoT de grandes ciudades o entornos rurales.
Este proyecto ha sido realizado para la Fundación CTIC, su uso es libre y no es necesarío ningún crédito en su uso (Revisar las licencia de las librerias utilizadas).