Reading a Quadrature Encoder connected to a Beaglebone [black]

My overall goal is like the title says: I need to read a quad encoder count, and I have a beaglebone black. Eventually, I’ll be using c++. Any help on how to proceed or links on things I should read are appreciated.

I’ve seen 3 ways of reading an encoder on the beaglebone: (1)polling GPIO pins, (2)using interrupts in a kernel driver, and (3)using the eQEP built in to the hardware of the beaglebone SOC. I’m interested in (3) because it seems to me that it would be the most efficient. However, it seems like most people are using (2), and I can’t find a whole lot on how to do (3).

Here’s what I have found so far in case it’s useful to anyone else.

I know people are working on the problem of making (3) easy to use. Is there some other link on how to do it that is eluding me?

If there’s not, in the meantime, I’m interested in device drivers, and I think it’s practical information, so I’d like to learn as much about them as I can. Perhaps I’ll even get to the point where I can help the ongoing eQEP effort. I’m rather inexperienced in driver writing, though. I’ve been wading through the linux device drivers book, so I guess that’s a start. However, I’ve never recompiled my own kernel, which it looks like I’ll probably have to do, and I’ve never even cross-compiled. Could somebody help me out with a place to start?

In the meantime, I’ll be looking at method (2). Thanks in advance.

I’ve actually put together a kernel driver for the eQEP hardware that presents a poll able sysfs interface. It plugs beautifully into the device tree, and supports absolute and relative modes. Relative resets the counter and notifies a polling program based on a provided period, which drives the eQEP unit timer. I’m posting all my code to my blog and to github today.

  • Nathaniel Lewis

Its just a work in progress, but here’s what I have now that its midnight. Tomorrow I’ll through together some documentation, test it further, and put together an API. Essentially in its current form its a couple of device tree overlays, a kernel patch (been using Robert’s linux-dev am33x-v3.8 kernel) which puts in the driver, and there is an example of polling the position attribute. I’ll put some docs together tomorrow, I’m tired.

https://github.com/Teknoman117/beaglebot/tree/master/encoders

Hi:

Can you make the eqep driver works?
I need some help, because I can’t…I trying and trying…and nothing.
I rebuild the kernel with EQEP, but when I try load the dtbo files, always the same: -sh - invalid argument…
I can load other capes, like pwm etc…but not the eqep driver.

I really apreciate if you can share some information…

Thanks

Hi,
same issue here.
I get the following error when trying to load the slot:

[ 1598.682521] bone-capemgr bone_capemgr.8: part_number ‘bone_eqep0’, version ‘N/A’
[ 1598.682703] bone-capemgr bone_capemgr.8: slot #9: generic override
[ 1598.682754] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 9
[ 1598.682805] bone-capemgr bone_capemgr.8: slot #9: ‘Override Board Name,00A0,Override Manuf,bone_eqep0’
[ 1598.683068] bone-capemgr bone_capemgr.8: slot #9: Requesting part number/version based 'bone_eqep0-00A0.dtbo
[ 1598.683121] bone-capemgr bone_capemgr.8: slot #9: Requesting firmware ‘bone_eqep0-00A0.dtbo’ for board-name ‘Override Board Name’, version ‘00A0’
[ 1598.683625] bone-capemgr bone_capemgr.8: slot #9: dtbo ‘bone_eqep0-00A0.dtbo’ loaded; converting to live tree
[ 1598.688201] of_resolve: Could not find symbol ‘eqep0’
[ 1598.693733] bone-capemgr bone_capemgr.8: slot #9: Failed to resolve tree

I also tried to recompile the DTS but I get the same error.
Could you please help?
I’m working on the following kernel:

Linux beaglebone 3.8.13-bone32 #3 SMP Mon Jan 13 18:02:42 CET 2014 armv7l GNU/Linux

Thanks
Lorenzo

Hi,
I have the same issue. When loading the equep0 slot I get:

[ 1598.682521] bone-capemgr bone_capemgr.8: part_number ‘bone_eqep0’, version ‘N/A’
[ 1598.682703] bone-capemgr bone_capemgr.8: slot #9: generic override
[ 1598.682754] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 9
[ 1598.682805] bone-capemgr bone_capemgr.8: slot #9: ‘Override Board Name,00A0,Override Manuf,bone_eqep0’
[ 1598.683068] bone-capemgr bone_capemgr.8: slot #9: Requesting part number/version based 'bone_eqep0-00A0.dtbo
[ 1598.683121] bone-capemgr bone_capemgr.8: slot #9: Requesting firmware ‘bone_eqep0-00A0.dtbo’ for board-name ‘Override Board Name’, version ‘00A0’
[ 1598.683625] bone-capemgr bone_capemgr.8: slot #9: dtbo ‘bone_eqep0-00A0.dtbo’ loaded; converting to live tree
[ 1598.688201] of_resolve: Could not find symbol ‘eqep0’
[ 1598.693733] bone-capemgr bone_capemgr.8: slot #9: Failed to resolve tree

I’m working on the following kernel:

Linux beaglebone 3.8.13-bone32 #3 SMP Mon Jan 13 18:02:42 CET 2014 armv7l GNU/Linux

Could you please help?
Thanks
Lorenzo

Nathaniel’s driver worked fine for me.

