@@ -195,7 +195,7 @@ def __init__(
195195
196196 logger .info (
197197 f"SX1262Radio configured: freq={ frequency / 1e6 :.1f} MHz, "
198- f"power={ tx_power } dBm, sf={ spreading_factor } , pre={ preamble_length } "
198+ f"power={ tx_power } dBm, sf={ spreading_factor } , bw= { bandwidth / 1000 :.1f } kHz, pre={ preamble_length } "
199199 )
200200 # Register this instance as the active radio for IRQ callback access
201201 SX1262Radio ._active_instance = self
@@ -315,7 +315,7 @@ def set_rx_callback(self, callback):
315315
316316 async def _rx_irq_background_task (self ):
317317 """Background task: waits for RX_DONE IRQ and processes received packets automatically."""
318- logger .info ("[RX] Starting RX IRQ background task" )
318+ logger .debug ("[RX] Starting RX IRQ background task" )
319319 rx_check_count = 0
320320 last_preamble_time = 0
321321 preamble_timeout = 5.0 # 5 seconds timeout for incomplete preamble detection
@@ -456,14 +456,14 @@ async def _rx_irq_background_task(self):
456456 raw_rssi = self .lora .getRssiInst ()
457457 if raw_rssi is not None :
458458 noise_floor_dbm = - (float (raw_rssi ) / 2 )
459- logger .info (
459+ logger .debug (
460460 f"[RX Task] Status check #{ rx_check_count } , "
461461 f"Noise: { noise_floor_dbm :.1f} dBm"
462462 )
463463 else :
464- logger .info (f"[RX Task] Status check #{ rx_check_count } " )
464+ logger .debug (f"[RX Task] Status check #{ rx_check_count } " )
465465 except Exception :
466- logger .info (f"[RX Task] Status check #{ rx_check_count } " )
466+ logger .debug (f"[RX Task] Status check #{ rx_check_count } " )
467467 else :
468468 await asyncio .sleep (0.1 ) # Longer delay when interrupts not set up
469469
@@ -484,7 +484,7 @@ def begin(self) -> bool:
484484 self .irq_pin = Button (self .irq_pin_number , pull_up = False )
485485 self .irq_pin .when_activated = self ._handle_interrupt
486486 self ._interrupt_setup = True
487- logger .info (f"[RX] IRQ setup successful on pin { self .irq_pin_number } " )
487+ logger .debug (f"[RX] IRQ setup successful on pin { self .irq_pin_number } " )
488488 except Exception as e :
489489 logger .error (f"IRQ setup failed: { e } " )
490490 raise RuntimeError (f"Failed to set up IRQ pin { self .irq_pin_number } : { e } " )
@@ -525,7 +525,11 @@ def begin(self) -> bool:
525525
526526 self .lora .setBufferBaseAddress (0x00 , 0x80 ) # TX=0x00, RX=0x80
527527
528- self .lora .setLoRaModulation (self .spreading_factor , self .bandwidth , self .coding_rate )
528+ # Enable LDRO if symbol duration > 16ms (SF11/62.5kHz = 32.768ms)
529+ symbol_duration_ms = (2 ** self .spreading_factor ) / (self .bandwidth / 1000 )
530+ ldro = symbol_duration_ms > 16.0
531+ logger .info (f"LDRO { 'enabled' if ldro else 'disabled' } (symbol duration: { symbol_duration_ms :.3f} ms)" )
532+ self .lora .setLoRaModulation (self .spreading_factor , self .bandwidth , self .coding_rate , ldro )
529533
530534 self .lora .setLoRaPacket (
531535 self .lora .HEADER_EXPLICIT ,
@@ -564,7 +568,11 @@ def begin(self) -> bool:
564568 self .lora .setTxParams (self .tx_power , self .lora .PA_RAMP_200U )
565569
566570 # Configure modulation and packet parameters
567- self .lora .setLoRaModulation (self .spreading_factor , self .bandwidth , self .coding_rate )
571+ # Enable LDRO if symbol duration > 16ms (SF11/62.5kHz = 32.768ms)
572+ symbol_duration_ms = (2 ** self .spreading_factor ) / (self .bandwidth / 1000 )
573+ ldro = symbol_duration_ms > 16.0
574+ logger .info (f"LDRO { 'enabled' if ldro else 'disabled' } (symbol duration: { symbol_duration_ms :.3f} ms)" )
575+ self .lora .setLoRaModulation (self .spreading_factor , self .bandwidth , self .coding_rate , ldro )
568576 self .lora .setPacketParamsLoRa (
569577 self .preamble_length ,
570578 self .lora .HEADER_EXPLICIT ,
@@ -600,9 +608,9 @@ def begin(self) -> bool:
600608 return True
601609
602610 self ._rx_irq_task = loop .create_task (self ._rx_irq_background_task ())
603- logger .info ("[RX] RX IRQ background task started" )
611+ logger .debug ("[RX] RX IRQ background task started" )
604612 else :
605- logger .info ("[RX] RX IRQ background task already running" )
613+ logger .debug ("[RX] RX IRQ background task already running" )
606614 except Exception as e :
607615 logger .warning (f"Failed to start RX IRQ background handler: { e } " )
608616 return True
@@ -759,13 +767,13 @@ async def _execute_transmission(self, driver_timeout: int) -> bool:
759767
760768 async def _wait_for_transmission_complete (self , timeout_seconds : float ) -> bool :
761769 """Wait for transmission to complete using interrupts. Returns True if successful."""
762- logger .info (f"[TX] Waiting for TX completion (timeout: { timeout_seconds } s)" )
770+ logger .debug (f"[TX] Waiting for TX completion (timeout: { timeout_seconds } s)" )
763771 start_time = time .time ()
764772
765773 # IRQ setup is required
766774 try :
767775 await asyncio .wait_for (self ._tx_done_event .wait (), timeout = timeout_seconds )
768- logger .info ("[TX] TX completion interrupt received!" )
776+ logger .debug ("[TX] TX completion interrupt received!" )
769777 return True
770778 except asyncio .TimeoutError :
771779 logger .error ("[TX] TX completion timeout - no interrupt received!" )
@@ -918,6 +926,23 @@ def get_last_snr(self) -> float:
918926 """Return last received SNR in dB"""
919927 return self .last_snr
920928
929+ def get_noise_floor (self ) -> Optional [float ]:
930+ """
931+ Get current noise floor (instantaneous RSSI) in dBm.
932+ Returns None if radio is not initialized or if reading fails.
933+ """
934+ if not self ._initialized or self .lora is None :
935+ return None
936+ try :
937+ raw_rssi = self .lora .getRssiInst ()
938+ if raw_rssi is not None :
939+ noise_floor_dbm = - (float (raw_rssi ) / 2 )
940+ return noise_floor_dbm
941+ return None
942+ except Exception as e :
943+ logger .debug (f"Failed to read noise floor: { e } " )
944+ return None
945+
921946 def set_frequency (self , frequency : int ) -> bool :
922947 """Set operating frequency"""
923948
0 commit comments