PWM programming issue in my BBB - pwm

Background: Bought a BBB and experimenting a bit, managed to control LEDS and relays.
Problem: can't get the expected behaviour from the servo, it keeps spinning CCW
Cause: don't know, whey I'm asking here :)
Facts:
BBB with Angstrom
External 5V DC to both BBB and servo
Servo: Tower Pro sg90 (very common servo) AND it's working as I tried it in my RC car.
Procedure: following som tutorials on the web (and used Adafruit_BBIO library), I'm trying to make my servo work, e.g. turn 0, 90, 180 etc so here's what I'm doing:
echo am33xx_pwm > /sys/devices/bone_capemgr.8/slots
echo bone_pwm_P8_13 > /sys/devices/bone_capemgr.8/slots
echo 20000000 > /sys/devices/ocp.2/pwm_test_P8_13.15/period (this is 50Hz,also tried 60Hz)
echo 10000000 > /sys/devices/ocp.2/pwm_test_P8_13.15/duty
echo 1 > /sys/devices/ocp.2/pwm_test_P8_13.15/run
Doing the above the servo spins CCW with no stop. I can read 50Hz (60Hz) and 1.66V and even tried to use level shifter so I get ~ 2.5V
I don't know what I'm doing wronge (if I am) or am I missing something?

I also struggled to get a servo working with the Beaglebone Black.
Ultimately, I was able to get good results by exactly following this tutorial: http://learn.adafruit.com/controlling-a-servo-with-a-beaglebone-black?view=all
As I understand it, the most recent versions of the Adafruit_BBIO library handle the pin muxing stuff completely, so your only interface to the BBB can be through a Python script, rather than having to do the command line stuff in your question.
The Adafruit_BBIO library has changed significantly in the last 30 days, so it's worth doing these steps in order:
reboot BBB
run pip install Adafruit_BBIO --upgrade
Try a simple Python script like the one in the tutorial from Adafruit.
I hope this helps!
Update in response to poster's comment:
Hmmm, sorry to hear that my steps didn't work! If your code is resulting in 13% duty cycle at 50 or 60Hz, that makes me think the code is fine, and the servo is having trouble.
I know you've probably checked it a dozen times, but is the 5v you're sending to the servo checking out? As in, is it coming from P9_5 or P9_6, which are from the high-current 5v supply?
Also, re-reading your question, you say the servo keeps spinning CCW - if it doesn't reach a limit and stop moving at some point, there's your problem: continuous-rotation servos aren't able to reach specific set points because they lack the feedback system that 0-180 servos have...

the voltage for the pinuots is 3.3v (except ADC 0-1.8V range (do not exceed!) ) not 5v, so is correct read 1.66v with duty cycle of 50%.

Valid pulse width for "Tower Pro sg90" is 500-2400 µs, so valid values for "duty" are 500000-2400000.
This should turn your servo in CW direction:
// On my BBB, polarity is inverted by default
echo 0 > /sys/devices/ocp.2/pwm_test_P8_13.15/polarity
echo 20000000 > /sys/devices/ocp.2/pwm_test_P8_13.15/period
echo 500000 > /sys/devices/ocp.2/pwm_test_P8_13.15/duty
echo 1 > /sys/devices/ocp.2/pwm_test_P8_13.15/run

Related

Beaglebone black GPIO registers not changing voltage on value change

I'm trying to turn on and off the GPIO headers on the beaglebone, but i'm unable to get the physical pins to switch from high to low and vice versa. Ive written some code within my application to do this but even when I change the values in the command line I have the same issues.
Firstly, all of the pins I want to use have been correctly exported. For this example lets focus on GPIO 117. I'm able to change into /sys/class/gpio/gpio117 and when I run cat value, its in line with what I expected from my program. When I run echo 0 > value it changes to a zero and when I run echo 1 > value its a 1. Everything as expected. When I go to measure the voltage on that pin, it is always high, independent of the value.
Am I missing something here?
GPIO 117 is gpio3_21 on the "MCSAP0_AHCLKX" pin. So it is probably used by some audio device, probably HDMI. You can disable that by adding disable_uboot_overlay_audio=1 to your /boot/uEnv.txt file, see https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Disable_on-board_devices

GPIO in IO expansion board for Edison from DFROBOT

