| Author |
Message |
pjc30943
Joined: 02 Dec 2005
|
|
Posted: 24 July 2008, 20:15 PM Post subject: PulseOut issue |
|
|
The following fails to produce pulses on a 1280n. However, alternate calls putpin with 0 and 1 states yield a toggling pin, so the detection is correct.
| Code: |
const debugPin as byte = J.1
putpin debugPin, 0
do
pulseout debugPin, 1E-5, 1
sleep 0.001
loop
|
Anyone have thoughts? Most likely this is something silly I'm doing wrong... |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 25 July 2008, 0:55 AM Post subject: Re: PulseOut issue |
|
|
| pjc30943 wrote: | | The following fails to produce pulses on a 1280n. | I copied your code verbatim and placed in inside Sub Main() ... End Sub. Running it produces a pulse 10.2uS long beginning approximately every 46 uS.
Can you duplicate that as a simple test case? |
|
| Back to top |
|
 |
pjc30943
Joined: 02 Dec 2005
|
|
Posted: 30 July 2008, 2:45 AM Post subject: Re: PulseOut issue |
|
|
| dkinzer wrote: | | pjc30943 wrote: | | The following fails to produce pulses on a 1280n. | I copied your code verbatim and placed in inside Sub Main() ... End Sub. Running it produces a pulse 10.2uS long beginning approximately every 46 uS.
Can you duplicate that as a simple test case? |
It does work as written above.
It turns out the problem arises from a part of the initialization routine, where I alter TMR4 (see below). Or at least I *think* I'm only using TMR4. If this section is commented out, pulseOut() works. Otherwise, if it's called after the following code, nothing is outputted.
Doesn't pulseOut() use TMR2?
| Code: | '~~~~~~~~~~~~ PWM ~~~~~~~~~~~~~~
'based on TMR4 (PWM)
OpenPWM motor1PWMCh, SERVO_REFRESH_RATE, zxCorrectPWM 'set up for RC control
PWM motor1PWMch, SERVO_PWM_CENTER_PERCENT
PWM servo1PWMch, SERVO_PWM_CENTER_PERCENT '0.0625
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
with
| Code: | public const motor1PWMch as byte = 7 'ch8 PWM, L.4, based on timer 4
public const servo1PWMch as byte = 8 'ch7 PWM, L.3 |
EDIT:
Additionally, the following does not work inside the loop:
| Code: |
dim testVar as single
testVar = 1.0 / 1E5
pulseout debugPin, testVar, 1
'pulseout debugPin, 1.0 / 1E5, 1
|
but if the comments are swapped then it does:
| Code: |
'dim testVar as single
'testVar = 1.0 / 1E5
'pulseout debugPin, testVar, 1
pulseout debugPin, 1.0 / 1E5, 1
|
The literal appears to give the expected result. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 30 July 2008, 23:38 PM Post subject: Re: PulseOut issue |
|
|
| pjc30943 wrote: | | Doesn't pulseOut() use TMR2? | No. On a ZX-1280 or ZX-1280n the timer used for I/O functions like PulseOut() is Timer4. This information is found in the Resource Usage section of the System Library Reference. The I/O timer is indicated in the column of the table with the heading I/O. |
|
| Back to top |
|
 |
pjc30943
Joined: 02 Dec 2005
|
|
Posted: 31 July 2008, 1:05 AM Post subject: |
|
|
Ah, okay. Thanks for clarifying.
What is still unclear, then, is the varied outcome for a literal vs. variable parameter. I'll verify the code, as it's probably a simple mistake that I'm doing. |
|
| Back to top |
|
 |
pjc30943
Joined: 02 Dec 2005
|
|
Posted: 31 July 2008, 20:25 PM Post subject: |
|
|
I verified the code. This example does not produce pulses:
| Code: | Option TargetCPU zx1280n
public const debugPin as byte = J.1
public bvars as single
Sub Main()
putpin debugPin, zxOutputLow
bvars = 2E-5
do
'pulseout debugPin, 2E-5, 1
pulseout debugPin, bvars, 1
sleep 0.002
loop
End Sub |
but this does:
| Code: | Option TargetCPU zx1280n
public const debugPin as byte = J.1
public bvars as single
Sub Main()
putpin debugPin, zxOutputLow
bvars = 2E-5
do
pulseout debugPin, 2E-5, 1
'pulseout debugPin, bvars, 1
sleep 0.002
loop
End Sub
|
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 31 July 2008, 21:51 PM Post subject: |
|
|
| pjc30943 wrote: | | This example does not produce pulses | We were able to reproduce the problem and have identified both the cause and the solution. It is an issue with native mode code generation for PulseOut() when it has type Single, non-constant value for the duration parameter. The compiler correctly deduces that in this particular case the value of bvars might change over the iterations of the loop since it is a public variable and could be modified by another task.
A workaround is to either make bvars local to Main() or introduce a local variable to hold the value as shown in the code below. Using the local variable allows the compiler to see that the value of the duration won't change over the iterations of the loop and, hence, it can compute the duration in IO_Timer ticks at compile time. With a non-constant value, code is generated to convert the Single value to IO_Timer ticks at run time and it was this code that was incorrect.
| Code: | Option TargetCPU zx1280n
public const debugPin as byte = J.1
public bvars as single
Sub Main()
putpin debugPin, zxOutputLow
bvars = 2E-5
Dim duration as Single
duration = bvars
do
pulseout debugPin, duration, 1
sleep 0.002
loop
End Sub |
|
|
| Back to top |
|
 |
|