433 MHz communication between Nano and Pro Mini

Setup:
Transmitter and Receiver code uses RadioHead/RH_ASK.h
433 MHz receiver connected to a Nano
433 MHz transmitter connected to either a Nano or Pro Mini.

Everything work when communicating from Nano to Nano.
No communication between Pro Mini and Nano.
In either case, the transmitter and receiver code are identical.

I tracked this down to different pulse lengths sent to the transmitter module.
The duration of the on-level for first train of pulses at the beginning of a transmission are are 0.5 msec with the Nano an 0.3 msec with the Pro Mini.
That probably means that the receiver code running on the other Nano does not recognize the transmission from the Pro Mini as proper protocol.

So, I suspect that there is some issue with setting up timers.
Interestingly, delay() works properly on both platforms.

Questions:
Which timers are being used by the RadioHead library? Any know issues with that?
What would be the proper protocol timing - 0.5 msec or 0.3 msec?

Any help or suggestions are greatly appreciated. Thanks!

Which "Nano"? There are half a dozen different ones.

Post the code, using code tags, and a wiring diagram, hand drawn is preferred.

And just as another experiment, I wired up a Pro Mini as a receiver.
It doesn't receive any messages either, neither from the Nano nor the Pro Mini.

I'm using the plain Nano, i.e. not BLE or IOT etc.
Here is a circuit diagram for the Pro Mini circuits, Nano look essentially the same.

Transmitter code:

#include "Common.h"
#include "Switch.h"

const char unit[] = "Sender";  // used by PRT() macro

Switch onSwitch(onPin, 5);
Switch offSwitch(offPin, 5);
Switch invSwitch(invPin, 5);


void setup(void) {
  Serial.begin((unsigned long)9600);
  
  if (!driver.init())
    Serial.println("Sender: driver.init() failed");

  // Reconfigure pins actually used.
  pinMode(onPin, INPUT_PULLUP);
  pinMode(offPin, INPUT_PULLUP);
  pinMode(invPin, INPUT_PULLUP);
  pinMode(intPin, INPUT_PULLUP);
  interrupts();

  driver.send((uint8_t *)msg_off, strlen(msg_off));
  driver.waitPacketSent();
}

void loop(void) {
    // Send a message every second and blink LED
    digitalWrite(LED_BUILTIN, 1);
    PRT(msg_inv);
    driver.send((uint8_t *)msg_inv, strlen(msg_inv));
    driver.waitPacketSent();
    digitalWrite(LED_BUILTIN, 0);
    delay(2000);
}

Receiver code:


#include "Common.h"


const char unit[] = "Receiver";

bool state = false;

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

  interrupts();
  if (!driver.init()) 
      Serial.println("Receiver: driver.init() failed");

  pinMode(outPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(grnPin, OUTPUT);
  pinMode(redPin, OUTPUT);

  state = false;

  PRTLN("init");
}

void loop() 
{
  const uint8_t buf_size = 12;
  uint8_t buf[buf_size];

  uint8_t buflen = buf_size - 1;
  bool error = false;
  if (driver.recv(buf, &buflen)) {
    buf[buflen] = '\0';

    Serial.print ("Message: "); Serial.println((char *)buf);

    if (buflen > buf_size) {
      PRTLN("Too long ?!?");
      error = true;
    } else if (strcmp((char *)buf, msg_on) == 0) {
      PRTLN("ON");
      state = true;
    } else if (strcmp((char *)buf, msg_off) == 0) {
      PRTLN("OFF");
      state = false;
    } else if (strcmp((char *)buf, msg_inv) == 0) {
      PRTLN("TOGGLE");
      state = !state;
    } else {
      PRTLN("???");
      error = true;
    }

    PRTLN(state);
    digitalWrite(outPin, state);
    digitalWrite(ledPin, state);
    digitalWrite(grnPin, state);
    digitalWrite(redPin, false);

    if (error) {
      digitalWrite(grnPin, false);
      digitalWrite(redPin, true);
    }
  }
}

The labels on the circuit diagram are mostly illegible. Please post a hand drawn version, with all the pins and parts clearly labeled.

I can't make out how the switches are wired. What is the purpose of 1N4148 diodes?

Post a link to the boost converter and the SSR.

The diodes decouple switches, so that each can generate an interrupt on pin2 - not used in the code as shown. The SSR is nothing special, turns on/off with a 1 / 0. The boost converter is off-the-shelve to get from 3V to 5V.

The transmitter's Din is connected to the pin 12, and the receiver's data pin is connected to D11.

Any input on my original questions:
Which timers are being used by the RadioHead library? Any know issues with that?
What would be the proper protocol timing - 0.5 msec or 0.3 msec?

I do not understand the question. You are limited by law, world wide, to a specific number of short transmissions per second because those frequencies are shared by many types of users.

My question about timing refers to the pulse width of the first few pulses sent by the controller to the RF transmitter. I want to understand whether the Nano (0.5 msec) or the Pro Mini (0.3 msec) has the correct timing.

This is redundant.

Where is 'driver' initiated and which class is it an object of?
Does this sketch compile the way you posted it?

Unusual use of the word "decouple". What do you mean by it, and what do you think the diodes do?

I suspect you are looking at the synchronizing signals sent by the transmitter internal controller and has nothing to do with either ARduino. You do have documentation on the 433 MHz device don't you?

OK, I figured out the problem:
I forgot to undo some experimental changes in boards.txt which changed the clock frequency.
As a result F_CPU had the wrong value, which messed up the computation in RH_ASK::timerCalc() by always returning too small a number in nticks, ultimately causing the pulse width to be too short.
Thank you very much to everybody who spent (wasted) cycles on this problem. My apologies.


Regarding the question about the diodes: I want to generate an interrupt by pulling down pin 2 whenever a button is pushed. In the ISR I will detect which button was pushed by querying pins 3-5. The diodes ensure that only that pin is low which is connected to the active button. Without the diodes all pins would be pulled low.

Ah, makes sense, but I don't think we'd have ever figured that out! Good that you found the issue.

You do know that you have interrupts on any GPIO, right? You only have to read the input register to figure out which pin triggered it. I'm not sure if this will also work if you need the interrupt to wake the controller from sleep; is that why you're stuck with pin2?

Good point.
I defaulted to pin 2 because attachInterrupts() only allows pins 2+3 as sources for interrupts.
I read through the relevant sections in the ATmega328P data sheet and I see how that should work. If I actually will end up with 3 buttons (instead of 1 toggle button), I will explore that further.
Thanks !!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.