0
\$\begingroup\$

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
}

enter image description here

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);
 }
 }
Nick Alexeev
38.9k17 gold badges104 silver badges248 bronze badges
asked Mar 2, 2018 at 19:54
\$\endgroup\$
3
  • 1
    \$\begingroup\$ First of all you should give up on using the unrelated library functions such as tone. 60Hz is a low frequency, so you can just "manually" generate it in the main loop. \$\endgroup\$ Commented Mar 2, 2018 at 20:01
  • 1
    \$\begingroup\$ what kind of a rotary encoder? \$\endgroup\$ Commented Mar 2, 2018 at 20:18
  • \$\begingroup\$ rotary encoder incremental \$\endgroup\$ Commented Mar 2, 2018 at 20:23

2 Answers 2

4
\$\begingroup\$

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)

enter image description here

answered Mar 2, 2018 at 20:59
\$\endgroup\$
3
\$\begingroup\$

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/

answered Mar 2, 2018 at 20:33
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.