Hardware in the loop quadrature encoder simulator

I’m trying to make a HIL simulator using 2 arduinos (later 2 arduinos and a raspberry pi).

The arduino UNO will be simulating the motor and encoder. I’d like to have it generate 2 square signals of varying frequency for testing and for the two signals to have a phase difference of either +90 or -90 (changeable in the code) to simulate both directions.

The arduino Nano would be on the receiving end to calculate the number of pulses and later on the RPM. Same will be done for the raspberry pi after I make sure the code is running and everything is good.

Now for my codes, I’m having issues.

I found one program that does something similar to what I’m looking for, but I couldn’t adapt it to suit my needs. And then I found another that should be doing exactly what I want but it’s not working for me.

Option #1:

// This code demonstrates how to generate two output signals
// with variable phase shift between them using an AVR Timer 

// The output shows up on Arduino pin 9, 10

// More AVR Timer Tricks at http://josh.com

void setup() {
  pinMode( 9 , OUTPUT );    // Arduino Pin  9 = OCR1A
  pinMode( 10 , OUTPUT );   // Arduino Pin 10 = OCR1B

  // Both outputs in toggle mode  
  TCCR1A = _BV( COM1A0 ) |_BV( COM1B0 );


  // CTC Waveform Generation Mode
  // TOP=ICR1  
  // Note clock is left off for now

  TCCR1B = _BV( WGM13) | _BV( WGM12);

  OCR1A = 0;    // First output is the base, it always toggles at 0


}

// prescaler of 1 will get us 8MHz - 488Hz
// User a higher prescaler for lower freqncies

#define PRESCALER 1
#define PRESCALER_BITS 0x01

#define CLK 16000000UL    // Default clock speed is 16MHz on Arduino Uno

// Output phase shifted wave forms on Arduino Pins 9 & 10
// freq = freqnecy in Hertz (  122 < freq <8000000 )
// shift = phase shift in degrees ( 0 <= shift < 180 )

// Do do shifts 180-360 degrees, you could invert the OCR1B by doing an extra toggle using FOC

/// Note phase shifts will be rounded down to the next neared possible value so the higher the frequency, the less phase shift resolution you get. At 8Mhz, you can only have 0 or 180 degrees because there are only 2 clock ticks per cycle.  

int setWaveforms( unsigned long freq , int shift ) {

  // This assumes prescaler = 1. For lower freqnecies, use a larger prescaler.

  unsigned long clocks_per_toggle = (CLK / freq) / 2;    // /2 becuase it takes 2 toggles to make a full wave

  ICR1 = clocks_per_toggle;

  unsigned long offset_clocks = (clocks_per_toggle * shift) / 180UL; // Do mult first to save precision

  OCR1B= offset_clocks;

  // Turn on timer now if is was not already on
  // Clock source = clkio/1 (no prescaling)
  // Note: you could use a prescaller here for lower freqnencies
  TCCR1B |= _BV( CS10 ); 

}

// Demo by cycling through some phase shifts at 50Khz  

void loop() {

  setWaveforms( 50000 , 0 );

  delay(1000); 

  setWaveforms( 50000 , 90 );

  delay(1000); 

  setWaveforms( 50000 , 180 );

  delay(1000); 


}

I’m getting the correct 50k Hz on the multimeter and I’m getting around 96603 on the nano. It’s suppose to be 100,000 (2*50K). Not sure why some fell off, but I guess overhead? I’ll write the code for the nano below here. I’m also getting the right 1MHz on proteus for some reason. My issue with this code right now is how to get the -90 and +90 phase difference. How to have change, say, every 5 seconds with a few second pauses.

Nano receiving code: (My post) (Original post)

unsigned long start;
const byte encoderPinA = 3;//A pin -> interrupt pin 0
const byte encoderPinB = 5;//B pin -> digital pin 4
volatile long pulse;
volatile bool pinB, pinA, dir;
const byte ppr = 12, upDatesPerSec = 2;
const int fin = 1000 / upDatesPerSec;
const float konstant = 60.0 * upDatesPerSec / (ppr * 2);
int rpm;


