Serial UART OUTPUT AS TONE - OOK DATA MODULATION

What would be the best way to create a serial output with a frequency modulated in the high bits?
Explaining for better understanding: I want the HIGH bits of a serial output to be a pulse train (a TONE tone at 1kHz) instead of just continuous high.
What would be the best way to do this without having to use some external hardware?

May done by a compartor configuration ? Serial output pin redirecting to an interrupt pin ?

For example, could I use a PWM pin making it output frequency (HIGH) or nothing (LOW) according to the bits of a common UART serial output?

I want send serial data as audio carrier to be decoded by a LM567 Tone decoder IC

Sorry, this makes no sense to me. Please make a timing diagram showing what you want the serial output to look like, and what "HIGH bits" means.

I want send serial data as audio carrier to be decoded by a LM567 Tone decoder IC

Use the tone() command to do this.

If you are referring to the TTL serial output pin on an Arduino? The pin is normally high and goes low the begin with a start bit. So it is actually inverted to your description.

At a very quick glance the LM567 Tone decoder IC allows to detect a given frequency (considering a certain bandwidth around the center) and pulling an output pin to LOW while the frequency is detected.

I understand that you want to convert data from a binary format into an audio signal that sounds when a HIGH bit shall be transmitted. Correct?

To do this with a Serial port is quite strange. As @jremington already posted that would be a job for the tone-Lib. It looks like a nice idea, but requires some knowledge about how Serial UARTs work and some decisions about the data rate you want to achieve.

1 kHz tone (as you mentioned) means 1 msec wavelength. If you have a Serial with, let us assume 9600 baud, you have already 9.6 symbol changes within 1 msec.

See here https://en.wikipedia.org/wiki/Symbol_rate

You will need a frequency with in minimum the double or more frequency of the datarate to get a reliable connection, (double is the theoretical minimum, better four to five times in minimum).

How UARTs work, see here

https://www.circuitbasics.com/basics-uart-communication/

So per byte in general in minimum 10 bit

  • 1 Start Bit
  • 8 Data Bits
  • 1 Stop Bit

to convert to a tone.

Good luck!

Doesn't make sense to me. If you try to interpret a serial output as a pulse train you will have issues. There is a start bit, data, and stop bit. If you add parity then there is one more bit.

I understand very well the serial uart communications. I want just modulate serial data in order it could be transmmited thru an audio channel and in the other end this audio could be demodulated by the LM567 as serial out again.
The baud rate and carrier frequency are not important to me now. No problem if very low baud rate as 1200 kbps.
The modulation name is OOK - On Off Keying. I believe may be that this could be done by redirecting a normal serial out pin to another interrupt pin. And the interrupt routine make another PWM output send the modulated bits. by stop and resuming the PWM output...

Yes . But we could easyly invert if necessary. The problem is how modulate the serial data out in an easy way by software

Consider using the SPI as you do not have start, stop, and parity bits to contend with. A codac would probably be better.

Set a Baud rate and use Serial.write().

But how send the serial data modulated not having to write for each bit of serial stream ?

data must be transmmited by an audio channel. It should be decoded by the LM567 as serial normal data..

When I tried a project with a LM567 a few years ago, it was very touchy about frequency. Are you SURE a square wave will work with a LM567?

Yes. It works very fine.

SPI not applicable because serial data must be transmitted thru an audio channel

By definition you must read or write each bit of the serial stream.

SERIAL = ONE BIT AT A TIME.

I don't understand your confusion. If you want to send tones corresponding to individual bits, you have to read one bit and send the corresponding tone, read the next bit and send the corresponding tone, etc. With start and stop bits for UART serial!

Hello.
Mr. Did you read the instructions on how to use the forum?
There it informs that Mr. You shouldn't post repeated posts on the same subject.
But I think Mr. did not meet this recommendation.

Right?

See: Saída Serial Modulada

Em português:
Olá.
O Sr. leu as instruções de como usar o fórum?
Lá informa que o Sr. não deve postar posts repetidos sobre o mesmo assunto.
Mas acho que o Sr. não atendeu esta recomendação.

Certo?

Veja : Saída Serial Modulada

Repeated posts ? Where ?

This may solve your intention:

const byte interruptPin = 2;
const byte tonePin = 8;

void setup() {
  Serial.begin(1200);
  Serial.println("Start");
  pinMode(tonePin, OUTPUT);
  digitalWrite(tonePin,HIGH);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), ToneOut, CHANGE);

}

void loop() {
  if (Serial.available()){
     char in = Serial.read();  
     Serial.print(in);
    }
  
}

void ToneOut() {
    if (digitalRead(interruptPin) == HIGH) noTone(tonePin);
                                      else tone(tonePin,10000);
   //digitalWrite(tonePin,digitalRead(interruptPin)); // This replicates Serial to tonePin 1:1
};

Just connect by wire

Serial RX Pin <-------> interruptPin

and catch the CHANGE interrupt as in the sketch above and switch tonePin to a given frequency or off. That's the output on my scope:

blue => Serial RX from PC (Pin 0 of the Arduino UNO board)
yellow => tonePin (digital Pin 8)
Baud rate = 1200
Tone Frequency => 10 kHz

The sketch is just a proof of concept, not optimized for use ...

Good luck with your project!

This way you do not have to cope with start/stop bits etc. as this is a dump replication of the Serial timings ...

1 Like

Very good !!!
This is correct . The LM567 is open collector and switch to GND when the tone is detected.
Thanks for nice solution !