@Lorenzo: Are you sure you rebuilt the kernel correctly with the eqep driver patch? I am quite inexperienced with device trees so you probably shouldn’t listen to me, but it looks like you built the device tree fragments correctly but the underlying mechanism can’t find the actual driver.

agni...@gmail.com: Can you provide a little more information? What’s the exact command you used and the exact error message?

Hi,
yesterday I was finally able to get it working!
I think that “agni…” is having the same error: when executing the “echo” of eqep in slots I get the same “invalid argument” error.
I get the additional details executing a dmesg command.

Investigating on device tree, I found that form some reason the installation script didn’t installed the DTB files on the SD.
From what I understood:

  1. the patch should add the EQEP tree items in “linux-dev/KERNEL/arch/arm/boot/dts/am33xx.dtsi” (you can verify searching for “eqep” in it)
  2. The “./tools/rebuild.sh” should build the DTB files and create an updated tar.gz file in “linux-dev/deploy” with the new version of the device tree
  3. Then the “./tools/install_kernel.sh” should install the kernel and copy the new DTB to the correct destination folder

Suspecting to have outdated DTB, I deleted the “linux-dev/KERNEL/arch/arm/boot/dts/am335x-*.dtb” and re-executed the point 2. This re-created the DTB files. Then I manually copied them to the SD, in the “/boot” partition (and a subfolder that I don’t remember in this moment, but you can find easily since it contains the same files).
This fixed my issue!!! Sincerly I suspect that my version of “./tools/install_kernel.sh” is newer than the one shown in http://www.youtube.com/watch?v=HJ9nUqYMjqs . But I don’t know if this is a real bug or it is caused by my configuration.

To get the encoder to work I also had to disable HDMI and HDMIN, as explained in https://groups.google.com/forum/#!topic/beagleboard/aU__9RGq3xU
Hope this helps.
Cheers
Lo

Hi

I’ve had the same issue.

i solved it by recompiling with:
tools/rebuils.sh, wait for linux menu config and choose:
System Type →
TI OMAP2/3/4 Specific Features and check TI OMAP 2

rebuild will take a while, but keep care to deactivate HDMI support,
otherwise you will get:

pinctrl-single 44e10800.pinmux: pin 44e108d8 already requested by hdmi.13; cannot claim for 48302180.eqep

Have fun :slight_smile:

I’ve had ths same issue,

I solved it by recompiling with the following changes in linux menu config:

System Type → TI OMAP2/3/4 Specific Features → TI OMAP 2 (checked)

but don’t forget ti deactivate HDMI (otherwise you will get: pinctrl-single 44e10800.pinmux: pin 44e108d8 already requested by hdmi.13; cannot claim for 48302180.eqep)

Heve fun :slight_smile:

I’ve had ths same issue,

I solved it by recompiling with the following changes in linux menu config:

System Type → TI OMAP2/3/4 Specific Features → TI OMAP 2 (checked)

but don’t forget ti deactivate HDMI (otherwise you will get: pinctrl-single 44e10800.pinmux: pin 44e108d8 already requested by hdmi.13; cannot claim for 48302180.eqep)

Heve fun :slight_smile:

Nathaniel,

First of all, thank you very much for all the work you have put into the BeagleBone and provided to the community through your Github repository. I am working on a robotics project using a BeagleBone Black and have thoroughly enjoyed using it as a hardware platform. Recently, I’ve been working towards getting a rotary encoder reading up and running using your eQEP method, but, being inexperienced with Linux kernel compilation, have run into a problem I can’t seem to solve. I’ve made it through most of Derek Molloy’s tutorial and patched it with your eqep script, but haven’t figured out how to deploy the image to SD card. Instead of install_image.sh in the linux-dev/tools directory, all I have is install_kernel.sh. Having configured the system.sh MMC variable for my SD card (/dev/sdd), I run the script, it asks the “are you 100% sure” question, I enter “y”, then it unmounts, displays the partitions on the card, and the script finishes without copying anything onto the card. Any advice or input would be greatly appreciated! I admit I don’t really know what I’m doing, but I’ve searched and searched for an answer and haven’t found one yet.

Thanks,
Willie

UPDATE: I figured out the issue - I needed to burn a fresh image onto the SD card before the script would copy the files. I would have appreciated some sort of error message :stuck_out_tongue: Anyways, using the manual .dtb file copy mentioned previously, I got the driver loaded and the device tree loaded for eqep0. However, I’m getting no useable output from the position variable. While troubleshooting, I began to wonder if the eQEPs will work with only Ain and Bin connected (all my encoder has). Is there a setting that needs to be changed to ignore INDEX and STROBE? Just wondering, though I’ll probably figure out how to get it operational sooner or later.

–Willie

Willie,
There's no need to connect index or strobe. Make sure you don't have any pin conflicts with the hdmi pins. You can also troubleshoot by connecting the eqep pins to ground and 3.3v in turn. I used a couple spdt buttons.

Thanks for the reply! I actually used dmesg to figure out it was an HDMI pin conflict, so I disabled it and SSHd. Voila! It works like a charm. I appreciate the support, and will surely have more questions down the road.

–Willie

Hi everyone,
I can not echo dtbo file to slots, plz guide me to implement it.
Much appreciated !