void setup() {
  Serial.begin(9600);
  pinMode(encoderPinA,INPUT);
  pinMode(encoderPinB,INPUT);
  attachInterrupt(1, readEncoder, CHANGE);

}

void loop() {
  if(millis() - start > fin)
  {
   
    static long pulseCopy;
    noInterrupts();
    pulseCopy = pulse;
    interrupts();
   
   
    start = millis();
    rpm = pulse * konstant;
    //Serial.println(rpm);
     Serial.println("Pulse value: "); Serial.print(pulse);
    //pulse = 0;
   
  }
}

void readEncoder()
{

  pinA = bitRead(PIND,encoderPinA);
  pinB = bitRead(PIND,encoderPinB);
  dir = pinA ^ pinB;          // if pinA & pinB are the same
  dir ? --pulse : ++pulse;    // dir is CW, else CCW
 
}

Option #2:

From the outside this is suppose to be what I’m looking for, but I’m having so much issues with the timer here.

By default it is set to prescaler: 8 and ICR1 set to 199. First off I’m confused by the prescaler and the ICR1. Prescaler set to 8 gives us 0.5 us which is 2000KHz, but then divided by 200. Gives us 10K period, so arduino nano should read 20k/second. However, it’s receiving 5K Hz on the multimeter and 100Khz on proteus. On the nano, I’m only getting 10k and not 20K. I’m not sure why. I’m not sure why all the differences.

I changed the loop function to this

void loop () {


if (millis() >= 1000 && millis()<2000)
{
    OCR1A = ICR1 - 1; //two different pulse widths almost 100% duty cycle
    OCR1B = OCR1A / 2; //offset by half period
    TCCR1B |= _BV(CS11);//start timer
} else{

    TCCR1B &= ~(_BV(CS11));//stop timer
    //TCCR1B = 0;
}

  if (millis() - prevDisplay >= interval)
  {
    prevDisplay += interval;
    noInterrupts();
    long copyEncoderCount = encoderCount;
    encoderCount = 0;
    long copyErrorCount = errorCount;
    errorCount = 0;
    interrupts();

    Serial.print(copyEncoderCount);
    Serial.print('\t');
    Serial.println(copyErrorCount);
  }
}

When I tried changing the prescaler, it worked the first time, but second time it wouldn’t work. Should I just add “|_BV(CS10)”

Any help would be appreciated. Thanks!

If you want to change the prescale, you have these bits in TCCR1B
CS12…10: Clock Select bits; These three bits control the prescaler of timer/counter 1 and the connection to an external clock on Pin T1.

CS12 CS11 CS10 Mode Description
0 0 0 Stop Timer/Counter 1
0 0 1 No Prescaler (Timer Clock = System Clock)
0 1 0 divide clock by 8
0 1 1 divide clock by 64
1 0 0 divide clock by 256
1 0 1 divide clock by 1024
1 1 0 increment timer 1 on T1 Pin falling edge
1 1 1 increment timer 1 on T1 Pin rising edge

Option #2 is from this thread and it does indeed give 20K encoder counts with the ICR1 value = 199 and a prescaler of 8 such that each timer tick is .5us. The fundamental timer repeat is at 10KHz and there are two quadrature edges per cycle.

//Quadrature signal generator two outputs offset 90 degrees
//emulate rotary encoder
//Timer 1 CTC with ICR1 TOP
//Switch direction with Serial input F/R/S Enter Capital F S or R with not line ending
//Pin Change Interrupts on Timer Output Pins

const char encTable[16] = {0, 1, -1, 0, -1, 0, -0, 1, 1, 0, 0, -1, 0, -1, 1, 0}; //gives -1, 0 or 1 depending on encoder movement
volatile long encoderCount;
volatile long errorCount;
volatile byte encState;
unsigned long prevDisplay;
unsigned long interval = 1000;

char Command = 'F'; //default state is Forward

