Go Down

Topic: Highest PWM frequency output for the Uno/Nano (Read 9979 times) previous topic - next topic

Docedison

If you were looking for frequency modulated RF @ 4 Mhz you might well consider an Analog Devices AD9851 DDS solution (Faster X2 to 60 MHz) or the readily available from Ebay AD9850 assemblies. they require a 40 bit serial load SPI I think and can operate from nearly DC to 30 MHZ, both sine and square wave outputs too. While NCO's aren't new this one is interesting and at about 7 to 9 dollars an inexpensive way to go. There are a couple of sketches I've found for mine but not yet the time to test them... Nor a good frequency counter either... Yet.

Bob
--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

lightt

Screenshot of above test confirms results:



Note the frequency and the duty cycle. To get a duty cycle of 33.3% you need OCR0B to be 2 rather than 1.
Dear Nick Gammon,

1.How and where Can I make such demo? (Good for presentation)

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

nkuck

#18
Mar 15, 2015, 03:44 am Last Edit: Mar 15, 2015, 03:45 am by nkuck
Thanks for the great sketch and information. I am having trouble understanding your sketch, maybe because I am fairly new to Arduino/C++. What I am trying to do is utilize the output from your sketch as a loop antenna that I can then detect by a secondary coil or loop. No need for accuracy, just detection of proximity. Can you advise where/how I get your output? Thanks very much.

Nick Gammon

Quote
Can you advise where/how I get your output?
I don't understand the question. My output is at my house.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

nkuck

I am totally unfamiliar with the timers library, maybe that is the root of my problem. One of your sketch comments (// output    OC0A   pin 12  (D6)) is confusing if the output is intended for digital pin 12 or 6?? I am just trying to obtain the output and feed it to a loop, and then be able to detect it on another loop, on another input pin. Can you assist me? Thanks for any direction.

Nick Gammon

OC0A is socket (pin) 6 on the Arduino board. However it is pin 12 on the Atmega328P chip. The distinction is important depending on whether you have a Uno (plug a wire into the header labelled "~6") or if you are working with the raw chip it is pin 12 on the processor chip.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

nkuck

Thanks very much. Not sure if I would have figured that one out.
 :smiley-mr-green:

nkuck

Why, when I attempt to add any delay, either via the sensorValue integer or in a delay in a Serial print routine, does it stop and not restart? Any recommendations? Thanks again for the help.

Nick Gammon

Does what stop? The timer runs whether or not you are doing delays.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

nkuck

Sorry for being too vague. I added a Serial.print function so that I can determine if the signal from the output pin is being inductively received by an input pin. Seems to work until I introduce a delay into the sketch, then readings stop. I need to spend more time with the code. Thanks for your reply.

aarg

What I am trying to do is utilize the output from your sketch as a loop antenna that I can then detect by a secondary coil or loop.
You'd best keep the power level extremely low, or you could easily be in violation of FCC regulations (or the radio regulations of your country if it's not the USA), and/or interfere with local radio services. Even with a loop antenna. Also your square wave signal will splatter RF sidebands all over the place, not just at 4Mhz.

nkuck

OK, here is my sketch, still somewhat ugly:
// Timer 0
// output    OC0A   pin 12  (D6)

#include <TimerHelpers.h>
const int timer0OutputA = 6;//***
int inputPin = A0;//***
int sensorValue = 0;//*** variable to store the value coming from the sensor
const int outputPin = 6;//***
int outputValue = 0;//***
int freqInput = 0;//**
int freqOutput = 0;
int ledPin = 13;//***

void setup() {
  //*** initialize serial communications at 9600 bps:
  Serial.begin(2400);//***
  pinMode (A0, INPUT);//***
  pinMode (outputPin, OUTPUT);
  pinMode (ledPin, OUTPUT);//***
  //  pinMode (timer0OutputA, OUTPUT); //***
  TIMSK0 = 0;  // no interrupts
  Timer0::setMode (2, Timer0::PRESCALE_1, Timer0::TOGGLE_A_ON_COMPARE);
  OCR0A = 1;  // count to 2
}  // end of setup

void loop()
{
  digitalWrite (ledPin, LOW);
  // read the value from the sensor:
  freqInput = analogRead(inputPin);//***
  freqOutput = analogRead(outputPin);
  //*** stop the program for <sensorValue> milliseconds:
  delay(sensorValue);//***
  Serial.print (freqInput);//***
  Serial.print("    ");//***
  Serial.print (freqOutput);//***
  delay (0);//***

  if abs(freqInput > 20)
  {
    Serial.println (" yes "); digitalWrite(ledPin, HIGH);
  }
  else
  { Serial.println (" no"); Serial.print(" "); digitalWrite (ledPin, LOW);
  }
}

When I attempt to pause or delay the output, or hold the ledPin HIGH for a longer period, for example with a WHILE or delay() statement, the Serial.print output stops and does not restart unless I reset the board. Other than that, I seem to be getting the performance I was looking for. That is, when a loop attached to the output pin is in close contact with the input pin loop, the LED lights and stays on while the condition is true. (Ignore the //***; just to remind me where I made changes.)
Thanks for any further thoughts or guidance.

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

nkuck

Code: [Select]
// Timer 0
// output    OC0A   pin 12  (D6)

#include <TimerHelpers.h>
const int timer0OutputA = 6;//***
int inputPin = A0;//***
int sensorValue = 0;//*** variable to store the value coming from the sensor
const int outputPin = 6;//***
int outputValue = 0;//***
int freqInput = 0;//**
int freqOutput = 0;
int ledPin = 13;//***

void setup() {
  //*** initialize serial communications at 9600 bps:
  Serial.begin(2400);//***
  pinMode (A0, INPUT);//***
  pinMode (outputPin, OUTPUT);
  pinMode (ledPin, OUTPUT);//***
  //  pinMode (timer0OutputA, OUTPUT); //***
  TIMSK0 = 0;  // no interrupts
  Timer0::setMode (2, Timer0::PRESCALE_1, Timer0::TOGGLE_A_ON_COMPARE);
  OCR0A = 1;  // count to 2
}  // end of setup

void loop()
{
  digitalWrite (ledPin, LOW);
  // read the value from the sensor:
  freqInput = analogRead(inputPin);//***
  freqOutput = analogRead(outputPin);
  //*** stop the program for <sensorValue> milliseconds:
  delay(sensorValue);//***
  Serial.print (freqInput);//***
  Serial.print("    ");//***
  Serial.print (freqOutput);//***
  delay (0);//***

  if abs(freqInput > 20)
  {
    Serial.println (" yes "); digitalWrite(ledPin, HIGH);
  }
  else
  { Serial.println (" no"); Serial.print(" "); digitalWrite (ledPin, LOW);
  }
}

Go Up