Replacing Robotis robot controllers with BBB

Greetings all,

I’ll apologize for the big lead up, I just want everyone to know where I’m coming from. I also apologize if I posted this to the wrong place or reposted it. I’m new here and still finding my way around.

I am considering getting a BBB to use with my Robotis robot kit to replace the CM-5 and CM-530 I’ve been using, and was hoping people here could give me help/advice/guidance, or direct me to those who can, as I have a million questions. I will start to list them here. Any help greatly appreciated in advance.

I’ve already written firmware for both the CM-5 (which is Atmega128 powered) and the CM-530 (which uses an STM32F103, an ARM Cortex M3), You can see the source for these here: http://sourceforge.net/projects/bioloidfirmware/ Obviously these are bare metal firmware given that the extremely limited platform in both cases couldn’t practically support an OS. I would like to port my code to the BBB. I want to stick with the bare metal approach, so I can go real time without having to use a patch for the OS or Xenomai, and since I won’t be interested in a good part of the functionality of the board initially (also I’m kind of a big Linux noob). I have already downloaded StarterWare and started poking around. The big draw for me to BBB is the processor clock speed (the CM-5 is just 16Mhz, the CM-530 not much better at 72), the huge memory (for the controllers I’m using now, we’re measuring in Kb), and the huge number for GPIOs (the CM-5 has none, the CM-530 only has a few). So here are some of my initial questions:

•Is anything special required to use the full 512MB memory? In other words, can I directly address all the available memory without having to go through any special procedures? Could I theoretically declare a really big structure (iike a MB or 2) or array and be able to handle it in code like I always have?
•With the code I’ve written thus far, the servos are updated 128 times a second. I have everything for doing that interrupt driven. I have a timer fire an interrupt every 8ms that calculates the next servo target positions and creates a packet to put in a buffer that feeds the shift register of the serial bus. The serial bus is also interrupt driven. When the buffer is loaded, an interrupt is enabled that fires whenever the shift register is empty. Every time it fires, it loads the next byte from the buffer. If the buffer is empty, it disables the interrupt. Receiving bytes is handled similarly, firing an interrupt every time a byte is received to put it in a buffer and empty the shift register. This allows the packets to be consumed as quickly as the 1Mb serial bus can consume them. Could I do something comparable on the BBB?
•My third, and heaviest question, is one of the main motivators for considering the BBB (and moving away from the above mention controllers). I would like to get into vision processing, so I would like to hook a camera (maybe two) to the BBB. I don’t want to use the camera cape (since I want to be able to position the camera somewhere else on the robot). Could I use something like the OV7670 hooked up to some GPIO pins? I was thinking something along the lines of having one pin output a clock to the camera (along with a pin for power and ground), and then have an input pin for the HREF, VSYNC, and pixel clock, and have the pixel clock pin set to fire an interrupt that would read the input pins that D0-D7 from the OV7670 are connected to and push them into a big buffer in memory. I figure for a 640 x 480 RGB565 image at 15 FPS, it would be about 9MB a second, and even if every byte was taking 20 to 30 clock cycles to handle (I think each interrupt could be handled much more quickly than this), it would only eat up at most 200Mhz a second (I’ve seen some posts talking about using the PRU for doing this). Does this sound totally off the wall? What would I need to interface the pins from the camera to the BBB GPIO pins?

I apologize for the long windedness of this. Like I said, I’m not really sure even where to start, or how applicable what little experience with ARM I already have is to this. Again, any help appreciated!

Hi,

The servo control sounds like a job for the PRU. PRU I/O is also suitable for interfacing OV7670. Here is a rough but working example for Beaglebone White: https://github.com/dinuxbg/pru-gcc-examples/tree/master/ov7670-cam/pru . Note that the example loader uses Linux and uio_pruss driver instead of Starterware.

Regards,
Dimitar

понеделник, 27 април 2015 г., 16:28:40 UTC+3, Bill M написа:

Greetings Dimitar,

I can’t thank you enough for the direction (I was afraid no one would want to slog through all that). I’m also interested in the hardware part of it. Are there any schematics for interfacing the camera to the board (will I need caps, resistors, voltage translations)? The few I have found online aren’t completely clear. I may still go the OS route if the learning curve isn’t too steep. I would still love to learn how to handle the PRU stuff in bare metal, though, so I need to get busier with the Starterware. Again, thanks for the help!

If you download the above project you’ll find:
README.md - general notes on the OV7670 example
ov7670-cam/pru-ov7670-cape/kicad/ - KiCad schematic and PCB design
ov7670-cam/pru-ov7670-cape/releases/ - PDF schematic and gerbers

I did not put buffers because straight connection works fine for me. But for any semi-serous use you should put buffers between the OV7670 (2.7V) and Beaglebone (3.3V). That said, the connection is straightforward:

lcd_data0.pr1_pru1_pru_r30_0 <-> do not connect
lcd_data1.pr1_pru1_pru_r30_1 <-> XCLK
lcd_data2.pr1_pru1_pru_r31_2 <-> D0
lcd_data2.pr1_pru1_pru_r31_3 <-> D1
lcd_data3.pr1_pru1_pru_r31_4 <-> D2
lcd_data4.pr1_pru1_pru_r31_5 <-> D3
lcd_data5.pr1_pru1_pru_r31_6 <-> D4
lcd_data6.pr1_pru1_pru_r31_7 <-> D5
lcd_vsync.pr1_pru1_pru_r31_8 <-> D6
lcd_hsync.pr1_pru1_pru_r31_9 <-> D7
lcd_pclk.pr1_pru1_pru_r31_10 <-> HREF
lcd_ac_bias_en.pr1_pru1_pru_r31_11 <-> VSYNC
uart1_rxd.pr1_pru1_pru_r31_16 <-> PCLK
gpmc_advn_ale.gpio2_2 <-> CAM_RESET

Regards,
Dimitar

сряда, 29 април 2015 г., 19:36:33 UTC+3, Bill M написа:

Greetings

I am looking at robotic control systems for something I wish to fabricate.

Downloaded the files listed earlier and I can see that they are programs.

Being a non programmer I may be missing something but I’m not seeing anything

about the hardware used for control and the software looks a little compact to be a
complete control system.

Am I wrong in this assessment? If so - - - what am I missing?

Are there other blogs or websites where I can find information on robotic

control systems (hardware AND software)?

I haven’t been able to find too much information that isn’t proprietary for hardware

and precious little on software.

Thanking you for listen and any pointers and/or information that you may have!

Dee

Hi,

Thanks for taking a look at my code!

The software I’ve written is not meant to be a comprehensive software package. There is a folder each for the CM-5 controller and the CM-530 controller. When these are compiled and uploaded to the respective controller, then when the controller boots up, it awaits a command over the serial port or for a button press on the controller, and then performs one of the motion pages (that have already been loaded into the controller memory with the Robotis software). There is also a folder for the Android project. This project is meant to be installed on an Android device (I’m using an old Motorola Blur) with Bluetooth capability, and when one of the buttons is pressed on the interface, it sends a command to the Bluetooth on the CM-5 or CM-530 and the controller executes a motion page.

The CM5/CM530 controller software only implements serial communication with the controller, serial communication to the servos, reading and writing motion pages in memory, and updating the servo position information in memory 128 times a second and sending it to the servos.

I agree that it is difficult to find anything that really walks you through the hardware and software from start to finish, and can’t really easily tell you where to start. It may help if you give us an idea of what you had in mind for your project. I’ve decided to go in the direction of BeagleBone because it seems like the hardware is well documented and the processor manufacturer does a good job of providing documentation (though not for beginners) and examples. I had considered Raspberry Pi, but from what I’ve read, the manufacturer of the processor for that (Broadcomm) is very tight-lipped with their documentation. The Arduino and AVR communities also appear to have a lot of documentation, examples, support, and people willing to provide advice, as well as free software to get you started. TI (the maker of the BeagleBone processor) also have some free software available.

Hope this helps.

Hi Dimitar,

This is perfect! Thanks again for all the info. I’ll post back with my experiences once I have the equipment and get it going. You rock!

Yes it does. Every snippet of information gets me closer to my goal!!

Some background - - - I am a machinist by trade and am trying to create a
robot(s) to do some highly repetitive functions that I don't want to do.
These functions are quite simple but need to be done with a reasonable
accuracy and in a short period of time.

Think a rotary carousel - -
1. robot arm #1 most to a taught spot and function one happens
2. arm #1 function 2 happens
3. robot arm #2 lifts two items presented at points a and b to taught spots.
4. robot arm #2 lifts item b to height c, tension a is held on the cord
(strap)
5. robot arm #3 sprays amount a of solution #1 to points a and b