void setup() {

  Serial.begin(115200);

  pinMode(9, OUTPUT); //output A
  pinMode(10, OUTPUT); //output B

  //Enable pin change interrupts on pins 9 and 10 PB 2 and 3
  PCICR |= (1 << PCIE0); //enable group interrupts on PORTB PCINT[7:0]
  PCMSK0 |= (1 << PCINT2); //enable interrupt pin 10
  PCMSK0 |= (1 << PCINT1); //enable interrupt pin 9

  TCCR1A = 0; //clear timer registers
  TCCR1B = 0;
  TCNT1 = 0;
  GTCCR |= 1 << PSRASY; //reset prescaler

  //ICR1 and Prescaler sets frequency
  //no prescaler .0625 us per count @ 16mhz
  //prescaler 8 .5 us per count

  TCCR1B |=  _BV(CS11); // prescaler 8
  //TCCR1B |= _BV(CS10); //no prescaler

  //counts are zero indexed 2edges per ICR1 period
  //numerical values for prescaler 8.
  //e.g. 10k period give 20k encoder counts

  ICR1 = 199;//10k ICR1 period  20k encoder counts
  //ICR1 = 99; //20k ICR1 period 40k encoder counts
  //ICR1 = 49; //40K ICR1 period 80k encoder counts
  //ICR1 = 46; //42.5K ICR1 period 85k encoder counts
  //ICR1 = 41; //47.5k ICR1 period 95K encoder counts
  //ICR1 = 39; //50k ICR1 period 100k encoder counts
  //ICR1 = 29; //66.6K ICR1 period 133k encoder counts
  //ICR1 = 19; //100k ICR1 period 200k encoder counts
  //ICR1 = 17;
  //ICR1 = 14;
  //ICR1 = 9;

  OCR1A = ICR1 - 1; //two different pulse widths almost 100% duty cycle
  OCR1B = OCR1A / 2; //offset by half period

  TCCR1B |= _BV(WGM13) | _BV(WGM12); //CTC mode with ICR1
  TCCR1A = _BV(COM1A0) | _BV(COM1B0); //Toggle OC1A/OC1B on compare match
}
void loop () {

  readCommand();

  if (Command == 'F')
  {
    OCR1A = ICR1 - 1; //two different pulse widths almost 100% duty cycle
    OCR1B = OCR1A / 2; //offset by half period
    TCCR1B |= _BV(CS11);//start timer
  }

  if (Command == 'R')
  {
    OCR1B = ICR1 - 1; //two different pulse widths almost 100% duty cycle
    OCR1A = OCR1B / 2; //offset by half period
    TCCR1B |=  _BV(CS11);//start timer
  }

  if (Command == 'S')
  {
    TCCR1B &= ~(_BV(CS11));//stop timer
  }

  if (millis() - prevDisplay >= interval)
  {
    prevDisplay += interval;
    noInterrupts();
    long copyEncoderCount = encoderCount;
    encoderCount = 0;
    long copyErrorCount = errorCount;
    errorCount = 0;
    interrupts();

    Serial.print(copyEncoderCount);
    Serial.print('\t');
    Serial.println(copyErrorCount);
  }
}

ISR (PCINT0_vect)
{
  encState = ((encState << 2) | ((PINB >> 1) & 3)) & 15; //use encoder bits and last state to form index
  encoderCount += encTable[encState];//update actual position on encoder movement
  if (encTable[encState] == 0)
    errorCount++;
}

void readCommand() {

  if (Serial.available() > 0)
  {
    Command = Serial.read();
    Serial.println(Command);
  }
}

However, it’s receiving 5K Hz on the multimeter and 100Khz on proteus. On the nano, I’m only getting 10k and not 20K. I’m not sure why. I’m not sure why all the differences.

This is strange. What do you see for Serial output?
Could your nano possible be running at 8MHz?

I’m aware. I changed it the first time and it worked and did some more testing. But when I changed it again later, for some reason it just wouldn’t work anymore. Even the serial monitor wouldn’t show anything.

Can I get like an equation for this. Like let’s say I want to change it to 50Khz or whatever arbitrary number, what should I do exactly?

Serial output for the Uno? It shows 20,000.
As for the nano, I’m not sure, I put the code I’m using. What can I do to provide more information?

