Legacy Forum: Preserving Nearly 20 Years of Community History - A Time Capsule of Discussions, Memories, and Shared Experiences.

API-compatible USB2Dynamixel-like wireless solution?

Bioloid robot kit from Korean company Robotis; CM5 controller block, AX12 servos..
12 postsPage 1 of 1
12 postsPage 1 of 1

API-compatible USB2Dynamixel-like wireless solution?

Post by Miamicanes » Wed Dec 10, 2008 8:30 pm

Post by Miamicanes
Wed Dec 10, 2008 8:30 pm

Is there any way to use a device like USB2Dynamixel with some kind of wireless link that transparently uses the CM5 as a power and/or serial host at the robot end, and is compatible with the official/de-facto API at the PC end?

For example, at the robot end, take a CM5, install Robotis' Zigbee interface inside, and reflash the CM5's AVR to act like a transparent serial host.

At the PC end, somehow connect a USB2Dynamixel (or conceptually similar device) to a Zigbee transceiver (possibly through additional glue circuitry).

The desired outcome would be the ability to use the API to write apps that behaved as though a USB2Dynamixel were directly connected to the robot's AX-12 bus, but in reality uses the radio to relay serial commands to and from the CM5.

I'm kind of frustrated. I've had my Bioloid for almost 2 years now, but every time I get back into it, I run into the problem of wanting to write "real" programs to control it that need a PC (ok, I admit it... I'm a hardcore Java guy), but all of the solutions I've seen so far for doing it have been ugly, awkward, inconvenient, or some combination of all the above. If I could just wirelessly offload the intelligence to a nearby PC host, but otherwise take advantage of the CM5 as a power supply and local communication host, I'd be delighted. Is there any "good" way to actually do something like this right now, with hardware I can buy ready-made? Or at least buy as a single kit and spare myself the cost of having to buy a one-off circuit board for some outrageous price, plus a half-dozen parts from Digikey with a shipping charge that redoubles it again?

Thanks! Christmas is coming, and I have about a week to put in my final requests before I'll have a week to play with my bot daily and rediscover it for the third time :-)
Is there any way to use a device like USB2Dynamixel with some kind of wireless link that transparently uses the CM5 as a power and/or serial host at the robot end, and is compatible with the official/de-facto API at the PC end?

For example, at the robot end, take a CM5, install Robotis' Zigbee interface inside, and reflash the CM5's AVR to act like a transparent serial host.

At the PC end, somehow connect a USB2Dynamixel (or conceptually similar device) to a Zigbee transceiver (possibly through additional glue circuitry).

The desired outcome would be the ability to use the API to write apps that behaved as though a USB2Dynamixel were directly connected to the robot's AX-12 bus, but in reality uses the radio to relay serial commands to and from the CM5.

I'm kind of frustrated. I've had my Bioloid for almost 2 years now, but every time I get back into it, I run into the problem of wanting to write "real" programs to control it that need a PC (ok, I admit it... I'm a hardcore Java guy), but all of the solutions I've seen so far for doing it have been ugly, awkward, inconvenient, or some combination of all the above. If I could just wirelessly offload the intelligence to a nearby PC host, but otherwise take advantage of the CM5 as a power supply and local communication host, I'd be delighted. Is there any "good" way to actually do something like this right now, with hardware I can buy ready-made? Or at least buy as a single kit and spare myself the cost of having to buy a one-off circuit board for some outrageous price, plus a half-dozen parts from Digikey with a shipping charge that redoubles it again?

Thanks! Christmas is coming, and I have about a week to put in my final requests before I'll have a week to play with my bot daily and rediscover it for the third time :-)
Miamicanes
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 28
Joined: Thu Dec 28, 2006 1:00 am

Post by siempre.aprendiendo » Wed Dec 10, 2008 9:10 pm

Post by siempre.aprendiendo
Wed Dec 10, 2008 9:10 pm

I use a simple solution to wireless:
CM-5 <=> RS232toBluetooth <=> PC. With the Toss mode.

The RS232 to BT I use is BlueConsole, it's not on sale now, but there are others :)

I have the USB2Dynamixel too, but I think that is more difficult to find a USB host to Bluetooth product.
I use a simple solution to wireless:
CM-5 <=> RS232toBluetooth <=> PC. With the Toss mode.

The RS232 to BT I use is BlueConsole, it's not on sale now, but there are others :)

I have the USB2Dynamixel too, but I think that is more difficult to find a USB host to Bluetooth product.
siempre.aprendiendo
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 559
Joined: Wed Aug 08, 2007 9:13 pm
Location: Barcelona

Post by limor » Wed Dec 10, 2008 10:29 pm

Post by limor
Wed Dec 10, 2008 10:29 pm

Solution1
----------
The first solution is to use the zig100 and zig2serial to communicate with the CM5 and write some "glue code" on the CM5 to convert back and forth between the slow zigbee and the fast Dynamixel serial 1mbps bus.

On the PC you can write in Java to your heat's delight using the COM or /dev/tty serial port. You basically write a library of calls to get and send commands to the CM5 using some better compressed protocol than the Dynamixel. One simple efficiency is that the CM5 will send you all the servo positions "relative" to the previous values one, and all in one go.. total of probably 4 bits per servo and without latency compared with 8 bytes per servo using Dynamixel.

To program the CM5 you use one of the libraries available here on the forum that have already implemented the Dynamixel bus protocol. You need to write a protocol convertor between the Dynamixel protocol and your very own efficient protocol.

If you do this over Christmas and share the results you will become very popular amongst all Bioloid owners.

although no one reported it yet, the newer Sparkfun bluesmirf bluetooth modules are V2.0 compatible which means they may be able to keep up with the speed of the Dynamixel bus. so you can just mirror the bytes coming back and forth between the two serial ports. connecting the bluesmirf to CM5 has been documented here extensively.

Solution2
-----------
Get a Gumstix with bluetooth and connect it to the Dynamixel bus as described here many times before. Then run your JVM on the Gumstix and talk to the Dynamixel bus via the USB interface, using the Dynamixel software written in Java.
This solution is more complicated because it involves "glue hardware" with voltage regulator to power the gumstix from the CM5 (or use a second smaller battery for the gumstix). and you also need to code something to the CM5 so that it doesnt act any more as bus master of the Dynamixel.
Solution1
----------
The first solution is to use the zig100 and zig2serial to communicate with the CM5 and write some "glue code" on the CM5 to convert back and forth between the slow zigbee and the fast Dynamixel serial 1mbps bus.

On the PC you can write in Java to your heat's delight using the COM or /dev/tty serial port. You basically write a library of calls to get and send commands to the CM5 using some better compressed protocol than the Dynamixel. One simple efficiency is that the CM5 will send you all the servo positions "relative" to the previous values one, and all in one go.. total of probably 4 bits per servo and without latency compared with 8 bytes per servo using Dynamixel.

To program the CM5 you use one of the libraries available here on the forum that have already implemented the Dynamixel bus protocol. You need to write a protocol convertor between the Dynamixel protocol and your very own efficient protocol.

If you do this over Christmas and share the results you will become very popular amongst all Bioloid owners.

although no one reported it yet, the newer Sparkfun bluesmirf bluetooth modules are V2.0 compatible which means they may be able to keep up with the speed of the Dynamixel bus. so you can just mirror the bytes coming back and forth between the two serial ports. connecting the bluesmirf to CM5 has been documented here extensively.

Solution2
-----------
Get a Gumstix with bluetooth and connect it to the Dynamixel bus as described here many times before. Then run your JVM on the Gumstix and talk to the Dynamixel bus via the USB interface, using the Dynamixel software written in Java.
This solution is more complicated because it involves "glue hardware" with voltage regulator to power the gumstix from the CM5 (or use a second smaller battery for the gumstix). and you also need to code something to the CM5 so that it doesnt act any more as bus master of the Dynamixel.
limor
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1845
Joined: Mon Oct 11, 2004 1:00 am
Location: London, UK

Post by Miamicanes » Thu Dec 11, 2008 1:34 am

Post by Miamicanes
Thu Dec 11, 2008 1:34 am

Hmmm... someone refresh my memory and tell me whether this is correct:

* The CM5 has a Mega128

* The Mega128 has two independent USARTs.

* USART #1 is connected to the AX12 bus

* USART #2 is connected in parallel to both the Bioloid serial cable that gets plugged into the 1/8" jack on the CM5, and pads on the CM5's circuit board intended for use by a Zig100

* There's some straightforward way to flash arbitrary firmware written in AVR Studio onto the CM5's Mega128, and an equally straightforward way to restore it to the "official" firmware if desired.

* The official Bioloid API (specifically, the Java library) works painlessly if you write a Java app on a host PC, and physically connect the host PC to the CM5 via the bundled serial cable... so anything capable of transparently emulating a physical serial cable should, in theory work as well.

One other thing...

Suppose I have a Java app, written using the official API running on a host PC. The host PC is physically connected to the CM5 using the bundled serial cable. Is the API aware of the physical data link's half-duplex nature, and designed to wait after sending a command until the response is received before sending the next command? Or if it somehow has 3 or 4 queued commands, will it blindly spray them at the CM5 one after another, and if the "gateway" app running on the CM5's Mega128 doesn't explicitly stop transmitting and buffer the next command(s) on its own initiative until the response arrives, potentially cause a head-on collision by trying to transmit the next command to the AX12 bus while one or more AX-12s on the bus are simultaneously trying to transmit back the response byte?
Hmmm... someone refresh my memory and tell me whether this is correct:

* The CM5 has a Mega128

* The Mega128 has two independent USARTs.

* USART #1 is connected to the AX12 bus

* USART #2 is connected in parallel to both the Bioloid serial cable that gets plugged into the 1/8" jack on the CM5, and pads on the CM5's circuit board intended for use by a Zig100

* There's some straightforward way to flash arbitrary firmware written in AVR Studio onto the CM5's Mega128, and an equally straightforward way to restore it to the "official" firmware if desired.

* The official Bioloid API (specifically, the Java library) works painlessly if you write a Java app on a host PC, and physically connect the host PC to the CM5 via the bundled serial cable... so anything capable of transparently emulating a physical serial cable should, in theory work as well.

One other thing...

Suppose I have a Java app, written using the official API running on a host PC. The host PC is physically connected to the CM5 using the bundled serial cable. Is the API aware of the physical data link's half-duplex nature, and designed to wait after sending a command until the response is received before sending the next command? Or if it somehow has 3 or 4 queued commands, will it blindly spray them at the CM5 one after another, and if the "gateway" app running on the CM5's Mega128 doesn't explicitly stop transmitting and buffer the next command(s) on its own initiative until the response arrives, potentially cause a head-on collision by trying to transmit the next command to the AX12 bus while one or more AX-12s on the bus are simultaneously trying to transmit back the response byte?
Miamicanes
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 28
Joined: Thu Dec 28, 2006 1:00 am

Post by Tyberius » Thu Dec 11, 2008 2:24 am

Post by Tyberius
Thu Dec 11, 2008 2:24 am

I'm actually working on a wireless drop-in replacement for the CM-5 controller using an Xbee and an Atmega128 (using one of Jon Hyland's projects as the basis). I've been so slammed with work and my RX-64 based bot lately I haven't had a chance to do much more than solder it all together and initially establish communication and control.

This essentially works like a wireless connection to the Dynamixel bus, so you can program in any language that can talk to a serial port and fire commands over the Xbee link to your Dynamixels. PC side I'm just using a USB Explorer from Sparkfun and another Xbee.

I'm getting some weird Dynamixel errors bouncing back, so I need to further troubleshoot this as soon as I get the time, but it is working. Might very well just be data fragments from the wireless connection.

Prototype:

Image

Atmega128 is totally overkill for this, but easy to prototype with.
I'm actually working on a wireless drop-in replacement for the CM-5 controller using an Xbee and an Atmega128 (using one of Jon Hyland's projects as the basis). I've been so slammed with work and my RX-64 based bot lately I haven't had a chance to do much more than solder it all together and initially establish communication and control.