I have been using Intel Edison Module for my project along with this IO expansion Board from DFRobot.
But I came across a problem when dealing with the GPIOs: the output level seems to be quite unstable compared with the Arduino-Compatible Board.
Here is what I did to use DIO7 as output for both IO borads (called X-board and Arduino-board):
According to this document, for the Arduino-borad, I first set an internal GPIO 255 to high so I can use GPIO48 (mapped to DIO7) as an output. Then I set GPIO 48 to high or low. Everything turns out OK.
echo 255 > /sys/class/gpio/export
echo 48> /sys/class/gpio/export
echo high > /sys/class/gpio/gpio255/direction
echo high or low > /sys/class/gpio/gpio48/direction
On the X-board, the procedure is quite straightforward. I set GPIO 48 to high or low directly.
echo 48> /sys/class/gpio/export
echo high or low > /sys/class/gpio/gpio48/direction
But when I monitor the voltage using an oscilloscope, the pin level on the Arduino-board is quite stable and fluctuates in a small range (10mV) while the one on X-board vibrates in 20MHz between 1-5V (sometimes 0-3V and sometimes stable), which is unacceptable.
I also try using mraa, but also no luck.
Does anybody know where is the problem or what have I missed? Any comment or suggestion will be appreciated.

Beaglebone Black Custom Audio Cape DMA/IRQ trouble

I'm running a BBB straight out of the box running debian. Kernel version is 3.8.13-bone-47.
I'm working with a cape that is very similar to the one here. The difference is that I'm using a TLV320AIC3106 instead of the AIC3104, and I only have enabled the audio out, I'm not interested in recording audio in this application.
My pinout for my application is identical to the cape in the link above.
I've followed the link here to get the cape up and running. Everything that I have matches the output of the tutorial up until I try and play a sample wave file.
When I play a sample wave file, I get the following message: aplay: pcm_write:1710: write error: Input/output error
Running dmesg gives me ALSA sound/core/pcm_lib.c:1010 playback write error (DMA or IRQ trouble?)
Where I'm having trouble is I don't understand how the DMA is coming in to play. Is this a DMA problem? Is it a symptom of something else going wrong like my I2C? Am I missing a configuration somewhere else?
Any thoughts on how to track this down are appreciated.
I realize it has been covered in multiple places before, but it can never be stressed enough. Make sure that when you're sending out information, make sure it goes to the right address over the I2C. I figured out this morning that the audio codec was at address 0x1B, while the driver was addressed to 0x18. Small but critical difference.
The easy fix is to edit the BB-BONE-AUDI-02-00A0.dts file.
Edit line 65 to <0x1B>. Re-compile using the line: dtc -O dtb -o BB-BONE-AUDI-02-00A0.dtbo -b 0 -# BB-BONE-AUDI-02-00A0.dts
move the generated file to the /lib/firmware directory
Insert it using echo BB-BONE-AUDI-02 > /sys/devices/bone_capemgr*/slots
After applying this simple fix it seems to work. I can't say for certain because I have to get the audio amplifier circuit up and running still. At least aplay will play the file without crashing out on me, which is a start.

(How) Can I get a stream of all sounds recorded from the microphone that my computer did not produce? (using PulseAudio or something else)

I've been playing around with some speech-to-text and text-to-speech systems, and am running into the problem that when the computer makes sounds that it can recognize, it starts taking commands from itself. To avoid this, I'd like a stream of all sounds picked up by the microphone that were not produced by the computer itself.
I see that PulseAudio has an echo cancellation module, but so far I have been unable to distinguish between its output and the raw microphone output: it still contains all the sounds picked up by the microphone that came from the computer speakers. I wonder if the default echo canceller is doing the opposite of what I want (i.e., it removes sounds heard by the microphone from being sent to the speakers).
Any idea how I can do this (preferably with pacmd)? I have thoroughly confused myself trying to specify non-default sources for the echo canceller, and have wandered into loopback modules and other things that are probably irrelevant. I know very little about PulseAudio, haven't found a good introduction to it (I've looked through much of the PulseAudio documentation but didn't see anything relevant), and might just be missing something simple. I feel frustrated that echo cancellation apparently doesn't work, I can't find documentation on it, and I can't find examples of it working from other people.
Thanks in advance for the help!
Other details that might be relevant: I'm running Ubuntu Saucy on a Lenovo Thinkpad T410. I'm using the built-in microphone and speakers (so, I'm pretty sure they're using the same sound card and I won't have clock drift issues). My actual application gets its sound through GStreamer, but GStreamer gets it from PulseAudio, and I don't think GStreamer itself has AEC capabilities. If there's a different way of doing this, I'd gladly switch to that.
Ah, I've got it! Merely loading the echo cancellation plugin isn't enough; you then need to start using it. In particular, it will only cancel echos of sounds passed into it, and if no sounds go through it, nothing will be cancelled. So, open /etc/pulse/default.pa and add the line
load-module module-echo-cancel
towards the bottom (I put it right after the line that loads module-filter-apply). Then, restart the PulseAudio daemon by running (as a non-root user) pulseaudio -k. Next, run pacmd to get a command line interface to PulseAudio, and give it the commands list-sources and list-sinks. Note the indices of the echo canceller in the responses. Edit /etc/pulse/default.pa again, and uncomment the two lines at the end about set-default, replacing the words input and output with the indices of the echo canceller's source and sink. Finally, restart PulseAudio again with pulseaudio -k (again, run as a non-root user).
Now, by default all sounds to be output get sent through the echo canceller before heading to the speakers, and all sounds to be input get pulled from the echo canceller after coming in through the microphone, and things actually work. You can verify that it's working by running pavucontrol and looking at the sound levels on the Input Devices screen (try playing some music and speaking, and note that the echo cancelled input shows normal sound levels when you speak but very low levels (verging on nothing) when you're silent but the music is playing).
This answer mostly comes from this post, which I wish I'd found weeks ago.