In the code you posted, with one interrupt and this isr you are only reading at half resolution and will see 10K counts per second instead of 20K. Quadrature encoders can be read so as to pick up 1,2, or 4 of the available quadrature transitions.

void readEncoder()
{

  pinA = bitRead(PIND,encoderPinA);
  pinB = bitRead(PIND,encoderPinB);
  dir = pinA ^ pinB;          // if pinA & pinB are the same
  dir ? --pulse : ++pulse;    // dir is CW, else CCW
 
}

Can I get like an equation for this. Like let’s say I want to change it to 50Khz or whatever arbitrary number, what should I do exactly?

See the examples in the original code. The prescaler and the ICR1 value set the fundamental timer repeat period. The encoders counts are 2X the frequency.

For 50K encoder counts/second you want the timer to repeat at 25KHz. That gives a timer repeat period of 40 us. (Period = 1/f) With the prescaler 8 and .5us per tick on a 16MHz processor, you want an ICR1 value of 79, which gives 80 counts per timer repeat.

I’m completely lost with this to be honest. How do you know it’s only reading the half the resolution? How do I fix it? I got this code from another thread and other people there were saying that it should be working in general. Plus, it technically worked with Option #1. So I’m not sure why it wouldn’t be compatible with option #2. I feel like the issue would come from the transmitting side rather than the receiving side then.

I tried it again with 25KHz as my frequency. So that should give me 50K pulses on the nano and 25KHz on the multimeter. I’m getting 12.5KHz on the multimeter and I’m getting 25K pulses on the nano. I would say that the multimeter and the nano are in sync properly AND that the transmitting arduino is at fault here. Maybe there’s something wrong with your code? I’m really not sure.

When I change the prescaler. For example, I want to set it to 64.

I should do TCCR1B |= _BV(CS11) | _BV(CS10); correct?

Should I also add it to the forward and reverse part? And when I want to have it stop. Do I then do

TCCR1B &= ~(_BV(CS11) | _BV(CS10));??

That looks correct to me.

How do you know it’s only reading the half the resolution?

Because the isr to increment the count is only triggered by change on one pin. You need to do some reading on quadrature encoders and how the outputs are arranged.

How do I fix it?

Use change interrupts on both the A and B pins and use an appropriate ISR.

Hello, you didn’t answer the rest of my question. This part.

As for the interrupts on both A and B pins. That’s not correct. I’ve read about the encoder. Some examples do use an interrupt for A and B, while others use what I’m doing, they get triggered by only one A and then use B to know the direction only. This is will be the case because I’ll need the other interrupt pin for the other motor. The robot has 2 wheels, each one will use one interrupt to the arduino (which only has 2 interrupt pins 2 and 3).

I’m not sure if that makes sense, and I’m not sure if there’s something wrong with my logic. I’m not really advanced and I’m trying to make this work.

The referenced code only generates the quadrature pattern. You can read this output with any quadrature reading code you choose. If you use the reading algorithm with only one interrupt, you will see half of the counts shown in the comments of the program because the reading code packaged with the generating code used two interrupts for full resolution.

you didn’t answer the rest of my question

If you read my previous reply more closely I said

That looks correct to me.

Can you walk me through this. Maybe I’m misunderstanding something and this is what’s causing the issue and I guess after I read some more, I’m still understanding the same thing.
With Quadrature encoders, it gives out two signals. In the code I have, it activates the interrupt on the first signal and checks the other signal. And depending if they’re both high or one is high and the other is low, it will decide if it’s going CW or CCW. Why do would this only get half the resolution? The counter depends on the number of rising or falling edges, so it should be 2 times the frequency. I don’t understand it’s not actually working properly in the end. Like logically and not programming wise. And honestly, programming wise, I’m not really knowledgeable enough to understand what you’re saying. I’m trying my best, but it seems like it’s not good enough. You’re saying that the receiving arduino needs to use both interrupt, but that would mean it can only read from one encoder. But I want it to work with both encoders, hence the need to use only one interrupt per encoder.

