Comunicazione Bidirezionale con LoRa tra Client e Server

Home Forum Le librerie ospitate nel sito EBYTE E22 dispositivi LoRa UART sx1262/sx1268 Comunicazione Bidirezionale con LoRa tra Client e Server

Visualizzazione 4 filoni di risposte
  • Autore
    Post
    • #27178
      Anelito
      Partecipante

        Ciao a tutti,
        vorrei realizzare una interfaccia radio-web bidirezionale tra due dispositivi radio basati su LoRa con funzioni di client e server.

        L’utilizzo immaginato è il seguente:
        1. Il client invia una richiesta al server.
        2. Il server, ricevuta la richiesta, effettua una chiamata HTTP, processa i dati ricevuti e ne effettua il parsing.
        3. Il server invia al client i dati formattati come risposta.

        Nella realizzazione sono emerse due criticità:

        1. Auto-ricezione del messaggio:
        Ho notato che il server “vede” il messaggio trasmesso. C’è un modo efficace per evitare che il server riceva il suo stesso messaggio?

        In particolare, il problema è qui (server):

        while True:
          if lora.available() > 0:
            data = parse_incoming(..)
            res = fetch(data)
            lora.send_transparent_message(res)
        

        Forse il destination address?

        2. Dati troncati:
        Quando il server riceve una trasmissione dal client, ho notato che questi dati vengono spesso troncati o non arrivano completi. Come posso garantire che i dati vengano ricevuti integralmente e in modo corretto?

        Il problema sembra essere nel file lora_e22.py alla riga 657
        time.sleep(0.08) # wait for the rest of the message
        Aumentando lo sleep time, l’errors di ricezione viene spostato più avanti nel messaggio.

        Lorem ipsum dolor sit amet, consectetur adipiscig elit.

        La parola dovrebbe essere adipiscing, ma invece una lettera è stata omessa. Modificando lo sleep time a 0.10s il messaggio è ricevuto per intero, ma non credo sia il modo corretto di risolvere il problema. Sono certo si ripresenterebbe in caso di pacchetti dati più pesanti.

        Grazie in anticipo per qualsiasi aiuto o suggerimento.

      • #27183
        Renzo Mischianti
        Amministratore del forum

          Ciao,
          scusa se rispondo solo ora ma sono fuori in questi giorni.
          I dispositivi lora caricano il buffer man mano che arrivano i dati, perciò serve che rimani in attesa per il completamento del messaggio, io ho inserito uno 0.8 e mi sembrava sufficiente per la ricezione del messaggio completo, ma a quanto pare, in condizioni particolari non è sufficiente.
          È corretto mettere un intervallo superiore così da non avere problemi.

          In trasparent tutto vedono tutto, dovresti usare un fixed per evitare di ricevere tutto da quel canale.

          Ciao Renzo

        • #27186
          Anelito
          Partecipante

            Non sarebbe meglio usare una stop word invece di un timer?
            Si potrebbe per esempio appendere a fine messaggio un carattere speciale, tipo “\n”, e solo quando viene ricevuto allora il metodo available() risponde True.
            Altrimenti il rischio è di avere un fine-tuning continuo del timer in base alla lunghezza dei messaggi da trasmettere, che a volte possono essere molto ridotti e a volte invece di qualche kB.

          • #27213
            Renzo Mischianti
            Amministratore del forum

              Ciao Anelito,
              per la gestione dei messaggi multipli puoi usare il metodo

              
                  def receive_message(self, delimiter=None, size=None) -> (ResponseStatusCode, any):
              

              specificando un delimitatore legge il messaggio fino a quel limite senza wait

              
                  def _read_until(self, terminator='\n') -> bytes:
                      line = b''
                      while True:
                          c = self.uart.read(1)
                          if c == terminator:
                              break
                          line += c
                      return line
              

              Credo che sia più o meno la stessa cosa.

              Ciao Renzo

            • #27245
              Anelito
              Partecipante

                Sì alla fine ho usato quel sistema però ho trovato vari bug nella libreria, il primo tra tutti quel ‘\n’ va codificato come byte.

                def _read_until(self, terminator=b'\n') -> bytes:

                altri invece legati alla gestione degli errori, capita spesso che a monte del messaggio ci siano dei byte “spuri” che causano errori nella codifica utf8

                ho risolto aggiungendo il flag replace

                data = data.decode('utf-8', errors='replace')

                infine nella funzione _read_until ho aggiunto un timeout altrimenti rischia di piantarsi

                    def _read_until(self, terminator=b'\n', timeout=10) -> bytes:
                        line = b''
                        start = time.time()
                        while True:
                            c = self.uart.read(1)
                            line += c
                            if c == terminator:
                                break
                            if time.time() - start > timeout:
                                logger.error("Message reading timeout")
                                return b''
                
                        return line
                
            Visualizzazione 4 filoni di risposte
            • Devi essere connesso per rispondere a questo topic.
            Exit mobile version