Change tx power and frequency during program run using LoRawan and OTAA

I am now trying to build a fieldtester base on AS923 with heltec wifi lora 32V2. The fieldtester is now fully functional, it send an uplink in DR0 and a downlink payload with gatewayid,rssi and snr will be queued on the server-side. The device receive the downlink payload and it show the uplink rssi, snr for each gateway.

The problem is that a field tester should be able to send by different tx power(no need to above max, maybe 14db,10db) and frequency(such as 923.2, 923.4, 923.6, 923.8 Mhz), but I dont know how to modify the tx power and frequency in the main program. I found them in the AS923.h and i can change the tx power as well as the frequency by modify the setting on the .h file. Unlike the datarate, these value seems cant be changed in the main program, which means they cannot modify by user input. Any idea for this issue?

I found that the Heltec_ESP32 library have setTxPower() and setFrequency() function but it does not support OTAA. ESP32_LoRaWAN library support OTAA but doesn’t have the function mentioned above

Noticed that ADR must turned off and OTAA must be used.

Problem solved, i complete it by deeply look at the esp32 lorawan library and modify it

hi @butterken

I am also facing similar problem like yours, i am also Flashing standard LoRaWAN.ino program from heltec esp32 dev boards but not getting a way to change the output TX Power. Can you please help me how you manage to fix this problem or how can i set the output tx power ?

Well, this is a bit complicated, cause my soluction require modification on Semtech default SX1262 chip library. But the adventage is that you can use the same method on other LoRa board with Semtech LoRa Chip(not only heltec one)

  1. You need to localize the esp32 lorawan library so that the change wont affect other sensor or produce error when library update. To do this, just copy the whole library into your working directory and include it in the .ino. For local library, you should change from #include “ESP32_LoRaWAN.h” to #include “src/ESP32_LoRaWAN/ESP32_LoRaWAN.h”
  2. in LoRaMac.c, create you own function like this:

int gettxpower(void){
return LoRaMacParams.ChannelsTxPower;
}

void settxpower(int txpower){
LoRaMacParams.ChannelsTxPower=txpower;
}

  1. add the function to ESP32_LoRaWAN.h and LoRaMac.h like this:
    extern int gettxpower(void);
    extern void settxpower(int txpower);

  2. call the function in your main problem

The problem of this method is that the tx power is reset everytime, you must call it and change the tx power everytime before you send.

Another method is passsing a TX power constant into sx1276.c (at my time it was sx1276, but it was the same for newer chip)

  1. In SX1276-board.c, you will find a function called SX1276SetTxConfig, for SX1262, it should located at src/driver/sx126x.c with function name SX126xSetTxParams. You are able to control all Tx parameters by modify this function. (Tx power called SX1276SetRfTxPower / )

The last method is a bit risky, which involve writing to register, but the benfit is easy to use and manage.

void setFrequency(long frequency)
{
uint64_t frf = ((uint64_t)frequency << 19) / 32000000;
writeRegister(REG_FRF_MSB, (uint8_t)(frf >> 16));
writeRegister(REG_FRF_MID, (uint8_t)(frf >> 8));
writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
}

void setTxPower(int8_t power)
{
uint8_t paConfig = 0;
paConfig = readRegister( REG_PA_CONFIG );
paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK );
paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
if ( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if ( power < 2 )
{
power = 2;
}
if ( power > 17 )
{
power = 17;
}
paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
writeRegister( REG_PA_CONFIG, paConfig );
}
}

Thanks you So much for the help and prompted response.