[Gelöst] ESP32, RMT und Manchester-Code

[Update: gelöst, war ein Hardwareproblem - siehe unten]

Hi,

eine neue Herausforderung… Ich hoffe, einer von Euch kennt sich ein bisschen mit dem RMT im ESP32 aus :wink:

Ich versuche, auf einem ESP32 (DevKitC) Signale zu verarbeiten, die per 433MHz-Empfänger einlaufen - das ist ein RXB6. Die Signale kommen von einem Wettersensor und sind Manchester-codiert, also immer HIGH/LOW-Sequenzen. Da es nichts Vorgefertigtes für den ESP32 gibt, möchte ich den RMT (Remote Control Processor) des ESP32 dazu benutzen, diese Signale zu empfangen. Die Dekodierung kommt dann hinterher und ist hier erst einmal weggelassen - das Problem tritt schon vorher auf.

Das klappt im Prinzip auch, mit diesem Code hier:

#include <Arduino.h>
#include <mini-printf.h>

extern "C" {
#include "esp_err.h"
#include "esp_log.h"
#include "driver/rmt.h"
#include "driver/periph_ctrl.h"
#include "soc/rmt_reg.h"
}

#define DATA_433 GPIO_NUM_14
#define RMT_RX_CHANNEL 0
#define RMT_CLK_DIV      255    /*!< RMT counter clock divider */
#define RMT_TICK_10_US (80000000/RMT_CLK_DIV/100000) /*!< RMT counter value for 10 us.(Source clock is APB clock) */

void setup() {
   Serial.begin(9600);

  // Configure RMT
  rmt_config_t rmt_rx;
  rmt_rx.channel = (rmt_channel_t)RMT_RX_CHANNEL;          // RMT channel
  rmt_rx.gpio_num = (gpio_num_t)DATA_433;     // GPIO pin
  rmt_rx.clk_div = RMT_CLK_DIV;               // Clock divider
  rmt_rx.mem_block_num = 8;                   // number of mem blocks used
  rmt_rx.rmt_mode = RMT_MODE_RX;              // Receive mode
  rmt_rx.rx_config.filter_en = true;          // Enable filter
  rmt_rx.rx_config.filter_ticks_thresh = 100; // Filter all shorter than 100 ticks
  rmt_rx.rx_config.idle_threshold = 2000;     // Timeout after 2000 ticks
  rmt_config(&rmt_rx);                        // Init channel
  rmt_driver_install(rmt_rx.channel, 4000, 0); // Install driver with ring buffer size 1000
}

void loop() {
    RingbufHandle_t rb = NULL;
    uint32_t cnt = 0;
    //get RMT RX ringbuffer
    rmt_get_ringbuf_handle((rmt_channel_t)RMT_RX_CHANNEL, &rb);
    rmt_rx_start((rmt_channel_t)RMT_RX_CHANNEL, 1);
    if(rb) {
        size_t rx_size = 0;
        //try to receive data from ringbuffer.
        //RMT driver will push all the data it receives to its ringbuffer.
        //We just need to parse the value and return the spaces of ringbuffer.
        rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 500);
        while(item) {
          char buffer[120];
          rmt_item32_t *it = item;

          for(uint32_t i=0;i<rx_size/sizeof(rmt_item32_t);i++)
          {
            mini_snprintf(buffer, 120, "Size=%d - %5d: %01d:%5d %01d:%5d\n", rx_size, cnt++, it->level0, it->duration0, it->level1, it->duration1);
            Serial.print(buffer);
            it++;
          }
          vRingbufferReturnItem(rb, (void*) item);
          item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 500);
        }
      }
      Serial.println("No more items.");
}

Die Parameter für den RMT habe ich mir von existierenden Beispielen abgeleitet; da die Senderate 1200bd beträgt, ist selbst mit dem maximalen rmt_clk_div von 255 immer noch ein 260-faches Oversampling vorhanden (80MHz/255=313kHz).

Ich würde also erwarten, dass für einzelne Bits (bzw. die Phasenwechsel von HIGH nach LOW und umgekehrt) im Mittel also etwa 260 Ticks verstreichen. Die Ausgabe des Programms zeigt aber etwas anderes. Hier beispielweise das Ende einer Sendung:

