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

MR-C3024 16Mhz

Hitec robotics including ROBONOVA humanoid, HSR-8498HB servos, MR C-3024 Controllers and RoboBasic
20 postsPage 1 of 21, 2
20 postsPage 1 of 21, 2

MR-C3024 16Mhz

Post by tum » Mon May 19, 2008 6:01 pm

Post by tum
Mon May 19, 2008 6:01 pm

It's theoretically possible to upgrade the uC to the 16Mhz version along with the crystal and get twice the speed right?

I think they're pin-pin compatible.

Anyone tried this?
It's theoretically possible to upgrade the uC to the 16Mhz version along with the crystal and get twice the speed right?

I think they're pin-pin compatible.

Anyone tried this?
tum
Savvy Roboteer
Savvy Roboteer
Posts: 34
Joined: Fri Jun 08, 2007 5:28 am

Post by i-Bot » Mon May 19, 2008 6:24 pm

Post by i-Bot
Mon May 19, 2008 6:24 pm

The firmware is totally dependant on clock speed with lots of software timing loops. Higher clock speed could be used with new firmware, but backwards compatibility would be lost unless speed was switched.
The firmware is totally dependant on clock speed with lots of software timing loops. Higher clock speed could be used with new firmware, but backwards compatibility would be lost unless speed was switched.
i-Bot
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am

Post by tum » Mon May 19, 2008 6:48 pm

Post by tum
Mon May 19, 2008 6:48 pm

i-Bot wrote:The firmware is totally dependant on clock speed with lots of software timing loops. Higher clock speed could be used with new firmware, but backwards compatibility would be lost unless speed was switched.


Yeah my goal is to rewrite the firmware and provide an open source C library for dynamic feedback & control.

Assuming the hitec servos really can be used at 19200, I've done a few calculations.

Assuming clock speed of 7372800 Hz
And baud rate of 19200
So we get 7372800/19200=384 clock cycles per bit
It takes 9 clock cycles to bang a single bit in assembly
So we get 384/9=42 bits we can bang simulataneously

Which basically means we have the CPU power to control 42 servos simultaneously.

Now assuming we're only using 24 servos, we have 168 clock cycles free every time we write a bit. Those clock cycles are wasted and we use them to time the bit bang.

Now, a write pos takes 70 bits, a read packet takes 70+70 bits. That's 210 bits for every servo. That gives us a refresh rate for each servo (assuming every refresh we're writing a position and getting a reading of the position) of 91Hz.

We probably want to be processing other things so we will end up with less than 91Hz.

I guess if we use a timer (for the 168 clock cycles between bits) then we can use the spare time to process stuff. I'm not yet sure how many clock cycles setting up a timer and responding to a timer takes so it might not be worth the trouble. Another better option might be to use the 168 clock cycles to perform ADC caching on all the inputs (I'm not sure if you can do ADC synchronously and not sure how many clock cycles it would take).

Another idea is to only send the position information every few seconds (to take care of unplugged/replugged servos). This would increase the refresh rate by 33%.

Using a 16Mhz Atmega AVR128 or reducing usable servos to 18 (pretty reasonable) would make things fit more comfortably.

All this ofcourse assumes that the hitec servo serial interface does work as expected and is not simply an advertised but nonfunctional feature! Errors (etc) would have to be taken care of which would take more clock cycles and would have to be carefully tuned.
i-Bot wrote:The firmware is totally dependant on clock speed with lots of software timing loops. Higher clock speed could be used with new firmware, but backwards compatibility would be lost unless speed was switched.


Yeah my goal is to rewrite the firmware and provide an open source C library for dynamic feedback & control.

Assuming the hitec servos really can be used at 19200, I've done a few calculations.

Assuming clock speed of 7372800 Hz
And baud rate of 19200
So we get 7372800/19200=384 clock cycles per bit
It takes 9 clock cycles to bang a single bit in assembly
So we get 384/9=42 bits we can bang simulataneously

Which basically means we have the CPU power to control 42 servos simultaneously.

Now assuming we're only using 24 servos, we have 168 clock cycles free every time we write a bit. Those clock cycles are wasted and we use them to time the bit bang.

Now, a write pos takes 70 bits, a read packet takes 70+70 bits. That's 210 bits for every servo. That gives us a refresh rate for each servo (assuming every refresh we're writing a position and getting a reading of the position) of 91Hz.

We probably want to be processing other things so we will end up with less than 91Hz.

I guess if we use a timer (for the 168 clock cycles between bits) then we can use the spare time to process stuff. I'm not yet sure how many clock cycles setting up a timer and responding to a timer takes so it might not be worth the trouble. Another better option might be to use the 168 clock cycles to perform ADC caching on all the inputs (I'm not sure if you can do ADC synchronously and not sure how many clock cycles it would take).

Another idea is to only send the position information every few seconds (to take care of unplugged/replugged servos). This would increase the refresh rate by 33%.

Using a 16Mhz Atmega AVR128 or reducing usable servos to 18 (pretty reasonable) would make things fit more comfortably.

All this ofcourse assumes that the hitec servo serial interface does work as expected and is not simply an advertised but nonfunctional feature! Errors (etc) would have to be taken care of which would take more clock cycles and would have to be carefully tuned.
tum
Savvy Roboteer
Savvy Roboteer
Posts: 34
Joined: Fri Jun 08, 2007 5:28 am

Post by i-Bot » Mon May 19, 2008 7:33 pm

Post by i-Bot
Mon May 19, 2008 7:33 pm

In my opinion your solution should work at 7.3728, and better at 16MHz. I find many people reluctant to change the firmware, never mind CPU and XTAL. If you are to provide a library, you need a user base willing to work with it.

You need to choose between HMI and pulse. My opinion is that HMI will work, but it new and unproven. I would suggest you evaluate carefully using the code from Fritzoid, or less servos.

If you do choose HMI, I did look at some options, and it looks possible to bit bang bytes, since the 24 servo bits are in 3 ports. It is a bit heavy on RAM, but you can prepare the frames as bytes to be sent on a 19200 bps interrupt. The preparation is to make the frames and rotate the data from 8 serial servo bytes to 8 parallel port bytes. The interrupt is fairly short to send the port bytes from memory. The prepare could be background, or a lower priority interrupt.

Also you only need to be refreshing servos when something changes. Remember that some messages are lost by the servo if it is busy, but you don't need to tell it twice otherwise. This puts processing power back in the bank, quite a lot in real situations.
In my opinion your solution should work at 7.3728, and better at 16MHz. I find many people reluctant to change the firmware, never mind CPU and XTAL. If you are to provide a library, you need a user base willing to work with it.

You need to choose between HMI and pulse. My opinion is that HMI will work, but it new and unproven. I would suggest you evaluate carefully using the code from Fritzoid, or less servos.

If you do choose HMI, I did look at some options, and it looks possible to bit bang bytes, since the 24 servo bits are in 3 ports. It is a bit heavy on RAM, but you can prepare the frames as bytes to be sent on a 19200 bps interrupt. The preparation is to make the frames and rotate the data from 8 serial servo bytes to 8 parallel port bytes. The interrupt is fairly short to send the port bytes from memory. The prepare could be background, or a lower priority interrupt.

Also you only need to be refreshing servos when something changes. Remember that some messages are lost by the servo if it is busy, but you don't need to tell it twice otherwise. This puts processing power back in the bank, quite a lot in real situations.
i-Bot
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am

Post by tum » Mon May 19, 2008 7:57 pm

Post by tum
Mon May 19, 2008 7:57 pm

BTW, could you please confirm that roboflashing any old hex file into robonova is reversable? It's not going to kill the bootloader and prevent me from reflashing the robonova firmware is it? Is there any possibility of accidentally killing the bootloader?
BTW, could you please confirm that roboflashing any old hex file into robonova is reversable? It's not going to kill the bootloader and prevent me from reflashing the robonova firmware is it? Is there any possibility of accidentally killing the bootloader?
tum
Savvy Roboteer
Savvy Roboteer
Posts: 34
Joined: Fri Jun 08, 2007 5:28 am

Post by i-Bot » Mon May 19, 2008 9:29 pm

Post by i-Bot
Mon May 19, 2008 9:29 pm

From the cboot code, which you will find in my file area. It appears the bootloader sits at location (word) 0xf000. The bootloader is only capable to write to the range 0x00 to 0x7f7f in the application area and to 0xff80 to 0xffff in the boot area. So it cannot write to the boot area used in one step. It also appears applications cannot write to the boot area.

It seems unlikely to damage the boot loader with any wild application code, or bad downloads.

It would appear possible to change the boot loader if you wrote and downloaded a loader loader to locations 0xff80, and used this to load the area at 0xf00 with a new bootloader.
From the cboot code, which you will find in my file area. It appears the bootloader sits at location (word) 0xf000. The bootloader is only capable to write to the range 0x00 to 0x7f7f in the application area and to 0xff80 to 0xffff in the boot area. So it cannot write to the boot area used in one step. It also appears applications cannot write to the boot area.

It seems unlikely to damage the boot loader with any wild application code, or bad downloads.

It would appear possible to change the boot loader if you wrote and downloaded a loader loader to locations 0xff80, and used this to load the area at 0xf00 with a new bootloader.
i-Bot
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am

Post by i-Bot » Mon May 19, 2008 9:29 pm

Post by i-Bot
Mon May 19, 2008 9:29 pm

From the cboot code, which you will find in my file area. It appears the bootloader sits at location (word) 0xf000. The bootloader is only capable to write to the range 0x00 to 0x7f7f in the application area and to 0xff80 to 0xffff in the boot area. So it cannot write to the boot area used in one step. It also appears applications cannot write to the boot area.

It seems unlikely to damage the boot loader with any wild application code, or bad downloads.

It would appear possible to change the boot loader if you wrote and downloaded a loader loader to locations 0xff80, and used this to load the area at 0xf00 with a new bootloader.
From the cboot code, which you will find in my file area. It appears the bootloader sits at location (word) 0xf000. The bootloader is only capable to write to the range 0x00 to 0x7f7f in the application area and to 0xff80 to 0xffff in the boot area. So it cannot write to the boot area used in one step. It also appears applications cannot write to the boot area.

It seems unlikely to damage the boot loader with any wild application code, or bad downloads.

It would appear possible to change the boot loader if you wrote and downloaded a loader loader to locations 0xff80, and used this to load the area at 0xf00 with a new bootloader.
i-Bot
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am

Post by kushlik » Mon Jun 02, 2008 10:13 pm

Post by kushlik
Mon Jun 02, 2008 10:13 pm

tum,

Keep in mind that you don't need to flip one bit at a time - you can set the whole output port to an 8-bit value. I tried this using a PIC microcontroller and it actually takes less time to set the whole output port than a single bit. I was able to get switching frequency of 1.25 Mhz (verified on the scope) on a 16F876A PIC with 20 Mhz crystal. Since PIC's clock speed is 1/4 of the oscillator, this tells me that it only takes 4 cycles to set the whole output port. This should speed up things quite a bit!

Btw, I am also working on interfacing the ROBONOVA to a PC with minimum overhead. I am actually planning on using one PIC microcontroller, mentioned above. I think it will be sufficient and there is no need for the "fancy" Atmel chip.

I was able to get one channel working with sending position command and reading feedback at ~100 Hz (also verified on the scope).. Now i "simply" need to make it work for 16 in parallel :)

Let me know if this makes sense..
tum,

Keep in mind that you don't need to flip one bit at a time - you can set the whole output port to an 8-bit value. I tried this using a PIC microcontroller and it actually takes less time to set the whole output port than a single bit. I was able to get switching frequency of 1.25 Mhz (verified on the scope) on a 16F876A PIC with 20 Mhz crystal. Since PIC's clock speed is 1/4 of the oscillator, this tells me that it only takes 4 cycles to set the whole output port. This should speed up things quite a bit!

Btw, I am also working on interfacing the ROBONOVA to a PC with minimum overhead. I am actually planning on using one PIC microcontroller, mentioned above. I think it will be sufficient and there is no need for the "fancy" Atmel chip.

I was able to get one channel working with sending position command and reading feedback at ~100 Hz (also verified on the scope).. Now i "simply" need to make it work for 16 in parallel :)

Let me know if this makes sense..
kushlik
Robot Builder
Robot Builder
Posts: 8
Joined: Mon Jun 02, 2008 10:04 pm

Post by Voelker » Tue Jun 03, 2008 1:22 pm

Post by Voelker
Tue Jun 03, 2008 1:22 pm

while reading fedback, does the servo gets loosy or does it keep its position. I don't know what kinf of pic you intend to use but to send position to 16 servos, you'll need a minimum of two timers ... I am actually designing a board for the robonova with a PIC32, maybe this could work as it has a lot of timers and processing power ...
while reading fedback, does the servo gets loosy or does it keep its position. I don't know what kinf of pic you intend to use but to send position to 16 servos, you'll need a minimum of two timers ... I am actually designing a board for the robonova with a PIC32, maybe this could work as it has a lot of timers and processing power ...
Voelker
Savvy Roboteer
Savvy Roboteer
Posts: 85
Joined: Thu Sep 06, 2007 7:32 pm

Post by kushlik » Tue Jun 03, 2008 2:35 pm

Post by kushlik
Tue Jun 03, 2008 2:35 pm

I think the idea, discussed here, is to use the serial protocol at 19200 baud, instead of generating 16 pwm lines. The trick is to implement the serial communication yourself and flip all 16 bits at once (or almost at once). This way, you can achieve almost parallel functionality of 16 servos. The nice thing is that, as opposed to generating PWM with different pulse widths, the timing for serial communication can be precisely synchronized for all 16 lines, allowing to write and read from all 16 servos at once by imply flipping output pins or reading from them at appropriate time steps. All you need for this is 16 IO pins, preferably 2 sets of 8 which are on the same ports, so that you can write a byte to the whole 8-bit IO port (exactly like one would do for standard parallel port communication)

Therefore, there is at most a single timer required, but i would suggest actually not using interrupts or checking timers, but hand-tweaking the inter-bit delay, since the interrupt overhead won't guarantee precise timing.. For example, i used a delay_us() function in PICC compiler with conjunction with NOP assembly codes to get the timing exactly right. Otherwise, function call overhead can screw you up! (the disadvantage is that while sending/receiving commands, the code won't do anything else, but it seems like the only purpose of the microcontroller is to do the communication of the motors, so it should be fine)
I think the idea, discussed here, is to use the serial protocol at 19200 baud, instead of generating 16 pwm lines. The trick is to implement the serial communication yourself and flip all 16 bits at once (or almost at once). This way, you can achieve almost parallel functionality of 16 servos. The nice thing is that, as opposed to generating PWM with different pulse widths, the timing for serial communication can be precisely synchronized for all 16 lines, allowing to write and read from all 16 servos at once by imply flipping output pins or reading from them at appropriate time steps. All you need for this is 16 IO pins, preferably 2 sets of 8 which are on the same ports, so that you can write a byte to the whole 8-bit IO port (exactly like one would do for standard parallel port communication)

Therefore, there is at most a single timer required, but i would suggest actually not using interrupts or checking timers, but hand-tweaking the inter-bit delay, since the interrupt overhead won't guarantee precise timing.. For example, i used a delay_us() function in PICC compiler with conjunction with NOP assembly codes to get the timing exactly right. Otherwise, function call overhead can screw you up! (the disadvantage is that while sending/receiving commands, the code won't do anything else, but it seems like the only purpose of the microcontroller is to do the communication of the motors, so it should be fine)
kushlik
Robot Builder
Robot Builder
Posts: 8
Joined: Mon Jun 02, 2008 10:04 pm

Post by kushlik » Tue Jun 03, 2008 2:37 pm

Post by kushlik
Tue Jun 03, 2008 2:37 pm

Oh, and when you use serial protocol, the servo does *not* get loose. Just checked it yesterday.
Oh, and when you use serial protocol, the servo does *not* get loose. Just checked it yesterday.
kushlik
Robot Builder
Robot Builder
Posts: 8
Joined: Mon Jun 02, 2008 10:04 pm

Post by Voelker » Tue Jun 03, 2008 3:16 pm

Post by Voelker
Tue Jun 03, 2008 3:16 pm

Does the serial protocol works on the stock servos ? I thought that HMI was disabled on those servos ... I agree that the interrupt overhead can give unprecise timings on a PIC18 running at 20Mhz as this kind of proccessor really runs at 5Mhz, but on a PIC32 running at 80Mhz (true core frequency) the induced overhead is lot less than 1µs. As each servo as 256 positions this overhead cannot affect the precision on digital servo. When using the serial protocol, do you have to refresh the servo position often ?
Does the serial protocol works on the stock servos ? I thought that HMI was disabled on those servos ... I agree that the interrupt overhead can give unprecise timings on a PIC18 running at 20Mhz as this kind of proccessor really runs at 5Mhz, but on a PIC32 running at 80Mhz (true core frequency) the induced overhead is lot less than 1µs. As each servo as 256 positions this overhead cannot affect the precision on digital servo. When using the serial protocol, do you have to refresh the servo position often ?
Voelker
Savvy Roboteer
Savvy Roboteer
Posts: 85
Joined: Thu Sep 06, 2007 7:32 pm

Post by kushlik » Tue Jun 03, 2008 3:48 pm

Post by kushlik
Tue Jun 03, 2008 3:48 pm

Voelker,

I guess you may be right about low overhead for higher clock speeds. There is only one way to find out - try it :).

The serial protocol works on Robonova's servos. The stock servos should also work - just make sure you buy the right type. If you look up the specs for the HSR-8498HB, it says that it supports it. I have ordered a couple of these servos, but they have not come in, so i can't say for sure that the stock servos of the same type support HMI. (if they don't, i am getting my money back! :) )

About the position refresh rate - the servo does not go limp when you stop sending commands via HMI protocol. Therefore, arbitrarily low update rate will work.
Voelker,

I guess you may be right about low overhead for higher clock speeds. There is only one way to find out - try it :).

The serial protocol works on Robonova's servos. The stock servos should also work - just make sure you buy the right type. If you look up the specs for the HSR-8498HB, it says that it supports it. I have ordered a couple of these servos, but they have not come in, so i can't say for sure that the stock servos of the same type support HMI. (if they don't, i am getting my money back! :) )

About the position refresh rate - the servo does not go limp when you stop sending commands via HMI protocol. Therefore, arbitrarily low update rate will work.
kushlik
Robot Builder
Robot Builder
Posts: 8
Joined: Mon Jun 02, 2008 10:04 pm

Post by Voelker » Tue Jun 03, 2008 3:59 pm

Post by Voelker
Tue Jun 03, 2008 3:59 pm

Sounds great, if the HMI protocol works on the robonova's servos updating position will be a lot less time taking than with the PWM interface. I hope to get my PIC32 board working soon in order to test this ...
Thanks
Sounds great, if the HMI protocol works on the robonova's servos updating position will be a lot less time taking than with the PWM interface. I hope to get my PIC32 board working soon in order to test this ...
Thanks
Voelker
Savvy Roboteer
Savvy Roboteer
Posts: 85
Joined: Thu Sep 06, 2007 7:32 pm

Post by i-Bot » Tue Jun 03, 2008 5:25 pm

Post by i-Bot
Tue Jun 03, 2008 5:25 pm

Serial HMI works fine on the HSR-8498HB for the position setting, position read, and speed. Some of the later HMI version features such as PID settings are not available.

The reading of position does not cause the torque of the servo to be turned off. There do appear to be some timing conflicts between the serial HMI and the internal servo working. If the servo is moving at a steady speed continous position reads can cause the motion to become uneven. Also not all reads are succesful. Interested to hear your findings.

Interrupts should be OK, since you only need 10% accuracy on the edges of the serial stream and 19.2 is pretty slow. If you don't use interrupts you are hanging up the processor for too long. I have just done a new PWM code for the standard 7.3728 MR-C3024 using interrupts. I can still get 1 us accuracy on 24 ports with other interrupts going at the same time. I set the timer to trigger early on one OCR, then wait in a tight loop for the next OCR. if the next PWM edge is within 10us, I time by code, else I go back and wait for the interrupt. The entire motion engine CPU load has dropped from 70% to less than 20%.
Serial HMI works fine on the HSR-8498HB for the position setting, position read, and speed. Some of the later HMI version features such as PID settings are not available.

The reading of position does not cause the torque of the servo to be turned off. There do appear to be some timing conflicts between the serial HMI and the internal servo working. If the servo is moving at a steady speed continous position reads can cause the motion to become uneven. Also not all reads are succesful. Interested to hear your findings.

Interrupts should be OK, since you only need 10% accuracy on the edges of the serial stream and 19.2 is pretty slow. If you don't use interrupts you are hanging up the processor for too long. I have just done a new PWM code for the standard 7.3728 MR-C3024 using interrupts. I can still get 1 us accuracy on 24 ports with other interrupts going at the same time. I set the timer to trigger early on one OCR, then wait in a tight loop for the next OCR. if the next PWM edge is within 10us, I time by code, else I go back and wait for the interrupt. The entire motion engine CPU load has dropped from 70% to less than 20%.
i-Bot
Savvy Roboteer
Savvy Roboteer
User avatar
Posts: 1142
Joined: Wed May 17, 2006 1:00 am

Next
20 postsPage 1 of 21, 2
20 postsPage 1 of 21, 2