Go Down

Topic: Creating Square Waves with Programmable Frequencies? (Read 1 time) previous topic - next topic

ArduinoTom


You will be changing a pin state to make a square wave edge? Why would it differ?




Sorry, I'm not following your point?   I will be using an attachInterrupt to monitor the original speedometer pulse, then looking to program a PWM output frequency to drive a speedometer guage....

pYro_65

Switch around your logic then, give the pin change job to a timer interrupt at your known interval, then in your loop check the speedo.
The timer then has 'higher priority' over the speedo check.

Also if you continually run the timer, you can disable timer0 ( millis / delay... ) and count intervals of your own timer unless you need the finer resolution.

Using PWM will be easier I think, the lost microseconds can just be fixed every couple of seconds/minutes

GoForSmoke

PWM runs at about 490 Hz and gives more or less time to HIGH than LOW. To change the PWM frequency as opposed to the PWM duty cycle you must change some clocks you might not want changed.

At the speeds you give, it'd be easier to toggle a pin by repeating time-out code and then maybe varying the time-out.

5 Hz is 200 ms, 50 Hz is 20 ms.
1 ms is 5 analog reads and processing. 1 ms is 500 digital reads with processing. 1 ms may be 100 to 1000 times through loop().
And you want to change a pin every 20 to 200 ms. Yeah, you can do that. You need 8 bytes RAM per timer though.

There are other ways. If you use intervals of ms in powers of 2 then you can mask the top bits of millis() off and rollover to 0 will come sooner. millis() & 0x0000007F rolls over every 128 ms.
I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

ArduinoTom

#8
Feb 14, 2013, 06:47 am Last Edit: Feb 14, 2013, 08:14 am by Coding Badly Reason: 1
Ok, after a little testing, it seems the original frequency can range from about 5Hz to as fast as about 300Hz.  The idea is measure that frequency, adjust it a bit based on the setting of a trim pot, and create an adjusted frequency to output.  With that as the goal, please comment on this as an approach:

Code: [Select]
//measures timing of square wave on pin 20 (interrupt 3)
//adjustes that speed based on setting of pot on pin A0
//creates a square wave with adjusted frequency on pin 21

volatile int adjustedFreq;  
volatile int latestSpeed;
volatile int lastSpeed;
unsigned long startTime;
unsigned long now;
int speedoPin =21;


void setup() {
 pinMode(speedoPin, OUTPUT);
 attachInterrupt(3, iSr, CHANGE);}


void loop()
//creates square
{
 startTime=micros(); now=startTime;
 while (now-startTime<adjustedFreq) {speedoPin=HIGH; now=micros();}
 startTime=micros(); now=startTime;
 while (now-startTime<adjustedFreq) {speedoPin=LOW; now=micros();}
}
 
void iSr()
//calculates length of most recent pulse and adjusts it based on pot setting on A0
{
 latestSpeed=micros();
 adjustedFreq=(latestSpeed-lastSpeed)*(analogRead(A0)/512);  
 lastSpeed=latestSpeed;
}  



Moderator edit: [code] [/code] tags added.

GoForSmoke

If you want to change a pin, you have to write to the pin. At least that looks like what you might think you're coding with speedoPin=HIGH (funny, it started as 21) and LOW.

You might want to slow down a little and check your syntax against actual C/C++.
I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Go Up