What’s confusing me is that when I connect the output pin to the multimeter I’m getting the same frequency as my receiving arduino and not the frequency on the transmitting arduino with your code. So my arduino and the multimeter read the same thing.

Also, the code in Option #1 seems to work better with my arduino, but it has other limitations.

I mentioned the source of my encoder reader and the people on that forum post were also saying it’s working.

You’re right, I’m sorry. I guess my focus was on trying to understand what’s happening with the code that I ended up not realizing my question was actually answered.

I do appreciate your help. I’m just confused and need to get this working properly and it’s not.

Quadrature has the latin root “quad” meaning four or fourth, and in the encoder it means that the two outputs A and B are 90 degrees phase shifted. There are four transitions in the repeating cycle(360 degrees) and there are four possible states between the two pins at transitions. 10 00 01 11. There are four transitions in the repeating cycle. A goes high, A goes low, B goes high and B goes low. There are four total rising and falling edges in a complete cycle.

Here is an animation of the encoder output which will help you see this.

http://www.creative-robotics.com/quadrature-intro

There are different algorithms to read the A B output from the encoder, and the algorithms look for changes on the channels. Some trigger on one channel rising or falling, and you only read one of the four states. Others like the one you use, trigger one one channel going both high and low, and this reads only two of the four possible combinations. Still others trigger on both A and B changes and read all four of the possible states in the cycle.
Many applications do not need the full resolution available from the encoder, and it saves procesor resources to only trigger on one channel.

You’re saying that the receiving arduino needs to use both interrupt, but that would mean it can only read from one encoder. But I want it to work with both encoders, hence the need to use only one interrupt per encoder.

You are focused on the case of the Uno which has only two “external interrupts”. Some Arduinos have more pins which can use the attachInterrupt() syntax. There are also “pin change interrupts” which opens up even more pins to read the transitions from an encoder.

Hello, thank you for your reply. I understand what you’re talking about. But here’s my issue.

Now all quadrature encoders produce the same signal, correct? So the reader in this case, whether it reads the four transitions or just two of them, should produce the same frequency and the difference would be the accuracy, correct? But this isn’t the case, I’m getting completely different frequency. Unless your original code doesn’t actually replicate an encoder, and in that case I’ve got everything wrong.

As I mentioned before, the code in option #1 partially works (only forward motion). And I can get the accurate reading on my arduino and on my multimeter. However, with your code, I can’t on either. I only get half the value and I don’t understand why does one work and not the other? Can you please help explain this to me? And furthermore, would can I change in my receiving code to get over this issue? I tried a different receiving code that gives me the same answer. This one also uses one pin as the trigger.

/*
 * Encoder example sketch
 * by Andrew Kramer
 * 1/1/2016
 *
 * Records encoder ticks for each wheel
 * and prints the number of ticks for
 * each encoder every 500ms
 *
 */

// pins for the encoder inputs
#define RH_ENCODER_A 3 
#define RH_ENCODER_B 5
#define LH_ENCODER_A 2
#define LH_ENCODER_B 4

// variables to store the number of encoder pulses
// for each motor
volatile signed long leftCount = 0;
volatile signed long rightCount = 0;
unsigned long myTime;

void setup() {
  pinMode(LH_ENCODER_A, INPUT);
   (LH_ENCODER_B, INPUT);
  pinMode(RH_ENCODER_A, INPUT);
  pinMode(RH_ENCODER_B, INPUT);
  
  // initialize hardware interrupts
  attachInterrupt(0, leftEncoderEvent, CHANGE);
  attachInterrupt(1, rightEncoderEvent, CHANGE);
  
  Serial.begin(9600);
}

void loop() {
  
  
  Serial.print("Right Count: ");
    Serial.println(rightCount);
  Serial.print("Left Count: ");
  Serial.println(leftCount);
  Serial.println();
  //delay(500);
  Serial.print("Time: ");
  myTime = millis();

  Serial.println(myTime); // prints time since program started
  delay(1000);          // wait a second so as not to send massive amounts of data
}

