2

The code below runs on an Arduino Pro Mini (8MHz 328p) sending temperature readings using an inexpensive ASK transmitter. I use OneWire to read the DS18B20s, and RadioHead to manage the radio.

The original problem was the send() calls at the top of the loop always worked, but the send() call in the temperature-reading loop never did.

The fix was to insert a call to setModeTx() ahead of the send() call. I'm pleased it works, but it's a hollow victory because I can't figure out why it works.

OneWire uses no timers and no interrupts. I wait for the temperature conversion using _delay_ms() which is a spin delay.

I've read and re-read the OneWire and RH_ASK code and am still puzzled. Can anyone explain?

Many thanks

Here's the gist of the code…

RH_ASK radio(1024, 0, 10, 0, false);
OneWire ow(2);

void loop()
{
    radio.send(/* build info */);     // always works
    radio.send(/* battery health */); // always works
    ow.reset_search();
    while (ow.search(addr))
    {
        read_thermometer(addr);

        // the following send() works ONLY
        // when preceded by setModeTx()
        // It *never* works without it
        radio.setModeTx();
        radio.send(/* one temp reading */);
    } 
}

UPDATE

@timemage was correct in that there are also calls to Serial (which resolve to HardwareSerial) interspersed. I'm no closer to solving it; however, by rearranging calls I can get the failure to happen more- or less often.

In a way this highlights the distinction between diagnosis and repair. I may in the end discover an ordering of the calls that makes the failure exceedingly rare, and in this case the problem will have been repaired; though not diagnosed.

Eric Nelson
  • 125
  • 4
  • 1
    I would expect `RH_ASK radio(1024, 0, 10, 0, false);` to interfere with `Serial`, but I have no way of testing that. But, you don't appear to be using `Serial`, but then you indicate it's not the complete code. But then... I don't know why `.setModeTx()` would have the effect it's having. In any case, it's not clear to me that `0` can mean "unused" there and is maybe something to fix regardless. – timemage Jan 03 '23 at 00:15
  • @timemage you're on to something. I had earlier dismissed interaction with `Serial`, which as you surmise I am using. Still looking… – Eric Nelson Jan 03 '23 at 03:15
  • I'm not even sure I'd go that far. I've seen some libraries use -1 as an indicator of "not used" or "not applicable". What I did was look the RadioHead library to see how it would interpret it. For the benefit of anyone that thinks this is an "answer" I feel the need to spell this out: No it's not. At it's an observation of something that should probably be fixed regardless and may or may not have any bearing at all on the actual problem as stated in the question. I'm not going to write it an an answer because there's no particularly good reason to think it is the answer or even an answer. – timemage Jan 03 '23 at 15:41
  • If you find out that it helps and why, you can write your own answer, because you'll actually _know_ that it's the answer and ideally _why._ – timemage Jan 03 '23 at 15:42
  • I could imagine two thngs that might happen (or not ;-)). First there is a code line somewhere in your code that configures the ASk driver for RX. Second the first two sends fill the write buffer and the third send does not work, because there is not enough place in the buffer to add the new data. The setModeTx might clean the buffer or simply needs some time the ASK driver needs to send the remaining data. Isn't there a `waitPacketSent()` method to wait before new data can be written? Perhaps worth I try??? – Peter Paul Kiefer Jan 07 '23 at 17:28
  • I think @PeterPaulKiefer is onto something. The `setModeTx()` does clear `_txIndex`, `_txBit`, `_txSample`. And the `transmitTimer()` has a check `if (_txIndex >= _txBufLen)`. Of course I am spitballing. But worth an investigation there. – Fahad Jan 10 '23 at 05:46

0 Answers0