Trying to Read some Optical Encoders w/out Knowledge...


I feel new again. Anyway…

  1. I bought something new
  2. This “new” item is actually an older model optical encoder w/ stepper attachment
  3. …and here some more of it

Would I use eQEP or eCAP or both or neither for handling the optical portion of the sensor readings?

I know the BBB has these peripherals. Do I know how to use them? No, I surely do not.

I have been studying. I am starting to understand the theory behind how these computations take place.

Can eCAP/eQEP handle 20MHz frequencies down to 5MHz?


P.S. I know a ton of people already understand the older model in which this is derived. I am still out there floating in the sea on this one.

This was something I saw in the updates to the BBB one day, i.e. recently. Is using UIO a thing on the BBB still?

I mean…is there a way to leverage this source to handle reading older Optical Encoders?


P.S. If so, are there any people in userland handling such a task and would you be inclined to share a snippet of ideas in source? I am asking only. I do not expect to be granted anything really. I would rather know that there is some type of lib. or another form of functions dedicated to making an older Optical Encoder work to my advantage.

Once the users understand that UIO is much better to fulfill hard real-time requirements, they will ask for it and they will get it.

CAP → speed only (1 pin frequency)
QEP → speed and direction

Both clocks are working @ 100 MHz → low resulution @ 20 MHz.

Check out examples:
pwm_cap: measures frequency/duty cycle of pwm signal (replace pwm signal by your sensor to test)
qep: simulation of QEP signals (A, B, I) and showing the resulting measurement (disconnect the simulation and connect the real sensor for testing)
pruss_toggle: generates high speed toogling by pruss GPIO (20 MHz) and measures the output by CAP


1 Like


This is more than I could have asked for currently. Thank you…

  1. I read over the examples sections.
  2. I am learning more about the eCAP and eQEP functionality slowly…

I will test at 20 MHz b/c of it being an older model sensor w/ the highest rate of frequency being 20 MHz…

Here is the datasheet, i.e. from here: Data sheet: RGH41 series readhead

and a photo of the connections that I should make, i.e. in case anyone is following along:


and then the digital signals, respectively…


Hello Again @DTJF ,

I was looking over the ideas listed on the Wiki Page for libpruio.

Is there a python3 set of examples or is everything written and meant for only python?

I know Python is a bit slower to compile and run but I figured I would try it first.


P.S. I see mention of kernel 3.x.x in the docs. pages too. So, UIO gets used in /boot/uEnv.txt, I need to comment out the RPROC section, and then reboot. Are the packages already on the BBB or are the installs needing to be made by apt still should be used?

Development started with kernel 3.8 in 2014. Here I use libpruio under different kernel version up to 5.x. Small adaptions are necessary when a sysfs path changes, but the libpruio API didn’t change all the time → single source for your project.

devbuild setup is included in the GIT-repo. RCN started to build the packages, but never finished (I don’t know why). Currently the best solution is to build/install from source.

The main part of the library is coded in PRU ASM and the API (text IO) is coded in FreeBASIC. All examples are coded in FreeBASIC. Additionally some examples (with text output, no grafics) are also available in C and Python code. The Python code is executing more than ten times slower than the compiled binaries (C/FreeBASIC).


PS: Does your sensor work at 3V3?

1 Like

Hello @DTJF ,


The sensor is 5v. I need to add some additional hardware to make it translate to 3.3v. I will build the repo. from git and see how far I get.


P.S. I just looked in /boot/uEnv.txt and the instances of PRU are not located in that file. I may need another, different image? Guidance is accepted on images that have UIO. I will post the uEnv.txt file soon…

debian@BeagleBone:~$ cat /boot/uEnv.txt


###U-Boot Overlays###
###Master Enable
###Overide capes with eeprom
###Additional custom capes
###Custom Cape
###Disable auto loading of virtual capes (emmc/video/wireless/adc)
###Cape Universal Enable
###Debug: disable uboot autoload of Cape
###U-Boot fdt tweaks... (60000 = 384KB)
###U-Boot Overlays###

cmdline=coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet

