Morse with simple 433mhz transceiver

Hi guys,
Might be a rookie question, yet I couldn’t find on Google or related to my specific search.
I have 2 Arduino nano and a set of simple 433mhz transmitter and receiver.
I found few online guidance how to build the circuit and sending data using RH_ASK.h library.
Everything works and I can send text messages between the devices using radio waves and even “beep” using a buzzer when receiving.

What I am struggling to do is to simplifying the process totally.
I don’t want to send any data on the carrier wave, I simple want to create a carrier wave that while receiving it I send the buzzer to beep. So like that I can create a constant “beep” instead of packets of information as RH_ASK.h seems to work.

Right now when I’m using the code, for a long press on the transmitter I receive intervals of “beep” “beep” with pause in between them, instead of constant “beep”.
by the end I want to be able to send “dot” and “dash” in order to send Morse signals and decode them on the other device.

Here is my transmitter sketch:

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library 
#include <SPI.h> 
 
// Create Amplitude Shift Keying Object
RH_ASK rf_driver(2000,11,2);

const byte sendButtonPin = 12;
byte buttonState = 0; 

void setup()
{
    Serial.begin(9600);
    pinMode(sendButtonPin, INPUT);
    // Initialize ASK Object
    rf_driver.init();
}
 
void loop()
{
    const char m = "1";
    buttonState = digitalRead(sendButtonPin);
    if (buttonState == HIGH) {
      Serial.println("Button + Sent data!");
      rf_driver.send((uint8_t *)m, 1);
      rf_driver.waitPacketSent();
    }
}

and here is my receiver sketch:

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library 
#include <SPI.h> 
 
// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

const byte buzzerPin = 10;

void setup()
{
    pinMode(buzzerPin, OUTPUT);
    // Initialize ASK Object
    rf_driver.init();
    // Setup Serial Monitor
    Serial.begin(9600);
}
 
void loop()
{
    // Set buffer to size of expected message
    uint8_t buf[1];
    uint8_t buflen = sizeof(buf);
    // Check if received packet is correct size
    if (rf_driver.recv(buf, &buflen))
    {
      digitalWrite(buzzerPin, HIGH);
      // Message received with valid checksum
      Serial.print("Message Received: ");
      Serial.println((char*)buf);
      delay(100);   
    } else {
      digitalWrite(buzzerPin, LOW);
    }
}

In the receiver sketch there is delay, I am aware, otherwise the buzzer will barely be heard as its too fast HIGH/LOW oscillations. Yet if I could make a constant transmission instead of packets, this delay wont be a bother anyway I guess.

Thanks in advance!
Ran

Your proposed method is not very good. Instead, I'd recommend one of two techniques:

  • Use the 'State Change' detection method to send the status of the switch (HIGH or LOW) only when it changes. The RX should hold the state of the buzzer (on or off) constant and not change it until the next state change is received from the TX.

  • Send the status of the switch (HIGH or LOW) on EVERY pass through loop (no delays, get rid of the Serial.println statement). Then in the RX, set the buzzer state to the value received. So, if you hold the switch, you'll continually transmit "1" and the RX will continually set the buzzer output. If not, you'll continually transmit "0" and the RX will continually clear the buzzer output.

In either case, get rid of delay() in the RX.

set of simple 433mhz transmitter and receiver

Which ones?

Most of the really simple ones that just use OOK (On Off Keying) have a single input pin on the transmitter and a single output pin on the receiver (plus ground and power).
Drive that pin high to transmit the carrier, low to turn the carrier off (or it could be inverted - check the datasheet)

Ditch the library, write to the pin directly.

Edit: Although I'm not sure how long an ON you can send. The AGC in the receiver may not like a continuous carrier.

pcbbc:
Edit: Although I'm not sure how long an ON you can send. The AGC in the receiver may not like a continuous carrier.

The AGC will come into play if there is a continuous on signal or a continuous off signal for a few tens of milliseconds and then the receiver will output "static" regardless of whether the transmitter is on or off. This can be simply demonstrated by hooking a suitable speaker to the transmitter "data" output.

You can modulate the transmitter with an audio tone which the receiver will reproduce when the transmitter is keyed. This can be done simply with the tone() function.

Concept demonstration code for the transmit side might look something like this (not tested):

#define txPin 8
#define dit 100
#define dah 300
#define space dit
#define toneFreq 400

void setup() {
}

void loop() {
  // Repeatedly transmit Morse dit, dah, followed by 1 second pause
  tone(txPin, toneFreq, dit) ;
  delay(dit + space) ;
  tone(txPin, toneFreq, dah) ;
  delay(dah + space) ;
  delay(1000) ;
}

It should be noted that, depending upon the specifics of one's locality, high duty cycle transmission on the 433 MHz band may not be strictly legal.

Hi,

Thanks for both of you for the responses!
True, I forgot to show an example of what transceiver I have, they look like this one:


Indeed there is 1 VCC, 1 GND, 1(TX)/2(RX) DATA pins.

@gfvalvo, would you mind to place an example code of each method? Not sure I understood completely how to implement your suggestion.

@pcbbc, alright, I will try that now to see if simple digitalWrite HIGH/LOW can work for my case!

Would you guys have an idea how can I format maybe "dot" and "dash" in my sketch?
I would a single quick press to be always similar TX so the RX can understand its "dot" and also a "dash" press to be be formatted in sort of a way that even if I press a bit more time it will format a constant transmission time of "dash".

@MrMark, maybe you actually just answered my question. So this will be the way to format the "dot"/"dash" in TX, but with command should I use to send that tone? Should I keep using the:

rf_driver.send((uint8_t *)m, 1);

with different variables?
and how may I reproduce those tones in the RX sketch?

Thanks again,
Ran

I suggest that you take time to digest what has been posted, and do some online research on the subject. Some of your comments on other aspects, such as reproducing the tone, also suggest to me that you haven't studied enough. There are rich online resources that will get you answers faster than a Q+A here. Only reply #1 comes even close to being legal in North America, anyway... basically you are just transmitting the leading and trailing edges of the dits and dahs. That will help to keep the duty cycle low. Otherwise you'll be blasting away all the outdoor thermometers and such in the general vicinity (which can happen without you ever finding out about). Direct OOK transmission of Morse with this hardware is futile because of the primitive receiver design, as well as possibly illegal, so forget about it.

aarg:
I suggest that you take time to digest what has been posted, and do some online research on the subject. Some of your comments on other aspects, such as reproducing the tone, also suggest to me that you haven’t studied enough. There are rich online resources that will get you answers faster than a Q+A here. Only reply #1 comes even close to being legal in North America, anyway… basically you are just transmitting the leading and trailing edges of the dits and dahs. That will help to keep the duty cycle low. Otherwise you’ll be blasting away all the outdoor thermometers and such in the general vicinity (which can happen without you ever finding out about). Direct OOK transmission of Morse with this hardware is futile because of the primitive receiver design, as well as possibly illegal, so forget about it.

Thank you @aarg for the reminder and help in the topic.
I am indeed a newbie here that tries to play around with some kits I got in hand. Of course I will do more research as you suggested.

would you mind to show me an example of implementation for that comment of yours?:

basically you are just transmitting the leading and trailing edges of the dits and dahs. That will help to keep the duty cycle low.

How may I do that so I will indeed keep the duty cycle low.

Thanks,
Ran

ranbracha:
@MrMark, maybe you actually just answered my question. So this will be the way to format the "dot"/"dash" in TX, but with command should I use to send that tone? Should I keep using the:

rf_driver.send((uint8_t *)m, 1);

with different variables?
and how may I reproduce those tones in the RX sketch?

rf_driver.send() is going to send data using the underlying protocol that RadioHead uses for data packet encoding. It works well enough doing that but the transmitted signal encoding isn anything like Morse code.

You can literally hook up a speaker to the receiver using the transmit example code above and Morse code (with intervening static) will come out of it. No processing on the receive side is strictly necessary. If you want to decode the Morse code stream on the receive side that's a non-trivial exercise, but there exist examples on the web where that has been done.

To review some of the concepts in the thread . . .

Post #1 describes a scheme to make it appear that Morse code is being transmitted in that a key press on the transmit side causes a tone on the receive side, but over the air it's really transmitting digital data packets using the magic of RadioHead that say "tone on" and "tone off" as interpreted by the receiver.

Post #2 describes using the transmitter as is done in practice for Morse code, but raises the issue that the receiver you have doesn't really support this mode of operation.

Post #3 describes a workaround for the receiver issue noted in Post #2 which should work well enough.

Usage regulations for the 433 MHz band typically restrict the transmitter duty cycle. In the US, I believe the longest continuous transmission is supposed to be less than 5 seconds with an intervening off period of 30 times the transmit period and no less than 10 seconds. The band is widely used for remote sensors (e.g. wireless thermometers) which typically update every minute or so, garage door openers (transmit maybe a few times per day), and such. A user that is transmitting continuously may interfere with the operation of these sorts of devices in the vicinity.

I suspect most every Arduino tinkerer who has experimented with these radios has probably, inadvertently or not, violated these regulations, but it's important to understand the bounds of good radio citizenry.

Thanks @MrMark,
I indeed tried to connect RX data pin directly to speaker (and led also just as curiosity)
and noticed that TX tone codes are being sent successfully and the RX directly play them on the speaker without Arduino to process anything.
By the way, I indeed had that static noise being heard on the speaker while no transmission, which I wonder how to filter out.
I also noticed that after a transmission finished the receiver was like "booting up", so if I connected led to the RX data pin I saw the led low bright on static, high bright on transmission and then off while dimming on until receiver is "up listening" again.
I am indeed looking now for how Arduino can receive those RX tones and process them, as you suggested that I might find on the web. (if you have URL handy, that will be nice to see!)

by post #3 you mean yours? :slight_smile:

Just as for the legal side aspect, I'm looking to manually experiment the radio topic and not transmitting non stop data over a large automated project. In other words, I'm using buttons and transmitting very low intervals of trials to ensure no signal is being constantly sent or looped in a way that will kill the bandwidth.
nonetheless, I highly appreciate you guys reminding that legal aspect, because it is indeed very important to be aware of.

ranbracha:
would you mind to show me an example of implementation for that comment of yours?:
How may I do that so I will indeed keep the duty cycle low.

Thanks,
Ran

It's the one in reply #1.

You can't "filter out" the noise at the receiver. You can mute it (treat periods of noise as no signal) - when you do that, you really have an analog/digital hybrid demodulator which doesn't respect the directness of your proposed "simple" approach. It's more like a step towards digital encoding, as it is designed for, except with a simpler digital protocol where an audio frequency carrier serves both to stabilize the receiver, and to provide an audible tone. That feature is just a happy accident. But if you have to digitally filter the bit stream, it seems kind of pointless.

What you have to realize, is that those radios have specific limitations on the signal, in order to work. Not only in signal amplitude but signal frequency too. During the time when the transmitter is active, there is a limit to how many consecutive zeroes or ones you can transmit reliably, which is why bipolar encoding (Manchester code) is used. That is incompatible with straightforward OOK transmissions like Morse. This basic incompatibility makes your idea impractical, and the results when it's taken as an experiment, inconclusive or meaningless.

The best you can hope for in a working version, is an "overlay" like the proposal in reply #1, which utilizes a mode of operation that is working and proven reliable. as a transport mechanism for the Morse stream.