/** * @file T3S3Factory.ino * @author Lewis He (lewishe@outlook.com) * @license MIT * @copyright Copyright (c) 2023 Shenzhen Xin Yuan Electronic Technology Co., Ltd * @date 2023-05-13 * */ #include #include #include #include #include #include #include "OLEDDisplayUi.h" #include #include "utilities.h" #include #include "LoRaBoards.h" using namespace ace_button; void radioTx(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); void radioRx(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); void hwInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); #if defined(USING_SX1276) #define CONFIG_RADIO_FREQ 868.0 #define CONFIG_RADIO_OUTPUT_POWER 17 #define CONFIG_RADIO_BW 125.0 SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN); #elif defined(USING_SX1278) #define CONFIG_RADIO_FREQ 433.0 #define CONFIG_RADIO_OUTPUT_POWER 17 #define CONFIG_RADIO_BW 125.0 SX1278 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN); #elif defined(USING_SX1262) #define CONFIG_RADIO_FREQ 868.0 #define CONFIG_RADIO_OUTPUT_POWER 22 #define CONFIG_RADIO_BW 125.0 SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); #elif defined(USING_SX1280) #define CONFIG_RADIO_FREQ 2400.0 #define CONFIG_RADIO_OUTPUT_POWER 13 #define CONFIG_RADIO_BW 203.125 SX1280 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); #elif defined(USING_SX1280PA) /* * Important: SX1280 PA Version * The 2.4G version does not have a power amplifier (PA). The permissible power setting is 13dBm. * If it is a version with a built-in PA, do not set the maximum power beyond 3dBm. * This is because a power amplifier is added to the RF front end; setting it to 3dBm will achieve an output power of 22dBm. * Setting it beyond 3dBm may damage the PA. */ #define CONFIG_RADIO_FREQ 2400.0 #define CONFIG_RADIO_OUTPUT_POWER 3 // PA Version power range : -18 ~ 3dBm #define CONFIG_RADIO_BW 203.125 SX1280 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); #elif defined(USING_LR1121) /* * Important: LR1121 PA Version * * The 2.4G version does not have a power amplifier (PA). The permissible power setting is 13dBm. * * If it is a version with a built-in PA, please do not exceed 0dBm in the maximum power setting. * This is because a power amplifier has been added to the RF front-end; setting it to 0dBm will achieve an output power of 22dBm. * Setting it to more than 1dBm may damage the PA. * * */ #define CONFIG_RADIO_FREQ 2450.0 #define CONFIG_RADIO_OUTPUT_POWER LILYGO_RADIO_2G4_TX_POWER_LIMIT #define CONFIG_RADIO_BW 125.0 // The maximum power of LR1121 Sub 1G band can only be set to 22 dBm // #define CONFIG_RADIO_FREQ 868.0 // #define CONFIG_RADIO_OUTPUT_POWER 22 // #define CONFIG_RADIO_BW 125.0 LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO9_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); #ifdef USING_LR1121PA // LR1121 Version PA RF switch table static const uint32_t pa_version_rf_switch_dio_pins[] = { RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_LR11X0_DIO8, RADIOLIB_NC }; static const Module::RfSwitchMode_t high_freq_switch_table[] = { // mode DIO5 DIO6 DIO7 DIO8 { LR11x0::MODE_STBY, { LOW, LOW, LOW, LOW} }, { LR11x0::MODE_TX, { LOW, LOW, LOW, HIGH} }, { LR11x0::MODE_RX, { LOW, LOW, HIGH, LOW} }, { LR11x0::MODE_TX_HP, { LOW, LOW, HIGH, LOW} }, { LR11x0::MODE_TX_HF, { LOW, LOW, HIGH, LOW} }, { LR11x0::MODE_GNSS, { LOW, LOW, LOW, HIGH} }, { LR11x0::MODE_WIFI, { LOW, LOW, LOW, HIGH} }, END_OF_MODE_TABLE, }; static const Module::RfSwitchMode_t low_freq_switch_table[] = { // mode DIO5 DIO6 DIO7 DIO8 { LR11x0::MODE_STBY, { LOW, LOW, LOW, LOW} }, { LR11x0::MODE_TX, { LOW, HIGH, LOW, LOW} }, { LR11x0::MODE_RX, { HIGH, LOW, LOW, LOW} }, { LR11x0::MODE_TX_HP, { LOW, HIGH, LOW, LOW} }, { LR11x0::MODE_TX_HF, { LOW, LOW, LOW, LOW} }, { LR11x0::MODE_GNSS, { LOW, LOW, LOW, LOW} }, { LR11x0::MODE_WIFI, { LOW, LOW, LOW, LOW} }, END_OF_MODE_TABLE, }; #endif /*USING_LR1121PA*/ #endif /*Radio define end*/ enum TransmissionDirection { LORA_NONE = 0, TRANSMISSION = 1, RECEIVE = 2, }; // save transmission state between loops int transmissionState = RADIOLIB_ERR_NONE; bool transmittedFlag = false; uint32_t transmissionCounter = 0; uint32_t recvCounter = 0; float radioRSSI = 0; bool isRadioOnline = false; bool isSdCardOnline = false; bool rxStatus = true; uint32_t radioRunInterval = 0; uint32_t batteryRunInterval = 0; SSD1306Wire display(0x3c, I2C_SDA, I2C_SCL); OLEDDisplayUi ui( &display ); FrameCallback frames[] = { hwInfo, radioTx, radioRx}; AceButton button; TransmissionDirection transmissionDirection = LORA_NONE; static uint8_t freq_index = 0; const float factory_freq[] = { #if !defined(USING_SX1280PA) && !defined(USING_SX1280) 433.0, 470.0, 850.0, 868.0, 915.0, 920.0, 923.0, #endif #if defined(USING_LR1121) || defined(USING_SX1280)|| defined(USING_SX1280PA) 2400, 2450 #endif }; float current_freq = CONFIG_RADIO_FREQ; void setFlag(void) { // we got a packet, set the flag transmittedFlag = true; } void deviceSleep() { display.clear(); digitalWrite(RADIO_RST_PIN, HIGH); gpio_hold_en((gpio_num_t) RADIO_RST_PIN); gpio_deep_sleep_hold_en(); radio.sleep(); display.drawString(60, 28, "Sleep"); display.display(); delay(2000); display.displayOff(); #ifdef BOARD_LED digitalWrite(BOARD_LED, LOW); #endif #ifdef RADIO_TCXO_ENABLE digitalWrite(RADIO_TCXO_ENABLE, LOW); #endif while (digitalRead(0) == LOW) delay(1); SPI.end(); Wire.end(); Serial.flush(); Serial.end(); pinMode(RADIO_CS_PIN, INPUT); pinMode(RADIO_RST_PIN, INPUT); #ifdef RADIO_DIO0_PIN pinMode(RADIO_DIO0_PIN, INPUT); #endif #ifdef RADIO_DIO1_PIN pinMode(RADIO_DIO1_PIN, INPUT); #endif #ifdef RADIO_DIO9_PIN pinMode(RADIO_DIO9_PIN, INPUT); #endif #ifdef RADIO_BUSY_PIN pinMode(RADIO_BUSY_PIN, INPUT); #endif pinMode(RADIO_CS_PIN, INPUT); pinMode(I2C_SDA, INPUT); pinMode(I2C_SCL, INPUT); pinMode(OLED_RST, INPUT); pinMode(RADIO_SCLK_PIN, INPUT); pinMode(RADIO_MISO_PIN, INPUT); pinMode(RADIO_MOSI_PIN, INPUT); pinMode(SDCARD_MOSI, INPUT); pinMode(SDCARD_MISO, INPUT); pinMode(SDCARD_SCLK, INPUT); pinMode(SDCARD_CS, INPUT); pinMode(BOARD_LED, INPUT); pinMode(ADC_PIN, INPUT); #if CONFIG_IDF_TARGET_ESP32 esp_sleep_ext1_wakeup_mode_t wakeup_mode = ESP_EXT1_WAKEUP_ALL_LOW; #else #if ESP_ARDUINO_VERSION_VAL(2,0,17) >= ESP_ARDUINO_VERSION esp_sleep_ext1_wakeup_mode_t wakeup_mode = ESP_EXT1_WAKEUP_ANY_LOW; #else esp_sleep_ext1_wakeup_mode_t wakeup_mode = ESP_EXT1_WAKEUP_ALL_LOW; #endif #endif // esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0); // T3 V3.0 ext1 sleep ~160uA // T3 S3 V1.3 ext1 sleep ~ 40uA esp_sleep_enable_ext1_wakeup(_BV(0), wakeup_mode); // T3 V3.0 Timer sleep ~ 160uA // esp_sleep_enable_timer_wakeup(30 * 1000 * 1000); esp_deep_sleep_start(); Serial.println("Never print()"); } void changeFreq() { #if defined(JAPAN_MIC) #else // Set freq function radio.standby(); #if defined(USING_LR1121) // check if we need to recalibrate image bool skipCalibration = true; int16_t state = radio.setFrequency(factory_freq[freq_index], skipCalibration); #else /*defined(USING_LR1121)*/ int16_t state = radio.setFrequency(factory_freq[freq_index]); #endif /*defined(USING_LR1121)*/ if (state != RADIOLIB_ERR_NONE) { Serial.printf("Selected frequency %.2f is invalid for this module!\n", factory_freq[freq_index]); return; } current_freq = factory_freq[freq_index]; freq_index++; Serial.printf("setFrequency:%.2f\n", current_freq); freq_index %= sizeof(factory_freq) / sizeof(factory_freq[0]); #if defined(USING_LR1121) bool forceHighPower = false; int8_t max_tx_power = LILYGO_RADIO_2G4_TX_POWER_LIMIT; if (current_freq < 2400) { max_tx_power = 22; forceHighPower = true; #if defined(USING_LR1121PA) Serial.printf("Using low frequency switch table for PA version\n"); radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, low_freq_switch_table); #endif /*USING_LR1121PA*/ } else { #if defined(USING_LR1121PA) Serial.printf("Using high frequency switch table for PA version\n"); radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, high_freq_switch_table); #endif /*USING_LR1121PA*/ } if (radio.setOutputPower(max_tx_power, forceHighPower) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { Serial.printf("Selected output power %d is invalid for this module!\n", max_tx_power); } #endif /*defined(USING_LR1121)*/ switch (transmissionDirection) { case TRANSMISSION: #ifdef RADIO_TX_CW radio.transmitDirect(); #else /*RADIO_TX_CW*/ transmissionState = radio.transmit((uint8_t *)&transmissionCounter, 4); if (transmissionState != RADIOLIB_ERR_NONE) { Serial.println(F("[Radio] transmit packet failed!")); } #endif /*RADIO_TX_CW*/ break; default: transmissionState = radio.startReceive(); if (transmissionState != RADIOLIB_ERR_NONE) { Serial.println(F("[Radio] Received packet failed!")); } break; } #endif /*defined(JAPAN_MIC)*/ } void handleEvent(AceButton *button, uint8_t eventType, uint8_t buttonState) { int state ; static uint8_t frameCounter = 1; switch (eventType) { case AceButton::kEventClicked: Serial.printf("frameCounter : %d\n", frameCounter); switch (frameCounter) { case 0: break; case 1: #ifdef RADIO_TX_CW Serial.println("Start transmit (CW)"); radio.standby(); delay(100); radio.transmitDirect(); #else Serial.println("Start transmit"); state = radio.transmit((uint8_t *)&transmissionCounter, 4); if (state != RADIOLIB_ERR_NONE) { Serial.println(F("[Radio] transmit packet failed!")); } #endif break; case 2: Serial.println("Start receive"); state = radio.startReceive(); if (state != RADIOLIB_ERR_NONE) { Serial.println(F("[Radio] Received packet failed!")); } break; default: break; } frameCounter++; ui.nextFrame(); frameCounter %= sizeof(frames) / sizeof(frames[0]); transmissionDirection = static_cast(frameCounter); break; case AceButton::kEventLongPressed: Serial.println("Long pressed!"); deviceSleep(); break; case AceButton::kEventDoubleClicked: changeFreq(); break; } } void setup() { if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_ALL) { gpio_deep_sleep_hold_dis(); gpio_hold_dis((gpio_num_t) RADIO_RST_PIN); } setupBoards(true/*Disable logo*/); setupBLE(); delay(1000); for (int i = 0; i < sizeof(factory_freq) / sizeof(factory_freq[0]); ++i) { const float _EPS_ = 1e-6f; int aa = static_cast(factory_freq[i] + _EPS_); int bb = static_cast(CONFIG_RADIO_FREQ + _EPS_); if (aa == bb) { freq_index = i + 1; freq_index %= sizeof(factory_freq) / sizeof(factory_freq[0]); } } #ifdef RADIO_TCXO_ENABLE pinMode(RADIO_TCXO_ENABLE, OUTPUT); digitalWrite(RADIO_TCXO_ENABLE, HIGH); #endif const uint8_t btn_num = BUTTON_PIN; pinMode(BUTTON_PIN, INPUT_PULLUP); button.init(btn_num); ButtonConfig *buttonConfig = button.getButtonConfig(); buttonConfig->setEventHandler(handleEvent); buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick); buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); // Initialising the UI will init the display too. ui.setTargetFPS(60); // You can change this to // TOP, LEFT, BOTTOM, RIGHT ui.setIndicatorPosition(BOTTOM); // Defines where the first frame is located in the bar. ui.setIndicatorDirection(LEFT_RIGHT); // You can change the transition that is used // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN ui.setFrameAnimation(SLIDE_LEFT); // Add frames ui.setFrames(frames, sizeof(frames) / sizeof(frames[0])); ui.disableAutoTransition(); // Initialising the UI will init the display too. ui.init(); display.flipScreenVertically(); Serial.printf("[%s]:", RADIO_TYPE_STR); Serial.print(F("Radio Initializing ... ")); int state = radio.begin(); if ( state == RADIOLIB_ERR_NONE) { Serial.println(F("success!")); } else { Serial.println(F("failed!")); } isRadioOnline = state == RADIOLIB_ERR_NONE; #if defined(RADIO_RX_PIN) && defined(RADIO_TX_PIN) //The SX1280 version needs to set RX, TX antenna switching pins radio.setRfSwitchPins(RADIO_RX_PIN, RADIO_TX_PIN); #endif /* * Sets carrier frequency. * SX1278/SX1276 : Allowed values range from 137.0 MHz to 525.0 MHz. * SX1268/SX1262 : Allowed values are in range from 150.0 to 960.0 MHz. * SX1280 : Allowed values are in range from 2400.0 to 2500.0 MHz. * LR1121 : Allowed values are in range from 150.0 to 960.0 MHz, 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations. * * * */ if (radio.setFrequency(current_freq) == RADIOLIB_ERR_INVALID_FREQUENCY) { Serial.println(F("Selected frequency is invalid for this module!")); while (true); } /* * Sets LoRa link bandwidth. * SX1278/SX1276 : Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz. Only available in %LoRa mode. * SX1268/SX1262 : Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz. * SX1280 : Allowed values are 203.125, 406.25, 812.5 and 1625.0 kHz. * LR1121 : Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz. * * * */ if (radio.setBandwidth(CONFIG_RADIO_BW) == RADIOLIB_ERR_INVALID_BANDWIDTH) { Serial.println(F("Selected bandwidth is invalid for this module!")); while (true); } /* * Sets LoRa link spreading factor. * SX1278/SX1276 : Allowed values range from 6 to 12. Only available in LoRa mode. * SX1262 : Allowed values range from 5 to 12. * SX1280 : Allowed values range from 5 to 12. * LR1121 : Allowed values range from 5 to 12. * * * */ if (radio.setSpreadingFactor(10) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) { Serial.println(F("Selected spreading factor is invalid for this module!")); while (true); } /* * Sets LoRa coding rate denominator. * SX1278/SX1276/SX1268/SX1262 : Allowed values range from 5 to 8. Only available in LoRa mode. * SX1280 : Allowed values range from 5 to 8. * LR1121 : Allowed values range from 5 to 8. * * * */ if (radio.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) { Serial.println(F("Selected coding rate is invalid for this module!")); while (true); } /* * Sets LoRa sync word. * SX1278/SX1276/SX1268/SX1262/SX1280 : Sets LoRa sync word. Only available in LoRa mode. * * */ if (radio.setSyncWord(0xAB) != RADIOLIB_ERR_NONE) { Serial.println(F("Unable to set sync word!")); while (true); } /* * Sets transmission output power. * SX1278/SX1276 : Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin). High power +20 dBm operation is also supported, on the PA_BOOST pin. Defaults to PA_BOOST. * SX1262 : Allowed values are in range from -9 to 22 dBm. This method is virtual to allow override from the SX1261 class. * SX1268 : Allowed values are in range from -9 to 22 dBm. * SX1280 : Allowed values are in range from -18 to 13 dBm. PA Version range : -18 ~ 3dBm * LR1121 : Allowed values are in range from -17 to 22 dBm (high-power PA) or -18 to 13 dBm (High-frequency PA), PA Version range : -9 ~ 0dBm * * * */ if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { Serial.println(F("Selected output power is invalid for this module!")); while (true); } #if !defined(USING_SX1280) && !defined(USING_LR1121) && !defined(USING_SX1280PA) /* * Sets current limit for over current protection at transmitter amplifier. * SX1278/SX1276 : Allowed values range from 45 to 120 mA in 5 mA steps and 120 to 240 mA in 10 mA steps. * SX1262/SX1268 : Allowed values range from 45 to 120 mA in 2.5 mA steps and 120 to 240 mA in 10 mA steps. * NOTE: set value to 0 to disable overcurrent protection * * * */ if (radio.setCurrentLimit(140) == RADIOLIB_ERR_INVALID_CURRENT_LIMIT) { Serial.println(F("Selected current limit is invalid for this module!")); while (true); } #endif /* * Sets preamble length for LoRa or FSK modem. * SX1278/SX1276 : Allowed values range from 6 to 65535 in %LoRa mode or 0 to 65535 in FSK mode. * SX1262/SX1268 : Allowed values range from 1 to 65535. * SX1280 : Allowed values range from 1 to 65535. * LR1121 : Allowed values range from 1 to 65535. * * */ if (radio.setPreambleLength(12) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) { Serial.println(F("Selected preamble length is invalid for this module!")); while (true); } // Enables or disables CRC check of received packets. if (radio.setCRC(false) == RADIOLIB_ERR_INVALID_CRC_CONFIGURATION) { Serial.println(F("Selected CRC is invalid for this module!")); while (true); } #if defined(USING_LR1121) #if defined(USING_LR1121PA) if (current_freq < 2400) { Serial.printf("LR1121 PA Version Using low frequency switch table for PA version\n"); radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, low_freq_switch_table); } else { Serial.printf("LR1121 PA Version Using high frequency switch table for PA version\n"); radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, high_freq_switch_table); } #else // Version without PA rf switch table Serial.println("LR1121 without PA Version"); static const uint32_t rfswitch_dio_pins[] = { RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC }; static const Module::RfSwitchMode_t rfswitch_table[] = { // mode DIO5 DIO6 { LR11x0::MODE_STBY, { LOW, LOW } }, { LR11x0::MODE_RX, { HIGH, LOW } }, { LR11x0::MODE_TX, { LOW, HIGH } }, { LR11x0::MODE_TX_HP, { LOW, HIGH } }, { LR11x0::MODE_TX_HF, { LOW, LOW } }, { LR11x0::MODE_GNSS, { LOW, LOW } }, { LR11x0::MODE_WIFI, { LOW, LOW } }, END_OF_MODE_TABLE, }; radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); #endif /*USING_LR1121PA*/ // LR1121 TCXO Voltage 2.85~3.15V radio.setTCXO(3.0); #endif /*USING_LR1121*/ // set the function that will be called // when new packet is received radio.setPacketReceivedAction(setFlag); // start listening for LoRa packets Serial.print(F("[Radio] Starting to listen ... ")); state = radio.startReceive(); if (state != RADIOLIB_ERR_NONE) { Serial.println(F("[Radio] Received packet failed!")); } } void loop() { button.check(); ui.update(); delay(2); } void radioTx(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { display->setTextAlignment(TEXT_ALIGN_LEFT); #ifdef RADIO_TX_CW display->drawString(0 + x, 0 + y, "Radio CW"); display->drawString(0 + x, 12 + y, "FREQ :" + String(current_freq)); #else if (millis() - radioRunInterval > 1000) { if (transmittedFlag) { // reset flag transmittedFlag = false; if (transmissionState == RADIOLIB_ERR_NONE) { // packet was successfully sent Serial.println(F("transmission finished!")); // NOTE: when using interrupt-driven transmit method, // it is not possible to automatically measure // transmission data rate using getDataRate() } else { Serial.print(F("failed, code ")); Serial.println(transmissionState); } // clean up after transmission is finished // this will ensure transmitter is disabled, // RF switch is powered down etc. radio.finishTransmit(); // send another one Serial.print(F("[Radio] Sending another packet ... ")); // you can transmit C-string or Arduino string up to // 256 characters long // transmissionState = radio.startTransmit("Hello World!"); radio.transmit((uint8_t *)&transmissionCounter, 4); transmissionCounter++; // you can also transmit byte array up to 256 bytes long /* byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; int state = radio.startTransmit(byteArr, 8); */ digitalWrite(BOARD_LED, 1 - digitalRead(BOARD_LED)); } Serial.println("Radio TX done !"); radioRunInterval = millis(); } display->drawString(0 + x, 0 + y, "Radio Tx"); display->drawString(0 + x, 12 + y, "FREQ :" + String(current_freq)); display->drawString(0 + x, 24 + y, "TX :" + String(transmissionCounter)); display->drawString(0 + x, 36 + y, "BW :" + String(CONFIG_RADIO_BW)); #endif } void radioRx(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { display->setFont(ArialMT_Plain_10); // The coordinates define the left starting point of the text display->setTextAlignment(TEXT_ALIGN_LEFT); // check if the flag is set if (transmittedFlag) { Serial.println("Radio RX done !"); digitalWrite(BOARD_LED, 1 - digitalRead(BOARD_LED)); // reset flag transmittedFlag = false; // you can read received data as an Arduino String int state = radio.readData((uint8_t *)&recvCounter, 4); // you can also read received data as byte array /* byte byteArr[8]; int state = radio.readData(byteArr, 8); */ if (state == RADIOLIB_ERR_NONE) { // packet was successfully received radioRSSI = radio.getRSSI(); Serial.println(F("[Radio] Received packet!")); Serial.print(F("[Payload] ")); Serial.println(recvCounter); Serial.print(F("[RSSI] ")); Serial.println(radioRSSI); } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { // packet was received, but is malformed Serial.println(F("[Radio] CRC error!")); } else { // some other error occurred Serial.print(F("[Radio] Failed, code ")); Serial.println(state); } // put module back to listen mode radio.startReceive(); } display->drawString(0 + x, 0 + y, "Radio Rx"); display->drawString(0 + x, 10 + y, "FREQ :" + String(current_freq)); display->drawString(0 + x, 22 + y, "RSSI:" + String(radioRSSI)); display->drawString(0 + x, 36 + y, "RX :" + String(recvCounter)); } void hwInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { static char buffer[64]; if (millis() - batteryRunInterval > 1000) { analogReadResolution(12); float voltage = (analogReadMilliVolts(ADC_PIN) * 2) / 1000.0; sprintf(buffer, "%.2fV", voltage > 4.2 ? 4.2 : voltage); batteryRunInterval = millis(); } display->setFont(ArialMT_Plain_10); display->setTextAlignment(TEXT_ALIGN_LEFT); display->drawString(0 + x, 10 + y, "Radio "); display->drawString(50 + x, 10 + y, isRadioOnline & 1 ? RADIO_TYPE_STR : "NA"); display->drawString(0 + x, 20 + y, "SD "); display->drawString(50 + x, 20 + y, SD.cardSize() != 0 ? "+" : "NA"); display->drawString(0 + x, 30 + y, "BAT "); display->drawString(50 + x, 30 + y, buffer); }