#In the event of edid real failures, uncomment this next line:
#cmdline=coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet video=HDMI-A-1:1024x768@60e

#Use an overlayfs on top of a read-only root filesystem:
#cmdline=coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet overlayroot=tmpfs

##enable Generic eMMC Flasher:

See… Oh and…

debian@BeagleBone:/etc/apt$ sudo apt install python-pruio libpruio-lkm libpruio-doc
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package python-pruio
E: Unable to locate package libpruio-lkm
E: Unable to locate package libpruio-doc


Ign:5 bullseye/ InRelease
Err:6 bullseye/ Release
  404  Not Found [IP: 80]
Reading package lists... Done
E: The repository ' bullseye/ Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

So, I think the error is the IP Address is not located there any longer. Git it is…

I cloned the git repo. but the dependencies are not available.

E: Unable to locate package fbc
E: Unable to locate package cmakefbc


am335x-pru-package is no longer available.

It’s much more easy with 4.x kernels. But in the Arch LINUX world there’re attempts to get uio_pruss running under 5.x kernels.

This is for the LED site of the photoelectric barrier. Perhaps the other site is working at 3V3? You could try to use pull-up resistors:

  1. call Qep->config() for pinmuxing
  2. call Io->setPin() (once for each pin) to add the pull-ups


Build from source:

sudo apt install freebasic git cmake
git clone
cd cmakefbc
mkdir build
cd build
cmake .. -DCMAKE_MODULE_PATH=../cmake/Modules
sudo make install

This dependency is obsolet. libprussdrv is included (and optimized) in libpruio since version 0.6.


1 Like

Hello @DTJF ,

Okay…building will take place. Thank you for following up. I will report back.


This may be a little late by a few months. But I have successfully used the PRU’s on BBB in a motor control scheme. I used the eQEP1A and eQEP1B pins P8_33 and P8_35 respectively as quadrature inputs to PRU0. PRU1 was used for a periodic interrupt and messaging for servo rotational velocity input, & PID tuning. For real time debugging I used scope PIN’s P8_16, PRU0 code and P9_26, PRU1 code.

I used aldo CCS11.2.0 IDE for code, linking, and the PRUand Linux Kernel Version 4.19 and the CCS Pru-software-support-package for the AM335x. Refer to the macros found in the support package particularly “sys_pwmss.h”. I use the Enoder A&B outputs to be able to get the rotation direction.

I am currently trying to migrate the code to the BBAI-64 without much success. Currently can’t get the “robotics-cape.dtbo” overlay to work.

1 Like

hi @klindsayjr
I had problems with the spi bus, tried the connection as I was using with black and bbai only and was ok to boot the boards with imu connected on the spi bus,but with bbai64 if I connect the spi sensor and tried to boot the board simply try to load the boot from somewhere and refuse to boot.
what kind of problem are you having ?

BTW, to read the encoders with ardupilot I just used the sysfs to read the encoders and was working great. Didnt used the pru or external software.

I developed a c++ class to handle the linux spi and haven’t had a issue with the BBB. Haven’t gotten around to porting it over to the BBAI-64. I will need to load one of the overlays, BONE-SPIx_x.dtbo to test my code. What device pins are you using? These are the pins that are assigned in the BONE-SPIO_0.dtbo: cs0 - P9_17, clk - P9_22, d0 -P9_21, d1 - P9_18. The symlink is “/dev/bone/spi.0.0”.

Running /dev/bone/spi/0.0 on my BBAI-64 successfully. Used the overlay BONE-SPI0_0.dtbo. Make sure you ignore the first 4 pins on P9. Actual pin locations begin after the first 4. Also you will need to load your SPI driver. On my system I do the following:

$ sudo insmod /lib/modules/5.10.153-ti-arm64-r86/kernel/drivers/spi/spidev.ko.xz
$ sudo chmod go+wr /dev/spidev*
$ ls -l /dev/bone/spi/0.0

1 Like

The question is not the spi itself but voltage is pulses in the spi meanwhile uboot is starting.

If I connect the imu after the boot everything is working fine, but if I power the board with the imu attached , the pins for the spi is the same of boot order and do a mess in the uboot side.