Software PWM

Email sent

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”

Section naming

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.

It feels like somethign is
It feels like somethign is missing. I cant see how all the code flows together.

Here is my main.asm

.ResetCode code 0x0000

call OSC_Setup ; defined in BL18F, from bootloader
bra Main ; go to start of main code

;----------------------------------------
; ISR @ 0x0008
.ISRCode code 0x0008

btfsc PIR1, TMR1IF
rcall isrServo
btfsc PIR1, TMR2IF
rcall isrLifeTick
retfie FAST

;----------------------------------------
.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.

Now i can see how it
Now i can see how it works. It all fell together when I saw the ISRcode part

I don’t see it

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 think the answer is yes

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.

No good

I thought as much. Driving one servo’s easy. Two is OKay. Four, I start to get the jitters. I really want to drive 16 servos, though.

A couple days without coffee
A couple days without coffee and I get the jitters.

16 is too many

that’s too many for one timer to handle.
So your requiremetns are …

1) 16 Servo Outputs
2) Programmable Servo Positions
3) I2C / Serial to recieve new position data

Is the micro doing anything else, like reading sensors or analyzing data, or is this a standalone servo controller chip ?

Nope

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.

interrupts

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.

no good
That only lets me upload pictures, I must not have the right privilages

Oh, yeah

No, actually, you’re correct.

 

filename extensions

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.