[SOLVED] Details for the Encoder

An example of the encoder is here:

Does anyone know the following information:

a) Is it reading out in X1, X2 or X4 counts ?

b) What is the maximum no. of counts and maximum number of counts / second it can measure ?

Thanks alot.

Hi,
encoders are counting at each edge of each signal, so it should be x4.
counters are 32 bit and signals are sampled at 100 MHz so realistically we should be able to handle input toggle rates of 20 million toggles per second, which i suppose is more than enough for any application...

Thanks!

This makes this Arduino a pretty low-cost high performance quadrature encoder that can be easily configured to dump the data onto a serial port.

Hi,
not only... actually the idea is to create a high performance controller as we also have pretty flexible PWMs and we can synthesize many more peripherals. PWMs are able to produce, from a single counter, multiple phases each with its own independent phase and duty, moreover we're planning to make a PID "soft-ip" running in the soft processor so that you can close the loop in real time while leaving SAM D21 free to do anything else. of course any suggestion is more than welcome!

DarioPennisi:
Hi,
not only... actually the idea is to create a high performance controller as we also have pretty flexible PWMs and we can synthesize many more peripherals. PWMs are able to produce, from a single counter, multiple phases each with its own independent phase and duty, moreover we're planning to make a PID "soft-ip" running in the soft processor so that you can close the loop in real time while leaving SAM D21 free to do anything else. of course any suggestion is more than welcome!

That's precisely what I had in mind!
I'm working on a robotics platform with a small group, and we're using the 4000 board for controlling peripherals, motors, and whatever other real-time tasks we end up implementing in the future.

I'm still really new to FPGA's, so right now I'm implementing the PID control loop in software, and using traditional PWM peripherals. However, I hope to implement everything on the FPGA as you described soon.

I'm currently pouring over the SAM timer/counter documentation to play with. I want to play with PWM frequencies so the motors aren't so loud, and hopefully to get better torque at lower speeds. I'm also running a fairly tight loop, and updating the pwm duty cycle so frequently probably isn't working well.

Anyway, I'm extremely excited for this platform to take off. How are there not a thousand or more projects/videos on youtube already? Maybe I should slap the first one together, and upload tomorrow :slight_smile:

Hi All,

Got my mkrvidor4000 and am playing around with it.
I have a sig.gen hooked up to it giving the 90 degrees out of phase signals.
The counting seems fine at 4x.

For some reason the read value seems to overflow at 65535 even though I have initialized it as a unsigned long.
I checked the header and cpp files which seems to suggest that the encoder.read should return a uint32_t.

Am I missing something ?

which library are you using? graphics or peripherals? which version?

I am using the VidorPeripherals version 1.1.0 and the example I am using is this:

You're right, counters have been parametrized to 16 bits to fit other peripherals. Do you think you need more bits? If so I can try to see if it fits with 32 but am afraid it won't as we filled the fpga as much as possible with all sorts of peripherals. Maybe the best solution is going for a "motor" configuration where we have more focus on motor control. I was also thinking about embedding a few PID controllers to close the loop...

Yup, if you could implement 32 bits it would be good.
I believe that it would be not too difficult to overflow 16 bits with precision motors with long stages. Or even better if there is a choice of 16 vs 32 bits. I think there is also going to be a GUI sometime to choose which FPGA modules to install ?

A PID controller on FPGA would be great.
Similarly another generic tool would be the implementation of FIR filters. I am not sure how a 'generic' FIR filters with an arbitary number of taps could be implemented though.

Anyway, in both cases I think a fixed sampling rate would be required and probably be maintained by the void loop().

For my case I am looking at high speed sampling of the quadrature encoders (ideally 10kHz) and then followed by a FIR filter to clean-up the motion and then output it slower via the serial port (ideally 400Hz). I am still thinking probably the only way to do this would be to keep a timer and activate various commands (eg. sampling every 0.1ms, FIR filter every 0.1 ms and output every 1/400 s). But in this case the loop with the longest set of command would also need to be completed within 0.1 ms. This may be a challenge.

If there is a FPGA implementation of the FIR filter that I could send the output from the encoder directly into (filter coefficients defined in the setup), then I would only need to call this function every 1/400s and then serial display it and this would be easy peasy.

cheers

ok, so from what i understand you want to filter velocity which would be the differential of the encoder output. any FIR filter would add a delay in the measurement so a long filter will probably delay too much. what you want to do is absolutely and easily feasible in the FPGA but at the moment the web UI is not ready so you won't be able to do it alone if not fiddling with RTL directly.
since i am working on the motor library any input on it is appreciated so please let me have your wildest dreams and let's see what can be done.
so far we have:

  • PWM (the current one should be fine... it has fixed frequency on all channels and variable phase/duty per channel)
  • encoder (we just need to parametrize it differently, maybe, since if loop is handled in FPGA 16 bits may be more than enough
  • FIR
  • PID
  • limit switch input (to reset absolute encoder values)
  • I2C bus master (for temp sensors and other devices to monitor status)
  • HDMI output (for user interface)
  • a mechanism to dynamically link everything

what else?

I did a check by running the encoder read/write inside a timing loop with a digital output connected to a scope.
Calling encoder read will take close to 800us and calling read and write takes about 1.5 ms. Are these values kind of expected ?

I can get by the 16 bit by doing a encoder.write(0) each loop and experimentally making sure that the counts do burst within the cycle. As you have guessed correctly, I am interested in the differential of the encoder.

I think what you have mentioned is about it, the last point about linking them together is probably the game changer here. Would it necessitate the dynamic creation of 'superblocks' depending on what how the user link things up?

We are accessing fpga via JTAG and that is slow. I didn't measure transaction time recently but it seems a bit too slow from your measurements but it may depend on us not optimizing some rpc functions.

Regarding the motor image I'm thinking about a method to create virtual graphs of blocks inside the fpga so that you can interconnect them via software without the need to recompile the fpga itself. At the Arduino level it would just look like objects that have a connect method or something like that...
This may come handy also for other applications such as dsp (audio, video)

Thanks for your replies, i hope some of the measurements I made would have some help.

Overall if the calls to the FPGA take about 1ms per loop, then if we reset the encoder to 32767 before we start counting, then the max number of counts per second would be 32 million. I think when I did my measurements it was 1 reset + 1 read per loop.

This is plenty, though I didn't check if there would be any 'lost' counts that occurred during the reading and then the reset of the encoder. A useful command would be to read the encoder and reset it (to 32767) at the same time to avoid this

If you could speed up the transfer between the FPGA and the SAMD, it would be great because the arduino can actually run much faster and is just limited by this transfer.

cheers

Speaking of encoder derivatives.
Ideally, the FPGA would count the number of clock cycles between encoder "ticks", and use that.
It'd have less latency, be more accurate, and put less load and timing requirements on the microcontroller.
Of course, you'd need a large counter, which I'm sure there's no more room for.
If that counter overflows, just set the derivative to '0', which would be a close enough approximation.