// encoder event for the interrupt call
void leftEncoderEvent() {
  if (digitalRead(LH_ENCODER_A) == HIGH) {
    if (digitalRead(LH_ENCODER_B) == LOW) {
      leftCount++;
    } else {
      leftCount--;
    }
  } else {
    if (digitalRead(LH_ENCODER_B) == LOW) {
      leftCount--;
    } else {
      leftCount++;
    }
  }
}

// encoder event for the interrupt call
void rightEncoderEvent() {
  if (digitalRead(RH_ENCODER_A) == HIGH) {
    if (digitalRead(RH_ENCODER_B) == LOW) {
      rightCount++;
    } else {
      rightCount--;
    }
  } else {
    if (digitalRead(RH_ENCODER_B) == LOW) {
      rightCount--;
    } else {
      rightCount++;
    }
  }
}

I am using a nano for two motors after all, so I have to work with that limitation whether I like it or not.

My aim is to test my code against verifiable data so I can know if it would better to use a raspberry pi or an arduino to read the encoder. I’m just looking to get a source that behaves just like the encoder I have on the motor that produces a reliable signal.

Correct.

Unless your original code doesn’t actually replicate an encoder

The original code does indeed replicate the output from a quadrature encoder and has been used and tested many times by several different users.

So the reader in this case, whether it reads the four transitions or just two of them, should produce the same frequency

Please explain what you mean by frequency in this case. Number of counts/second will not be the same for the two and four transitions reading.

What are you measuring with the multimeter to give a frequency?

Let me explain what I mean, maybe have some of my fundamentals wrong. The encoder produces 2 square waves, 50% duty cycle coming out of both connections (one connection per square wave). When B is 90 degrees ahead, then it’s going CW and when B is 90 degrees bbehind then it’s going counter clockwise.

So in this case, my frequency would be the number of full cycles in a second (high and low). The number of pulses would be 2 times the frequency because I’m counting the rising and the falling edges.

For example in the encoder I have, it does 12 pules per revolution. but I guess they mean only rising edge. So what I would then do is get the number of pulses from the encoder, divide it by 2 and then continue as normal… I would multiply it by 60 and divide it by the PPR (12) to get the RPM. Gear ratio too if there is one.

Does that make sense?

I’m measuring the output of pin 9 and ground. My encoder code should read 2 times the number that is shown on the multimeter and it should read the same value that comes out of your code’s serial print, correct?

Again, this is what I’m getting from Option #1 code which from what I understand should be doing the same thing as what you’re doing.

EDIT: From what I understand is that you can tell the speed even using one connection only. But the good thing about Quadrature encoders is that if needed, you can also tell the direction too. So assuming I’m only using one connection, I should get the speed correct.

For example in the encoder I have, it does 12 pules per revolution, but I guess they mean only rising edge.

Encoder specifications vary by manufacturer. In most cases pulses per revolution (PPR) only refers to one pin. For example if the A pin gives 12 pulses per revolution there are 12 rising edges of the pulse and 12 falling edges of the pulse. So, depending on which edge of the A pin is used as a trigger, and how the B pin is treated, you can use different algorithms to read 12, 24 or 48 counts per revolution.

So in this case, my frequency would be the number of full cycles in a second (high and low). The number of pulses would be 2 times the frequency because I’m counting the rising and the falling edges.

Your description is a little confusing, and I think that some of it is the definition of “pulse” and “edge”. I would say that a pulse has two edges, a rising edge and a falling edge, and the number of transitions is 2X the frequency of the “pulse”.

EDIT: From what I understand is that you can tell the speed even using one connection only. But the good thing about Quadrature encoders is that if needed, you can also tell the direction too. So assuming I’m only using one connection, I should get the speed correct.

If speed is revolutions per second (or revolutions per minute) then the number of counts per revolution is a key value. As previously said, if the encoder can provide 12, 24 or 48 counts per revolution, you need to know which is being used to get a speed.

Question for later: How do I make sure which one I have so I can calculate it properly when it comes to testing it out with an actually encoder. The one I have right now is this. I’ll be using this motor/encoder combo later down the line.

