Go Down

### Topic: How to create a 38 Khz pulse with arduino using timer or PWM? (Read 65091 times)previous topic - next topic

#### praky

#15
##### Apr 23, 2012, 01:21 am
Thanks for the explanation. This method it is, then!

#### praky

#16
##### Apr 24, 2012, 10:41 amLast Edit: Apr 24, 2012, 10:43 am by praky Reason: 1
I used the following 2 fxn to measure frequency using your (nick gammon's timer method) code.

long getFrequencySampled()
{
#define SAMPLES 4096
long freq = 0;
for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);
return freq / SAMPLES;
}

long getFrequency()
{
long duration=pulseIn(pin, HIGH, 250000);
Serial.print("duration of pulse is: ");
Serial.println(duration);  //in microseconds
duration=duration*2;
Serial.print("duration of pulse is: ");
Serial.println(duration);  //in microseconds
freq = 1000000/duration;
Serial.print("Frequency is: ");
Serial.println(freq);

return freq;
}

getFrequencySampled() returned a value of 40.5-41 Khz.
getFrequency() returns a value that alternates randomly between 35 Khz and 41 Khz. (for pulse durations of 12 & 14 microseconds)

Any idea why the frequency doesn't equal the theoretical value?

#### nickgammon

#17
##### Apr 24, 2012, 11:22 am

long duration=pulseIn(pin, HIGH, 250000);

My code doesn't use pulseIn. Can you post the whole sketch?
Please post technical questions on the forum, not by personal message. Thanks!

#### praky

#18
##### Apr 24, 2012, 11:31 am
I used pulseIn to measure the freq.

Here is the whole code...
Code: [Select]
`const int pin = 7;unsigned long duration;long x;long freq;const byte LED = 10;  // Timer 2 "A" output: OC2Avoid setup(){  pinMode(pin, INPUT);  Serial.begin(9600);    //  pinMode (LED, OUTPUT);    // set up Timer 2  TCCR2A = _BV (COM2A0) | _BV(WGM21);  // CTC, toggle OC2A on Compare Match  TCCR2B = _BV (CS20);   // No prescaler  OCR2A =  209;          // compare A register value (210 * clock speed)                         //  = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095  //  tone (10, 38000);}long getFrequency() {  long duration=pulseIn(pin, HIGH, 250000);  Serial.print("duration of pulse is: ");  Serial.println(duration);  //in microseconds  duration=duration*2;  Serial.print("duration of pulse is: ");  Serial.println(duration);  //in microseconds  freq = 1000000/duration;  Serial.print("Frequency is: ");  Serial.println(freq);    return freq;}void loop(){  x=getFrequency();  Serial.print("Frequency is: ");  Serial.println(x);  }long getFrequencySampled() {  #define SAMPLES 4096  long freq = 0;  for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);  return freq / SAMPLES;}`

#### praky

#19
##### Apr 24, 2012, 12:23 pm
Is it possible to create a 38 khz modulated wave by the same method?

#### AWOL

#20
##### Apr 24, 2012, 12:45 pm
If you're going to use it for modulated IR, just connect one end of your LED to your constant 38kHz source, and the other end to another output pin.
Waggling the other output pin at your desired (<38kHz!) rate produces a modulated 38kHz IR beam.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### Grumpy_Mike

#21
##### Apr 24, 2012, 02:55 pm
If you want to modulate the IR then that is what the interrupted service routine was to do in the code I originally posted. It is best to do this since the modulation can be synchronised with the carrier.

#### nickgammon

#22
##### Apr 25, 2012, 01:08 am
PulseIn isn't particularly accurate. From the documentation:

Quote
The timing of this function has been determined empirically and will probably show errors in longer pulses

I checked the timer output on the oscilloscope. Plus, assuming your clock is accurate, it matches the theory. PulseIn just works by counting in a loop.

It looks like Mike's solution incorporates an ISR to turn the output of the timer on or off, exactly at the start of each pulse, which, as he says, would synchronize with the carrier.
Please post technical questions on the forum, not by personal message. Thanks!

#### nickgammon

#23
##### Apr 25, 2012, 01:12 am

Code: [Select]
`void setIrModOutput(){  // sets pin 3 going at the IR modulation rate  pinMode(3, OUTPUT);  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // Just enable output on Pin 3 and disable it on Pin 11  TCCR2B = _BV(WGM22) | _BV(CS22);  OCR2A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz  OCR2B = 26;  // deines the duty cycle - Half the OCR2A value for 50%  TCCR2B = TCCR2B & 0b00111000 | 0x2; // select a prescale value of 8:1 of the system clock}`

He's using a different mode (PWM) and a different prescaler, but you can work out the maths:

Code: [Select]
`1 / ((1 / 16e6) * 8 * 52) = 38461.538`

So, his timer will generate 38.46 KHz, as advertised.
Please post technical questions on the forum, not by personal message. Thanks!

#### praky

#24
##### Apr 25, 2012, 03:08 am
I am a newbie with assembly with avr. can you please post the code of 38 Khz wave modulated with 1 Khz wave to be used with TSOP1738.
Will be a life saver. Thanks.

#### nickgammon

#25
##### Apr 25, 2012, 03:22 am
What was wrong with Claghorn's suggestion on page 1?
Please post technical questions on the forum, not by personal message. Thanks!

#### praky

#26
##### Apr 25, 2012, 05:24 am
i don't know a lot about modulation and synchronization. I get the idea that grumpy_mike's code with little modification will produce a modulated 38 Khz wave with 1 Khz. Any idea what to modify in that code?

#### DuaneB

#27
##### Apr 25, 2012, 05:42 am
Hi,
If all you are trying to do is generate a 38khz carrier, switched at 1khz, why not do it in hardware with a single 556 Timer, that what this does -

http://rcarduino.blogspot.com/2012/03/punk-consoles-and-ir-transmitters-555.html

It costs about 2 dollars to build.

Duane B

rcarduino.blogspot.com
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

#### praky

#28
##### Apr 26, 2012, 07:05 am
As I have said before, I really don't want to do that unless I can't do it with software.

I am successful in generating 38 Khz thanks to you guys, now I just need it modulated with 1Khz

#### praky

#29
##### Apr 26, 2012, 07:33 am
@nick
Your code produces output at pin 10 using timer 2. Can't I similarly produce output of 1 KHz using Timer1 at some other pin? Then connect this pin at the other end of led?

Go Up