EMPA Workshop – İstanbul
EMPA LoRa Accelerator Workshop’a hoşgeldiniz, Lütfen önceki yazımızdaki (EMPA Workshop’a gelmeden önce yapılıcaklar) talimalatları eksiksiz yaptığınızdan emin olunuz.
Hands-On sırasında takip edilecek talimatlara ve ek dosyalara aşağıdaki linkden erişebilirsiniz.
Link: https://empadigital.com/shared/cPtvz0PPIK
LoRa Point to Point Uygulaması
LoRa p2p uygulaması için slaytlar içerisinde “4_STM32WL_WS_P2P_040221” dosyası takip edilecektir.
Bu örnekte “Point2Point_Phy -> Projects -> NUCLEO-WL55JC -> Applications -> SubGHz_Phy -> P2P_Sensor -> .project” dosyasına tıklayarak projeyi CubeIDE’ye aktarabilirsiniz.
LoRaWan End Node Uygulaması
LoRaWan Uygulaması için slaytlar içerisinde “5_STM32WL_WS_hands-on_Lorawan_040221” dosyası takip edilecektir.
Uygulama sırasında eklenecek kod parçaları “LoRaWAN_End_Node_attendee” isimli text dosyasından alınacaktır.
LoRa P2P & EMPA Cloud
Bu Örnekte başlangıç noktası olarak STM32CubeIDE WL55 exampları arasında bulunan SubGHz_Phy_PingPong örneği seçilmiştir. CubeIDE’de bu örneği açtığınıza emin olunuz.
1-ilk olarak “Application->SubGHz_Phy->subghz_phy_app.c” dosyasını açalım.
2- App dosyası içerine yeni bir state ekleyelim. PTD bölgesindeki stateleri güncelleyelim.
/* USER CODE BEGIN PTD */
typedef enum {
JOIN, RX, RX_TIMEOUT, RX_ERROR, TX, TX_TIMEOUT,
} States_t;
/* USER CODE END PTD */
3- onRxDone handlerının içerisini aşağıdaki gibi değiştirelim.
static void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi,
int8_t LoraSnr_FskCfo) {
/* USER CODE BEGIN OnRxDone */
APP_LOG(TS_ON, VLEVEL_L, "OnRxDone\n\r");
#if ((USE_MODEM_LORA == 1) && (USE_MODEM_FSK == 0))
APP_LOG(TS_ON, VLEVEL_L, "RssiValue=%d dBm, SnrValue=%ddB\n\r", rssi,
LoraSnr_FskCfo);
/* Record payload Signal to noise ratio in Lora*/
SnrValue = LoraSnr_FskCfo;
#endif /* USE_MODEM_LORA | USE_MODEM_FSK */
#if ((USE_MODEM_LORA == 0) && (USE_MODEM_FSK == 1))
APP_LOG(TS_ON, VLEVEL_L, "RssiValue=%d dBm, Cfo=%dkHz\n\r", rssi, LoraSnr_FskCfo);
SnrValue = 0; /*not applicable in GFSK*/
#endif /* USE_MODEM_LORA | USE_MODEM_FSK */
/* Update the State of the FSM*/
State = RX;
/* Clear BufferRx*/
memset(BufferRx, 0, MAX_APP_BUFFER_SIZE);
/* Record payload size*/
RxBufferSize = size;
if (RxBufferSize <= MAX_APP_BUFFER_SIZE) {
memcpy(BufferRx, payload, RxBufferSize);
}
/* Record Received Signal Strength*/
RssiValue = rssi;
/* Record payload content*/
APP_LOG(TS_ON, VLEVEL_H, "payload. size=%d \n\r", size);
/* Run PingPong process in background*/
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process),
CFG_SEQ_Prio_0);
/* USER CODE END OnRxDone */
}
4- /* USER CODE BEGIN PrFD / ve / USER CODE END PrFD */ arasındaki bütün kodları silelim.
5- Bu silinen araya sırası ile aşağıdakileri ekleyelim.
6- id ve appkeyleri ekleyelim ve size verdiğimiz numarayı id yerine yazalım. Burada örnek olarka b2 yazılmıştır.
uint8_t devEui[30] = "b2";
uint8_t appkey[] = "DGX3TQM3mmHHOjQRqVwgHC8AxwpfJ9Z5";
7-Global kullanacağımız Variableları ekleyelim.
uint8_t Payload[2048] = { 0 };
char *ptr;
uint8_t gCounter = 0;
uint8_t app_request_ack = 0;
uint8_t joined = 0;
uint8_t cnt_appdata=0;
8- State machinelerimizin yer aldığı APP taskını ekleyelim. (kopyalama sırasında hatalar olabilir.)
static void PingPong_Process(void) {
Radio.Sleep();
switch (State) {
case JOIN:
APP_LOG(TS_ON, VLEVEL_L, "Request Sended\n\r")
;
sprintf(Payload, "REQ+%s", devEui);
Radio.Send(Payload, PAYLOAD_LEN);
break;
case RX:
APP_LOG(TS_ON, VLEVEL_L, "Geldi bisiler %s\n\r",BufferRx);
if (!joined) {
if (strstr(BufferRx, "REQAPP") != NULL) {
ptr = strstr(BufferRx, "+");
ptr++;
if (strcmp(devEui, ptr) == 0) {
APP_LOG(TS_ON, VLEVEL_L, "APP Key Requested\n\r");
sprintf(Payload, "APP+%s+%s", devEui, appkey);
app_request_ack = 1;
Radio.Send(Payload, PAYLOAD_LEN);
break;
}
}
if (strstr(BufferRx, "JACK") != NULL) {
APP_LOG(TS_ON, VLEVEL_L, "Joined\n\r");
ptr = strstr(BufferRx, "+");
ptr++;
APP_LOG(TS_ON, VLEVEL_L, "Joined %s\n\r",ptr);
if (strcmp(devEui, ptr) == 0) {
joined = 1;
app_request_ack = 0;
gCounter = 0;
HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_Pin);
Radio.Rx(RX_TIMEOUT_VALUE);
cnt_appdata=1;
Radio.Rx(RX_TIMEOUT_VALUE);
}else {
Radio.Rx(RX_TIMEOUT_VALUE);
}
break;
}
if (strstr(BufferRx, "ACK") != NULL) {
ptr = strstr(BufferRx, "+");
ptr++;
if (strcmp(devEui, ptr) == 0) {
APP_LOG(TS_ON, VLEVEL_L, "ACK Received\n\r");
Radio.Rx(RX_TIMEOUT_VALUE);
break;
}
}
Radio.Rx(RX_TIMEOUT_VALUE);
break;
}else{
if (strstr(BufferRx, "ACK") != NULL) {
ptr = strstr(BufferRx, "+");
ptr++;
if (strcmp(devEui, ptr) == 0) {
APP_LOG(TS_ON, VLEVEL_L, "ACK Received\n\r");
cnt_appdata=1;
Radio.Rx(RX_TIMEOUT_VALUE);
}else {
Radio.Rx(RX_TIMEOUT_VALUE);
}
}
else if (strstr(BufferRx, "LEDTOGGLE") != NULL) {
ptr = strstr(BufferRx, "+");
ptr++;
if (strstr(ptr, devEui) != NULL) {
APP_LOG(TS_ON, VLEVEL_L, "Led Toggle Request Received\n\r");
BSP_LED_Toggle(LED_GREEN);
Radio.Rx(RX_TIMEOUT_VALUE);
}
else
{
Radio.Rx(RX_TIMEOUT_VALUE);
}
}
else{
Radio.Rx(RX_TIMEOUT_VALUE);
}
}
break;
case TX:
if (!joined) {
Radio.Rx(RX_TIMEOUT_VALUE);
}
else
{
Radio.Rx(RX_TIMEOUT_VALUE);
}
break;
case RX_TIMEOUT:
case RX_ERROR:
;
if (!joined) {
if (app_request_ack) {
gCounter++;
if (gCounter < 3) {
HAL_Delay(300);
Radio.Rx(RX_TIMEOUT_VALUE);
} else {
sprintf(Payload, "APP+%s+%s", devEui, appkey);
Radio.Send(Payload, PAYLOAD_LEN);
}
} else {
gCounter++;
if (gCounter < 3) {
HAL_Delay(300);
Radio.Rx(RX_TIMEOUT_VALUE);
} else {
gCounter = 0;
State = JOIN;
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process),
CFG_SEQ_Prio_0);
}
}
} else {
if (cnt_appdata == 0) {
gCounter++;
if (gCounter > 3) {
gCounter = 0;
sprintf(Payload, "APPDATA+%s", devEui);
Radio.Send(Payload, PAYLOAD_LEN);
break;
}
}else {
gCounter++;
if (gCounter > 100) {
gCounter = 0;
sprintf(Payload, "APPDATA+%s", devEui);
cnt_appdata = 0;
Radio.Send(Payload, PAYLOAD_LEN);
break;
}
}
Radio.Rx(RX_TIMEOUT_VALUE);
}
break;
case TX_TIMEOUT:
break;
default:
break;
}
}
9- Son olarak SubghzApp_Init içerisinde bulunan aşağıdaki iki satırı commente alalım veya silelim.
/* Led Timers*/
UTIL_TIMER_Create(&timerLed, LED_PERIOD_MS, UTIL_TIMER_ONESHOT, OnledEvent, NULL);
UTIL_TIMER_Start(&timerLed);
10- Artık Build alabilirsiniz.
WorkShop aşamaları tamamlanmıştır. Katılımınız için Teşekkürler, Bir sonraki etkinlikte görüşmek üzere.