Okay. Using your description. There is one pulse per cycle. So if my frequency is 5000Hz, I have 5000 pulses and I have 10000 transitions, correct? My issue is when I set your code to 5000Hz, I should get 10,000 transitions on my receiving arduino. I don’t actually receive 10K transitions, I receive 5,000 transitions ONLY. AND the multimeter reads 2.5KHz which also equals 5,000 transitions.

By transition, I mean either a rising or a falling edge,.

Fair enough, I would need to know if it’s 12, 24, or 48 based on the actual encoder. But I still can get all of that from a single pin, correct? Then I don’t really need to have an interrupt on both pins.

The pololu spec for the current encoder says

The encoder board senses the rotation of the magnetic disc and provides a resolution of 12 counts per revolution of the motor shaft when counting both edges of both channels.

The later version with 49:1 says

• Encoder counts per output shaft turn: 980

That 20 counts per revolution of the motor and my guess is that its with both edges of both pulses. The way to test is to turn the motor slowly by hand and read the output with a simple digital read program for each output. You could use your multimeter or a scope as well.

Fair enough, I would need to know if it’s 12, 24, or 48 based on the actual encoder. But I still can get all of that from a single pin, correct? Then I don’t really need to have an interrupt on both pins.

No, from a single pin you can only get the 12 or 24 counts per revolution. For the 48 counts you need to count both transitions on both pins, but for slow operation you probably don’t need an interrupt to do it. State change detection on a pin with digitalRead is common. There is an example in the digital examples section of the ide.

My issue is when I set your code to 5000Hz, I should get 10,000 transitions on my receiving arduino. I don’t actually receive 10K transitions, I receive 5,000 transitions ONLY.

What settings do you apply for 5000Hz?
I think you misunderstand the output from the timer. Each timer cycle does not generate a complete pulse. Instead, the timer code toggles the pin on a compare match so you only get one transition on each pin per timer cycle. Each timer cycle generates only one edge of each pulse A and B.

I see, so for the pololu, I would count 6 edges in my own code (since I only count one pin) and I wouldn’t divide them, since those 6 edges will make one revolution of the motor. Correct?

This still doesn’t actually fix my original issue. My original issue was using that code I would get 230 transitions. My gear ratio of the motor is supposedly (chinese website) 30:1. I thought I’d get 3012 = 360. But you’re now saying that this is wrong and I should do 3060 =180. Still far off from the 230 I’m getting. Hmmmm

Multimeter can only get the frequency and not just the number of transitions. I’d be able to do that with my code once I iron out all the issues though.

For 5000 Hz, I have the prescalar set to 64. And ICR1 set to 49 (50).

Should this not do 5000 full cycles (pulses) per second per pin? What do you mean by only one edge per time cycle? Can you draw the graph for it, I guess that’s the key to the confusion for me then.

You have the timer cycling at every 200 microseconds, which is 5Khz. Let’s just consider the A output pin which is set to toggle (change state) when the timer reaches top and resets. Pin A will go high at timer top and then 200 microseconds later it will go low. Then 200 microsecond latter it will go high and on and on. Thus, the A pulse is 200 us High and 200 us low. That’s 400 us for the complete square wave or a frequency of 2500 Hz. The square wave pulse frequency is half the timer repeat frequency.

This still doesn’t actually fix my original issue. My original issue was using that code I would get 230 transitions. My gear ratio of the motor is supposedly (chinese website) 30:1. I thought I’d get 3012 = 360. But you’re now saying that this is wrong and I should do 3060 =180. Still far off from the 230 I’m getting. Hmmmm

Yes, at 6 counts per revolution and a 30:1 gear ratio you should be getting 180 counts per revolution of the output shaft. It’s a magnetic encoder so there should not be switch bounce and I don’t understand why your read 230 counts/rev.
What is your measurement technique for determining a full revolution.

I’m unclear about what you are doing. At first it sounded like you wanted to emulate an encoder and were using the quadrature output program to provide signals in place of an actual encoder.

Now is sounds like you are trying to read a real encoder and match he specified output. You will need to provide the code you are using. Are you using pullup resistors on the output pins? Is the encoder exactly the model you think it is?