This essentially works like a wireless connection to the Dynamixel bus, so you can program in any language that can talk to a serial port and fire commands over the Xbee link to your Dynamixels. PC side I'm just using a USB Explorer from Sparkfun and another Xbee.

I'm getting some weird Dynamixel errors bouncing back, so I need to further troubleshoot this as soon as I get the time, but it is working. Might very well just be data fragments from the wireless connection.

Prototype:

Image

Atmega128 is totally overkill for this, but easy to prototype with.
Tyberius
Savvy Roboteer
Savvy Roboteer
Posts: 108
Joined: Tue Nov 27, 2007 6:57 pm

Post by Miamicanes » Thu Dec 11, 2008 4:04 am

Post by Miamicanes
Thu Dec 11, 2008 4:04 am

Oooh... I think I just remembered what seemingly fatal problem kicked me in the teeth and killed my controller project dead back in June: battery charging.

From what I remember, the CM5 apparently depends on firmware running on the Mega128 itself to initiate and manage battery charging. The thing is, I wasn't able to find any info anywhere that gave any insight as to whether whatever was responsible for battery charging was part of the CM5's Mega128's bootloader (which I wasn't planning to change in any case), or whether it was an undocumented part of the CM5's Mega128's "normal" firmware (which I was planning to blow away and totally replace with my own.

Does anyone have any insight into what role the Mega128's firmware has in CM5 battery charging, and whether whatever is responsible for managing it is part of the bootloader, or part of the main control program running on the Mega128 itself?

I'd really like to just repurpose the CM5's Mega128 if I can, for the simple reason that it's already there, in a purpose-built enclosure that integrates nicely with the rest of the Bioloid universe. Whenever I end up deviating from the path of repurposing the CM5's Mega128 and integrating whatever I do entirely into the CM5 itself, it seems like I inevitably open up an entire can of worms and new problems to which there really aren't any "nice" solutions (everything from using the CM5 as a powersource without using it as a controller, to figuring out how in god's name a bare circuit board should be somehow integrated into an actual robot). Designing a circuit board? Easy. Getting it into some kind of decent physical enclosure that elegantly integrates with the rest of the Bioloid universe? Um... er... yikes ;-)
Oooh... I think I just remembered what seemingly fatal problem kicked me in the teeth and killed my controller project dead back in June: battery charging.

From what I remember, the CM5 apparently depends on firmware running on the Mega128 itself to initiate and manage battery charging. The thing is, I wasn't able to find any info anywhere that gave any insight as to whether whatever was responsible for battery charging was part of the CM5's Mega128's bootloader (which I wasn't planning to change in any case), or whether it was an undocumented part of the CM5's Mega128's "normal" firmware (which I was planning to blow away and totally replace with my own.

Does anyone have any insight into what role the Mega128's firmware has in CM5 battery charging, and whether whatever is responsible for managing it is part of the bootloader, or part of the main control program running on the Mega128 itself?

I'd really like to just repurpose the CM5's Mega128 if I can, for the simple reason that it's already there, in a purpose-built enclosure that integrates nicely with the rest of the Bioloid universe. Whenever I end up deviating from the path of repurposing the CM5's Mega128 and integrating whatever I do entirely into the CM5 itself, it seems like I inevitably open up an entire can of worms and new problems to which there really aren't any "nice" solutions (everything from using the CM5 as a powersource without using it as a controller, to figuring out how in god's name a bare circuit board should be somehow integrated into an actual robot). Designing a circuit board? Easy. Getting it into some kind of decent physical enclosure that elegantly integrates with the rest of the Bioloid universe? Um... er... yikes ;-)
Miamicanes
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 28
Joined: Thu Dec 28, 2006 1:00 am

Post by Miamicanes » Thu Dec 11, 2008 5:35 am

Post by Miamicanes
Thu Dec 11, 2008 5:35 am

Just to elaborate a bit on what I'm working towards and exploring...

My goal is to write replacement firmware for the CM5's Mega128 that enables it to efficiently and transparently serve as an application-level gateway between a host PC and Dynamixel bus.

The physical layer between the host PC and CM5's Mega128 might be a serial cable, or it might be a high-speed transparently error-correcting wireless link of some kind. I'm leaning heavily towards Zigbee (specifically, a pair of series 2.5 XBee modules),

At the PC end, it should be capable of dealing with a multithreaded Java control app whose threads have no idea what the others are doing, or when they themselves are communicating.

The theory:

AVR microcontrollers have a VERY cool feature: 9-bit serial. It's trivially easy to use... with 9-bit serial enabled, you simply read the ninth bit from the control register before reading the value of the most recently-received byte from the input register, or set the 9th bit's value before writing the next byte you plan to send to the output register. It's incredibly handy, because it gives you a "flag" bit that can be used WITHOUT having to escape, wrap, or otherwise encode 8-bit values being sent as data.

At the PC end, it's a little harder, since no USB-serial adapter I'm aware of directly supports 9-bit data (partly because the abstract Windows serial adapter interface has no concept of 9-bit data). HOWEVER, I've discovered by trial and error that it can be kludged with the SiLabs CP2103's driver. Basically, I determine whether the ninth bit needs to be 0 or 1 before sending each byte, and forcibly change the mode between PARITY_SPACE (all bytes sent with '0' for 9th bit) and PARITY_MARK (all bytes sent with '1' for 9th bit) if necessary. I've heard through the grapevine that at least one driver + Windows-version combination for another chipset (FTDI? Cypress?) has a memory leak, and at least one other insists on trying to do housekeeping every time you try switching between parity modes & kills your performance. In any case, the CP2103 with Vista32 and Gnu RXTX library seems to work fine.

The Workflow:

The gateway (my app running on the CM5's Mega128 that replaces its default firmware) waits until a byte is received via USART1.

The gateway examines the ninth bit of the byte it just received. If the bit is set, it means that the penultimate byte (currently sitting in the buffer) is the final (checksum) byte of a datagram, and upon sending it, it should switch into receive mode and wait to receive however many bytes is indicated by the most recently-received byte's value.

If the bit is clear, and there's no byte currently in the buffer, we just buffer that byte, and wait for the next one after making a note to remind ourselves that there IS a byte buffered.

If the bit is clear, and there IS a byte already in the buffer, we send the byte in the buffer to the Dynamixel bus at 1mbps, then buffer the byte we just received.

The advantage is that our latency and throughput is only slightly less than what we'd get by directly driving the Dynamixel bus from the host PC using a USB2Dynamixel. In fact, if whatever wireless layer we use is faster than 56kbit/sec, it's even faster than what we'd get by directly connecting the PC to the CM5 via serial in "Toss" mode. Since we delay sending each byte to the Dynamixel bus until we know for a fact that there's either one or more remaining data bytes to send after the one currently in the buffer, or until we know for a fact that the byte in the buffer IS the last byte of the datagram, and we know exactly how many bytes to expect in response, the Mega128 can send the byte in the buffer and IMMEDIATELY switch into 'receive' mode.

At the PC end, a singleton instance of a communication class has a synchronized method that takes a datagram as its argument, and returns the response datagram when it arrives. Because it's synchronized and singleton, invidiual Threads can hammer away at it to get their own requests over to the Robot and back without having to worry about what the other threads are up to. If at some point I realize that multiple threads are asking for the same information, I might abstract it a bit further and have proxy objects that make periodic requests (say, to read sensors on the Dynamixel bus), then use the responses to satisfy queries from one or more threads over the next few microseconds, until it makes another query to read the sensors again.

Ideally, I'd like to use something like the XBee series 2.5 at both the CM5 and PC ends, mainly because it seems as though the Zig100 is arbitrarily limited to 56kbit/sec (though that limit MIGHT simply be imposed by assumptions made by Toss mode, and have nothing whatsoever to do with the hardware capabilities of the Zig100 modules themselves... does anybody know?). However, I have to go take another look at someone's pics of the CM5's interior to see how much room I have, because it's been a while since I've directly peered inside ;-)

So... does anyone have any thoughts? See anything blatantly wrong, or that others have tried and already discovered won't work?

As far as I can tell by skimming over the past few months' worth of postings here, nobody has actually tried going as far as repurposing a CM5 to work in a way that should (in theory) be compatible with the hardware, but pretty different from how Robotis itself handles wireless communication between a PC and CM5 (via the USB2Dynamixel and Zig2serial... I just discovered the Zig2serial about 2 hours ago).

As noted in my previous post, however, the 800 pound elephant sitting in the room is the CM5's battery-charging method. If battery charging is NOT handled by the bootloader, and I can't find documentation on how to implement it myself, my plan of blowing the CM5's Mega128's main firmware away and replacing it with my own goes out the window.
Just to elaborate a bit on what I'm working towards and exploring...

My goal is to write replacement firmware for the CM5's Mega128 that enables it to efficiently and transparently serve as an application-level gateway between a host PC and Dynamixel bus.

The physical layer between the host PC and CM5's Mega128 might be a serial cable, or it might be a high-speed transparently error-correcting wireless link of some kind. I'm leaning heavily towards Zigbee (specifically, a pair of series 2.5 XBee modules),

At the PC end, it should be capable of dealing with a multithreaded Java control app whose threads have no idea what the others are doing, or when they themselves are communicating.

The theory:

AVR microcontrollers have a VERY cool feature: 9-bit serial. It's trivially easy to use... with 9-bit serial enabled, you simply read the ninth bit from the control register before reading the value of the most recently-received byte from the input register, or set the 9th bit's value before writing the next byte you plan to send to the output register. It's incredibly handy, because it gives you a "flag" bit that can be used WITHOUT having to escape, wrap, or otherwise encode 8-bit values being sent as data.

At the PC end, it's a little harder, since no USB-serial adapter I'm aware of directly supports 9-bit data (partly because the abstract Windows serial adapter interface has no concept of 9-bit data). HOWEVER, I've discovered by trial and error that it can be kludged with the SiLabs CP2103's driver. Basically, I determine whether the ninth bit needs to be 0 or 1 before sending each byte, and forcibly change the mode between PARITY_SPACE (all bytes sent with '0' for 9th bit) and PARITY_MARK (all bytes sent with '1' for 9th bit) if necessary. I've heard through the grapevine that at least one driver + Windows-version combination for another chipset (FTDI? Cypress?) has a memory leak, and at least one other insists on trying to do housekeeping every time you try switching between parity modes & kills your performance. In any case, the CP2103 with Vista32 and Gnu RXTX library seems to work fine.

The Workflow:

The gateway (my app running on the CM5's Mega128 that replaces its default firmware) waits until a byte is received via USART1.

The gateway examines the ninth bit of the byte it just received. If the bit is set, it means that the penultimate byte (currently sitting in the buffer) is the final (checksum) byte of a datagram, and upon sending it, it should switch into receive mode and wait to receive however many bytes is indicated by the most recently-received byte's value.

If the bit is clear, and there's no byte currently in the buffer, we just buffer that byte, and wait for the next one after making a note to remind ourselves that there IS a byte buffered.

If the bit is clear, and there IS a byte already in the buffer, we send the byte in the buffer to the Dynamixel bus at 1mbps, then buffer the byte we just received.

The advantage is that our latency and throughput is only slightly less than what we'd get by directly driving the Dynamixel bus from the host PC using a USB2Dynamixel. In fact, if whatever wireless layer we use is faster than 56kbit/sec, it's even faster than what we'd get by directly connecting the PC to the CM5 via serial in "Toss" mode. Since we delay sending each byte to the Dynamixel bus until we know for a fact that there's either one or more remaining data bytes to send after the one currently in the buffer, or until we know for a fact that the byte in the buffer IS the last byte of the datagram, and we know exactly how many bytes to expect in response, the Mega128 can send the byte in the buffer and IMMEDIATELY switch into 'receive' mode.

At the PC end, a singleton instance of a communication class has a synchronized method that takes a datagram as its argument, and returns the response datagram when it arrives. Because it's synchronized and singleton, invidiual Threads can hammer away at it to get their own requests over to the Robot and back without having to worry about what the other threads are up to. If at some point I realize that multiple threads are asking for the same information, I might abstract it a bit further and have proxy objects that make periodic requests (say, to read sensors on the Dynamixel bus), then use the responses to satisfy queries from one or more threads over the next few microseconds, until it makes another query to read the sensors again.

Ideally, I'd like to use something like the XBee series 2.5 at both the CM5 and PC ends, mainly because it seems as though the Zig100 is arbitrarily limited to 56kbit/sec (though that limit MIGHT simply be imposed by assumptions made by Toss mode, and have nothing whatsoever to do with the hardware capabilities of the Zig100 modules themselves... does anybody know?). However, I have to go take another look at someone's pics of the CM5's interior to see how much room I have, because it's been a while since I've directly peered inside ;-)

So... does anyone have any thoughts? See anything blatantly wrong, or that others have tried and already discovered won't work?

As far as I can tell by skimming over the past few months' worth of postings here, nobody has actually tried going as far as repurposing a CM5 to work in a way that should (in theory) be compatible with the hardware, but pretty different from how Robotis itself handles wireless communication between a PC and CM5 (via the USB2Dynamixel and Zig2serial... I just discovered the Zig2serial about 2 hours ago).

As noted in my previous post, however, the 800 pound elephant sitting in the room is the CM5's battery-charging method. If battery charging is NOT handled by the bootloader, and I can't find documentation on how to implement it myself, my plan of blowing the CM5's Mega128's main firmware away and replacing it with my own goes out the window.
Miamicanes
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 28
Joined: Thu Dec 28, 2006 1:00 am

Post by i-Bot » Thu Dec 11, 2008 10:26 am

Post by i-Bot
Thu Dec 11, 2008 10:26 am

Isn't Bioloid control http://bioloidcontrol.sourceforge.net/ what you are looking for ?

It repurposes the CM5 and I think now has the battery charge source too.

It uses a message based interface to the PC, which will be much faster and efficient than your character based approach, because wireless, USB and drivers also tend to be message based and have a limited message rate
Isn't Bioloid control http://bioloidcontrol.sourceforge.net/ what you are looking for ?

It repurposes the CM5 and I think now has the battery charge source too.

It uses a message based interface to the PC, which will be much faster and efficient than your character based approach, because wireless, USB and drivers also tend to be message based and have a limited message rate
i-Bot
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am

Post by limor » Thu Dec 11, 2008 11:28 am

Post by limor
Thu Dec 11, 2008 11:28 am

Miamicanes wrote:Hmmm... someone refresh my memory and tell me whether this is correct:

* The CM5 has a Mega128

* The Mega128 has two independent USARTs.

* USART #1 is connected to the AX12 bus

* USART #2 is connected in parallel to both the Bioloid serial cable that gets plugged into the 1/8" jack on the CM5, and pads on the CM5's circuit board intended for use by a Zig100

* There's some straightforward way to flash arbitrary firmware written in AVR Studio onto the CM5's Mega128, and an equally straightforward way to restore it to the "official" firmware if desired.


Right!

Miamicanes wrote:* The official Bioloid API (specifically, the Java library) works painlessly if you write a Java app on a host PC, and physically connect the host PC to the CM5 via the bundled serial cable... so anything capable of transparently emulating a physical serial cable should, in theory work as well.

One other thing...

Suppose I have a Java app, written using the official API running on a host PC. The host PC is physically connected to the CM5 using the bundled serial cable. Is the API aware of the physical data link's half-duplex nature, and designed to wait after sending a command until the response is received before sending the next command? Or if it somehow has 3 or 4 queued commands, will it blindly spray them at the CM5 one after another, and if the "gateway" app running on the CM5's Mega128 doesn't explicitly stop transmitting and buffer the next command(s) on its own initiative until the response arrives, potentially cause a head-on collision by trying to transmit the next command to the AX12 bus while one or more AX-12s on the bus are simultaneously trying to transmit back the response byte?


Please note: The interface with Java support is not for CM5 but for USB2Dynamixel which has USB interface to the PC and connects directly to the servos. (the servos need to be powered by CM5 or with SMPS2Dynamixel)
Miamicanes wrote:Hmmm... someone refresh my memory and tell me whether this is correct:

* The CM5 has a Mega128

* The Mega128 has two independent USARTs.

* USART #1 is connected to the AX12 bus

* USART #2 is connected in parallel to both the Bioloid serial cable that gets plugged into the 1/8" jack on the CM5, and pads on the CM5's circuit board intended for use by a Zig100

* There's some straightforward way to flash arbitrary firmware written in AVR Studio onto the CM5's Mega128, and an equally straightforward way to restore it to the "official" firmware if desired.


Right!

Miamicanes wrote:* The official Bioloid API (specifically, the Java library) works painlessly if you write a Java app on a host PC, and physically connect the host PC to the CM5 via the bundled serial cable... so anything capable of transparently emulating a physical serial cable should, in theory work as well.

One other thing...

Suppose I have a Java app, written using the official API running on a host PC. The host PC is physically connected to the CM5 using the bundled serial cable. Is the API aware of the physical data link's half-duplex nature, and designed to wait after sending a command until the response is received before sending the next command? Or if it somehow has 3 or 4 queued commands, will it blindly spray them at the CM5 one after another, and if the "gateway" app running on the CM5's Mega128 doesn't explicitly stop transmitting and buffer the next command(s) on its own initiative until the response arrives, potentially cause a head-on collision by trying to transmit the next command to the AX12 bus while one or more AX-12s on the bus are simultaneously trying to transmit back the response byte?


Please note: The interface with Java support is not for CM5 but for USB2Dynamixel which has USB interface to the PC and connects directly to the servos. (the servos need to be powered by CM5 or with SMPS2Dynamixel)
limor
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1845
Joined: Mon Oct 11, 2004 1:00 am
Location: London, UK

Post by Miamicanes » Thu Dec 11, 2008 6:01 pm

Post by Miamicanes
Thu Dec 11, 2008 6:01 pm

Hmmm... had a bit of disillusionment between last night and about 15 minutes ago:

* Realized that XBee can't do 9-bit serial. At least, there doesn't seem to be any obvious way to do it.

* Realized that my kludge for 9-bit serial at the PC end only works for sending. Even if the ninth bit's value could be ignored for incoming bytes, the interface's parity-checking will reject the byte and treat it as a frame error.

I thought about putting another AVR between the CP2103 and its XBee, and using two of the CP2103's GPIO lines to convey the ninth bit the same way the AVR does (at the AVR end, read GPIO #1 when a new byte arrives, and set or clear GPIO #2 when sending a byte to the PC... at the Windows end, set/clear GPIO #1 when sending a byte, read GPIO #2 when a new byte arrives), but I'm not feeling very confident at the moment that it would work reliably. Among other things, I'd have to use the other two GPIO lines to see whether the AVR or PC had read the most recently-sent byte before sending the next (probably by assigning one to each end, and flipping its value when reading the most recently-sent byte).

The bigger problem is that at the driver level, GPIO behavior isn't guaranteed to be deterministic in realtime. In fact, SiLabs tech support made a point of emphasizing that GPIO exists mainly for "slow" things, like detecting button presses or illuminating LEDs, and doesn't get a high level of priority compared to UART data handling. In other words, not only is it not GUARANTEED to be deterministic, it's officially doesn't even pretend to be deterministic. Put another way, if the AVR changes the state of GPIO #2 on the CP2103, then transmits a byte to the CP2103's UART, there's absolutely NO guarantee that the CP2103 will notice or care that the GPIO's state changed before it receives the byte via its uart, no guarantee that it will notify the PC driver via USB that GPIO2's state changed before notifying the PC driver that a byte was received by the UART if it DOES notice the GPIO's state change first, and no guarantee that the PC driver will update its object data to reflect the newly-observed GPIO state before notifying an observer that a new byte was received by the UART.

Worse, I can't even use a second GPIO as a semaphore (doing something like setting GPIO state, sending a byte, then toggling the semaphore's state to signal that both the GPIO and received byte are in agreement), because the miniport driver was written in C# as managed code, and Microsoft's CLR -- like Java -- reserves the right to execute code out of order unless it's synchronized. So even if the driver received a datagram via USB telling it that the CP2103's GPIO pins were polled, and this byte indicates their current state, there's no guarantee that the object corresponding to GPIO #4's state wouldn't be updated before the object corresponding to GPIO #2's state was. Argh.

Sigh. I have a major love-hate relationship with 9-bit serial... I love it because it's so convenient and nice... but hate it because it's not supported by anything besides Atmel MCUs, and its very nice-ness encourages me to keep trying extreme, ugly kludges to try and forcibly make it work with other hardware anyway. :-(
Hmmm... had a bit of disillusionment between last night and about 15 minutes ago:

* Realized that XBee can't do 9-bit serial. At least, there doesn't seem to be any obvious way to do it.

* Realized that my kludge for 9-bit serial at the PC end only works for sending. Even if the ninth bit's value could be ignored for incoming bytes, the interface's parity-checking will reject the byte and treat it as a frame error.

I thought about putting another AVR between the CP2103 and its XBee, and using two of the CP2103's GPIO lines to convey the ninth bit the same way the AVR does (at the AVR end, read GPIO #1 when a new byte arrives, and set or clear GPIO #2 when sending a byte to the PC... at the Windows end, set/clear GPIO #1 when sending a byte, read GPIO #2 when a new byte arrives), but I'm not feeling very confident at the moment that it would work reliably. Among other things, I'd have to use the other two GPIO lines to see whether the AVR or PC had read the most recently-sent byte before sending the next (probably by assigning one to each end, and flipping its value when reading the most recently-sent byte).

The bigger problem is that at the driver level, GPIO behavior isn't guaranteed to be deterministic in realtime. In fact, SiLabs tech support made a point of emphasizing that GPIO exists mainly for "slow" things, like detecting button presses or illuminating LEDs, and doesn't get a high level of priority compared to UART data handling. In other words, not only is it not GUARANTEED to be deterministic, it's officially doesn't even pretend to be deterministic. Put another way, if the AVR changes the state of GPIO #2 on the CP2103, then transmits a byte to the CP2103's UART, there's absolutely NO guarantee that the CP2103 will notice or care that the GPIO's state changed before it receives the byte via its uart, no guarantee that it will notify the PC driver via USB that GPIO2's state changed before notifying the PC driver that a byte was received by the UART if it DOES notice the GPIO's state change first, and no guarantee that the PC driver will update its object data to reflect the newly-observed GPIO state before notifying an observer that a new byte was received by the UART.

Worse, I can't even use a second GPIO as a semaphore (doing something like setting GPIO state, sending a byte, then toggling the semaphore's state to signal that both the GPIO and received byte are in agreement), because the miniport driver was written in C# as managed code, and Microsoft's CLR -- like Java -- reserves the right to execute code out of order unless it's synchronized. So even if the driver received a datagram via USB telling it that the CP2103's GPIO pins were polled, and this byte indicates their current state, there's no guarantee that the object corresponding to GPIO #4's state wouldn't be updated before the object corresponding to GPIO #2's state was. Argh.

Sigh. I have a major love-hate relationship with 9-bit serial... I love it because it's so convenient and nice... but hate it because it's not supported by anything besides Atmel MCUs, and its very nice-ness encourages me to keep trying extreme, ugly kludges to try and forcibly make it work with other hardware anyway. :-(
Miamicanes
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 28
Joined: Thu Dec 28, 2006 1:00 am

Post by Miamicanes » Thu Dec 11, 2008 7:47 pm

Post by Miamicanes
Thu Dec 11, 2008 7:47 pm

Update: I haven't totally given up yet... it occurred to me that if I can manage to find SOME wireless system capable of transparently bridging 9-bit serial (either explicitly, or by willingly ignoring what it believes to be parity errors and just passing the raw bits along verbatim with the expectation that if the client on the receiving end cares, it will notice the parity error and take action of its own), I could probably get it to work by using a USB FIFO bridge with another AVR to sit between the PC's wireless module and the PC's USB port... IF I can find one capable of bidirectionally sending at least 10 atomic bits at a time (8 for data, 1 for flagbit, 1 to toggle and indicate to the receiver that the next byte is ready to read).

(goes off to start reading about the XBee's "API Mode" to see whether it might work, after verifying that the FT245 is capable of atomically conveying the state of at least 10 bits at a time...)

Oh, I finally got a good look at the USB2Dynamixel API last night... and scratched it off the list as a mandatory requirement. I was under the impression that it included library objects to provide high-level abstractions of things like motions and state. From what I saw, it looks like the API literally just does what code I've already written does... handle the bundling and unbundling of datagram bytes. My original reason for caring about it was the assumption that others have written libraries that build upon it. As far as I can tell, that's not the case.

Sigh. Did I mention yet that I have a bad habit of working really hard so I can be lazy?
Update: I haven't totally given up yet... it occurred to me that if I can manage to find SOME wireless system capable of transparently bridging 9-bit serial (either explicitly, or by willingly ignoring what it believes to be parity errors and just passing the raw bits along verbatim with the expectation that if the client on the receiving end cares, it will notice the parity error and take action of its own), I could probably get it to work by using a USB FIFO bridge with another AVR to sit between the PC's wireless module and the PC's USB port... IF I can find one capable of bidirectionally sending at least 10 atomic bits at a time (8 for data, 1 for flagbit, 1 to toggle and indicate to the receiver that the next byte is ready to read).

(goes off to start reading about the XBee's "API Mode" to see whether it might work, after verifying that the FT245 is capable of atomically conveying the state of at least 10 bits at a time...)

Oh, I finally got a good look at the USB2Dynamixel API last night... and scratched it off the list as a mandatory requirement. I was under the impression that it included library objects to provide high-level abstractions of things like motions and state. From what I saw, it looks like the API literally just does what code I've already written does... handle the bundling and unbundling of datagram bytes. My original reason for caring about it was the assumption that others have written libraries that build upon it. As far as I can tell, that's not the case.

Sigh. Did I mention yet that I have a bad habit of working really hard so I can be lazy?
Miamicanes
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 28
Joined: Thu Dec 28, 2006 1:00 am

Post by billyzelsnack » Fri Dec 12, 2008 2:06 am

Post by billyzelsnack
Fri Dec 12, 2008 2:06 am

Miamicanes wrote:Sigh. Did I mention yet that I have a bad habit of working really hard so I can be lazy?


No other good reason to work hard!
Miamicanes wrote:Sigh. Did I mention yet that I have a bad habit of working really hard so I can be lazy?


No other good reason to work hard!
billyzelsnack
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 618
Joined: Sat Dec 30, 2006 1:00 am


12 postsPage 1 of 1
12 postsPage 1 of 1