Pages: 1 [2] 3 4 5   Go Down
Author Topic: How to create a 38 Khz pulse with arduino using timer or PWM?  (Read 18774 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the explanation. This method it is, then!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
« Last Edit: April 24, 2012, 03:43:57 am by praky » Logged

Global Moderator
Online Online
Brattain Member
*****
Karma: 480
Posts: 18730
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

My code doesn't use pulseIn. Can you post the whole sketch?
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I used pulseIn to measure the freq.

Here is the whole code...
Code:
const int pin = 7;
unsigned long duration;
long x;
long freq;
const byte LED = 10;  // Timer 2 "A" output: OC2A
void 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;
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is it possible to create a 38 khz modulated wave by the same method?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 619
Posts: 33966
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Online Online
Brattain Member
*****
Karma: 480
Posts: 18730
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Global Moderator
Online Online
Brattain Member
*****
Karma: 480
Posts: 18730
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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:
1 / ((1 / 16e6) * 8 * 52) = 38461.538

So, his timer will generate 38.46 KHz, as advertised.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Online Online
Brattain Member
*****
Karma: 480
Posts: 18730
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What was wrong with Claghorn's suggestion on page 1?
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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?
Logged

Pages: 1 [2] 3 4 5   Go Up
Jump to: