Hi, I'm not sure about how to go about a 50Hz timer intterupt to refresh a servo actuator and turning off interruppts or the timer1 for using glcd ssd1306.h and srf04.h.
I need to stop and restart the timer for the srf04 to measure distance and the glcd as a line in my setup #define I2C_DISABLE_INTERRUPTS ON
My interrupt is
on interrupt timer1overflow Call servo
inittimer1(OSC,PS1_2)
Starttimer 1
the interrupt and the get range are
sub get_range ;us sensor
;intoff
StopTimer 1
do until range > 0
range = USDistance(1)
wait 10 ms
loop
;inton;settimer 1, 25535
Starttimer 1
end sub
;;;;;;;;
sub servo ;servo interrupt
settimer 1, 25535
pulseout Servo_Pin , radarpos 10us
end sub
You can see my efforts. I need to use the glcd as well. Please show me the best way.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Don't think you can do it like that. Stopping the timer will stop the servo pulse. Suggest you use a CCP module for the servo function instead of Timer with interrupt/pulse out.
What I see in the code is 1 servo. Are there more ? One Servo gives you approximately 19 ms between interrupts to do stuff. Probably not enough time to get the range info and update the display without interruption. Using a hardware CCP module to generate the Servo Pulse eliminates the need for an interrupt.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have been using micro servo's for the last year just by sending them a pulse until they settle into a position. They seem to stay in that position just fine for long time (hour plus).
This way you would not need the interrupt to send the pulses continuously to the servo.
I wanted to uses only a byte for the position so that is why the time is " 10 us". So position by the book would be 100 to 200 which would be 1000us to 2000us. But the little blue servos seem to work over these limits. 60 to 240 which give a little more rotation.
The pulse is repeated long enough for the servo to get to the position and 25 times is too much but safe. Then I don't send a pulse until a new position is needed. In my application only 2 positions are needed. I keep the times for the 4 servos and two positions each in a table and can tune both the normal position and the tripped position after mounting.
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for the feedback,appreciated. mmotte said "I have been using micro servo's for the last year just by sending them a pulse until they settle into a position. They seem to stay in that position just fine for long time (hour plus)." This is interesting as I used a servo on a robot with a us sensor mounted on the servo and it rotating left-right BUT the servo LOST position ie a variable servoposition would not be accurate...in fact the servo gone daft doing own thing.
The documented way is servos need refreshing at least 50Hz. That works for me.
mmotte saying "just by sending them a pulse until they settle into a position" is maybe my error ie I just pulseout servoposition,it moves but then loses it if the next pulseout is late. I will try your method with 2 to 4 pulses and see.
The interrupt I used works ok with a sharp optical rangefinder but they sample too slow for my robot.
The glcd is for testing variables at the mo but will be a face...the eyes and mouth sorted and animated.
William Roth,I have thought pwm but it's too coarse and fast but using ccp is beyond me. Is it documented in gcb ie around 5% duty but precise? I can't see a way with the pwm.h but that maybe my fault (probably).and the timer stuff is hard to follow (for me).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Stan,
"by sending them a pulse until they settle into a position" , I should have said send multiple pulses of a certain size. I thought it was infered from the code example of sending 25 pulses of "A3pos2" size. I also told you 25 was probably to high. They usually work fine with as few as 10 but your suggestion of 2 or 4 is too few. Also make sure you wait between pulses. Read code eaxample. My many different servos never drifted after doing this. I know this is not according to the "rules" but works and would save you a timer for other purposes.
73
M
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My use is a us range finder on a servo scanning left to right to left. I need to know the position to know where an object is. The us sensor needs 10ms to settle. That is enough time for the servo to reset and lose position ie 150 is not centre. OK I could split the 10ms with pulseouts but not elegant solution and other delays in my code.
I'll figure a method like William Roth suggested. nice one.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
How about using Timer0 for the interrupt, and make a scheduler based on the lowest common time frame. Say, set Timer0 to overflow every 5ms and use a counter in the interrupt. Then in main:
SelectCasecounterCase0'start ultrasonic readingCase1'5 ms'do other stuffCase2'10 ms'take ultrasonic readingCase3'15 ms'output to glcd?Case4'20 ms'update servo with new CCP valueend select
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks kent,I have learning to do with timer overflow and trigerring events on overflow or matching preset register values. As is, this works fine. I forgot to zero range. doh.
sub get_range ;us sensor
range=0
do until range > 0
StopTimer 1
range = USDistance(1)
settimer 1, 25535
Starttimer 1
wait 10 ms
loop
end sub
The glcd I'll sort with experiment..not logic. Robots don't do much really,lots of spare time for non mechanical stuff. Cheers.
PS as I see servos it's the pulse width input to voltage and matching the pot voltage so no pulses..no voltage...but that just my interpretation.
ps encore une fois...settimer 1, 65534 would start it faster for missed time?
Last edit: stan cartwright 2017-05-29
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Some newer PIC Chips have highly configurable 16-Bit PWM Modules. These are not yet supported in GCB but you can still use these 16 Bit PWMS with a bit of datasheet reading and some experimentation.
In the code below I have used a PIC16F1788 with 16-bit PWM6. No interrupt is nedded to generate a Servo output at 50 hz with 16-bit PWM Duty resolution. This means there are ~4000 discrete steps with a servo pulse of 500us to 2500us (Servo full range).
.
In your code, simply set the new duty cycle ( servo position) when necesary, After setting the duty cycle, the code MUST subsequently then load the buffer with " Set PWM6LD ON" to initiate the change.
''' Single Servo Control using 16-bit PWM6 on PIC16F1778
#chip 16f1778, 16
#config OSC = INTOSC
#config MCLRE=ON, WDTE=OFF, BOREN = Off
#option explicit
DIM PWM6_Period ALIAS PWM6PRH, PWM6PRL As WORD
DIM PWM6_Duty ALIAS PWM6DCH, PWM6DCL As WORD
PWM6_Period = 39850 '// 50 Hz
PWM6_Duty = 0
Dir PORTC.3 OUT '// PWM6 Out on PORTC.3
UnLockPPS
RC3PPS = 0x001E 'PWM6OUT > RC3
LockPPS
PWM6CLKCON = 0b00110000 '// PWM6 Clock = FOSC / 8
PWM6CON = 0b00000000 '// Standard Mode / Module Disabled
SET PWM6EN ON ' Enable the PWM6 Module
''' Servo Test Full Range Sweep / Adjust duty values as needed
Do
For PWM6_duty = 1000 to 5000 Step 5
Set PWM6LD ON '// Load PWMDCx Buffer
Wait 5 ms
Next
wait 2 s
For PWM6_duty = 5000 to 1000 Step - 5
Set PWM6LD ON '// Load PWMDCx Buffer
Wait 5 ms
Next
Wait 2 s
Loop
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, same for a little bit older chip like the 18f1330, and others, that have the 14 bit Power PWM modules. A real bear to set up, but once initlialized, it is ready to go. A servo example with all the gory details, not set for max resolution, but more than is required:
Thanks for the code examples. I find data sheets hard reading but if the register bit names are usable in gcb then that's a start. The best I got was lowering the clock to 1mhz but the duty was still too coarse.I still haven't figured out the hpwm which does stepped pwm and anti-phase if setup right it looks like. The mega328p has modes I've not worked out,true phase I read and again the registers names are used by gcb. All on my to do list. Thanks again.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
sub get_range ;us sensor
range=0
do until range > 0
intoff
range = USDistance(1)
inton
wait 10 ms
loop
end sub
;;;;;;;;
sub servo ;servo interrupt
settimer 1, 25535
pulseout Servo_Pin , radarpos 10us
end sub
I'm not convinced 100% it's ok.I sent a vid to Evan showing the servo working and hpwm to slow the motors cos the 2 diodes don't drop enough volts from the 2 batteries. Robots are easy with GCB. I find it fun.This needs 2 seperate 5v supplies. https://youtu.be/SAvBMbFqiOc
ps forgot the camera mic was on...won't happen again
Last edit: stan cartwright 2017-06-04
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, I'm not sure about how to go about a 50Hz timer intterupt to refresh a servo actuator and turning off interruppts or the timer1 for using glcd ssd1306.h and srf04.h.
I need to stop and restart the timer for the srf04 to measure distance and the glcd as a line in my setup #define I2C_DISABLE_INTERRUPTS ON
My interrupt is
the interrupt and the get range are
You can see my efforts. I need to use the glcd as well. Please show me the best way.
Don't think you can do it like that. Stopping the timer will stop the servo pulse. Suggest you use a CCP module for the servo function instead of Timer with interrupt/pulse out.
What I see in the code is 1 servo. Are there more ? One Servo gives you approximately 19 ms between interrupts to do stuff. Probably not enough time to get the range info and update the display without interruption. Using a hardware CCP module to generate the Servo Pulse eliminates the need for an interrupt.
Stan,
I have been using micro servo's for the last year just by sending them a pulse until they settle into a position. They seem to stay in that position just fine for long time (hour plus).
This way you would not need the interrupt to send the pulses continuously to the servo.
Example code:
I wanted to uses only a byte for the position so that is why the time is " 10 us". So position by the book would be 100 to 200 which would be 1000us to 2000us. But the little blue servos seem to work over these limits. 60 to 240 which give a little more rotation.
The pulse is repeated long enough for the servo to get to the position and 25 times is too much but safe. Then I don't send a pulse until a new position is needed. In my application only 2 positions are needed. I keep the times for the 4 servos and two positions each in a table and can tune both the normal position and the tripped position after mounting.
Mike
Thanks for the feedback,appreciated. mmotte said "I have been using micro servo's for the last year just by sending them a pulse until they settle into a position. They seem to stay in that position just fine for long time (hour plus)." This is interesting as I used a servo on a robot with a us sensor mounted on the servo and it rotating left-right BUT the servo LOST position ie a variable servoposition would not be accurate...in fact the servo gone daft doing own thing.
The documented way is servos need refreshing at least 50Hz. That works for me.
mmotte saying "just by sending them a pulse until they settle into a position" is maybe my error ie I just pulseout servoposition,it moves but then loses it if the next pulseout is late. I will try your method with 2 to 4 pulses and see.
The interrupt I used works ok with a sharp optical rangefinder but they sample too slow for my robot.
The glcd is for testing variables at the mo but will be a face...the eyes and mouth sorted and animated.
William Roth,I have thought pwm but it's too coarse and fast but using ccp is beyond me. Is it documented in gcb ie around 5% duty but precise? I can't see a way with the pwm.h but that maybe my fault (probably).and the timer stuff is hard to follow (for me).
Stan,
"by sending them a pulse until they settle into a position" , I should have said send multiple pulses of a certain size. I thought it was infered from the code example of sending 25 pulses of "A3pos2" size. I also told you 25 was probably to high. They usually work fine with as few as 10 but your suggestion of 2 or 4 is too few. Also make sure you wait between pulses. Read code eaxample. My many different servos never drifted after doing this. I know this is not according to the "rules" but works and would save you a timer for other purposes.
73
M
My use is a us range finder on a servo scanning left to right to left. I need to know the position to know where an object is. The us sensor needs 10ms to settle. That is enough time for the servo to reset and lose position ie 150 is not centre. OK I could split the 10ms with pulseouts but not elegant solution and other delays in my code.
I'll figure a method like William Roth suggested. nice one.
How about using Timer0 for the interrupt, and make a scheduler based on the lowest common time frame. Say, set Timer0 to overflow every 5ms and use a counter in the interrupt. Then in main:
Thanks kent,I have learning to do with timer overflow and trigerring events on overflow or matching preset register values. As is, this works fine. I forgot to zero range. doh.
The glcd I'll sort with experiment..not logic. Robots don't do much really,lots of spare time for non mechanical stuff. Cheers.
PS as I see servos it's the pulse width input to voltage and matching the pot voltage so no pulses..no voltage...but that just my interpretation.
ps encore une fois...settimer 1, 65534 would start it faster for missed time?
Last edit: stan cartwright 2017-05-29
@Stan
Some newer PIC Chips have highly configurable 16-Bit PWM Modules. These are not yet supported in GCB but you can still use these 16 Bit PWMS with a bit of datasheet reading and some experimentation.
In the code below I have used a PIC16F1788 with 16-bit PWM6. No interrupt is nedded to generate a Servo output at 50 hz with 16-bit PWM Duty resolution. This means there are ~4000 discrete steps with a servo pulse of 500us to 2500us (Servo full range).
.
In your code, simply set the new duty cycle ( servo position) when necesary, After setting the duty cycle, the code MUST subsequently then load the buffer with " Set PWM6LD ON" to initiate the change.
Yes, same for a little bit older chip like the 18f1330, and others, that have the 14 bit Power PWM modules. A real bear to set up, but once initlialized, it is ready to go. A servo example with all the gory details, not set for max resolution, but more than is required:
Thanks for the code examples. I find data sheets hard reading but if the register bit names are usable in gcb then that's a start. The best I got was lowering the clock to 1mhz but the duty was still too coarse.I still haven't figured out the hpwm which does stepped pwm and anti-phase if setup right it looks like. The mega328p has modes I've not worked out,true phase I read and again the registers names are used by gcb. All on my to do list. Thanks again.
After testing this is best way for me.
I'm not convinced 100% it's ok.I sent a vid to Evan showing the servo working and hpwm to slow the motors cos the 2 diodes don't drop enough volts from the 2 batteries. Robots are easy with GCB. I find it fun.This needs 2 seperate 5v supplies. https://youtu.be/SAvBMbFqiOc
ps forgot the camera mic was on...won't happen again
Last edit: stan cartwright 2017-06-04
ebay stuff and a pic and GCB. C.2 hpwm goes to both motors.