Go Down

Topic: Short-range (10') AM-band transmit from 3.5mm Android headphone jack (Read 762 times) previous topic - next topic

p1ne

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.

Code: [Select]

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);
}

Grumpy_Mike

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
Code: [Select]
OCR1A =  14;       // 530 MHz
What makes you think you can generate 530MHz from a processor that is only running at 16MHz?

p1ne

First of all this is illegal in most countries.
Read Part 15 Devices of FCC regs: https://www.fcc.gov/media/radio/low-power-radio-general-information

Hint, do something with the result of your analogue read value.
Ok will work on that.

Code: [Select]
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):
Code: [Select]

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();
}

p1ne

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.

Code: [Select]
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);

}

Grumpy_Mike

Quote
Read Part 15 Devices of FCC regs: https://www.fcc.gov/media/radio/low-power-radio-general-information
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.

Quote
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.

Quote
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 ). https://en.wikipedia.org/wiki/Amplitude_modulation
This requires external hardware, for a variety of circuits search for images using the words:-
collector modulation method for generating am wave


p1ne

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?

 

 

Grumpy_Mike

Quote
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.

Quote
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.

p1ne

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.

p1ne

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.
Code: [Select]

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);
}

Grumpy_Mike

Quote
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.

zoomx

p1ne
maybe this post can be useful
http://forum.arduino.cc/index.php?topic=88422.msg2181964#msg2181964

Code: [Select]
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!

Grumpy_Mike


p1ne

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.


Code: [Select]

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);
}

Grumpy_Mike

Quote
.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.

Quote
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.

p1ne

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

Go Up