I need to generate signals at the output of a Mega Arduino to simulate the signals of a rotary encoder. I know how to generate frequency signals through the function below. How could I generate the signals as in the image below, with a time lag between them? I have to take into account that the frequency must be the same.
void Encoder() {
tone(51,60);//Generates a 60Hz signal at output 51
tone(52,60);//Generates a 60Hz signal at output 52
}
update:
I was able to generate the desired signal by doing the following:
void Encoder() {
int i;
for (i == 0; i <= 10000; i++) {
digitalWrite(50, HIGH);
delay(10);
digitalWrite(48, HIGH);
delay(10);
digitalWrite(50, LOW);
delay(10);
digitalWrite(48, LOW);
delay(10);
digitalWrite(50, HIGH);
delay(10);
digitalWrite(48, HIGH);
delay(10);
digitalWrite(50, LOW);
delay(10);
digitalWrite(48, LOW);
delay(10);
}
}
2 Answers 2
If you don't care too much about the exact frequency and timing you can use the below method- delays are 1/4 of 1/60 second or 4167us ideally, but the writes and the loop use some time so the frequency will be a bit lower than 60Hz.
If you need very accurate timing or you need the micro to be available for other tasks you can access the on-chip timers directly, but that's a bit more effort.
// play with the below number a bit to change the timing
#define DLY 4167
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
}
void loop() {
delayMicroseconds(DLY);
digitalWrite(12, HIGH);
delayMicroseconds(DLY);
digitalWrite(13, HIGH);
delayMicroseconds(DLY);
digitalWrite(12, LOW);
delayMicroseconds(DLY);
digitalWrite(13, LOW);
}
(ignore the voltage display, they are both 0/5V)
As Eugene Sh pointed out, the simplest solution, if you don't have anything else to do in the loop is to repeatedly turn your pins high/low, and adjust the delay between those events.
If you can't afford to dedicate a whole board to this task (having a few of extra Nano is cheap and useful), then you should run timers interrupts to do the switching at a precise time, and leave the rest of the time clear for your other stuff.
The official doc that explains this idea is here: https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM
You might find the examples from this other page more enlightening: http://www.instructables.com/id/Arduino-Timer-Interrupts/
tone
. 60Hz is a low frequency, so you can just "manually" generate it in the main loop. \$\endgroup\$