Author Topic: Generating Simultaneous Tones  (Read 16035 times)

0 Members and 1 Guest are viewing this topic.

Offline fourfathom

  • Super Contributor
  • ***
  • Posts: 1884
  • Country: us
Re: Generating Simultaneous Tones
« Reply #100 on: May 01, 2021, 03:47:24 pm »
The tones I have chosen are non harmonically related through 5th order and are based on prime numbers so the FFT decoder should have an easy time keeping the tone display "clean".

You've got that backwards. An FFT can only give a 'clean' output for tones that are periodic within the sample set. Everything else will spill in to other bins.

I think he's got that much right.  Say you have a FFT with a bin width of 50 Hz.  Use prime-related tones of 50 x {2, 3, 5 ... 53} (first 16 primes).  This gives you tones of 100Hz, 150Hz, 250Hz ... 265 Hz.  You can scale the bins and multipliers to better fit the VHF audio channel characteristics, but this will avoid false detection of distortion products.  I haven't looked at any windowing requirements, so perhaps the spectral leakage will be an issue.
We'll search out every place a sick, twisted, solitary misfit might run to! -- I'll start with Radio Shack.
 

Offline rfclown

  • Frequent Contributor
  • **
  • Posts: 407
  • Country: us
Re: Generating Simultaneous Tones
« Reply #101 on: May 01, 2021, 05:36:29 pm »
... I cannot see why this can't be dealt with as a parallel to serial conversion, simple transmission, serial to parallel at the other end. These are decades old techniques with simple, cheap and well proven technology....

I completely agree. I was baffled as I read the LONG description. What would make someone devise the proposed multitone solution to the problem?

> A mobile can vote between 3 or 4 receivers in ONE second -NO packet system is that fast.

So the data needs to be sent at least at a 1 Hz rate. 16 bits every 1 second.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Generating Simultaneous Tones
« Reply #102 on: May 01, 2021, 09:04:31 pm »
... I cannot see why this can't be dealt with as a parallel to serial conversion, simple transmission, serial to parallel at the other end. These are decades old techniques with simple, cheap and well proven technology....

I completely agree. I was baffled as I read the LONG description. What would make someone devise the proposed multitone solution to the problem?

> A mobile can vote between 3 or 4 receivers in ONE second -NO packet system is that fast.

So the data needs to be sent at least at a 1 Hz rate. 16 bits every 1 second.

The OP is not thinking about the problem from a perspective of understanding the actual comms technology.  He is thinking in very simplistic terms that don't properly analyze the problem.  He hasn't really explained his thinking much at all, focusing on the higher level problem instead.  The mapping of requirements to the lower level problem of the actual transmission format was therefore faulty. 

One crucial requirement I don't think I've seen is the time between an event and the time it is recognized at the other end.  That is what seems to dominate his thinking as if it needs to be as close to zero as possible rather than defining a number then working with that. 

Meanwhile people are proposing many solutions which result in different values for this delay so that potentially NONE of them may actually meet this requirement.  Is this my mistake and he does have a delay time in mind? 

I don't know the bit rate that can be sent over the channel, but a packet system doesn't limit the data rate.  I assume he is referring to preexisting packet systems.  If he is going to roll his own tone based system there is no reason why he can't roll his own "packet" system which is another name for aggregating bits and sending them serially with a simple modulation scheme. 

I think we put together something like that in a sophomore level lab class in school.  It is hard to find a more simple idea.  Yeah, a "packet' of three bytes.  One is a counter, (0, 1, ... 255, 0...) for sync and the other two are the data.  A really simple MCU can handle that at both ends with a very short end to end delay (shorter than an FFT most likely) and so much more simple to implement. 

Another nice feature of the "packet" approach is the size of the "packet" is very easy to change for different applications.  Add another byte and the delay time goes up by 33%.  In the tone approach the resolution of the FFT pushes up the length of the FFT according to N but the processing time by N*log(N)
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline fourfathom

  • Super Contributor
  • ***
  • Posts: 1884
  • Country: us
Re: Generating Simultaneous Tones
« Reply #103 on: May 01, 2021, 09:23:46 pm »
Using the simplest 300-baud 2FSK modulation (300 bits/second, 12 bits gives you RS232-UART-style "start/8-data/parity/stop/stop") you could have a simple message format: [Sync, Data1, Data2, Checksum].  That's 48 bits, 6.25 times per second, carrying sixteen user-databits.  Extremely simple and dirt-cheap.  No reason not to add a few more user-data bytes per message.  300 baud 2FSK is easily carried over any reasonable VHF channel.
We'll search out every place a sick, twisted, solitary misfit might run to! -- I'll start with Radio Shack.
 

Online oPossum

  • Super Contributor
  • ***
  • Posts: 1418
  • Country: us
  • Very dangerous - may attack at any time
Re: Generating Simultaneous Tones
« Reply #104 on: May 01, 2021, 09:50:34 pm »
All of the bins will be harmonics (integer multiples) of the bin spacing. That is the harmonic relationship I am referring to. I am assuming the frequencies have been chosen without regard to this harmonic relationship and are thus non-periodic within the FFT sample set. They will spill over into other bins, the FFT will not be 'clean'.

The tones I have chosen are non harmonically related through 5th order and are based on prime numbers so the FFT decoder should have an easy time keeping the tone display "clean".

You've got that backwards. An FFT can only give a 'clean' output for tones that are periodic within the sample set. Everything else will spill in to other bins.

