i have been trying to capture an RC receiver pulse value and transmit it via the chips hardware usart to a terminal so i can see its value but after spending several hours last night going through most things in the manual and doing forum searches i still cannot get anything to show on the terminal other than zero.
i am using the pulsin command and have yet to see a value on the screen for the pulse.
i changed over to a picaxe on my breadboard last night to make sure my receiver was good and it was happily measuring the pulse and transmitting the value so my receiver is ok.
clearly i have/am missing something and need some more experienced eyes to help as i cannot seem to get anywhere relying on the help manuals or forum search results.
ide is gcb@syn
chip is pic 12f1840
uart functions moved to alternate pins
pulse signal input from receiver to pin RA2 via 470r resistor
breadboard circuit/receiver all running from regulated supply of 5v
code:
; ----- Configuration
'Set chip model:
#chip 12F1840, 4
'Set internal oscillator to 4MHz
Set IRCF = b'1101'
'set uart TX/RX pins to RA4 and RA5 alternate pin locations:
set APFCON.7 = 1
set APFCON.2 = 1
'Set the pin directions:
Dir PORTA.4 Out 'send on Pin 3
Dir PORTA.5 In 'receive on Pin 2
Dir PORTA.2 in 'signal pulse input
'Config Hardware-UART:
#define USART_BLOCKING
#define USART_BAUD_RATE 4800
dim rxvalue as byte
Do
Pulsein PORTA.2,rxvalue, 1 s
HSerprint rxvalue
HSerSend 13
HSerSend 10
Wait 1 s
Loop
i simply want to be able to measure the pulse value and display it on the terminal.
the chips uart pins are going out to my ftdi-usb adapter, i can use serprint/sersend to output data with no issues that i can view but trying to get a measured pulse seems to be a challenge.
pulsein is a feature that i use alot with most of my picaxe code that i need to port over to gcb so i need to get this working/understand everything better
thanks,
tony
Last edit: tony golding 2015-02-25
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
also to mention i have also tried setting the variable to hold the pulse value as a word and tried hsersend as well all efforts so far to try and either understand the manual examples or to get any form of success are not getting anywhere
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i get a warning about innaccurate ms delay due to clock speed and use of variable
also still getting nothing other than zeroes and the occasional 1 or 4.
if i do it with the picaxe i get a changing value from 90 to 210 depending on the position i place the switch in on my transmitter but still nothing with this using gcb
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anobium, the PulseIn Help (GCBasic web site) example is missing a comma between PortPin and variable. And, port pin and variable are swapped from prototype Syntax, even though it compiles both ways.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
so i take it no one can really offer any help then?
i have been going around for hours last night and these last few today.
my equipment being used is all functioning correctly and tested multiple ways, a second 12f1840 has been tetsed with the same results.
both 12f1840's have been tested using mplabx and the timer1gate method of capturing a pulse and that works so why do i get no results with gcb regardless of any attempts?
Last edit: tony golding 2015-02-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have setup a PIC12f1822 on a breadboard, so same family more or less as the 12f1840. Using default RX/TX locations and PicKit2 UART Tool. The setup on the breadboard has a problem unless I have a 10k pulldown resistor (might even need less) on the PulseIn pin. Make sure micro has a bypass cap too. I also found that using less of a wait period in the loop helpful, like 100 Ms.
Been a long time since playing with an RC transmitter, but doesn't that invert the logic? If that is the case then the PulseIn logic needs modifying, and then could use the internal pullup of the PulseIn pin.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tony,
By looking under the hood in include/stdbasic.h you would find that PulseIn is a macro.
~~~~~~
'PulseIn
macro PulseIn (Pin, Variable, Units)
Variable = 0
Do While Pin = On
Wait 1 Units
Variable += 1
If Variable = 0 Then Exit Do
Loop
end macro
~~~~~
It looks like the third passing variable is "Units" of the "wait" timer,not a time out like you supposed.
So you are looking for 0.5ms to 2.5ms on a servo for your range so the suggested unit of 10uS seems logical. It would give a range of 50 to 250 .
So there is two ways out of the Do Loop
1) Pin goes low
2) variable overflows to 0
trouble shooting? you want to divide and conquer. little steps
So you should test your serial connection first by sending some numbers and seeing them show up . Or send a greeting and explanation. or some units after the number sent.
73
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
if i manually set the value of rxvalue then it will transmit fine to the terminal where i can see it correctly, it is also the same for sending any text, all good,
even after adding the stdbasic.h include and setting the units to 10us i still get nothing but zero back on the terminal when trying the pulsein command.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i have the bypass cap on the 12f thats a good habit at least ive managed to get into, i just added a 10k pulldown onto the pulsein pin also so will change the values and see.
i have used my logic analyzer on the output of the rx and as far as i can see from the signal it is as expected a low to high transition for the start of the pulse period im trying to capture.
thanks,
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tony,
Because your HSerrint is working use it to your advantage.
Don't get hung up on pulsein. It is only six lines of code that you can built right into a practice program putting HSerprints of the count or position in the program out to your terminal.
I agree with Kent that it still could be hardware. I made a low speed freq counter program on an '887 that would pick up 60 hz off of a 4 inch jumper that was not terminated(antenna).
try something simple like
hserprint "before wait for 1"
wait until PORTA.2 = 1
hserprint "we got a 1"
wait until PORTA.2 =0
hserprint "we got a 0" ' input is toggling
~~~~~~~
*******
If it toggles then you know your input is working.
now make your own pulse measurement code
*******
count = 0
Do While PortA.2 = On
Wait 1 100us
count += 1
HSerprint count
If count = 0 Then Exit Do
Loop
HSerprint "outside loop now"
HSerprint count
~~~~~~~
Good luck
Sometimes just sleep on it and try tommorrow.
mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
PulseIn code is working alright. Using 8MHz clock is going to give the micro more overhead to get things done. Upon further review it looks like not having a pulldown on the PulseIn pin may give better results when working with 10us period, try without. Working on a breadboard and scratching Vdd with a wire is not the way to do this, but I can verify readings :) ....(still using 100 Ms for loop delay).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
hserprint "before wait for 1"
wait until PORTA.2 = 1
hserprint "we got a 1"
wait until PORTA.2 =0
hserprint "we got a 0" ' input is toggling
so trying this i get the confirmation of the pin high/low transition being detected
then gave this a try
count = 0
Do While PortA.2 = On
Wait 1 100us
count += 1
HSerprint count
If count = 0 Then Exit Do
Loop
HSerprint "outside loop now"
HSerprint count
error again about delay units not specified only cleared by changing wait 1 100us to wait 1 10us and when run i either just get a count value of either 1 or 0.
if i change the wait 1 10us to wait 10 10us then i get still either just 0 or 1
so now i am here which is where it seems to be staying
; FILE: hardware uart alternate pins.gcb
; ----- Configuration
'Set chip model:
chip 12F1840, 4
include <stdbasic.h>
'set uart TX/RX pins to RA4 and RA5 alternate pin locations:
set APFCON.7 = 1
set APFCON.2 = 1
'Set the pin directions:
Dir PORTA.4 Out 'send on Pin 3
Dir PORTA.5 In 'receive on Pin 2
Dir PORTA.2 in 'signal pulse input
'Config Hardware-UART:
define USART_BLOCKING
define USART_BAUD_RATE 4800
Do
count = 0
Do While PortA.2 = On
Wait 10 10Us
count += 1
HSerprint count
If count = 0 Then Exit Do
Loop
HSerprint "outside loop now"
hserprint crlf
HSerprint count
Loop
it doesnt matter what frequency i run it at or whether or not the pulldown is their or not i am not seeing anything other than 0 or 1, across multiple chips that otherwise work with this equipment if used in another ide, whats going on with this?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First there should be no need to Set the IRCF bits or to include the stdbasic.h file. If the compiler is doing it's job, this will be done automatically. It does for me. So remove those lines.
Pulsein is a Macro located in the stdbasic.h file and reads as follows.
'PulseIn
macro PulseIn (Pin, Variable, Units)
Variable = 0
Do While Pin = On
Wait 1 Units
Variable += 1
If Variable = 0 Then Exit Do
Loop
end macro
.
This cannot possibly work for accurate readings in the servo range of 750us to 2500us due to processing overhead. At 4 MHz each instruction cycle is 1us and there are a bunch due to the loops and the ifs. This command can only do rough readings at higher pulse widths since there is no accounting for instruction overhead.
I got the same results as you with a PIC12F1840 (Repurposed Picaxe 08M2) at 4mhz. It outputted "O" as the Pulsein command did not properly catch the high signal and never counted anything. It needs some work to be more usable.
Whats nice about GCB is that you can write your own "commands" in the form of subs or macros and when compiled they run really fast.
I propose you create your own command that works better than GCB's limited PulseIn. The code below shows how I did it to get microsecond us accuracy in the range of servo pulse widths.
A Picaxe was programmed to send pulses of exactly 750us and 2500us spaced 20ms apart (50Hz). These were sent to the PIC12F1840 PORTA.4 with a 22K pull down resistor on PORTA.4. I did not redirect the TX or RX. I created a sub called ReadPulse to replace PulseIn. Here's the Complete Code:
; Test Code to Read Servo Pulses - William Roth
#chip 12f1840, 32
#Config PLLEN_ON
;USART settings
#define USART_BAUD_RATE 9600
#define USART_BL0CKING
Dir PORTA.0 Out
Dir PortA.4 IN
''' LONG required for large maths but adds extra instruction cycles
''' Could be done with WORD and casting - later maybe
DIM Pulse_Width as LONG
; ****** MAIN PROGRAM STARTS HERE ******
''' Main loop
Do
ReadPulse
wait 1 ms
HSerPrint pulse_width
HSerPrintCRLF
Wait 1 ms
Loop
sub ReadPulse
Pulse_width = 0
''' Loop 1
''' Wait for Pin to go high
''' Warning no time out !
do while PORTA.4 = OFF
loop
''' Loop 2
''' no delay, we will count loops then calculate time later
''' increment variable every loop
''' exit when input pin goes low
do While PORTA.4 = ON
Pulse_Width += 1
Loop
''' calculate the pulse width in microseconds
''' number of loops * 11 instruction cycles * 125 nano seconds / 1000
''' then subtract 1 or 2 us to allow for time to jump from loop 1 to loop 2
Pulse_Width = Pulse_width * 11 * 125 / 1000 -2
end sub
; This might could be used as a starting Point for a better PulseIn Command
; Accuracy over the range of 750us to 2500us should be within about 2 - 3 us
.
.
Use this code exactly as above with no changes. It works well for me.
Remap the TX/RX pins after this is confirmed to work ok.
William
Last edit: William Roth 2015-02-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
With casting it should be even more accurate as incrementing a word takes 4 less instruction cycles than incrementing a long variable. The code below uses casting so that the loop increments a WORD instead of a LONG. So we multiply by 7 instruction cycles instead of 11.
;Test Code to Read Servo Pulses - WMR
#chip 12f1840, 32
#Config PLLEN_ON
;USART settings
#define USART_BAUD_RATE 9600
#define USART_BL0CKING
Dir PORTA.0 Out
Dir PortA.4 IN
DIM Num_Loops as WORD
DIM Pulse_Width as Word 'LONG required for pulse widths > 65535 us
; MAIN PROGRAM STARTS HERE
''' Main loop
Do
ReadPulse
wait 1 ms
HSerPrint Pulse_Width
HSerPrintCRLF
Wait 1 ms
Loop
sub ReadPulse
Num_Loops = 0
''' Loop 1
''' Wait for Pin to go high
''' Warning no time out !
do while PORTA.4 = OFF
loop
''' Loop 2
''' no delay, we will count loops then calculate time later
''' increment variable every loop
''' exit when input pin goes low
do While PORTA.4 = ON
Num_Loops += 1
Loop
''' calculate the pulsewidth in microseconds
''' number of loops * 7 instruction cycles * 125ns / 1000
''' subtract 1 or 2us to allow for jump from loop 1 to loop 2
Pulse_Width = [LONG]Num_loops * 7 * 125 / 1000 -1
end sub
Last edit: William Roth 2015-02-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Tony and William,
I didn't have chance until this afternoon to set up a protoboard to test the program. I saw William's post and tried it. Then like any good code, I had to modify it to measure both the on part and the off part of a pulse.
~~~~~~~~
'A program to measure the pulse width of a servo in uS
' actualy it measure both the on period and the off period
'
'Chip model
chip 16F886, 8
'Set USART receive pin to input
Dir PORTC.7 In
Dir PORTC.6 Out
'Set the pin directions
dir PORTB.0 out
dir PORTB.1 out
Dir PORTA.2 in 'signal pulse input
'Config Hardware-UART:
define USART_BLOCKING
define USART_BAUD_RATE 4800
'Turn one LED on,
SET PORTB.0 ON
wait 1 sec
'Now toggle the LED
SET PORTB.0 OFF
wait 1 sec
'Main routine
Start:
hserprint "Pulse ON Time Pulse Off time for one cycle"
DIM Pulse_Width_On as LONG
DIM Pulse_Width_Off as LONG
; *** MAIN PROGRAM STARTS HERE ***
''' Main loop
Do
ReadPulse
wait 1 ms
HSerPrint pulse_width_On
HSerPrint " <on...off> "
HSerPrint pulse_width_Off
HSerPrintCRLF
Wait 1 sec
Loop
sub ReadPulse
Pulse_width_On = 0
Pulse_width_Off = 0
''' Loop 1
''' Wait for Pin to go high
''' Warning no time out !
do while PORTA.2 = OFF
loop
''' Loop 2
''' no delay, we will count loops then calculate time later
''' increment variable every loop
''' exit when input pin goes low
do While PORTA.2 = ON
Pulse_Width_On += 1
Loop
do While PORTA.2 = OFF
Pulse_Width_Off += 1
Loop
''' calculate the pulse width in microseconds
''' number of loops * 11 instruction cycles * 125 nano seconds / 1000
''' then subtract 1 or 2 us to allow for time to jump from loop 1 to loop 2
Pulse_Width_On = Pulse_width_On * 11 * 500 / 1000 -2
Pulse_Width_Off = Pulse_width_Off * 11 * 500 / 1000 -2
end sub
goto Start
' results of using a short open ended jumper onto PortA.2 as an antenna
' to receive 60 hz out of the air . this is a sample of the printout
'9177 <on...off> 7483
'9172 <on...off> 7483
'9188 <on...off> 7483
'9188 <on...off> 7467
'9177 <on...off> 7478
'9194 <on...off> 7467
' these are in uS and total up to 1/60 sec or ~16660uS
~~~~~~
I used a different processor at a different clock speed.
I measured hum in the air and the results are very good.
Just a bit ago I saw that William modified his code. I did not try that.
73
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
bill i have just tried the first code and its spot on, and now with the pin config changed it becomes
; Test Code to Read Servo Pulses - William Roth
#chip 12f1840, 32
#Config PLLEN_ON
;USART settings
#define USART_BAUD_RATE 9600
#define USART_BL0CKING
'set uart TX/RX pins to RA4 and RA5 alternate pin locations:
set APFCON.7 = 1
set APFCON.2 = 1
'Set the pin directions:
Dir PORTA.4 Out 'send on Pin 3
Dir PORTA.5 In 'receive on Pin 2
Dir PORTA.2 in 'signal pulse input
''' LONG required for large maths but adds extra instruction cycles
''' Could be done with WORD and casting - later maybe
DIM Pulse_Width as LONG
; ****** MAIN PROGRAM STARTS HERE ******
''' Main loop
Do
ReadPulse
wait 1 ms
HSerPrint pulse_width
HSerPrintCRLF
Wait 1 ms
Loop
sub ReadPulse
Pulse_width = 0
''' Loop 1
''' Wait for Pin to go high
''' Warning no time out !
do while PORTA.2 = OFF
loop
''' Loop 2
''' no delay, we will count loops then calculate time later
''' increment variable every loop
''' exit when input pin goes low
do While PORTA.2 = ON
Pulse_Width += 1
Loop
''' calculate the pulse width in microseconds
''' number of loops * 11 instruction cycles * 125 nano seconds / 1000
''' then subtract 1 or 2 us to allow for time to jump from loop 1 to loop 2
Pulse_Width = Pulse_width * 11 * 125 / 1000 -2
end sub
; This might could be used as a starting Point for a better PulseIn Command
; Accuracy over the range of 750us to 2500us should be within about 2 - 3 us
measuring 1506us for centre
920us for low
2094us for high.
now thats more like im used to seeing, thank you that works perfectly (but im sure you knew it would :P ) now i will play with the second one and see how each differs.
tony
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As a relatively new GCB user myself, I can tell you that GCB is extremely versatile, but sometimes you have to look at things differently than with interpreted basics where everything is done for you invisibly under the hood.
Unlike interpreted BASIC, with CGB you can look under the hood and see what's happening (and make changes if you are careful). I imagine that the Pulsin used in that other Basic is interrupt/Timer based and therefore more accurate than the bit-banged PulseIn added to GCB. I do not think that GCB's PulseIn was intended to measure pulses to microsecond accuracy. GCB's PulseIn is a rare case of a not very well implemented "command".
But, as you can see from the example code that that I did, that even without interrupts and timers, GCB is versatile enough so that a moderately experienced programmer can write relatively simple BASIC code to do stuff at ASM speed.
Also understand that the Author of GCB (Hugh Considine) and the Volunteer Developers such as Anobium and others look at these posts and take things to heart to make improvements and correct bugs as soon as practical. GCB is improving by leaps & bounds on a near daily basis.
I imagine that PulseIn will get some official attention in the near future.
Stick around you will see GCB get even better.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Looking back at my Vex receiver code, I see that it used polling as previously suggested. That made me want to revisit and apply to some Futaba Tx/Rx parts that I had. The results were consistent and repetitive, although the range seemed slightly limited. I'll call it a rough and ready version compared to Williams more precise solution.
'Decoding a Futaba Magnum Jr. TX and
'Futaba FP-R233UE 2 channel receiver
'Rough calibration routine is to
'Trim servo channel for no jitter
'Then adjust Do While loop to approx. 150
'(i.e. 150 x 10us is 1.5ms center)
'Could make use on nop's here if needed
'Servo values are from 113 to 172
'Kent Schafer 2/26/2015
#chip 12f1822, 16
'Set the pin directions
Dir PortA.0 Out 'TX on 12f1822
Dir PortA.2 IN 'PPM channel
#define PPM PortA.2
dim TimerHigh, TimerLow, RMotorHigh, RMotorLow, RMotorOut as word
'Config Hardware-UART:
#define USART_BLOCKING
#define USART_BAUD_RATE 256000
Main:
TimerHigh = 0
TimerLow = 0
'TimerHigh output is zero if PPM
'is tested High first. Reason??
'Do While PPM On '= 1
' wait 8 us
' TimerHigh = TimerHigh + 1
'Loop
Do While PPM Off '= 0
wait 8 us 'adjust as required
TimerLow = TimerLow + 1
Loop
Do While PPM On '= 1
Wait 8 us 'adjust as required
TimerHigh = TimerHigh + 1
Loop
RMotorHigh = TimerHigh 'First channel
RMotorLow = TimerLow 'First channel
RMotorOut = RMotorHigh+RMotorLow
HSerPrint RMotorHigh
HSerPrint " "
HSerPrint RMotorLow
HSerPrint " "
HSerPrint RMotorOut
HSerPrint " "
HSerSend 10
HSerSend 13
goto Main
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
i have been trying to capture an RC receiver pulse value and transmit it via the chips hardware usart to a terminal so i can see its value but after spending several hours last night going through most things in the manual and doing forum searches i still cannot get anything to show on the terminal other than zero.
i am using the pulsin command and have yet to see a value on the screen for the pulse.
i changed over to a picaxe on my breadboard last night to make sure my receiver was good and it was happily measuring the pulse and transmitting the value so my receiver is ok.
clearly i have/am missing something and need some more experienced eyes to help as i cannot seem to get anywhere relying on the help manuals or forum search results.
ide is gcb@syn
chip is pic 12f1840
uart functions moved to alternate pins
pulse signal input from receiver to pin RA2 via 470r resistor
breadboard circuit/receiver all running from regulated supply of 5v
code:
i simply want to be able to measure the pulse value and display it on the terminal.
the chips uart pins are going out to my ftdi-usb adapter, i can use serprint/sersend to output data with no issues that i can view but trying to get a measured pulse seems to be a challenge.
pulsein is a feature that i use alot with most of my picaxe code that i need to port over to gcb so i need to get this working/understand everything better
thanks,
tony
Last edit: tony golding 2015-02-25
also to mention i have also tried setting the variable to hold the pulse value as a word and tried hsersend as well all efforts so far to try and either understand the manual examples or to get any form of success are not getting anywhere
Try shorter time period.
Pulsein PORTA.2,rxvalue, 10 us
Do you get a result?
ill alter that and get back to you, i wasnt sure if the time period specified per the manual was a timeout period for a max time to wait for a signal.
tony
Last edit: tony golding 2015-02-25
i get a warning about innaccurate ms delay due to clock speed and use of variable
also still getting nothing other than zeroes and the occasional 1 or 4.
if i do it with the picaxe i get a changing value from 90 to 210 depending on the position i place the switch in on my transmitter but still nothing with this using gcb
tony
Anobium, the PulseIn Help (GCBasic web site) example is missing a comma between PortPin and variable. And, port pin and variable are swapped from prototype Syntax, even though it compiles both ways.
There is no space between the "10" and "Us", ie 10Us.
P.S. GCBasic automatically sets the OSCCON register.
Last edit: kent_twt4 2015-02-25
ok changingthe 10 us to 10us has eliminated the error warning but i am still getting absolutely nothing but zeroes sent to the terminal via the usart
so i take it no one can really offer any help then?
i have been going around for hours last night and these last few today.
my equipment being used is all functioning correctly and tested multiple ways, a second 12f1840 has been tetsed with the same results.
both 12f1840's have been tested using mplabx and the timer1gate method of capturing a pulse and that works so why do i get no results with gcb regardless of any attempts?
Last edit: tony golding 2015-02-26
I have setup a PIC12f1822 on a breadboard, so same family more or less as the 12f1840. Using default RX/TX locations and PicKit2 UART Tool. The setup on the breadboard has a problem unless I have a 10k pulldown resistor (might even need less) on the PulseIn pin. Make sure micro has a bypass cap too. I also found that using less of a wait period in the loop helpful, like 100 Ms.
Been a long time since playing with an RC transmitter, but doesn't that invert the logic? If that is the case then the PulseIn logic needs modifying, and then could use the internal pullup of the PulseIn pin.
Tony,
By looking under the hood in include/stdbasic.h you would find that PulseIn is a macro.
~~~~~~
'PulseIn
macro PulseIn (Pin, Variable, Units)
Variable = 0
Do While Pin = On
Wait 1 Units
Variable += 1
If Variable = 0 Then Exit Do
Loop
end macro
~~~~~
It looks like the third passing variable is "Units" of the "wait" timer,not a time out like you supposed.
So you are looking for 0.5ms to 2.5ms on a servo for your range so the suggested unit of 10uS seems logical. It would give a range of 50 to 250 .
So there is two ways out of the Do Loop
1) Pin goes low
2) variable overflows to 0
trouble shooting? you want to divide and conquer. little steps
So you should test your serial connection first by sending some numbers and seeing them show up . Or send a greeting and explanation. or some units after the number sent.
73
Mike
hi mike,
if i manually set the value of rxvalue then it will transmit fine to the terminal where i can see it correctly, it is also the same for sending any text, all good,
even after adding the stdbasic.h include and setting the units to 10us i still get nothing but zero back on the terminal when trying the pulsein command.
tony
kent,
i have the bypass cap on the 12f thats a good habit at least ive managed to get into, i just added a 10k pulldown onto the pulsein pin also so will change the values and see.
i have used my logic analyzer on the output of the rx and as far as i can see from the signal it is as expected a low to high transition for the start of the pulse period im trying to capture.
thanks,
tony
so is their a problem with the pulsein command itself? does it not actually function like the help guide says it does because nothing works
Tony,
Because your HSerrint is working use it to your advantage.
Don't get hung up on pulsein. It is only six lines of code that you can built right into a practice program putting HSerprints of the count or position in the program out to your terminal.
I agree with Kent that it still could be hardware. I made a low speed freq counter program on an '887 that would pick up 60 hz off of a 4 inch jumper that was not terminated(antenna).
try something simple like
count = 0
Do While PortA.2 = On
Wait 1 100us
count += 1
HSerprint count
If count = 0 Then Exit Do
Loop
HSerprint "outside loop now"
HSerprint count
~~~~~~~
Good luck
Sometimes just sleep on it and try tommorrow.
mike
PulseIn code is working alright. Using 8MHz clock is going to give the micro more overhead to get things done. Upon further review it looks like not having a pulldown on the PulseIn pin may give better results when working with 10us period, try without. Working on a breadboard and scratching Vdd with a wire is not the way to do this, but I can verify readings :) ....(still using 100 Ms for loop delay).
hserprint "before wait for 1"
wait until PORTA.2 = 1
hserprint "we got a 1"
wait until PORTA.2 =0
hserprint "we got a 0" ' input is toggling
so trying this i get the confirmation of the pin high/low transition being detected
then gave this a try
count = 0
Do While PortA.2 = On
Wait 1 100us
count += 1
HSerprint count
If count = 0 Then Exit Do
Loop
HSerprint "outside loop now"
HSerprint count
error again about delay units not specified only cleared by changing wait 1 100us to wait 1 10us and when run i either just get a count value of either 1 or 0.
if i change the wait 1 10us to wait 10 10us then i get still either just 0 or 1
so now i am here which is where it seems to be staying
; FILE: hardware uart alternate pins.gcb
; ----- Configuration
'Set chip model:
chip 12F1840, 4
include <stdbasic.h>
'set uart TX/RX pins to RA4 and RA5 alternate pin locations:
set APFCON.7 = 1
set APFCON.2 = 1
'Set the pin directions:
Dir PORTA.4 Out 'send on Pin 3
Dir PORTA.5 In 'receive on Pin 2
Dir PORTA.2 in 'signal pulse input
'Config Hardware-UART:
define USART_BLOCKING
define USART_BAUD_RATE 4800
Do
count = 0
Do While PortA.2 = On
Wait 10 10Us
count += 1
HSerprint count
If count = 0 Then Exit Do
Loop
HSerprint "outside loop now"
hserprint crlf
HSerprint count
Loop
it doesnt matter what frequency i run it at or whether or not the pulldown is their or not i am not seeing anything other than 0 or 1, across multiple chips that otherwise work with this equipment if used in another ide, whats going on with this?
Hi Tony, I think I can help with this.
First there should be no need to Set the IRCF bits or to include the stdbasic.h file. If the compiler is doing it's job, this will be done automatically. It does for me. So remove those lines.
Pulsein is a Macro located in the stdbasic.h file and reads as follows.
.
This cannot possibly work for accurate readings in the servo range of 750us to 2500us due to processing overhead. At 4 MHz each instruction cycle is 1us and there are a bunch due to the loops and the ifs. This command can only do rough readings at higher pulse widths since there is no accounting for instruction overhead.
I got the same results as you with a PIC12F1840 (Repurposed Picaxe 08M2) at 4mhz. It outputted "O" as the Pulsein command did not properly catch the high signal and never counted anything. It needs some work to be more usable.
Whats nice about GCB is that you can write your own "commands" in the form of subs or macros and when compiled they run really fast.
I propose you create your own command that works better than GCB's limited PulseIn. The code below shows how I did it to get microsecond us accuracy in the range of servo pulse widths.
A Picaxe was programmed to send pulses of exactly 750us and 2500us spaced 20ms apart (50Hz). These were sent to the PIC12F1840 PORTA.4 with a 22K pull down resistor on PORTA.4. I did not redirect the TX or RX. I created a sub called ReadPulse to replace PulseIn. Here's the Complete Code:
.
.
Use this code exactly as above with no changes. It works well for me.
Remap the TX/RX pins after this is confirmed to work ok.
William
Last edit: William Roth 2015-02-26
UPDATED CODE:
With casting it should be even more accurate as incrementing a word takes 4 less instruction cycles than incrementing a long variable. The code below uses casting so that the loop increments a WORD instead of a LONG. So we multiply by 7 instruction cycles instead of 11.
Last edit: William Roth 2015-02-26
well this is as far as i got last night finally getting some consistent and changing values when i changed the pulsevalue vie the rc transmitter
close but still not giving the values i expect so next is to digest andwork with your suggestion/example bill,
thankyou for the offering i shall get on with that today at least now some progress has been made.
also what are the code formatting tabs to make this darn code more suitable when posting?
tony
Last edit: tony golding 2015-02-26
Tony and William,
I didn't have chance until this afternoon to set up a protoboard to test the program. I saw William's post and tried it. Then like any good code, I had to modify it to measure both the on part and the off part of a pulse.
~~~~~~~~
'A program to measure the pulse width of a servo in uS
' actualy it measure both the on period and the off period
'
'Chip model
chip 16F886, 8
'Set USART receive pin to input
Dir PORTC.7 In
Dir PORTC.6 Out
'Set the pin directions
dir PORTB.0 out
dir PORTB.1 out
Dir PORTA.2 in 'signal pulse input
'Config Hardware-UART:
define USART_BLOCKING
define USART_BAUD_RATE 4800
'Turn one LED on,
SET PORTB.0 ON
wait 1 sec
'Now toggle the LED
SET PORTB.0 OFF
wait 1 sec
'Main routine
Start:
hserprint "Pulse ON Time Pulse Off time for one cycle"
DIM Pulse_Width_On as LONG
DIM Pulse_Width_Off as LONG
; *** MAIN PROGRAM STARTS HERE ***
sub ReadPulse
Pulse_width_On = 0
Pulse_width_Off = 0
''' Loop 1
''' Wait for Pin to go high
''' Warning no time out !
end sub
goto Start
' results of using a short open ended jumper onto PortA.2 as an antenna
' to receive 60 hz out of the air . this is a sample of the printout
'9177 <on...off> 7483
'9172 <on...off> 7483
'9188 <on...off> 7483
'9188 <on...off> 7467
'9177 <on...off> 7478
'9194 <on...off> 7467
' these are in uS and total up to 1/60 sec or ~16660uS
~~~~~~
I used a different processor at a different clock speed.
I measured hum in the air and the results are very good.
Just a bit ago I saw that William modified his code. I did not try that.
73
Mike
bill i have just tried the first code and its spot on, and now with the pin config changed it becomes
measuring 1506us for centre
920us for low
2094us for high.
now thats more like im used to seeing, thank you that works perfectly (but im sure you knew it would :P ) now i will play with the second one and see how each differs.
tony
Tony,
First a belated welcome to the GCB forums.
As a relatively new GCB user myself, I can tell you that GCB is extremely versatile, but sometimes you have to look at things differently than with interpreted basics where everything is done for you invisibly under the hood.
Unlike interpreted BASIC, with CGB you can look under the hood and see what's happening (and make changes if you are careful). I imagine that the Pulsin used in that other Basic is interrupt/Timer based and therefore more accurate than the bit-banged PulseIn added to GCB. I do not think that GCB's PulseIn was intended to measure pulses to microsecond accuracy. GCB's PulseIn is a rare case of a not very well implemented "command".
But, as you can see from the example code that that I did, that even without interrupts and timers, GCB is versatile enough so that a moderately experienced programmer can write relatively simple BASIC code to do stuff at ASM speed.
Also understand that the Author of GCB (Hugh Considine) and the Volunteer Developers such as Anobium and others look at these posts and take things to heart to make improvements and correct bugs as soon as practical. GCB is improving by leaps & bounds on a near daily basis.
I imagine that PulseIn will get some official attention in the near future.
Stick around you will see GCB get even better.
This looks like a good demonstration program!!
:-)
Glad Tony is on his way, and also welcome.
Looking back at my Vex receiver code, I see that it used polling as previously suggested. That made me want to revisit and apply to some Futaba Tx/Rx parts that I had. The results were consistent and repetitive, although the range seemed slightly limited. I'll call it a rough and ready version compared to Williams more precise solution.