2

I'm supposed to write a raspberry pi and arduino code to read the RPM of a motor with an encoder attached to it. However, I'm having weird numbers and I'm unsure about the specs on the motor and the encoder. So I thought it would be smart to use a second arduino to simulate the motor with encoder.

The simulator would need to produce a 2 signals representing the two signals from the encoder. I want to be able to set the frequency and phase shift of these signals in software to imitate changes in speed and direction of the motor rotation. Forward would have one signal 90 degrees ahead, and then reverse having that same signal to be 90 degrees behind. So phase difference of plus or minus 90 degrees.

I'd like to eventually have the simulator be able to simulate motor actions like oscillating between forward and reverse 5 seconds each, or forward for 5 seconds and then stop completely.

I found this code by bigjosh which is more or less what I want to do. However, that code doesn't allow for a shift of -90 deg by default. I know there's a comment there to change it, but I'm not knowledgeable enough to understand what's going on exactly. I'd like someone to help me with that.

1
  • 2
    what is your question? ... this site is a Q&A site, not a forum, and not a brainstorming site – jsotola Apr 30 at 1:31
2

Wow, that turned out to be way harder than I expected. It is very hard to do cleanly on the AVR timer. But I was able to come up with this working function, which I think is what you are looking for...

// freq_hz is frequency in hertz from 122 to 4,000,000
// shift_deg is phase shift between output A and output B in degrees (values outside -180 to +180 are normalized)

// Note that at frequencies above 44KHz you will loose precision on phase shift. At 4Mhz, everything is rounded to just 0 or +/-90 degrees.
// Note that all timing happens in 1/16Mhz increments, so frequencies that do not land on integer multipules of that will be aproximiate. 
// Use startWaveforms() directly for more precise control. 

void startQuadrature( unsigned long freq_hz , int shift_deg  );

It can glitch at start-up, shutdown, and changes in speed and direction... but so can a motor encoder so I guess that is ok. It would be possible to create a glitch-free version but more work.

Github repo here... https://github.com/bigjosh/Quadrature

So, to simulate a motor going forward with 50KHz pulse rate, you would use something like...

startQuadrature( 50000 , +90);

...and the same pulse rate going backwards would be...

startQuadrature( 50000 , -90);

Do note that if you connect an Arduino UNO output pin to a Raspberry Pi input pin that it will likely damage the Pi. This is because the UNO outputs 5 volts for a "1" signal, but the Pi can only tolerate a maximum 3.3V on any pin. You can google "5V 3.3V level shifting" for solutions to this problem.

4
  • Wow! Thank you so much! I can't believe you actually went all out like that! Much appreciated honestly. I have a couple of questions: 1. Are you using a program to simulate the arduino and oscilloscope or are you using real hardware and taking snapshots? 2. I'm actually getting a lot of glitches that is making this extremely unstable. To the point that it's not working out for me at all. I'm not sure if this is error on my side (receiving arduino) or the hardware cannot do much better. Thanks again! For voltage level shifting, I was gonna use resistors until I buy a proper module – krusion May 1 at 1:04
  • @krusion, if you found it useful you should vote it up. – timemage May 1 at 15:21
  • bigjosh - Nice work! I just dl'd the repo and tried it on a spare Uno here - works like a charm, once I got all my stupidities cleared up ;-) – starship15 May 4 at 19:23
  • @user3765883, that indicates it makes sense to "accept" it as the answer. – timemage May 8 at 1:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.