I’m currently using an Arduino and my main goal is to output 2 signals from 2 digital pins. Pin 1 (D7) would output a 1 kHz signal with a 50% duty cycle and pin 2 (D8) would output half of pin 1's frequency.
I wrote some a simple code in Arduino that turns the output pins on and off but when I connect the outputs to the scope, they have a lower than expected frequency and a duty cycle of 66%.
I’m not sure about if it's a hardware or software issue. I think it might be software as when I was using a single pin, there was no issue.
Here's the code:
int channel_1 = 7;
int channel_2 = 8;
int time1 =492;
int time2 = time1/2;
void setup()
{
pinMode(channel_1, OUTPUT);
pinMode(channel_2, OUTPUT);
}
void loop()
{
int state = 0;
while(1)
{
digitalWrite(7, LOW);
delayMicroseconds(time1);
digitalWrite(7, HIGH);
delayMicroseconds(time1);
digitalWrite(8, LOW);
delayMicroseconds(time2);
digitalWrite(8, HIGH);
delayMicroseconds(time2);
/*
//492 = 1Khz
//992 = 500Hz
delayMicroseconds(0.01);
*/
}
}
-
2\$\begingroup\$ "I’m not sure about if it’s a hardware issue" -> please show your schematic "or software" -> please show the code. \$\endgroup\$Huisman– Huisman2019年08月07日 08:23:23 +00:00Commented Aug 7, 2019 at 8:23
-
1\$\begingroup\$ Can you please elaborate 492usec => 1Khz and 992us => 500Hz? one digitalWrite() takes 4us? \$\endgroup\$Huisman– Huisman2019年08月07日 08:31:42 +00:00Commented Aug 7, 2019 at 8:31
-
1\$\begingroup\$ BTW, channel 4 is a less nice square. If you swap probes of channel 1 and 4 and you see the same effect on channel 1 you should calibrate the probe. \$\endgroup\$Huisman– Huisman2019年08月07日 08:35:38 +00:00Commented Aug 7, 2019 at 8:35
-
1\$\begingroup\$ 'delay' delays at least delay, and then there's more time consumed in the other instructions messing with the other output. If you want accurate real-time timing, you need to use interrupts. Set an internal timer to (say) 100uS, have it trigger an ISR, and then check in the ISR what the time is and optionally set the outputs. Arduino digital writes take a long time, 10s of cycles, you might want to find out how to use native AVR writes. \$\endgroup\$Neil_UK– Neil_UK2019年08月07日 08:46:34 +00:00Commented Aug 7, 2019 at 8:46
-
2\$\begingroup\$ Delays are a bad way to generate timed signals. You've already discovered that, since you are using "fudged" values for the delay. Either look into using timers directly, or check out the timer1 library. \$\endgroup\$JRE– JRE2019年08月07日 09:43:35 +00:00Commented Aug 7, 2019 at 9:43
1 Answer 1
Your two delay loops are running sequentially, NOT in parallel:
digitalWrite(7, LOW);
delayMicroseconds(time1);
digitalWrite(7, HIGH);
delayMicroseconds(time1);
// Here starts your second delay which means all the time this is running
// Output 7 is high!
digitalWrite(8, LOW);
delayMicroseconds(time2);
digitalWrite(8, HIGH);
delayMicroseconds(time2);
// Back to your first delay which means all the time that is running
// Output 8 is high!
Is there a way to make them run sequentially?
I assume you mean in parallel.
In this case, because time2 is half of time1, yes you can. There are several ways, a very simplistic one which is just a small variant on your existing code is this:
digitalWrite(7, LOW);
digitalWrite(8, LOW);
delayMicroseconds(time2);
digitalWrite(8, HIGH);
delayMicroseconds(time2);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
delayMicroseconds(time2);
digitalWrite(8, HIGH);
delayMicroseconds(time2);
-
\$\begingroup\$ Is there a way to make them run sequentially? \$\endgroup\$Neamus– Neamus2019年08月07日 11:07:10 +00:00Commented Aug 7, 2019 at 11:07
-
\$\begingroup\$ Not and achieve your goals and. Why would you want them to be sequential? Also beware there will be a brief periodic distortion unless you disable the timer interrupt. \$\endgroup\$Chris Stratton– Chris Stratton2019年08月07日 14:18:12 +00:00Commented Aug 7, 2019 at 14:18
Explore related questions
See similar questions with these tags.