
“ ไร้สายทำให้ง่าย!” -การเพิ่มการเชื่อมต่อ lora peer-to-peer ลงในแอปพลิเคชัน Lorawan ที่มีอยู่

ภายใต้การปฏิบัติตามข้อกำหนดเหล่านี้คุณอาจใช้ซอฟต์แวร์ไมโครชิปและอนุพันธ์ใด ๆ กับผลิตภัณฑ์ไมโครชิปโดยเฉพาะ เป็นความรับผิดชอบของคุณที่จะต้องปฏิบัติตามข้อกำหนดใบอนุญาตของบุคคลที่สามที่ใช้บังคับกับการใช้ซอฟต์แวร์ของบุคคลที่สาม (รวมถึงซอฟต์แวร์โอเพนซอร์ส) ที่อาจมาพร้อมกับซอฟต์แวร์ไมโครชิป
ซอฟต์แวร์นี้จัดทำโดยไมโครชิป "ตามที่เป็นอยู่" ไม่มีการรับประกันไม่ว่าจะโดยชัดแจ้งหรือตามกฎหมายใช้กับซอฟต์แวร์นี้รวมถึงการรับประกันโดยนัยของการไม่ละเมิดความสามารถในการค้าและความเหมาะสมสำหรับวัตถุประสงค์เฉพาะ
ไม่ว่าในกรณีใด microchip จะต้องรับผิดชอบต่อการสูญเสียความเสียหายค่าใช้จ่ายหรือค่าใช้จ่ายใด ๆ ที่เกี่ยวข้องกับซอฟต์แวร์ใด ๆ ที่เกี่ยวข้องกับซอฟต์แวร์ เท่าที่กฎหมายได้รับอนุญาตอย่างเต็มที่ตามกฎหมายความรับผิดทั้งหมดของ Microchip ในการเรียกร้องทั้งหมดในทางใด ๆ ที่เกี่ยวข้องกับซอฟต์แวร์นี้จะไม่เกินจำนวนค่าธรรมเนียมถ้ามีคุณจ่ายโดยตรงไปยังไมโครชิปสำหรับซอฟต์แวร์นี้
โต้ตอบกับเพื่อนของคุณเกี่ยวกับซอฟต์แวร์นี้ใน Lora Forum
จากแอปพลิเคชั่น Lorawan Mote ที่สร้างขึ้นจาก ASFV3 รหัสตัวอย่างนี้แสดงให้เห็นถึงการอยู่ร่วมกันของแอปพลิเคชัน Lorawan และการสื่อสารทางวิทยุบริสุทธิ์ระหว่าง 2X ATSAMR34 XPLAINT BOARDS โดยใช้การปรับ LORA
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับอุปกรณ์ Microchip ATSAMR34 LORA SIP เยี่ยมชมเว็บเพจ Microchip:
https://www.microchip.com/design-centers/wireless-connectivity/low-power-wide-area-area-networks/lora-technology/sam-r34-r35

ชุดการประเมินผล Pro AtSAMR34 XPLAINED เป็นแพลตฟอร์มฮาร์ดแวร์ที่ใช้ในการประเมิน ATSAMR34 LOWA LORA® Sub-GHz SIP ได้รับการสนับสนุนโดย Microchip Studio 7.0 IDE และคอลเลกชันของรหัสตัวอย่างมีให้บริการจาก Framework Software Advanced (ASFV3) ตั้งแต่การเปิดตัว 3.44.0 ชุดการประเมินผลซีรีย์ XPLAINTE PRO MCU รวมถึงตัวดีบักฝังตัวบนบอร์ด (EDBG) และไม่จำเป็นต้องใช้เครื่องมือภายนอกในการโปรแกรมหรือดีบั๊ก ATSAMR34 ชุดนำเสนอชุดของคุณสมบัติที่ช่วยให้ผู้ใช้เริ่มต้นด้วยอุปกรณ์ต่อพ่วง Sub-GHz SUP SUP SUP SUP SUP ATSAMR34 ทันทีและเพื่อทำความเข้าใจวิธีการรวมอุปกรณ์ในการออกแบบของคุณเอง ชุด ATSAMR34 XPLAINED PRO มีรายการต่อไปนี้:

เพื่อแสดงให้เห็นถึงการสื่อสารแบบเพียร์ทูเพียร์คุณจำเป็นต้องมีบอร์ด Pro Xplained อย่างน้อย 2X ATSAMR34
โครงการนี้รวม API ซอฟต์แวร์ Microchip Lorawan Stack (MLS) ซึ่งให้อินเทอร์เฟซกับโมดูลซอฟต์แวร์ที่แตกต่างกัน
สำหรับแอปพลิเคชันนี้เราจะ“ หยุด” เลเยอร์ Lorawan Mac (MAC) และใช้ Lorawan Radio Layer (TAL) สำหรับการสื่อสารแบบ peer-to-peer และ“ Resume” ชั้น Lorawan Mac เพื่อดำเนินการ Lorawan
ในการกำหนดค่าแบบเพียร์ทูเพียร์เลเยอร์ Lorawan Mac ถูกข้ามและปล่อยให้ความสามารถในการขับเคลื่อนวิทยุโดยตรงโดยไม่มีโปรโตคอลไม่มีความปลอดภัยไม่มีตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์และเห็นได้ชัดว่าไม่มีการทำงานร่วมกันและระบบนิเวศ (ตรงข้ามกับ Lorawan) สิ่งนี้สามารถแสดงให้เห็นถึงความสามารถในการใช้การสื่อสาร P2P ในแอปพลิเคชัน Lorawan
โปรดตรวจสอบให้แน่ใจว่าไม่ละเมิดกฎระเบียบท้องถิ่นสำหรับแถบความถี่ที่สอดคล้องกัน เช่น 25MW และรอบการทำงาน 1% สำหรับ 868MHz-band ภายในยุโรป

