Hi guys, I am looking to add a rpm detector to my project to help smooth things out. I currently have a 8 bit encoder attached to a shaft that will run up to 8000 rpm and I would like to detect rpm at least 8 times per revolution for internal use, may output to some led's or logic analyzer to ensure it's working correctly. I am using a lattice machxo2 and 50mhz on board osc. I was thinking of have a 16bit value representing rpm. I have an understanding of what I have to do, just curious if anyone has a proven and sound method of doing this. I already have the encoder inputs filtered for a single clock wide pulse output for the 8 points. I would appreciate any help or guidance. Thank you, Chris.
ChrisChris wrote: > a 8 bit encoder What kind of "8 bit encoder" is that? Ist one revolution equal to 256 steps? Do you have a link to such a thing? > I would like to detect rpm at least 8 times per revolution Is your system that dynamical? > to a shaft that will run up to 8000 rpm What kind of motor is that? A gasoline engine? > I was thinking of have a 16bit value representing rpm. Then you want a resolution of 0.1 rpm? Ok, to get that accuracy througout the whole rpm range (even from 7999.9 to 8000.0) you must measure 1/8 of a turn with 65535 counts. At maximum freqeuncy this is 8000rpm = 133rps => 133Hz * 8 = 1064 => 1064Hz*65535 = 70MHz. So all in all with the 50MHz oscillator you will be slightly worse than your desired 16 bit accuracy at maximum rpm. > I have an understanding of what I have to do Count the time for 1/8 turns and the reciprocal value is your rpm (maybe a little bit scaling is necessary...).
The encoder is a quadrature, 256cpr, decoded in fpga to a plus/minus counter, I thought it through a little more today, I guess that I don't specifically need to know the rpm exactly, I'm just trying to make variables based on 50rpm increments, so between 0-50rpm I'll have the first led indicate, and 50-100 and so on. So I'll basically just create a counter from clk to binary and focus on the MSB's that are within the ranges I need?
ChrisChris wrote: > So I'll basically just create a counter from clk to binary and focus on > the MSB's that are within the ranges I need? Thats the big picture, yes (although a "counter from clk to binary" is a little bit figurative: usually its only a "counter running on clk", because most of the counter inside an FPGA are binary). What I would do: generate a saturating counter counting with that 100MHz clock frequency. So that counter is an integer from 0 to 100MHz/((49/60)Hz*8) --> 0..15000000 (at 0 rpm its no need to count longer than at 50 rpm because 0..50rpm targets the same "frequency range"). And then i would let run that counter for 32 steps of the quad decoder and afterwards simply check the range as you proposed.
Interesting, so I need to figure out how to use the internal PLL and bring the clock up to 100mhz for this process, which would be nice for the rest of my system too, except my bit banged spi. I got it to work, so far by checking 4 points per revolution, for every 100rpm higher I divide the timer by +1, ex if freq < 3_755_000 and freq >= 1_877_500 then leds<= "11111110" (3755000\2). then next was 3755000/3 and so on.
ChrisChris wrote: > Interesting, so I need to figure out how to use the internal PLL and > bring the clock up to 100mhz for this process, In fact the 50MHz clock ist fast enough also. After a few calculations you will find out: 170kHz is the limit, so even counting 500kHz will do the trick... > except my bit banged spi. You really do SPI in software on a FPGA?
It's just a single master, it does 1 dummy and 2 requests , then I snag the 12 out of 14 bits in the register. I'm very new to fpga, I'm a year in on designing electronics for a small company, but we use avr and arm and I just make the electronics work and design the boards/bom. The boss does the C coding. It takes me a little bit longer to catch onto the software side, like using the internal flash and hardened spi , I just get overwhelmed, all of my code is in a single .vhd cause I haven't figured out how to separate them yet. I'm learning as I go, been on this single project for almost a year. With the bit banged spi I can use any pins I want which really helped with routing my board too, straight connections. I want and need to learn more, my only time for my project comes in around 10pm to 3am, few hours of sleep (2-3) then of to work. Most of my of work time is with my two girls and my wife.
ChrisChris wrote: > With the bit banged spi I can use any pins I want which really helped > with routing my board too, straight connections. What do you mean with "bit banged SPI"? Is it software? Or is it VHDL? Just to do one step back: SPI is simply a shift register. See the pics there: http://www.lothar-miller.de/s9y/archives/15-SPI.html Therefore its fairly easy to run it at high speed... Here is one in VHDL: http://www.lothar-miller.de/s9y/categories/45-SPI-Master > all of my code is in a single .vhd cause I haven't figured out how to > separate them yet. Just wirte some more modules in some vhdl files. Add them to your project and use the module as a component in the "top level" module. You can see that there: http://www.lothar-miller.de/s9y/archives/57-Sinusausgabe-mit-PWM.html The "top-level" is SinusPWM, it uses the two VHDL modules DDFS and PWM as components. And the best is: the testbench is just a VHDL entity without ports. It uses the top-level SinusPWM as a component. Or you can see that there: the entity Totzeit is used as a component in the top-level PWM_Totzeit, which could also be implemented in the SinusPWM for dead time generation. All in all you must be aware: VHDL is NOT a programming language because its name is not VH-P-L. It is a description language. And to describe something you must have a picture of it. So at first you must have a kind of schematic or sketch with functions blocks. Then you can describe it...