I think he's got that much right.  Say you have a FFT with a bin width of 50 Hz.  Use prime-related tones of 50 x {2, 3, 5 ... 53} (first 16 primes).  This gives you tones of 100Hz, 150Hz, 250Hz ... 265 Hz.  You can scale the bins and multipliers to better fit the VHF audio channel characteristics, but this will avoid false detection of distortion products.  I haven't looked at any windowing requirements, so perhaps the spectral leakage will be an issue.
 

Offline OldVoltsTopic starter

  • Contributor
  • Posts: 23
  • Country: us
Re: Generating Simultaneous Tones
« Reply #105 on: May 02, 2021, 01:42:51 am »
I thought you said it was going to be an Arduino???  KISS, no?
Not enough I/O pins on simple Arduinos.
Turns out Propeller is cheap and, with 8 cores and 32 I/O pins I'll be spoiled for choices.
Write simple code - once.  Load from Hub to each core.  Hit "Go".
Very KISS.

Bill
 

Offline MIS42N

  • Frequent Contributor
  • **
  • Posts: 511
  • Country: au
Re: Generating Simultaneous Tones
« Reply #106 on: May 02, 2021, 01:45:35 am »
One crucial requirement I don't think I've seen is the time between an event and the time it is recognized at the other end.  That is what seems to dominate his thinking as if it needs to be as close to zero as possible rather than defining a number then working with that. 
I did ask about that, but no reply. The implication is a person could see events in real time. A person takes quite a few milliseconds to notice an event and many more to react. A good 'below human perception' delay is 20ms, the frame rate of some television. And if it is a person reacting, a certain level of error tolerance is built in - 1 bit in a 100 would be noticed by a person but quickly ignored. Using straight async characters with start bit, stop bit = 8 data bits and 2 overhead. 16 bits of data takes 20 bits, which at 1200 baud takes less than 20ms. 1200 baud is slow by amateur radio standards.

My preferred solution (given the meager specification) would be to capture and time stamp events, and have some way of recording everything. That way, events can be analyzed at leisure. Also, it doesn't need someone sitting looking at it. At one time I was responsible for 75 computers around the world. Each one generated a couple of hundred events a day. These were compressed (zip) and sent daily to a computer on our site. Then a scheduled job filtered and summarised, so I had a report at 8:00 a.m. when I arrived at work, which may have a dozen items for action. Usually a simple fix, but sometimes a trawl through the raw data to get a picture (The events were recorded in local time, but before zipping they were adjusted to UTC. Why certain operating systems don't run on UTC is an annoyance. One mainframe was turned off for an hour at start of daylight savings, couldn't handle records time stamped in the future. Some of our problems were on networks crossing time zones so UTC made correlation easier).

my 2¢.
 

Offline OldVoltsTopic starter

  • Contributor
  • Posts: 23
  • Country: us
Re: Generating Simultaneous Tones
« Reply #107 on: May 02, 2021, 01:52:10 am »
I completely agree. I was baffled as I read the LONG description. What would make someone devise the proposed multitone solution to the problem?
> A mobile can vote between 3 or 4 receivers in ONE second -NO packet system is that fast.
So the data needs to be sent at least at a 1 Hz rate. 16 bits every 1 second.
Try 10 "updates" per second - 10 Baud per "carrier".
Bill
 

Offline OldVoltsTopic starter

  • Contributor
  • Posts: 23
  • Country: us
Re: Generating Simultaneous Tones
« Reply #108 on: May 02, 2021, 01:59:29 am »
One crucial requirement I don't think I've seen is the time between an event and the time it is recognized at the other end.  That is what seems to dominate his thinking as if it needs to be as close to zero as possible rather than defining a number then working with that. 
I did ask about that, but no reply. The implication is a person could see events in real time. A person takes quite a few milliseconds to notice an event and many more to react. A good 'below human perception' delay is 20ms, the frame rate of some television. And if it is a person reacting, a certain level of error tolerance is built in - 1 bit in a 100 would be noticed by a person but quickly ignored. Using straight async characters with start bit, stop bit = 8 data bits and 2 overhead. 16 bits of data takes 20 bits, which at 1200 baud takes less than 20ms. 1200 baud is slow by amateur radio standards.

My preferred solution (given the meager specification) would be to capture and time stamp events, and have some way of recording everything. That way, events can be analyzed at leisure. Also, it doesn't need someone sitting looking at it. At one time I was responsible for 75 computers around the world. Each one generated a couple of hundred events a day. These were compressed (zip) and sent daily to a computer on our site. Then a scheduled job filtered and summarised, so I had a report at 8:00 a.m. when I arrived at work, which may have a dozen items for action. Usually a simple fix, but sometimes a trawl through the raw data to get a picture (The events were recorded in local time, but before zipping they were adjusted to UTC. Why certain operating systems don't run on UTC is an annoyance. One mainframe was turned off for an hour at start of daylight savings, couldn't handle records time stamped in the future. Some of our problems were on networks crossing time zones so UTC made correlation easier).

my 2¢.
Worth several times that amount.
Scenario:
I am listening to a mobile (in motion) and as the signal switches between remote receivers (due to the transmitting station being in-motion) I notice that the system is voting a receiver with (lets say) 60 Hz hum - a failing power supply.  Which remote is it?
The remote monitor enables me to correlate, in real time, the activities of the system (what I hear) with the current actions of the voting system (which receivers receiving and receiver voted and repeated).  Historical - even by seconds - simply doesn't cut it.
Closest analogy: out of sync lips / voice in "What's Up Tiger Lilly".
Bill

 mobile
 

Offline fourfathom

  • Super Contributor
  • ***
  • Posts: 1884
  • Country: us