Size=296 -    49: 1:  110 0:   25
Size=296 -    50: 1:   11 0:   43
Size=296 -    51: 1:   89 0:   32
Size=296 -    52: 1:  289 0:   20
Size=296 -    53: 1:  160 0:   42
Size=296 -    54: 1:   93 0:   32
Size=296 -    55: 1:  229 0:   23
Size=296 -    56: 1:   28 0:   11
Size=296 -    57: 1:  134 0:   14
Size=296 -    58: 1:  155 0:   19
Size=296 -    59: 1:  278 0:   56
Size=296 -    60: 1:   15 0:   61
Size=296 -    61: 1:  198 0:   71
Size=296 -    62: 1:  470 0:   25
Size=296 -    63: 1:  693 0:   19

Size=296 -    64: 1:  689 0:   14
Size=296 -    65: 1:  397 0:   25
Size=296 -    66: 1:  819 0:   10
Size=296 -    67: 1:  215 0:   38
Size=296 -    68: 1:  202 0:   20
Size=296 -    69: 1:   60 0:   29
Size=296 -    70: 1:  905 0:   23
Size=296 -    71: 1:  128 0:   11
Size=296 -    72: 1:  164 0:   16
Size=296 -    73: 1:  291 0:   15
Size=12 -    74: 0:   43 1:   61
Size=12 -    75: 0:   17 1:  209
Size=12 -    76: 0:   24 1:    0
Size=4 -    77: 0:   24 1:    0
Size=4 -    78: 0:    9 1:    0
Size=12 -    79: 0:   16 1: 1869
Size=12 -    80: 0:   11 1: 1073
Size=12 -    81: 0:   12 1:    0
Size=4 -    82: 0:   19 1:    0
Size=24 -    83: 0:    9 1: 1031
Size=24 -    84: 0:   20 1:  877
Size=24 -    85: 0:   14 1:  361
Size=24 -    86: 0:   14 1:  576
Size=24 -    87: 0:   11 1:   30
Size=24 -    88: 0:   10 1:    0
No more items.

Es gibt also viel kürzere und auch viel längere Tick-Phasen bis zu einem Phasenwechsel.

  • Warum sind das nicht alles grob überschlagen Vielfache von 260?
  • Warum kommen Zeilen wie " 87: 0: 11 1: 30" überhaupt vor? Beide Tickzahlen zusammen (11+30=41) sind deutlich unter der filter_ticks_thresh von 100 und sollten nach meinem Verständnis überhaupt nicht vom RMT beachtet werden?
  • Randproblem, das nicht in der Ausgabe oben zu sehen ist: manchmal kommen diese Fehler vom RMT: “E (382891) rmt: RMT RX BUFFER FULL”. Wie kann das sein, wo doch a) alle 512 Memory Blocks des RMT für meinen Channel 0 reserviert sind und b) auch der Ringbuffer groß genug sein sollte?

Argh. Kaum hat man das Problem beschrieben, fällt einem noch eine Möglichkeit ein!

Es war ein Hardwareproblem. Die Antenne am RXB6 ist eine aus isoliertem Schaltdraht gewickelte "air cooled" Antenne. Nur leider hatte sie innerhalb der Isolierung einen Drahtbruch...

Durch die auto gain-Funktion des Empfängers wurde also beliebiges Rauschen so hochverstärkt, bis ein hauptsächlich zufälliges Signal entstand.

Mit einer neuen Antenne klappt es prächtig:

Size=380 -     0: 1:  245 0:  243
Size=380 -     1: 1:  249 0:  242
Size=380 -     2: 1:  249 0:  488
Size=380 -     3: 1:  493 0:  493
Size=380 -     4: 1:  492 0:  487
Size=380 -     5: 1:  247 0:  245
Size=380 -     6: 1:  492 0:  493
Size=380 -     7: 1:  243 0:  245
Size=380 -     8: 1:  492 0:  242
Size=380 -     9: 1:  249 0:  243
Size=380 -    10: 1:  248 0:  488
Size=380 -    11: 1:  246 0:  245
Size=380 -    12: 1:  246 0:  246
Size=380 -    13: 1:  491 0:  488
Size=380 -    14: 1:  246 0:  245
Size=380 -    15: 1:  492 0:  491
Size=380 -    16: 1:  488 0:  247
Size=380 -    17: 1:  246 0:  492
Size=380 -    18: 1:  492 0:  243
Size=380 -    19: 1:  245 0:  248

Nicht ganz 260, sondern eher 245, aber klar erkennbare HIGH und LOW :)

Hi

Besten Dank für das direkte Feedback inklusive Auflösung! Daß so eine 'gewickelte Antenne' einen Drahtbruch haben kann, hätte ich nicht erwartet - netter Fehler! Und 245 ist nun auch nicht so weit von 260 weg ... Das sind Komma-Fehler ;)

MfG