empa Elektornik

KURUMSAL

ÇÖZÜMLER

GİRİŞ YAP

ARAMA

empa logo
empa logo

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.