You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • Sorry for the delay getting back to you on this... I'd be pretty sure the freezing itself stems from the device getting swamped with Bluetooth advertisements.

    What happens is when an advertisment is received, it's poked into a queue in the interrupt, and handled by the event loop (where it is filtered). If the event loop doesn't manage to handle the items fast enough, then you hit FIFO_FULL and a bunch of issues stem from that.

    The event loop should limit the amount of packets it executes such that timers still work when it's swamped with data, but maybe that is failing somehow and it's just sitting there trying to handle BLE packets.

    jsble_exec_pending: Unknown enum type ...

    This shouldn't happen with 2v09 and later firmwares, but it seems like the queue got full and then only part of a Bluetooth message was added to it, which then caused things to get really messed up. How many devices do you have broadcasting? If I can reproduce it here I might be able to fix that particular issue.

    Looking at the code I think there are a few places you could help it out though. Mainly, you want the handler for setScan to be super fast, so you want as few function calls as possible (and to bail out as soon as possible if you don't care about the device). It looks like you have a few different function calls, and you could try something like:

    function scanHandler(d) {
      var v = Velo.list[d.id];
      if (!v || !d.manufacturerData) return;
    
      Display.rxCnt += 1;
    
      v.rssi = d.rssi;
      v.bat = d.manufacturerData[0];
    
      switch (v.state) {
        case 0:
          v.state = 1;
          v.rxCount = 0;
          v.rssiMin = null;
          v.rssiMax = null;
          break;
        case 1:
          if(d.rssi >= CONST.RSSI_THRESHOLD) {
            v.state = 2;
            Led.flash();
          }
          break;
      }
    
      var t = getTime();
      v.tRssiLast = t;
      v.rxCount += 1;
    
      if(v.rssiMax == null || rssi >vthis.rssiMax) {
        v.rssiMax = rssi;
        if(v.state == 2) {
          v.tRssiMax = t;
        }
      }
      if(v.rssiMin == null || rssi < v.rssiMin) {
        v.rssiMin = rssi;
      }
    }
    // ...
    NRF.setScan(
      scanHandler,
      {filters: [{manufacturerData: {0x0590: {}}}]}
    );
    
  • Thanks @Gordon, having the scan handler super short was also something I had in mind.
    Good that you confirm this, I will try to optimize it.

    There are currently 8 pucks available for me, so that is the maximum I should handle - would be nice if there were more.
    However "in the field" not all should be in range at the same time - only when starting the race.

    But it would be good if conditions like these would not break the whole setup.

    My main issue was the memory though I think. Limiting the log to 100 laps made it stable for now.
    I am considering pushing the lap data to an external SD card.
    Is that something you can advise or does it make things slower/worse?

    I would create a new directory for every one (timestamp of start time as directory name to make it simple).
    And then create just one short file for every lap event like (00001.csv) for the first lap, (00002.csv) for the second.
    No longish CSV file, short open and writes.

    But I would like to be able to "serve" this file data via BLE as well so it can be pulled via a Laptop at race time - I would have to be able to scan a directory on request and push out record (file) by record.
    Do you see issues here doing that in parallel?
    I'm about to hook up a SD card to the rig now and see how it works...

About

Avatar for Gordon @Gordon started