Short-range (10') AM-band transmit from 3.5mm Android headphone jack

I've transmitted digital tones 10' in AM band, but now I want to transmit analog audio from Uno with 3.5mm headphone jack (Android phone) input. I've annotated code below, if someone would please help me out. I'm not getting any radio signal at all.

int audioPin = A1; // positive lead from 3.5mm phone headphone jack; other lead to GND
int transmitPin = 9; // positive lead to antenna; neg. antenna lead to GND
//int val = 0;

void setup() {
  pinMode(transmitPin, OUTPUT);
 
 // set up Timer 1
 TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match, Timer Interrupts
 TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC (clear timer) no prescaler
 OCR1A =  14;       // 530 MHz
}

void loop() {
  analogRead(audioPin);
  //digitalWrite(transmitPin, HIGH); 
  analogWrite(transmitPin, HIGH);
}

First of all this is illegal in most countries.
Second all you are doing is setting pin 9 high, nothing else.

Hint, do something with the result of your analogue read value.

However it still probably won’t do much for you. I think you need to read up on how to generate digital audio.

By the way

OCR1A =  14;       // 530 MHz

What makes you think you can generate 530MHz from a processor that is only running at 16MHz?

Grumpy_Mike:
First of all this is illegal in most countries.

Read Part 15 Devices of FCC regs: Low Power Radio - General Information | Federal Communications Commission

Grumpy_Mike:
Hint, do something with the result of your analogue read value.

Ok will work on that.

Grumpy_Mike:

OCR1A =  14;       // 530 MHz

What makes you think you can generate 530MHz from a processor that is only running at 16MHz?

Because this works (actually you helped someone in previous thread with similar):

const byte ANTENNA = 9;

unsigned long A = calcDelayTimeForFreq(440);
unsigned long B = calcDelayTimeForFreq(494);
unsigned long C = calcDelayTimeForFreq(523);
unsigned long D = calcDelayTimeForFreq(587);
unsigned long E = calcDelayTimeForFreq(659);
unsigned long F = calcDelayTimeForFreq(699);
unsigned long G = calcDelayTimeForFreq(784);
unsigned long _A2 = calcDelayTimeForFreq(880);
unsigned long rest = 1;

unsigned long q = 652;
unsigned long e = q/2;
unsigned long s = e/2;
unsigned long t = s/2;
unsigned long h = q*2;
unsigned long f = q*4;

void setup() {
  // set up Timer 1
  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC (clear timer), no prescaler (no reduction of 16 mHz frequency)
  OCR1A =  14;       // compare A register value to 10 (zero relative)
}  // end of setup

void tone(unsigned long dTime, unsigned long playTime) {
  unsigned long end = millis() + playTime;
  
  while (end > millis()) {
    pinMode (ANTENNA, OUTPUT);
    delayMicroseconds(dTime);
    pinMode (ANTENNA, INPUT);
    delayMicroseconds(dTime);    
  }
}

void note(unsigned long dTime, unsigned long playTime) {
  tone(dTime,playTime-50);
  tone(rest,50);
}

unsigned long calcDelayTimeForFreq(unsigned long freq) {
  return 500000/freq;
}


void notes() {
  note(C,q);
  note(G,q);
  note(_A2,q);
  note(F,q);
  note(E,q);
  note(D,q);
} 

void locateTone() {
  note(A,t);
  note(B,t);
  note(C,t);
  note(D,t);
  note(E,f);
  note(D,t);
  note(C,t);
  note(B,t);
}

void loop() {
  notes();
}

Making headway, as this is transmitting screeches at 530 MHz, (but 3.5mm jack input should transmit music, not screeches). I know it's transmitting from phone as when I pause audio, the screeching stops. Since digital pin 9 does not generate screeches, I'm guessing something might be done to tweak PWM voltage from input source? Or should a digital pin be the transmit, and I'm missing something in the code? I'm at an impasse so any tips for moving forward appreciated.

int audioPin = A0; // positive lead from 3.5mm phone headphone jack; other lead to GND
int transmitPin = 6; // positive lead to antenna; neg. antenna lead to GND; tried digital pin 9 also but that doesn't make noise.

int val = 0;

void setup() {
  pinMode(transmitPin, OUTPUT);
 
 // set up Timer 1
 TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match, Timer Interrupts
 TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC (clear timer) no prescaler
 OCR1A =  14;       // 530 MHz
}

void loop() {
  val = analogRead(audioPin);
  //digitalWrite(transmitPin, val); pin 9 isn't transmitting screeches as mentioned.
  analogWrite(transmitPin, val);

}

Read Part 15 Devices of FCC regs: Low Power Radio - General Information | Federal Communications Commission

Yes I have read it and understood it, have you? You have to be able to prove you do not exceed the maximum ERP ( Effective Radiated Power ) and you must avoid certain frequencies. With this technique you can't.

What makes you think you can generate 530MHz from a processor that is only running at 16MHz?

Because this works (actually you helped someone in previous thread with similar):

NO! - those frequencies are in KHz not MHz.

this is transmitting screeches at 530 MHz,

As I said it is not MHz, what radio are you picking this up on? You will get a screech at 560KHz but you will not get any music or speech. This is because you are not producing amplitude modulation of the audio signal on the carrier wave but actually PWM which stands for Pulse Width Modulation.

So you need a radio that can pick up PWM or you need to generate AM ( Amplitude Modulation ). Amplitude modulation - Wikipedia
This requires external hardware, for a variety of circuits search for images using the words:-
collector modulation method for generating am wave

AM signals transmitting at 10' comply with FCC Part 15 Devices. Read the link I referenced; it should be easy for you to understand.

My typo on MHz meaning KHz.

I suspected I'd have to modulate this signal as you've pointed out (like a 1300 : 8 ohm transformer does using discrete components). If / when I get to that point will I be transmitting on analogWrite or digitalWrite?

If / when I get to that point will I be transmitting on analogWrite or digitalWrite?

The PWM output will need an RC filter to turn it into an analogue Audio signal. You will also need another PWM signal at the carrier frequency that has a fixed duty cycle.

AM signals transmitting at 10' comply with FCC Part 15 Devices. Read the link I referenced; it should be easy for you to understand.

Given that you are struggling to understand the concept of AM, and given that I have been a radio ham since 1973, I would suggest that it is you who do not understand that document and what it implies. You need to be able to demonstrate either with test equipment or detailed mathematics how you are complying. I find your comment insulting.

Grumpy_Mike:
The PWM output will need an RC filter to turn it into an analogue Audio signal. You will also need another PWM signal at the carrier frequency that has a fixed duty cycle.

Thanks I'll research RC filter as I've seen examples on this site & experiment with fixed duty cycle. I respect your experience & expertise in radio, Arduino & electronics.

Would someone please help me bridge the gap in analog audio in to PWM out RF transmission? I've interfaced a 104 (.1uF) capacitor with 100/100K voltage divider on 3.5mm input from Android phone. I'm getting about 2.5v on the Serial Port. I think I understand that an analog audio sine wave has to coalesce to square PWM wave. Notes throughout code are things I've tried over the past 2 days.

int audioPin = A0; // positive lead from 3.5mm phone headphone jack; other lead to GND
//int transmitPin = 10; // positive lead to antenna; neg. antenna lead to GND
const byte ANTENNA = 9;
//int val = 8;

void setup() {
  Serial.begin(9600);
  pinMode(ANTENNA, OUTPUT);
 
 // set up Timer 1
 TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match, Timer Interrupts
 TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC (clear timer) no prescaler
 OCR1A =  14;       // 530 kHz

}

void loop() {
  int sensorValue = analogRead(audioPin);
    float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
  
  //val = analogRead(audioPin);
  digitalWrite(ANTENNA, voltage);
  //analogWrite(ANTENNA, voltage);
}

I think I understand that an analog audio sine wave has to coalesce to square PWM wave.

Yes.

Do not do any serial printing or floating point arithmetic in the loop because it slows down the sample rate to an extent that it will not be high enough to work. There is no need to convert the number into a voltage. You should see that 2.5 voltage change as you apply audio, if it does not change then it is either wired up wrong or you have not got a big enough input signal. Ideally you should get a swing between 20 and 1000 or so, if you see the full range of 0 to 1023 that means the audio is too loud and you are getting clipping which will distort the audio.

The analogue read returns a number between 0 and 1023, where as an analogue write accepts a number between 0 and 255. Give it a bigger number and it will just wrap round, that is it will just take the value of the least significant byte of the number you give it. So you must process what you receive by dividing it by four before you send it out, do this by shifting the value two places to the right with the shift operator >>

I do feel that this project is pushing the limits of your current knowledge and you are being hampered by your lack of fundamental knowledge of both what you need to do and how to do it.

p1ne
maybe this post can be useful

Grumpy_Mike:

OCR1A =  14;       // 530 MHz

What makes you think you can generate 530MHz from a processor that is only running at 16MHz?

530Mhz are too much but you can reach FM band at around 95-98MHz, maybe harmonics?
http://forum.arduino.cc/index.php?topic=85275.msg2608247#msg2608247
I tested it usind an SDR radio, it works. I fin also many other frequencies. Arduino make a lot of noise!

But the OP is asking for AM not FM.

Mike, I wasn't seeing voltage change before removing 100K voltage divider on audio input (I read about in similar thread), but after only applying .1 uF capacitor from audio input (3.5mm Android phone jack), I'm getting .25 volt difference when audio is applied (.45 no audio; .70 with audio), so that seems promising. If I remove .1 uF input capacitor, no voltage is returned in Serial Port. Although audio transmission is not working (yet), static is detected at 530 kHz, near jumper wire from pin 9. Now that I know voltage difference, do I continue on analogRead to digitalWrite & if so how to do calculation? analogWrite does not get detected by the radio at at all, on any pin.

int audioPin = A0; // positive lead from 3.5mm phone headphone jack; other lead to GND
const byte ANTENNA = 9;
int val = 0;

void setup() {
  Serial.begin(9600);
  pinMode(ANTENNA, OUTPUT);
 
 // set up Timer 1
 TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match, Timer Interrupts
 TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC (clear timer) no prescaler
 OCR1A =  14;       // 530 kHz

}

void loop() {
  int sensorValue = analogRead(audioPin);
    float voltage = sensorValue * (5.0 / 1023.0);
  Serial.println(voltage);
  
  //val = analogRead(audioPin);
  digitalWrite(ANTENNA, voltage);
  //analogWrite(ANTENNA, voltage);
}

.45 no audio; .70 with audio

That sounds wrong.
With audio the voltage should read above and below the voltage with no audio. If you don’t get that then nothing will work.

Your descriptions are hard to follow can you post a schematic please.

I wasn't seeing voltage change before removing 100K voltage divider on audio input

If you remove the voltage bias circuit then there is no chance it will work even if you see voltage changes as your input is floating and will pick up all sorts of rubbish.

Ok here's my schematic. Code and notes were posted in last reply.

Yes that circuit is basically correct although you don’t draw connections going into a capacitor like that. Just have one wire out of the capacitor and connecting to the other components. However the capacitor needs to be a lot bigger something like 47uF.

Now if you read the analogue input with no audio you will get a reading around 512 and with audio it will be above and below this. If you don’t get that then you have something wrong or the Audio from your phone is not loud enough.

Ok I'm using 47uF capacitor interfacing with 100K resistors as you suggested & A0 pin input and getting 485 reading with audio off, and 520 - 460 range with audio on. Still no music reception on AM 530 although pin 9 is definitely transmitting something as proximity to antenna is affected only at that radio frequency (static / hiss). Here's updated code. (I commented out Serial.println to test radio reception.)

int audioPin = A0; // positive lead from 3.5mm phone headphone jack; other lead to GND

const byte ANTENNA = 9;
int val = 0;

void setup() {
  Serial.begin(9600);
  pinMode(ANTENNA, OUTPUT);
 
 // set up Timer 1
 TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match, Timer Interrupts
 TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC (clear timer) no prescaler
 OCR1A =  14;       // 530 kHz

}

void loop() {
  int sensorValue = analogRead(audioPin);

  //Serial.println(sensorValue);
  
  digitalWrite(ANTENNA, sensorValue);
}

and 520 - 460 range with audio on.

That is only a small range and I would suggest it is not going to do much. That signal needs amplifying.

Still no music reception on AM 530

Not surprised because, as I have said before, you are not actually generating AM but pulse width modulation, and most radios are not equipped to demodulate that.

The first link I posted is of a sketch being able to generate an AM modulated signal. But I don't remember if I have tested it like I did on FM example.

Have you any idea about what that sketch actually did?
You might have got some tones but that could not be considered to be AM. It transmitted all over everywhere and the FCC would not have considered that to be legal. As the OP has found while it will transmit tones it can not transmit speach.