Re: Generating Simultaneous Tones
« Reply #109 on: May 02, 2021, 05:50:42 pm »
Historical - even by seconds - simply doesn't cut it.
As has been mentioned, human response being what it is you would prefer that the delay between event and display to be no greater than 30 ms.  My suggestion to use 300 bps 2FSK gave you a response time of perhaps 200 ms (which I suspect would be perfectly usable for your needs.)  On a good ham VHF link you can pretty easily bump that datarate from 300 up to 1200, giving you a 50ms transmission time.  You can speed this further by simplifying my four word "packet", perhaps by eliminating the final checksum byte and instead relying on the parity bits for error checking.

I claim that this will be perfectly usable and vastly simpler than your DMT implementation.  There are many other simple methods that would work.

As has also been mentioned, there is no free lunch when it comes to bits per second throughput over a noisy, band-limited channel.  Overcomplicating the modulation method doesn't buy you anything.  The reason for many of the fancier schemes is to allow graceful optimization of the datarate in the presence of variations in channel capacity caused by noise and interference.  I don't see this capability being useful in your situation (and you certainly haven't implemented such.)
We'll search out every place a sick, twisted, solitary misfit might run to! -- I'll start with Radio Shack.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Generating Simultaneous Tones
« Reply #110 on: May 02, 2021, 07:54:48 pm »
I'm sure I posted this last night, but it has disappeared... sorry if this is a double-up

Anyhow... here's some code to generate upto 16 concurrent tones (can be easily implemented in all integer) - 580Hz -> 1940Hz at 8000 S/s, along with some (pretty average) code to decode it. As written it send random 16-bit values, The value transmitted could change 20 times per second, but for easy decoding you don't want to change it that much unless you put some effort in detect and align to the transition.

Decoding could also be implemented in fixed point if effort is put in to analyze it, or implement in fixed point servicing the ADC data, and floating point for display results.

Signal is generated in +/- 32768, but still works fine with samples reduced to +/-7, so ADC bit depth will not be a big deal. I guess if you used it over a SSB channel you need to be tuned within +/-10 Hz for it to work.

With no noise added
Code: [Select]
$ ./encode | ./decode | more
Hard limited     % of max
1110011010100010 100 100 100   0   0 100 100   0 100   0 100   0   0   0 100   0
1110011010100010 100 100 100   0   0 100 100   0 100   0 100   0   0   0 100   0
1110011010100010 100 100 100   0   0 100 100   0 100   0 100   0   0   0 100   0
1110011010100010 100 100 100   0   0 100 100   0 100   0 100   0   0   0 100   0
1110011010100010 100 100 100   0   0 100 100   0 100   0 100   0   0   0 100   0
0110001111000100   0 100 100   0   0   0 100 100 100 100   0   0   0 100   0   0
0110001111000100   0 100 100   0   0   0 100 100 100 100   0   0   0 100   0   0
0110001111000100   0 100 100   0   0   0 100 100 100 100   0   0   0 100   0   0
0110001111000100   0 100 100   0   0   0 100 100 100 100   0   0   0 100   0   0
0110001111000100   0 100 100   0   0   0 100 100 100 100   0   0   0 100   0   0
...
With 50% random noise added
Code: [Select]
$ ./encode | ./decode | more
Hard limited     % of max
1110011010100010  91  90  95   6  11  95  92   6 100  11  90  11  11  16  88  11
1110011010100010 100 100  94   5   9  96  75  14  89   4  98   6  19  17  99  16
1110011010100010  88 100  82   8   6  95  69   2  90   5  87   9   2  18  91  11
1110011010100010  90  83  89  13  15 100  78   3  87  18  80   4   7  11  66   4
1110011010100010 100  77  81   7   3  92  85   5  60  11  85  12   6  11  73  10
1111000111101110  98  86  87  89   9  18  26  77  83  99  85   7  97 100  91   4
1111000111101110  93  87  86  84  18  18  12  86  76  89  77   9 100  74  88  14
1111000111101110  95  95  88  90   3  13  20  87  93  97  94  22 100  76  89  10
1111000111101110  80  78  83  75   4  10  10  75  56 100  84   9  86  87  87   7
1111000111101110  96  83  73  98   4  12  11  88 100  90  96  11  90  84  79  12
0000001101101100   4  15   7   3   9   1 100  92   9  90  96   5  96  93  11   7
0000001101101100   5   9   9   4   6   7  98 100  11  99  88  10  93  99  10   6
0000001101101100   5   6   5   7   6   5  86 100   5  75  80   3  83  97  13   9
0000001101101100   9   9   2  15   5   9  99  95   6  88 100  11  95  95   2   2
0000001101101100  12   2   7   9  14   3  89 100   8  95  97   9  98  93   8   8
1010010001001110  83   3  87   9   9  75  11   7   4  85   4   6  91  78 100  11
1010010001001110  89   6  94   4  10 100  14  10   4  87  10   6  85  89  97   5
1010010001001110  93   4 100  19   9  89   8  14   5  89   5   8 100  91  94   4
1010010001001110  87   6 100  15  13  98   2   8  13  93   4  10  94  93  99   7
1010010001001110  85  12  87   5   4 100  14   5   3  91   3  13  92  93  88   3
1000011100111100  90  10   6  11  23  84 100  96   4   8  89  87  98  95  11   5
1000011100111100  88   8  10   8  16  91  89  89   6   8  95  93  94 100  12   7
1000011100111100  82  12   7   4   5 100  79  86  13   7  91  91  97  78  16   4
1000011100111100  86   6  13   7   6  81  87  81  10   4  90  83 100  96   9  13
1000011100111100  75   5  14  10  14  81  81 100   9  21  72  86  90  89  17   4
0110011100110111   9  78 100  16  22  81  81  89  18   7  84  94  10  78  85  91
0110011100110111   3 100  92  16   9  90  99  94  12   9  92  84  24  83  61  87
0110011100110111  12  89  99  15  13 100  84  86  19  13  91  87  11 100  99  95
0110011100110111  15  87  97  15  18  88  79  91   2  15  67 100  24  97  82  86
0110011100110111   5  88  76   7   6 100  85  78   9   9  82  90  15  78  89  77
1111000110011101  97  80 100  86   5  16  20  82  78  18  13  92  99  82   5  90
1111000110011101  87 100  71  98  15   5  11  98  87   6   7  89  88  93   4 100
1111000110011101  74  65  90  84   9  13  16  86  81  10   9 100  90  77  19  67
...
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: OldVolts

Online gf

  • Super Contributor
  • ***
  • Posts: 1202
  • Country: de
Re: Generating Simultaneous Tones
« Reply #111 on: May 02, 2021, 08:08:05 pm »
Seems there was a forum outage, and some messages were lost.
 

Offline rfclown

  • Frequent Contributor
  • **
  • Posts: 407
  • Country: us
Re: Generating Simultaneous Tones
« Reply #112 on: May 03, 2021, 03:54:18 am »
I completely agree. I was baffled as I read the LONG description. What would make someone devise the proposed multitone solution to the problem?
> A mobile can vote between 3 or 4 receivers in ONE second -NO packet system is that fast.
So the data needs to be sent at least at a 1 Hz rate. 16 bits every 1 second.
Try 10 "updates" per second - 10 Baud per "carrier".
Bill

ok, so 10x that. How would I transmit 160 bits/sec? Simplest things I can think of are OOK and FSK. As mentioned before, all that is needed here is a parallel to serial converter. What I have lying around are Arduino Pro Minis, just the ticket.  17 completely undedicated digital I/Os (PORTB 0-4, PORTC 0-5, PORTD 2-7). If you need more you can use the RESET line, XTAL (PORTB 6-7 and use internal 8MHZ RC) PORTB 5 (LED) and TX/RX (PORTD 0-1), but I'm going to use the Tx/Rx. I won't even have to touch the Arduinos. All I need is one resistor.

Coded u_tx.c just to generate numbers and throw them out the UART at 600 baud. Yes, for 16 bit packets I'd have some frame byte and two data bytes, but I'm just showing the concept. Hooked the ATmega Tx UART output through a resitor to the FM modulation port of my signal generator set for 500 MHz, 5 kHz peak deviation.

For the receiver, I hauled out my modulation analyzer. Set for FM demod, 75usec de-emphasis, 3kHz lowpass. Fed the modulation output directly into the Rx UART pin of another Arduino Pro Mini running u_rx.c. All the code does is take the UART Rx input, and send it out the UART Tx so I can see it on my PC.

Picture shows setup. Both ATmegas are on a single small solderless breadboad sitting on my laptop keyboard. Square wave FSK input of sig gen is shown on scope as well as Modulation Analyzer demod output. PC is running a terminal program that shows sequential numbers being received.

For the simple code, I use Arduino hardware and the gcc and avrdude that gets installed with the Arduino install, but I ditch the Arduino UI and use the avr libraries. I call gcc and avrdude from the command line.
 

Offline MIS42N

  • Frequent Contributor
  • **
  • Posts: 511
  • Country: au
Re: Generating Simultaneous Tones
« Reply #113 on: May 03, 2021, 04:31:12 am »
ok, so 10x that. How would I transmit 160 bits/sec? Simplest things I can think of are OOK and FSK. As mentioned before, all that is needed here is a parallel to serial converter. What I have lying around are Arduino Pro Minis, just the ticket.  17 completely undedicated digital I/Os (PORTB 0-4, PORTC 0-5, PORTD 2-7). If you need more you can use the RESET line, XTAL (PORTB 6-7 and use internal 8MHZ RC) PORTB 5 (LED) and TX/RX (PORTD 0-1), but I'm going to use the Tx/Rx. I won't even have to touch the Arduinos. All I need is one resistor.

Coded u_tx.c just to generate numbers and throw them out the UART at 600 baud. Yes, for 16 bit packets I'd have some frame byte and two data bytes, but I'm just showing the concept. Hooked the ATmega Tx UART output through a resitor to the FM modulation port of my signal generator set for 500 MHz, 5 kHz peak deviation.

For the receiver, I hauled out my modulation analyzer. Set for FM demod, 75usec de-emphasis, 3kHz lowpass. Fed the modulation output directly into the Rx UART pin of another Arduino Pro Mini running u_rx.c. All the code does is take the UART Rx input, and send it out the UART Tx so I can see it on my PC.

Picture shows setup. Both ATmegas are on a single small solderless breadboad sitting on my laptop keyboard. Square wave FSK input of sig gen is shown on scope as well as Modulation Analyzer demod output. PC is running a terminal program that shows sequential numbers being received.

For the simple code, I use Arduino hardware and the gcc and avrdude that gets installed with the Arduino install, but I ditch the Arduino UI and use the avr libraries. I call gcc and avrdude from the command line.
I had a closer look at what OP is on about. I gather all the information needed is going into or coming out of the RVS-8. There are 16 signals to deal with, 8 incoming signals and 8 output signals. The voted repeater output is one bit on one of 8 outputs and as OP pointed out, this could be coded as 4 bits, 1 to say if any line is selected and 3 for which of the 8.

I was thinking along the Pro Mini line myself. I don't write C, just assembler. As the output was to be audio tones rather than FM I was going to generate PWM output applied to a low pass filter to generate one of two tones. See similar idea here https://chapmanworld.com/2015/04/07/arduino-uno-and-fast-pwm-for-afsk1200/. I hadn't looked too hard at the receiver end but I think the Pro is fast enough to decode the audio applied to an analog input pin.

We don't know the link over which the data is moved. Maybe the FM scheme will work if the transmitter/receiver handle it. If the restriction is audio in/audio out I'm pretty sure the Pro Mini could do it, but it may take more than 1 resistor.
 

Offline rfclown

  • Frequent Contributor
  • **
  • Posts: 407
  • Country: us
Re: Generating Simultaneous Tones
« Reply #114 on: May 03, 2021, 01:44:57 pm »
ok, so 10x that. How would I transmit 160 bits/sec? Simplest things I can think of are OOK and FSK. As mentioned before, all that is needed here is a parallel to serial converter. What I have lying around are Arduino Pro Minis, just the ticket.  17 completely undedicated digital I/Os (PORTB 0-4, PORTC 0-5, PORTD 2-7). If you need more you can use the RESET line, XTAL (PORTB 6-7 and use internal 8MHZ RC) PORTB 5 (LED) and TX/RX (PORTD 0-1), but I'm going to use the Tx/Rx. I won't even have to touch the Arduinos. All I need is one resistor.

Coded u_tx.c just to generate numbers and throw them out the UART at 600 baud. Yes, for 16 bit packets I'd have some frame byte and two data bytes, but I'm just showing the concept. Hooked the ATmega Tx UART output through a resitor to the FM modulation port of my signal generator set for 500 MHz, 5 kHz peak deviation.

For the receiver, I hauled out my modulation analyzer. Set for FM demod, 75usec de-emphasis, 3kHz lowpass. Fed the modulation output directly into the Rx UART pin of another Arduino Pro Mini running u_rx.c. All the code does is take the UART Rx input, and send it out the UART Tx so I can see it on my PC.

Picture shows setup. Both ATmegas are on a single small solderless breadboad sitting on my laptop keyboard. Square wave FSK input of sig gen is shown on scope as well as Modulation Analyzer demod output. PC is running a terminal program that shows sequential numbers being received.

For the simple code, I use Arduino hardware and the gcc and avrdude that gets installed with the Arduino install, but I ditch the Arduino UI and use the avr libraries. I call gcc and avrdude from the command line.
I had a closer look at what OP is on about. I gather all the information needed is going into or coming out of the RVS-8. There are 16 signals to deal with, 8 incoming signals and 8 output signals. The voted repeater output is one bit on one of 8 outputs and as OP pointed out, this could be coded as 4 bits, 1 to say if any line is selected and 3 for which of the 8.

I was thinking along the Pro Mini line myself. I don't write C, just assembler. As the output was to be audio tones rather than FM I was going to generate PWM output applied to a low pass filter to generate one of two tones. See similar idea here https://chapmanworld.com/2015/04/07/arduino-uno-and-fast-pwm-for-afsk1200/. I hadn't looked too hard at the receiver end but I think the Pro is fast enough to decode the audio applied to an analog input pin.

We don't know the link over which the data is moved. Maybe the FM scheme will work if the transmitter/receiver handle it. If the restriction is audio in/audio out I'm pretty sure the Pro Mini could do it, but it may take more than 1 resistor.

For number of IOs and bits actually needed for the problem, I'm afraid the OP will discard suggestions on something other than what he has already determined. He said, "Not enough I/O pins on simple Arduinos.", but I count enough on an ATmega32 (Uno, Nano, ProMini, all simple Arduinos) which I enumerated.

My first thought when I decided to throw something together was also to PWM two different tones. But before I started doing that I looked at my RF signal generator which has a DC coupled FM port and realized all I needed was two DC levels. No reason to do anything else.

 >We don't know the link over which the data is moved.
This is a major factor in the question that we don't know. The original question should have been stated as "I want to transfer data at X bits/sec over a Y radio link." I assume it is an FM link, so I showed how 160bps could be sent with simple FM.

I just realized my mistake with the OP
...Please note: I’m NOT looking for other ways to do this – 16 tones at a time is where we’re going....
He clearly stated that he isn't open for suggestions against his 16 tone solution.
 

Offline fourfathom

  • Super Contributor
  • ***
  • Posts: 1884
  • Country: us
Re: Generating Simultaneous Tones
« Reply #115 on: May 03, 2021, 02:14:19 pm »
We don't know the link over which the data is moved. Maybe the FM scheme will work if the transmitter/receiver handle it. If the restriction is audio in/audio out I'm pretty sure the Pro Mini could do it, but it may take more than 1 resistor.

I've been assuming (perhaps incorrectly) that the modulation would be audio tones.  This audio signal will be connected to the transmitter audio input (microphone or AUX port), and these audio tones modulate the FM carrier.  For demodulation, the demodulated audio output of the receiver will be these audio tones which will be sent to an audio demodulator (FSK, DMT, or whatever is used).  This has been how most ham radio digital transmission is done, at least when using external modems.

With this method, any pre-emphasis or de-emphasis is done inside the transceiver, although there may be some response-shaping done in the modem.
We'll search out every place a sick, twisted, solitary misfit might run to! -- I'll start with Radio Shack.
 

Offline fourfathom

  • Super Contributor
  • ***
  • Posts: 1884
  • Country: us
Re: Generating Simultaneous Tones
« Reply #116 on: May 03, 2021, 02:17:50 pm »
I just realized my mistake with the OP
...Please note: I’m NOT looking for other ways to do this – 16 tones at a time is where we’re going....
He clearly stated that he isn't open for suggestions against his 16 tone solution.

Apparently the only acceptable response was supposed to be "Wow!  What an amazingly great scheme!"
We'll search out every place a sick, twisted, solitary misfit might run to! -- I'll start with Radio Shack.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Generating Simultaneous Tones
« Reply #117 on: May 04, 2021, 02:31:52 am »
I just realized my mistake with the OP
...Please note: I’m NOT looking for other ways to do this – 16 tones at a time is where we’re going....
He clearly stated that he isn't open for suggestions against his 16 tone solution.

Apparently the only acceptable response was supposed to be "Wow!  What an amazingly great scheme!"

I'm sure he will get something to work.  It will either meet some requirement he has not actually shared with us in a clear manner, or it will be a lot more work than a simpler solution. 

I don't recall how he said he was going to demodulate the tones.  Would each propeller CPU be used as a tone detector? 

Actually, he might not need a demodulator on the receiving end.  Aren't spectral displays common on receiver outputs?  Or maybe they are only on the RF rather than the audio output.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Online oPossum

  • Super Contributor
  • ***
  • Posts: 1418
  • Country: us
  • Very dangerous - may attack at any time
Re: Generating Simultaneous Tones
« Reply #118 on: May 04, 2021, 02:50:41 am »
I don't recall how he said he was going to demodulate the tones.  Would each propeller CPU be used as a tone detector? 

Quote from: OldVolts
Decoding is simple: Google for "Arduino audio analyzer" - plenty of examples.

Propeller was for tone generation. Two of them.

It can be done with an ATMega328. Here is some code that uses DDS for 16 tones. IFFT could also be used.

Code: [Select]

#include <xc.h>

static int8_t const st[1 << 8] = {
    0,    3,    6,    9,   12,   15,   18,   21,   24,   27,   30,   33,   36,   39,   42,   45,
   48,   51,   54,   57,   59,   62,   65,   67,   70,   73,   75,   78,   80,   82,   85,   87,
   89,   91,   94,   96,   98,  100,  102,  103,  105,  107,  108,  110,  112,  113,  114,  116,
  117,  118,  119,  120,  121,  122,  123,  123,  124,  125,  125,  126,  126,  126,  126,  126,
  127,  126,  126,  126,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,  118,
  117,  116,  114,  113,  112,  110,  108,  107,  105,  103,  102,  100,   98,   96,   94,   91,
   89,   87,   85,   82,   80,   78,   75,   73,   70,   67,   65,   62,   59,   57,   54,   51,
   48,   45,   42,   39,   36,   33,   30,   27,   24,   21,   18,   15,   12,    9,    6,    3,
    0,   -3,   -6,   -9,  -12,  -15,  -18,  -21,  -24,  -27,  -30,  -33,  -36,  -39,  -42,  -45,
  -48,  -51,  -54,  -57,  -59,  -62,  -65,  -67,  -70,  -73,  -75,  -78,  -80,  -82,  -85,  -87,
  -89,  -91,  -94,  -96,  -98, -100, -102, -103, -105, -107, -108, -110, -112, -113, -114, -116,
 -117, -118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -126, -126, -126,
 -127, -126, -126, -126, -126, -126, -125, -125, -124, -123, -123, -122, -121, -120, -119, -118,
 -117, -116, -114, -113, -112, -110, -108, -107, -105, -103, -102, -100,  -98,  -96,  -94,  -91,
  -89,  -87,  -85,  -82,  -80,  -78,  -75,  -73,  -70,  -67,  -65,  -62,  -59,  -57,  -54,  -51,
  -48,  -45,  -42,  -39,  -36,  -33,  -30,  -27,  -24,  -21,  -18,  -15,  -12,   -9,   -6,   -3   
};

static uint8_t const pi[16] = { 2, 3, 5, 7, 8, 11, 12, 13, 17, 19, 20, 23, 25, 27, 28, 29 };

static volatile uint8_t samples[1 << 8];
static volatile uint8_t update;
static volatile uint8_t timer;

static void generate(uint16_t const tones)
{
    uint8_t n = 0;
    uint8_t pa[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    while(update);
   
    do {
        int16_t i = 0;
        for(uint8_t t = 0; t < 16; ++t) {
            if(tones & (1 << t)) i += st[pa[t]];
            pa[t] += pi[t];
        }
        samples[n] = (2048 + i) >> 4;
   } while(++n);
 
    update = 1;
}

void __attribute__ ((signal, used, externally_visible)) TIMER1_CAPT_vect(void)
{
    static uint8_t n;
    static uint8_t new;
    static uint8_t out[1 << 8];

    if(new) out[n] = samples[n];
    OCR1A = 100 + out[n];
   
    if(!n++) {
        --timer;
        if(new) {
            new = 0;
            update = 0;
        } else {
            new = update;
        }
    }
}

int main(void)
{
    PORTB = PORTC = PORTD = 0;
    DDRB = DDRC = DDRD = 0xFF;
    TCCR1A = 0xA2;
    TCCR1B = 0x19;
    TCCR1C = 0x00;
    ICR1 = 13 * 32 - 1;
    OCR1A = OCR1B = 100 + 128;
    TIFR1 = 0;
    TIMSK1 = 0x20;
    __asm__ __volatile__ ("sei" ::: "memory");
   
    generate(~0);
    timer = 255; while(timer);
   
    uint16_t lfsr = 1;
    for(;;) {
        timer = 7; while(timer);
        lfsr ^= lfsr >> 7; lfsr ^= lfsr << 9; lfsr ^= lfsr >> 13;
        generate(lfsr);
    }
   
    return 0;
}

 
The following users thanked this post: OldVolts

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Generating Simultaneous Tones
« Reply #119 on: May 04, 2021, 03:28:48 am »
I don't recall how he said he was going to demodulate the tones.  Would each propeller CPU be used as a tone detector? 

Quote from: OldVolts
Decoding is simple: Google for "Arduino audio analyzer" - plenty of examples.

Propeller was for tone generation. Two of them.

It can be done with an ATMega328. Here is some code that uses DDS for 16 tones. IFFT could also be used.

Code: [Select]

#include <xc.h>

static int8_t const st[1 << 8] = {
    0,    3,    6,    9,   12,   15,   18,   21,   24,   27,   30,   33,   36,   39,   42,   45,
   48,   51,   54,   57,   59,   62,   65,   67,   70,   73,   75,   78,   80,   82,   85,   87,
   89,   91,   94,   96,   98,  100,  102,  103,  105,  107,  108,  110,  112,  113,  114,  116,
  117,  118,  119,  120,  121,  122,  123,  123,  124,  125,  125,  126,  126,  126,  126,  126,
  127,  126,  126,  126,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,  118,
  117,  116,  114,  113,  112,  110,  108,  107,  105,  103,  102,  100,   98,   96,   94,   91,
   89,   87,   85,   82,   80,   78,   75,   73,   70,   67,   65,   62,   59,   57,   54,   51,
   48,   45,   42,   39,   36,   33,   30,   27,   24,   21,   18,   15,   12,    9,    6,    3,
    0,   -3,   -6,   -9,  -12,  -15,  -18,  -21,  -24,  -27,  -30,  -33,  -36,  -39,  -42,  -45,
  -48,  -51,  -54,  -57,  -59,  -62,  -65,  -67,  -70,  -73,  -75,  -78,  -80,  -82,  -85,  -87,
  -89,  -91,  -94,  -96,  -98, -100, -102, -103, -105, -107, -108, -110, -112, -113, -114, -116,
 -117, -118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -126, -126, -126,
 -127, -126, -126, -126, -126, -126, -125, -125, -124, -123, -123, -122, -121, -120, -119, -118,
 -117, -116, -114, -113, -112, -110, -108, -107, -105, -103, -102, -100,  -98,  -96,  -94,  -91,
  -89,  -87,  -85,  -82,  -80,  -78,  -75,  -73,  -70,  -67,  -65,  -62,  -59,  -57,  -54,  -51,
  -48,  -45,  -42,  -39,  -36,  -33,  -30,  -27,  -24,  -21,  -18,  -15,  -12,   -9,   -6,   -3   
};

static uint8_t const pi[16] = { 2, 3, 5, 7, 8, 11, 12, 13, 17, 19, 20, 23, 25, 27, 28, 29 };

static volatile uint8_t samples[1 << 8];
static volatile uint8_t update;
static volatile uint8_t timer;

static void generate(uint16_t const tones)
{
    uint8_t n = 0;
    uint8_t pa[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    while(update);
   
    do {
        int16_t i = 0;
        for(uint8_t t = 0; t < 16; ++t) {
            if(tones & (1 << t)) i += st[pa[t]];
            pa[t] += pi[t];
        }
        samples[n] = (2048 + i) >> 4;
   } while(++n);
 
    update = 1;
}

void __attribute__ ((signal, used, externally_visible)) TIMER1_CAPT_vect(void)
{
    static uint8_t n;
    static uint8_t new;
    static uint8_t out[1 << 8];

    if(new) out[n] = samples[n];
    OCR1A = 100 + out[n];
   
    if(!n++) {
        --timer;
        if(new) {
            new = 0;
            update = 0;
        } else {
            new = update;
        }
    }
}

int main(void)
{
    PORTB = PORTC = PORTD = 0;
    DDRB = DDRC = DDRD = 0xFF;
    TCCR1A = 0xA2;
    TCCR1B = 0x19;
    TCCR1C = 0x00;
    ICR1 = 13 * 32 - 1;
    OCR1A = OCR1B = 100 + 128;
    TIFR1 = 0;
    TIMSK1 = 0x20;
    __asm__ __volatile__ ("sei" ::: "memory");
   
    generate(~0);
    timer = 255; while(timer);
   
    uint16_t lfsr = 1;
    for(;;) {
        timer = 7; while(timer);
        lfsr ^= lfsr >> 7; lfsr ^= lfsr << 9; lfsr ^= lfsr >> 13;
        generate(lfsr);
    }
   
    return 0;
}

Nice, very nice.

A little outside of the voice 300 -> 3k bandwidth requirement, but that's just selecting the right range of primes and sample rate...
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Generating Simultaneous Tones
« Reply #120 on: May 04, 2021, 04:08:50 am »
I don't recall how he said he was going to demodulate the tones.  Would each propeller CPU be used as a tone detector? 

Quote from: OldVolts
Decoding is simple: Google for "Arduino audio analyzer" - plenty of examples.

Propeller was for tone generation. Two of them.

Yes, that's my point.  Anyone who would use a pair of propeller multiprocessors for generating tones that any MCU could generate would clearly not be happy with anything simple for tone detection.  In fact, I expect he would want to program distinct FIR filters for each tone, one per propeller CPU. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Generating Simultaneous Tones
« Reply #121 on: May 04, 2021, 05:43:18 am »
In lost post of mine I was saying that multichannel transmission does not increase information transmission speed, nor improve latency.

Example: OOK/BPSK spectral efficiency is 1bit/Hz, 1600bps transmission requires 1600Hz frequency band of single channel. Transmission of 16 bits will take 1/100 sec. When we split 1600Hz channel into smaller 16 non-interfering 100Hz subchannels and transmit using OOK/BPSK, then those who can do the math will see that latency of 16 bit transmission will be 1/100 sec. In short: 16-tone requirement only adds unnecessary complexity, does improve nothing in terms of speed or latency.
« Last Edit: May 04, 2021, 07:03:55 am by ogden »
 
The following users thanked this post: gnuarm

Online gf

  • Super Contributor
  • ***
  • Posts: 1202
  • Country: de
Re: Generating Simultaneous Tones
« Reply #122 on: May 04, 2021, 10:02:42 am »
It can be done with an ATMega328. Here is some code that uses DDS for 16 tones.
Thanks for the practical proof of concept, showing that the core functionality of a software DDS is indeed not more than a handful lines of code.
I'm not sure whether this was understood by the OP, when a DDS was proped pretty early in this thread (w/o giving a practical code example showing the final implementation on a µC).

A little outside of the voice 300 -> 3k bandwidth requirement, but that's just selecting the right range of primes and sample rate...
Given that a 300...3000Hz channel is available (as specified by the OP), larger primes need to be selected so that fmax/fmin does does exceed 10:1. For instance the 16 primes in the 7...67 range, in conjunction with a base frequency of 44.6Hz would fit (orthogonality of tones were granted then for window sizes which are integral multiples of 22.422ms). For DDS, the sampling rate does not need to be an integral multiple of the generated frequency. By using a larger phase accumulator (e.g. 32bits), and doing phase truncation, one can basically generate arbitrary frequencies at much finer granularity (at the cost of a bit of phase noise, but the amount can be controlled via the the waveform table size). Of course it is certainly helpful if a sampling rate can be selected which does not require phase truncation, but if it can't, then it is not a disaster either.
« Last Edit: May 04, 2021, 11:05:32 am by gf »
 
The following users thanked this post: OldVolts

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Generating Simultaneous Tones
« Reply #123 on: May 04, 2021, 04:59:20 pm »
In lost post of mine I was saying that multichannel transmission does not increase information transmission speed, nor improve latency.

Example: OOK/BPSK spectral efficiency is 1bit/Hz, 1600bps transmission requires 1600Hz frequency band of single channel. Transmission of 16 bits will take 1/100 sec. When we split 1600Hz channel into smaller 16 non-interfering 100Hz subchannels and transmit using OOK/BPSK, then those who can do the math will see that latency of 16 bit transmission will be 1/100 sec. In short: 16-tone requirement only adds unnecessary complexity, does improve nothing in terms of speed or latency.

Bingo!  1+   :-+
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Generating Simultaneous Tones
« Reply #124 on: May 04, 2021, 05:53:42 pm »
It can be done with an ATMega328. Here is some code that uses DDS for 16 tones.
Thanks for the practical proof of concept, showing that the core functionality of a software DDS is indeed not more than a handful lines of code.
I'm not sure whether this was understood by the OP, when a DDS was proped pretty early in this thread (w/o giving a practical code example showing the final implementation on a µC).

A little outside of the voice 300 -> 3k bandwidth requirement, but that's just selecting the right range of primes and sample rate...
Given that a 300...3000Hz channel is available (as specified by the OP), larger primes need to be selected so that fmax/fmin does does exceed 10:1. For instance the 16 primes in the 7...67 range, in conjunction with a base frequency of 44.6Hz would fit (orthogonality of tones were granted then for window sizes which are integral multiples of 22.422ms). For DDS, the sampling rate does not need to be an integral multiple of the generated frequency. By using a larger phase accumulator (e.g. 32bits), and doing phase truncation, one can basically generate arbitrary frequencies at much finer granularity (at the cost of a bit of phase noise, but the amount can be controlled via the the waveform table size). Of course it is certainly helpful if a sampling rate can be selected which does not require phase truncation, but if it can't, then it is not a disaster either.

In an application like this phase noise is not likely to be significant at all.  If it is, it is not hard to mitigate with a linear approximation after the sine lookup using the remaining low order bits of the phase word.  It is not uncommon to use a linear approximation to reduce the size of the sine table.  I recall a method using a trig equivalence sin(a+b) = sin(a)cos(b) + cos(a)sin(b) ~= sin(a) + cos(a)sin(b) or two table lookups (functionally equivalent to the linear approximation).  The noise levels attainable are actually quite remarkable and show why digital techniques can be superior to analog.  In this case the limitation will be in the noise generated in the DAC process. 

Using an FFT for the tone decoding has some problems.  Because the frequencies being detected are so low, it is easy to detect them with simple band pass filters.  This eliminates the need for the frequencies to be multiples of any fundamental rate and eliminates the need for windowing.  With a bank of tone detectors each detector works asynchronously with no framing, only exhibiting a delay corresponding to the width of the band detected.  Unlike the FFT, there is no windowing so no "bin splatter".

The interplay between FFT bins and prime numbers result in some bins being very closely spaced so larger data sets are needed increasing the computational loads and delaying the response.  The FFT can be run on overlapping input data, but that results in much higher computational loads.  I have not looked at the ability of simple MCUs to perform FFTs in a while.  If a processor like the ARM CM4F is used, I suspect this won't be a problem.  Certainly they are not any more expensive or power consuming than the propeller devices and are much easier to program, not to mention only requiring a single device rather than two.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf