Yes, I use timer 1 and I store 5 servo values. One value for each servo and a fifth value for the “dead time”. The way I know if it is the fifth servo is I check my ServoIndex variable, and if bit 2 is set, I am on Index 4 ( the fifth one ) and so I don’t set any outputs, I just reset my index to zero. You should be able to see it in the code.
Maybe I should I clarify it some more, my ServoIndex variable can be any number from 0 - 4, and in binary that is …
00000000, 00000001, 00000010, 00000011, 00000100
I do a bit test on my index to see if bit 2 is set, which means the timer has been set for the long delay.
thanks. I’ve only glanced thanks. I’ve only glanced at the code since i’m trying to get a lab report done but it looks like I should be able to figure it out once i get some time. the first few lines i dont understand but the rest of it looks familiar. what is the dot infront of the lable for? for example this line “.ServoData udata”
When writing relocateable code, it’s always a good idea to give your sections a name. Since microchip names their sections .udata and .code, I have just adopted that naming convention myself, so I know when looking at a map file or listing file that the name belongs to a section.
‘udata’ is ‘uninitialized data that is not in the access ram area’. In other words, it is ram that can only be accessed by using pointers, the FSR/INDF registers. There are 3 of them on the 18F4620. So the lines …
.ServoData udata
ServoValue res 10
reserves 10 bytes (5 16 bit values) in the udata section, and I give it the section name of .ServoData.
;---------------------------------------- .MainCode code Main rcall SetupLifeTick ; begin setup rcall SetupServos call RS232_Init
bsf INTCON, PEIE bsf INTCON, GIE ; enable interrupts
MainLoop
btfsc PIR1, RCIF ; check if a command has arrived call ExecuteCommand
; execute normal robot operations
bra MainLoop
;----------------------------------------
All you need to do is call isrServo whenever Timer 1 interrupts.
Load W with a servo # ( 0 - 3 ) and call SetServoPointer. Then load W with the servo value ( 0 - 255 ) and call SetServo. There is nothing else to it, the Interrupt Service Routine (ISR) takes care of everything.
What do you think is missing ? My software does 2 things at the moment …
1) Blinks an L.E.D.
2) Drives 4 servos.
My software, including linker scripts and makefile, is in 8 different files. I also have a "command" file that accepts commands from the serial port. One of the commands is a Servo command, which sets the servos values.
If you use a timer overflow at the end of the mark time and at the end of the space time, doesn’t that mean that you can only have one servo under control ata time? I can see how the end of the space would be the same for all four servos, but the ends of their respective marks might all be different.
I use one timer and do one servo "mark" at a time. I store the "mark" time as a 16 bit value, measured in microseconds. The final "space" time is always 30000 microseconds ( 30 mSec ). So if all servos are at their minimum of 1 mSec, then the total cycle time is 34 mSec. If all servos are at the maximum of 2 mSec, than the total cycle time is 38 mSec. I also put a 470 ohm resitor in series with the drive signal. This setup has been driving 2 HS311 and 2 HS425BB servos without jitter.
Initially it was, but I took those functions off and decided to go with an MCU per function strung together on I2C.
It’s not that it’s too much for one timer. In fact a 16-bit timer provides loads more resolution than I need. It’s the fact that the comparison of the timer with the demanded position, 16 times occupies more processor cycles than the length of one step of resolution.
I’m thinking four servos per controller and several controllers on an I2C bus.
my servo routine is interrupt driven, so I don’t do any “comparison”. I simply set the timer, turn on the servo bit, and return to my main loop. When the timer “interrupts”, I turn of all servo outputs and setup the timer for the next servo. The “space” time is handled like a special servo with no output pin.
I wish LMR had a code library, then I could post my servo code, bootloader, I2C subroutines, etc.
POst your own Topic If you post your own topic you can attach files. There is also a file area. Yours is https://www.robotshop.com/letsmakerobots/user/1054/imce. Even if you can’t post files here, you can upload tehm to you file area and create a link here to them.
The uploader will only complain about unknown filename extensions. Use something inappropriate like .c or .mp3 and make sure you readers know what the proper filename ought to be.
This is considered a bug in our CMS that we just don’t have any coding time left for. Cuz we lazy.