I am replicating human actions but don't want to need the human.
Sorry good labor that is conscientious AND reliable and can work 7 days a
week over 18 hours a day is NOT easy to find so I would like to use robotic
without paying enormous costs for the robots. (Basic robot is actually not
that complicated its the motion controls that have me baffled at this time.

TIA

Dee

Hi Dimitar,

I wanted to thank you again. With your advice and help, I was able to get the OV7670 camera working with the BBB. I borrowed some of the code from your project, and got everything working bare metal. It isn’t pretty, but it works. I posted about the results at https://groups.google.com/forum/#!topic/beagleboard/CU-FlZDoOt8 . Again, Thanks for all of your help!

Greetings Dimitar,

I was wondering if you could offer me some more guidance? I managed to get an OV7670 working with the PRU (I’m using PRU1), but I have noticed an issue. If the VSYNC, HREF, PCLK, and XCLK wires are more than 4 inches long, I get some incomplete or corrupted scan lines. Shorter than 4 inches, the picture is perfect. Can you tell me how long are the wires you are using? Any idea how I can overcome this limitation? Any help appreciated!

Hi,

For prototyping I used 4inch cables, dispersed as far apart from each other as possible. I had issues due to crosstalk between the wires.

You could try using a ribbon cable where every second wire is connected to ground (akin to 80-wire 40-pin IDE cables). Try to keep all wire lengths roughly the same.

Regards,
Dimitar

четвъртък, 9 юли 2015 г., 3:42:44 UTC+3, Bill M написа:

Hi Dimitar, Thanks for the suggestion. It looks like crosstalk was/is the issue, but I was thinking it was just the timing wires doing it to one another. It turns out it is the parallel pixel lines that are doing it to the timing wires. I moved them away from the timing lines, and the picture cleared up, even with 8 inch lines. Thanks again for all of your help!

Greetings Dimitar,

Sorry to bother you again. Were you able to get the I2C working with the OV7670? I have it wired up as you do and am trying to read it in Debian using i2cdetect. Should i2cdetect be able to read the SCCB bus? Any help appreciated.

Thanks,
Bill

Oh, but I don’t have the PWDN and RESET pins on the OV7670 connected.

Yes, i2cdetect should detect the camera. The C code in host/ov7670-i2c.c is tested and works.

But there are important prerequisites for the OV7670 I2C communication:

  • Ensure XCLK is running.
  • Pulse the RESET line and leave it set to VCC.
  • Either leave PWDN Not Connected (it has a built-in pull-down), or connect to GCC.

Regards,
Dimitar

събота, 1 август 2015 г., 23:44:35 UTC+3, Bill M написа:

Thanks a million Dimitar! You are, as always, awesome. That did the trick. The only problem I’m having now is with the color from the modules, it is practically non-existent. I have tweaked various registers, without much success (I’ve gotten a bit of orange for things that are bright red, but that is about it). I know my code is working correctly, because I also bought an OV7675 module and it is producing color perfectly. Did you run into any of this? I bought a 7670 from three different suppliers, and they all suffer the same washed-out color issue. Thanks again!

For comparison I’ve attached an image shot with my OV7670. It is out of focus and colors are far from perfect, but at least they are there.

I used to have many issues with image quality until I started using the register settings from the linux kernel driver (see host/ov7670-defs.c). Per the source comments, these settings have been reccomended by OmniVision.

Regards,
Dimitar

вторник, 4 август 2015 г., 16:46:55 UTC+3, Bill M написа:

out2.png

I didn’t get quite the same effect…

I’m pumping the values to the camera from the command line with this script (of course I’ll understand if you don’t want dig through it. my eyes glazed over putting it together…):

i2cset -f -y 0x01 0x21 0x11 0x01
i2cset -f -y 0x01 0x21 0x3A 0x04
i2cset -f -y 0x01 0x21 0x12 0x00

echo set hardware window

i2cset -f -y 0x01 0x21 0x17 0x13
i2cset -f -y 0x01 0x21 0x18 0x01
i2cset -f -y 0x01 0x21 0x32 0xB6
i2cset -f -y 0x01 0x21 0x19 0x02
i2cset -f -y 0x01 0x21 0x1A 0x7A
i2cset -f -y 0x01 0x21 0x03 0x0A
i2cset -f -y 0x01 0x21 0x0C 0x00
i2cset -f -y 0x01 0x21 0x3E 0x00

echo Mystery scaling numbers

i2cset -f -y 0x01 0x21 0x70 0x3A
i2cset -f -y 0x01 0x21 0x71 0x35
i2cset -f -y 0x01 0x21 0x72 0x11
i2cset -f -y 0x01 0x21 0x73 0xF0
i2cset -f -y 0x01 0x21 0xA2 0x02
i2cset -f -y 0x01 0x21 0x15 0x00

echo Gamma values

i2cset -f -y 0x01 0x21 0x7A 0x20
i2cset -f -y 0x01 0x21 0x7B 0x10
i2cset -f -y 0x01 0x21 0x7C 0x1E
i2cset -f -y 0x01 0x21 0x7D 0x35
i2cset -f -y 0x01 0x21 0x7E 0x5A
i2cset -f -y 0x01 0x21 0x7F 0x69
i2cset -f -y 0x01 0x21 0x80 0x76
i2cset -f -y 0x01 0x21 0x81 0x80
i2cset -f -y 0x01 0x21 0x82 0x88
i2cset -f -y 0x01 0x21 0x83 0x8f
i2cset -f -y 0x01 0x21 0x84 0x96
i2cset -f -y 0x01 0x21 0x85 0xA3
i2cset -f -y 0x01 0x21 0x86 0xAF
i2cset -f -y 0x01 0x21 0x87 0xC4
i2cset -f -y 0x01 0x21 0x88 0xD7
i2cset -f -y 0x01 0x21 0x89 0xE8

echo AGC and AEC parameters

i2cset -f -y 0x01 0x21 0x13 0xE0
i2cset -f -y 0x01 0x21 0x00 0x00
i2cset -f -y 0x01 0x21 0x10 0x00
i2cset -f -y 0x01 0x21 0x0D 0x40
i2cset -f -y 0x01 0x21 0x14 0x18
i2cset -f -y 0x01 0x21 0xA5 0x05
i2cset -f -y 0x01 0x21 0xAB 0x07
i2cset -f -y 0x01 0x21 0x24 0x95
i2cset -f -y 0x01 0x21 0x25 0x33
i2cset -f -y 0x01 0x21 0x26 0xE3
i2cset -f -y 0x01 0x21 0x9F 0x78
i2cset -f -y 0x01 0x21 0xA0 0x68
i2cset -f -y 0x01 0x21 0xA1 0x03
i2cset -f -y 0x01 0x21 0xA6 0xD8
i2cset -f -y 0x01 0x21 0xA7 0xD8
i2cset -f -y 0x01 0x21 0xA8 0xF0
i2cset -f -y 0x01 0x21 0xA9 0x90
i2cset -f -y 0x01 0x21 0xAA 0x94
i2cset -f -y 0x01 0x21 0x13 0xE5

echo Almost all of these are magic reserved values

i2cset -f -y 0x01 0x21 0x0E 0x61
i2cset -f -y 0x01 0x21 0x0F 0x4B
i2cset -f -y 0x01 0x21 0x16 0x02
i2cset -f -y 0x01 0x21 0x1E 0x07
i2cset -f -y 0x01 0x21 0x21 0x02
i2cset -f -y 0x01 0x21 0x22 0x91
i2cset -f -y 0x01 0x21 0x29 0x07
i2cset -f -y 0x01 0x21 0x33 0x0B
i2cset -f -y 0x01 0x21 0x35 0x0B
i2cset -f -y 0x01 0x21 0x37 0x1D
i2cset -f -y 0x01 0x21 0x38 0x71
i2cset -f -y 0x01 0x21 0x39 0x2A
i2cset -f -y 0x01 0x21 0x3C 0x78
i2cset -f -y 0x01 0x21 0x4D 0x40
i2cset -f -y 0x01 0x21 0x4E 0x20
i2cset -f -y 0x01 0x21 0x69 0x00
i2cset -f -y 0x01 0x21 0x6B 0x4A
i2cset -f -y 0x01 0x21 0x74 0x10
i2cset -f -y 0x01 0x21 0x8D 0x4F
i2cset -f -y 0x01 0x21 0x8E 0x00
i2cset -f -y 0x01 0x21 0x8F 0x00
i2cset -f -y 0x01 0x21 0x90 0x00
i2cset -f -y 0x01 0x21 0x91 0x00
i2cset -f -y 0x01 0x21 0x96 0x00
i2cset -f -y 0x01 0x21 0x9A 0x00
i2cset -f -y 0x01 0x21 0xB0 0x84
i2cset -f -y 0x01 0x21 0xB1 0x0C
i2cset -f -y 0x01 0x21 0xB2 0x0E
i2cset -f -y 0x01 0x21 0xB3 0x82
i2cset -f -y 0x01 0x21 0xB8 0x0A

echo More reserved Magic

i2cset -f -y 0x01 0x21 0x43 0x0A
i2cset -f -y 0x01 0x21 0x44 0xF0
i2cset -f -y 0x01 0x21 0x45 0x34
i2cset -f -y 0x01 0x21 0x46 0x58
i2cset -f -y 0x01 0x21 0x47 0x28
i2cset -f -y 0x01 0x21 0x48 0x3A
i2cset -f -y 0x01 0x21 0x59 0x88
i2cset -f -y 0x01 0x21 0x5A 0x88
i2cset -f -y 0x01 0x21 0x5B 0x44
i2cset -f -y 0x01 0x21 0x5C 0x67
i2cset -f -y 0x01 0x21 0x5D 0x49
i2cset -f -y 0x01 0x21 0x5E 0x0E
i2cset -f -y 0x01 0x21 0x6C 0x0A
i2cset -f -y 0x01 0x21 0x6D 0x55
i2cset -f -y 0x01 0x21 0x6E 0x11
i2cset -f -y 0x01 0x21 0x6F 0x9F
i2cset -f -y 0x01 0x21 0x6A 0x40
i2cset -f -y 0x01 0x21 0x01 0x40
i2cset -f -y 0x01 0x21 0x02 0x60
i2cset -f -y 0x01 0x21 0x13 0xE7

echo Matrix coefficients

i2cset -f -y 0x01 0x21 0x4F 0x80
i2cset -f -y 0x01 0x21 0x50 0x80
i2cset -f -y 0x01 0x21 0x51 0x00
i2cset -f -y 0x01 0x21 0x52 0x22
i2cset -f -y 0x01 0x21 0x53 0x5E
i2cset -f -y 0x01 0x21 0x54 0x80
i2cset -f -y 0x01 0x21 0x58 0x9E
i2cset -f -y 0x01 0x21 0x41 0x08
i2cset -f -y 0x01 0x21 0x3F 0x00
i2cset -f -y 0x01 0x21 0x75 0x05
i2cset -f -y 0x01 0x21 0x76 0xE1
i2cset -f -y 0x01 0x21 0x4C 0x00
i2cset -f -y 0x01 0x21 0x77 0x01
i2cset -f -y 0x01 0x21 0x3D 0xC3
i2cset -f -y 0x01 0x21 0x4B 0x09
i2cset -f -y 0x01 0x21 0xC9 0x60
i2cset -f -y 0x01 0x21 0x41 0x38
i2cset -f -y 0x01 0x21 0x56 0x40
i2cset -f -y 0x01 0x21 0x34 0x11
i2cset -f -y 0x01 0x21 0x3B 0x12
i2cset -f -y 0x01 0x21 0xA4 0x88
i2cset -f -y 0x01 0x21 0x96 0x00
i2cset -f -y 0x01 0x21 0x97 0x30
i2cset -f -y 0x01 0x21 0x98 0x20
i2cset -f -y 0x01 0x21 0x99 0x30
i2cset -f -y 0x01 0x21 0x9A 0x84
i2cset -f -y 0x01 0x21 0x9B 0x29
i2cset -f -y 0x01 0x21 0x9C 0x03
i2cset -f -y 0x01 0x21 0x9D 0x4C
i2cset -f -y 0x01 0x21 0x9E 0x3F
i2cset -f -y 0x01 0x21 0x78 0x04

echo Extra weird stuff

i2cset -f -y 0x01 0x21 0x79 0x01
i2cset -f -y 0x01 0x21 0xC8 0xF0
i2cset -f -y 0x01 0x21 0x79 0x0F
i2cset -f -y 0x01 0x21 0xC8 0x00
i2cset -f -y 0x01 0x21 0x79 0x10
i2cset -f -y 0x01 0x21 0xC8 0x7E
i2cset -f -y 0x01 0x21 0x79 0x0A
i2cset -f -y 0x01 0x21 0xC8 0x80
i2cset -f -y 0x01 0x21 0x79 0x0B
i2cset -f -y 0x01 0x21 0xC8 0x01
i2cset -f -y 0x01 0x21 0x79 0x0C
i2cset -f -y 0x01 0x21 0xC8 0x0F
i2cset -f -y 0x01 0x21 0x79 0x0D
i2cset -f -y 0x01 0x21 0xC8 0x20
i2cset -f -y 0x01 0x21 0x79 0x09
i2cset -f -y 0x01 0x21 0xC8 0x80
i2cset -f -y 0x01 0x21 0x79 0x02
i2cset -f -y 0x01 0x21 0xC8 0xC0
i2cset -f -y 0x01 0x21 0x79 0x03
i2cset -f -y 0x01 0x21 0xC8 0x40
i2cset -f -y 0x01 0x21 0x79 0x05
i2cset -f -y 0x01 0x21 0xC8 0x30
i2cset -f -y 0x01 0x21 0x79 0x26
i2cset -f -y 0x01 0x21 0xFF 0xFF
echo end

screen.png

Ok, I took out the setting of registers 3A and 3D. I guess it was swapping around my YUV values. After that I found that my reds were blue and my blues were red, so I swapped U and V in my rendering code. This is what it looks like now. A bit better, but still a bit washed out. The pens should be blue, red, and green from left to right.

better.png