That is correct. The mega328 only has one 16-bit timer and its uses for PWM and for I/O timing (e.g. PulseIn) are mutually exclusive. If you're not using Timer2 for other purposes, you could use 8-bit PWM instead. Besides 8-bit PWM the only other routines in the ZBasic Library that use Timer2 are the software UART channels (3-6).liam.zbasic wrote:Could it by that PWM and PULSEIN will not work together in the same program and 328n device?
InputCapture vs. PulseIn w/CallTask
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
That's a relief - only one 16-bit timer. I was beginning to think my 328n chip was damaged. It's an early device with limited program memory. Anyway, 8-bit resolution for output-distance-in-volts is too low. I'll trying using the "GetElapsedMicroTime" function and count how long the sensor is HIGH. This approach will not interrupt the 16-bit timer, right?
Correct. The "micro time" value is merely a combination of the RTC tick value and the RTC timer count value at the time of the call. It's the latter element that gives the resultant value the higher resolution, equal to the inverse of Register.RTCTimerFrequency.liam.zbasic wrote:This approach will not interrupt the 16-bit timer, right?
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
It Works! I am able to measure ultrasonic distance without PulseOut and PulseIn commands and continuously output distance as a voltage with PWM. Now I can use my zx328n device as a slave dedicated to streaming pseudo-analog distance without SPI or I2C communication.
The trigger-pulse was done with simple PutPin & Pause combinations, and the echo was measured with GetElapsedMicroTime. The calculated distance has a negligible error due to "ticks" stolen by the if/then statements. I enclosed the code for those interested.
The trigger-pulse was done with simple PutPin & Pause combinations, and the echo was measured with GetElapsedMicroTime. The calculated distance has a negligible error due to "ticks" stolen by the if/then statements. I enclosed the code for those interested.
Code: Select all
option base 1
option TargetDevice zx328n
public const runtime as single = 300.0 ' (sec)
public const ping_pin as byte = 14 ' Ping sonar sensor output (zx328n)
public const pwm_hz as single = 20000.0 ' PWM Frequency (hz)
public const sos as single = 13397.2441 ' Speed of sound (in/sec) at sea-level (std. atm.)
public const max_dx as single = 108.0 ' Ping sensor max distance (inches)
sub main()
dim hour as byte, minute as byte, sec as single
dim t as single, told as single, dt as single, tick as single
dim listen as byte, wait as byte, go as integer, t0(1 to 5) as Byte
dim n as UnsignedLong, echo_n as UnsignedLong, echo_t as single, echo_dx as single, duty as single
' INITIALIZE PWM
'---------------------------
call closepwm(1) 'zx328 device: pwm1 is pin 15
Call OpenPWM(1, pwm_hz, zxFastPWM)
Register.TCCR1B = Register.TCCR1B Or &H01 ' temporary workaround to set prescaler for freq. > 225Hz
' MAIN LOOP
'--------------
tick = csng(Register.RTCTimerFrequency)
max_dt = max_dx / sos
t = 0.0
dt = 0.0
told = 0.0
duty = 0.0
while t <= runtime
call GetTime(hour, minute, sec)
t = CSng(minute)*60.0 + sec
dt = t - told
told = t
' BUILD TRIGGER PULSE
'----------------------------------
Pause(0.001000) ' delay for next measurement
Call PutPin(ping_pin, 0): Call Pause(0.000005) ' trigger pulse low
Call PutPin(ping_pin, 1): Call Pause(0.000005) ' trigger pulse high
Call PutPin(ping_pin, 0): Call Pause(0.000005) ' trigger pulse low
' COUNT RETURN PULSE
'---------------------
go = 1
wait = 0
do while (go = 1)
listen = GetPin(ping_pin)
' PULSE LEADING EDGE
if (listen = 1) AND (wait = 0) then
Call GetMicroTime(t0)
wait = 1
end if
' PULSE TRAILING EDGE
if (listen = 0) AND (wait = 1) then
echo_n = GetElapsedMicroTime(t0)
echo_t = csng(echo_n) / tick
go = 0
end if
loop
' CALCULATE DISTANCE
'---------------------
echo_dx = echo_t * sos / 2.0 ' Equation halved for one-way distance, not round-trip
' CONVERT DISTANCE TO PWM DUTY-CYCLE
'-----------------------------------
duty = echo_dx/max_dx * 100.0
Call PWM(1, duty)
'debug.print "time = " & t & " dx = " & echo_dx & " duty = " & duty & " v = " & duty/100.0*5.04
wend
end sub