Beaglebone gpio input not working

I am using beaglebone to access digital input from specific pin using sysfs interface. And I can change the output states but not the input :(. What I did is, I have two pins pinA and pinB. pinA I made it output and pinB I made input. Connected pinA to pinB. Configured pinA as output pin by sending out to direction attribute in sysfs and pinB as input by passing in. And I changed value of PinA to 1 and it is giving 1 as output (I tested using LED). But when I read the value of PinB it is giving 0 only, even I pass 0 to value of pinA. what may be the reason ?
Thank you :)
As I understood, the steps you followed:
echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad6
echo 38 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio38/direction
cat /sys/class/gpio/gpio38/value
I also did the same mistake and it took me hours, but the answer was simple: The first line starting with "echo 7" is the problem. Look at the muxing bits:
Bit 5: 1 - Input, 0 - Output
Bit 4: 1 - Pull up, 0 - Pull down
Bit 3: 1 - Pull disabled, 0 - Pull enabled
Bit 2 \
Bit 1 |- Mode
Bit 0 /
You were entering echo 7 which is --> 0 0 0111 and it means: bit 0,1 and 2 is 1, so the mode is set. No problem. However you just forgot to set whether it's an input or output. And it should be like this:
echo 0x27 > /sys/kernel/debug/omap_mux/gpmc_ad6
your bits are now: 1 0 0111 binary which is 0x27 (hex).
When you write "cat /sys/class/gpio/gpio38/value" while giving input, you can see a wonderful 1 :) I’m sure you will be very happy as much as I was :)
Also, one more thing, you are right for Analog input about 1.8V, but GPIO operates with 3.3v.
Several possible causes:
1) Did you set the IO direction of the input pin?
eg. echo "in" > /sys/class/gpio/gpioN/direction
2) (less likely) Is the GPIO pin you're using as an input multiplexed as a GPIO line and in the right direction? Most of the GPIO pins on the OMAP SoCs are multi-function. You're kernel might have set it for an alternate function.
You can check it with:
cat /sys/kernel/debug/omap_mux/board/core
Which dumps the configurations of all IO pins. The output looks like this:
OMAP4_MUX(CSI22_DY1, OMAP_PIN_INPUT | OMAP_MUX_MODE0),
/* gpio_81 */
OMAP4_MUX(CAM_SHUTTER, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
OMAP4_MUX(CAM_STROBE, OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
/* gpio_83 */
In this case, CAM_SHUTTER is set an output, and routed as to the GPIO module (OMAP_MUX_MODE3)
[Caveat: this is from my OMAP4 board - without having the OMAP3 data sheet to hand - there will be a fair amount of similarity]
You can't change this through sysfs - instead you'll need to modify either your kernel (or possibly boot-loader if the kernel uses the configuration it set up).
In the board-file for your system - which I think in your case will be in <linux_source_root>/arch/arm/mach-omap2/board-omap3beagle.c - you'll find a initialiser for the MUX table. You will need the board's schematics, the kernel source tree and the SoC data sheet to get between the primary function name of the pin (in my example above CAM_SHUTTER) and a GPIO number.
3) I was a bit confused by even I pass 0 to value of pinA - I wonder whether you meant that? This does however point to another thing to watch for - there is the programmable pull-up or -down on each IO pin. These are set with the MUX settings. There may conceivably be an external one as well - again you'll need the schematics to be sure.
Yes. The internal pull up and down is configured in the same register as the mux-mode - so it might be that you can configure this in the same way you're setting the mux-mode. Get the AM335x TRM (for OMAP4 the chapter is called Control Module).
In terns of the kernel, look in <linux_source_root>/arch/arm/mach-omap2/mux.h where a bunch of macros are defined
As an example for use I have in my board file:
/* PIC -> OMAP4 interrupt line 2 - GPIO81 */
OMAP4_MUX(CAM_SHUTTER, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
and
OMAP4_MUX(GPMC_AD11, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
From memory you get a choice of either a pull-up or pull-down but can't select neither.

Resources