เลเยอร์ Mac ให้ฟังก์ชั่นการดำเนินงานที่กำหนดไว้ในข้อกำหนดของ Lorawan
Tal Layer ใช้ไดรเวอร์วิทยุและให้การเข้าถึงตัวรับส่งสัญญาณ SX1276
เพื่อให้สามารถตั้งค่าอุปกรณ์สำหรับการเชื่อมต่อจุดหนึ่งไปยังจุดรหัสจำเป็นต้อง:
void LORAWAN_Init(AppDataCb_t appdata, JoinResponseCb_t joindata);
StackRetStatus_t LORAWAN_Reset (IsmBand_t ismBand);
uint32_t LORAWAN_Pause (void);
RadioError_t RADIO_SetAttr(RadioAttribute_t attribute, void *value);
RADIO_SetAttr(WATCHDOG_TIMEOUT,(void *)&wdt) ;
RadioError_t RADIO_Receive(RadioReceiveParam_t *param);
ฟังก์ชั่นนี้ตั้งค่าอุปกรณ์ในโหมดรับเพื่อรับข้อมูลและจัดเก็บไว้ในพื้นที่ตัวชี้บัฟเฟอร์โดยทำการโพสต์งานไปยัง Radio_RxHandler
RadioError_t RADIO_Transmit(RadioTransmitParam_t *param);
ฟังก์ชั่นนี้ส่งข้อมูลโดยทำโพสต์งานไปยัง Radio_TxHandler
สำหรับการสื่อสารแบบเพียร์ทูเพียร์รหัสตัวอย่างจะกำหนดค่าวิทยุด้วยพารามิเตอร์ต่อไปนี้:
typedef enum _AppTaskIds_t
{
DISPLAY_TASK_HANDLER,
PROCESS_TASK_HANDLER,
APP_TASKS_COUNT
}AppTaskIds_t;
typedef enum _AppTaskState_t
{
RESTORE_BAND_STATE,
DEMO_CERT_APP_STATE,
DEMO_APP_STATE,
JOIN_SEND_STATE
}AppTaskState_t;
static SYSTEM_TaskStatus_t (*appTaskHandlers[APP_TASKS_COUNT])(void) = {
/* In the order of descending priority */
displayTask,
processTask
};
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
/*********************************************************************//**
brief Calls appropriate functions based on state variables
*************************************************************************/
static SYSTEM_TaskStatus_t displayTask(void)
{
switch(appTaskState)
{
case RESTORE_BAND_STATE:
displayRunRestoreBand();
break;
case DEMO_CERT_APP_STATE:
displayRunDemoCertApp();
break;
case DEMO_APP_STATE:
displayRunDemoApp();
break;
case JOIN_SEND_STATE:
displayJoinAndSend();
break;
default:
printf("Error STATE Enteredrn");
break;
}
return SYSTEM_TASK_SUCCESS;
}
/*********************************************************************//**
brief Displays and activates LED's for joining to a network
and sending data to a network
*************************************************************************/
static void displayJoinAndSend(void)
{
printf("rn1. Send Join Requestrn");
printf("2. Send Datarn");
// new menu with p2p
printf("3. Main Menurn") ;
printf("4. MAC Pausern") ;
printf("5. MAC Resumern") ;
printf("6. Configure Radiorn") ;
printf("7. Send Radio Datarn") ;
printf("8. Enter Radio Receive modern") ;
printf("9. Exit Radio Receive modern") ;
#ifdef CONF_PMM_ENABLE
printf("0. Sleeprn") ;
#endif
printf("rnEnter your choice: ");
set_LED_data(LED_AMBER,&off);
set_LED_data(LED_GREEN,&off);
startReceiving = true;
}
/*********************************************************************//**
brief Pulls the data from UART when activated
*************************************************************************/
void serial_data_handler(void)
{
int rxChar;
char serialData;
/* verify if there was any character received*/
if (startReceiving == true)
{
if((-1) != (rxChar = sio2host_getchar_nowait()))
{
serialData = (char)rxChar;
if((serialData != 'r') && (serialData != 'n') && (serialData != 'b'))
{
startReceiving = false;
serialBuffer = rxChar;
appPostTask(PROCESS_TASK_HANDLER);
printf("rn");
}
}
}
}
/*********************************************************************//**
brief Calls appropriate functions based on state variables
*************************************************************************/
static SYSTEM_TaskStatus_t processTask(void)
{
switch(appTaskState)
{
case RESTORE_BAND_STATE:
processRunRestoreBand();
break;
case DEMO_CERT_APP_STATE:
processRunDemoCertApp();
break;
case DEMO_APP_STATE:
processRunDemoApp();
break;
case JOIN_SEND_STATE:
processJoinAndSend();
break;
default:
printf("Error STATE Enteredrn");
break;
}
return SYSTEM_TASK_SUCCESS;
}
/*********************************************************************//**
brief Sends Join request or Data to the network
*************************************************************************/
static void processJoinAndSend(void)
{
StackRetStatus_t status = LORAWAN_SUCCESS;
if(serialBuffer == '1')
{
status = LORAWAN_Join(DEMO_APP_ACTIVATION_TYPE);
if (LORAWAN_SUCCESS == (StackRetStatus_t)status)
{
set_LED_data(LED_GREEN,&on);
printf("nJoin Request Sentnr");
}
else
{
set_LED_data(LED_AMBER,&on);
print_stack_status(status);
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
}
else if(serialBuffer == '2' && joined == true)
{
sendData();
}
else if(serialBuffer == '2' && !joined)
{
set_LED_data(LED_AMBER,&on);
printf("Device not joined to the networkrn");
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
#ifdef CONF_PMM_ENABLE
else if(serialBuffer == '0')
{
static bool deviceResetsForWakeup = false;
PMM_SleepReq_t sleepReq;
/* Put the application to sleep */
sleepReq.sleepTimeMs = DEMO_CONF_DEFAULT_APP_SLEEP_TIME_MS;
sleepReq.pmmWakeupCallback = appWakeup;
sleepReq.sleep_mode = CONF_PMM_SLEEPMODE_WHEN_IDLE;
if (CONF_PMM_SLEEPMODE_WHEN_IDLE == SLEEP_MODE_STANDBY)
{
deviceResetsForWakeup = false;
}
if (true == LORAWAN_ReadyToSleep(deviceResetsForWakeup))
{
app_resources_uninit();
if (PMM_SLEEP_REQ_DENIED == PMM_Sleep(&sleepReq))
{
HAL_Radio_resources_init();
sio2host_init();
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
printf("rnsleep_not_okrn");
}
}
else
{
printf("rnsleep_not_okrn");
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
}
#endif
else if (serialBuffer == '3')
{
// main menu
appTaskState = DEMO_APP_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
else if (serialBuffer == '4')
{
// Pause the Microchip LoRaWAN Stack
uint32_t time_ms ;
time_ms = LORAWAN_Pause() ;
printf("rnMAC Pause %ldrn", time_ms) ;
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '5')
{
// Resume the Microchip LoRaWAN Stack
LORAWAN_Resume() ;
printf("rnMAC Resumern") ;
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '6')
{
// Configure Radio Parameters
// --------------------------
// Bandwidth = BW_125KHZ
// Channel frequency = FREQ_868100KHZ
// Channel frequency deviation = 25000
// CRC = enabled
// Error Coding Rate = 4/5
// IQ Inverted = disabled
// LoRa Sync Word = 0x34
// Modulation = LoRa
// PA Boost = disabled (disabled for EU , enabled for NA)
// Output Power = 1 (up to +14dBm for EU / up to +20dBm for NA)
// Spreading Factor = SF7
// Watchdog timeout = 60000
// Bandwidth
RadioLoRaBandWidth_t bw = BW_125KHZ ;
RADIO_SetAttr(BANDWIDTH, &bw) ;
printf("Configuring Radio Bandwidth: 125kHzrn") ;
// Channel Frequency
uint32_t freq = FREQ_868100KHZ ;
RADIO_SetAttr(CHANNEL_FREQUENCY, &freq) ;
printf("Configuring Channel Frequency %ldrn", freq) ;
// Channel Frequency Deviation
uint32_t fdev = 25000 ;
RADIO_SetAttr(CHANNEL_FREQUENCY_DEVIATION, &fdev) ;
printf("Configuring Channel Frequency Deviation %ldrn", fdev) ;
// CRC
uint8_t crc_state = 1 ;
RADIO_SetAttr(CRC, &crc_state) ;
printf("Configuring CRC state: %drn", crc_state) ;
// Error Coding Rate
RadioErrorCodingRate_t cr = CR_4_5 ;
RADIO_SetAttr(ERROR_CODING_RATE, &cr) ;
printf("Configuring Error Coding Rate 4/5rn") ;
// IQ Inverted
uint8_t iqi = 0 ;
RADIO_SetAttr(IQINVERTED, &iqi) ;
printf("Configuring IQ Inverted: %drn", iqi) ;
// LoRa Sync Word
uint8_t sync_word = 0x34 ;
RADIO_SetAttr(LORA_SYNC_WORD, &sync_word) ;
printf("Configuring LoRa sync word 0x%xrn", sync_word) ;
// Modulation
RadioModulation_t mod = MODULATION_LORA ;
RADIO_SetAttr(MODULATION, &mod) ;
printf("Configuring Modulation: LORArn") ;
// PA Boost
uint8_t pa_boost = 0 ;
RADIO_SetAttr(PABOOST, &pa_boost) ;
printf("Configuring PA Boost: %drn", pa_boost) ;
// Tx Output Power
int16_t outputPwr = 1 ;
RADIO_SetAttr(OUTPUT_POWER, (void *)&outputPwr) ;
printf("Configuring Radio Output Power %drn", outputPwr) ;
// Spreading Factor
int16_t sf = SF_7 ;
RADIO_SetAttr(SPREADING_FACTOR, (void *)&sf) ;
printf("Configuring Radio SF %drn", sf) ;
// Watchdog Timeout
uint32_t wdt = 60000 ;
RADIO_SetAttr(WATCHDOG_TIMEOUT, (void *)&wdt) ;
printf("Configuring Radio Watch Dog Timeout %ldrn", wdt) ;
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '7')
{
// Radio Transmit
// the counter value
counter++ ;
if (counter > 255) counter = 0 ;
tx_buffer[0] = counter ;
printf("Buffer transmitted: ") ;
print_array(tx_buffer, 1) ;
RadioError_t radioStatus ;
RadioTransmitParam_t radioTransmitParam ;
radioTransmitParam.bufferLen = 1 ;
radioTransmitParam.bufferPtr = (uint8_t *)&tx_buffer ;
radioStatus = RADIO_Transmit(&radioTransmitParam) ;
switch (radioStatus)
{
case ERR_NONE:
{
printf("Radio Transmit Successrn") ;
}
break ;
case ERR_DATA_SIZE:
{
// do nothing, status already set to invalid
}
break ;
default:
{
printf("Radio Busyrn") ;
}
}
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '8')
{
// Enter Radio Receive mode
RadioReceiveParam_t radioReceiveParam ;
uint32_t rxTimeout = 0 ; // forever
radioReceiveParam.action = RECEIVE_START ;
radioReceiveParam.rxWindowSize = rxTimeout ;
if (RADIO_Receive(&radioReceiveParam) == 0)
{
printf("Radio in Receive modern") ;
}
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else if (serialBuffer == '9')
{
// Stop Radio Receive mode
RadioReceiveParam_t radioReceiveParam ;
radioReceiveParam.action = RECEIVE_STOP ;
if (RADIO_Receive(&radioReceiveParam) == 0)
{
printf("Radio Exit Receive modern") ;
}
appTaskState = JOIN_SEND_STATE ;
appPostTask(DISPLAY_TASK_HANDLER) ;
}
else
{
set_LED_data(LED_AMBER,&on);
printf("Invalid choice enteredrn");
appTaskState = JOIN_SEND_STATE;
appPostTask(DISPLAY_TASK_HANDLER);
}
}
/* OTAA Join Parameters */
#define DEMO_DEVICE_EUI {0xde, 0xaf, 0xfa, 0xce, 0xde, 0xaf, 0xfa, 0xce}
#define DEMO_APPLICATION_EUI {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}
#define DEMO_APPLICATION_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}
conf_board.h ไฟล์:
/* TODO: If Board is having EDBG with DEV_EUI flashed in
Userpage Enable this Macro otherwise make it as 0 */
#define EDBG_EUI_READ 1







