Page 1 of 1

1ms in ZBasic

Posted: 01 March 2007, 20:47 PM
by hacktorious
I just learned Pbasic and I am now working on learning Zbasic by converting some of my BS2 programs to my ZX-24a. I am bumping into some issues though. Some I have figured out some I have not.

How can I create a time of 1ms in zbasic to use with the FreqOut command? There are several other instances where I need 1ms, 1.5ms etc. I read the docs on zbasic and am now thoroughly confused on how to create these times.

It seems to me zbasic has issues with values under 2ms.

Please help. Thanks.
:lol:

Re: 1ms in ZBasic

Posted: 01 March 2007, 21:11 PM
by mikep
hacktorious wrote:How can I create a time of 1ms in zbasic to use with the FreqOut command? There are several other instances where I need 1ms, 1.5ms etc. I read the docs on zbasic and am now thoroughly confused on how to create these times.
I think we need to start with the question of what are you trying to do. The 1ms, 1.5ms, 2ms times mentioned look suspiciously like the pulse times needed for a servo. If so then you should look at PulseOut and not FreqOut.

The RTCTick is 1.95ms but that does not mean ZBasic has trouble with producing signals with a smaller duration.

Re: 1ms in ZBasic

Posted: 01 March 2007, 21:24 PM
by dkinzer
hacktorious wrote:How can I create a time of 1ms in zbasic to use with the FreqOut command?
The fourth parameter to FreqOut() can be either an integral value or a floating point value. If you use an integral value, the duration of the output signal is approximately that many milliseconds. Alternately, if you use a floating point value the duration will be approximately that length of time in seconds with a resolution of 1mS.

The call below will result in a signal with a duration of about 1mS.

Code: Select all

Call FreqOut(12, 1000, 1000, 1.0e-3)
As noted above, the resolution of the output duration is approximately 1mS. The call below will result in a signal with a duration of about 5mS.

Code: Select all

Call FreqOut(12, 1000, 1000, 5.5e-3)
The value of 1.5mS that you mentioned is not possible since the resolution is approximately 1mS.

If you need higher resolution, you should look at OutputCapture(). Whereas FreqOut() outputs two combined frequencies (such as is needed for DTMF generation), OutputCapture() can only output a single frequency. Another difference is that the output of FreqOut() is a synthesized sine wave whereas the output of OutputCapture is a square wave.

What is it that you're trying to accomplish?

Re: 1ms in ZBasic

Posted: 01 March 2007, 21:42 PM
by dkinzer
hacktorious wrote:It seems to me zbasic has issues with values under 2ms.
Each of the time-based System Library routines has limitations and an inherent resolution that are described in the manual pages for each routine. Some of them have a resolution of 1.95mS because they are based on the real time clock which has that resolution. Other routines have various other resolutions dictated by the way that they are implemented. The PulseIn() and PulseOut() routines have a resolution of 1.085uS and the InputCapture() and OutputCapture() routines have a resolution of 67.8nS.

Posted: 02 March 2007, 7:03 AM
by hacktorious
Great info, thanks.

At the moment I am just trying to use some IR sensors to detect objects.

Soon I will be attempting to drive some motors to get the BOE-Bot to drive around.

I am using the FreqOut command to enable a Piezo to make sound.

Here is my code so far:

Code: Select all

Sub Main()

' Robotics with the Boe-Bot - FastIrRoaming.bas
' Higher performance IR object detection assisted navigation

  Console.WriteLine("Program Running!")
	
  Dim irDetectLeft  As Byte
  Dim irDetectRight As Byte	
  Dim pulseLeft     As Integer
  Dim pulseRight    As Integer
	
  Call PutPin(C.0,zxOutputHigh)
  Call FreqOut(C.3,3000,3000,400) 
	
  Do
    Call FreqOut(C.0,38500,38500,	
    irDetectLeft = GetPin(C.3)
  Loop
End Sub

Posted: 02 March 2007, 13:23 PM
by dkinzer
hacktorious wrote: Call FreqOut(C.0,38500,38500,1)
You probably have noticed that the maximum frequency that can be generated by FreqOut() is 14.4KHz. For driving an IR emitter, you don't really need a sine wave - you need a square wave instead. The OutputCaptureEx() routine can easily generate a square wave frequency burst by using the optional fifth parameter that specifies a cycle count. The code below shows how this can be done using a calling sequence similar to the PBasic FreqOut routine. If you want better than 1mS resolution on the burst duration, you could change the second parameter to OutBurst() to be type Single.

Code: Select all

'
'' OutBurst
'
' This subroutine is similar in function to PBasic's FreqOut.  The
' 'duration' parameter is the number of milliseconds for the length
' of the burst and the 'freq' parameter is the frequency of the
' burst in Hertz.
'
' Note that the duration parameter could be changed to a Single type
' to allow better resolution.
'
Sub OutBurst(ByVal pin as Byte, ByVal duration as UnsignedInteger, ByVal freq as UnsignedInteger)
  Const resolution as Single = 67.8E-9
  Const maxCount as Single = 65535.0
  Const level as Byte = 1
  Dim data(1 to 2) as UnsignedInteger
  Dim period as Single
  Dim t as Single
  Dim cycles as UnsignedInteger

  ' confirm that the frequency is not too low to handle
  If &#40;freq < CUInt&#40;1.0 / resolution / maxCount / 2.0&#41;&#41; Then
    Exit Sub
  End If
  
  ' compute the period of the burst and the duration, both in seconds
  period = 1.0 / CSng&#40;freq&#41;
  t = CSng&#40;duration&#41; / 1000.0

  ' confirm that the duration is neither too short nor too long
  If &#40;&#40;t < period&#41; Or &#40;t > &#40;period * maxCount&#41;&#41;&#41; Then
    Exit Sub
  End If

  ' compute the high/low times for the output
  data&#40;1&#41; = CUInt&#40;period / resolution&#41; \ 2
  data&#40;2&#41; = data&#40;1&#41;

  ' compute the number of cycles to generate
  cycles = CUInt&#40;t / period&#41;

  ' generate the frequency burst
  Call OutputCaptureEx&#40;pin, data, 2, level, cycles&#41;
End Sub

Posted: 02 March 2007, 17:46 PM
by hacktorious
HUH?

I don't understand the params for the OutputCaptureEx command. I read the manual, but it didn't help. I need it dumbed down a bit...lol

Posted: 02 March 2007, 18:23 PM
by dkinzer
hacktorious wrote:I don't understand the params for the OutputCaptureEx command.
Both OutputCapture() and OutputCaptureEx() can generate an arbitrary waveform. You specify the waveform to be generated by giving the duration of the successive segments (high, low, high, etc.) of the desired waveform.

OutputCapture() is limited to generating the waveform on a specific pin, e.g. on the ZX-24 it is pin 27. OutputCaptureEx() is more flexible - it can generate a waveform on any output pin. It also has the ability to specify a repeat count so that the waveform specified by the segment duration array is repeated a number of times.

For OutputCaptureEx() the first parameter is the pin on which the waveform will be output. The second parameter refers to the array containing the segment duration values while the third parameter specifies how many segment duration values are in the array. The duration of each waveform segment is 67.8nS times the segment duration value, e.g. the value 10 specifies a duration of 678nS.

The fourth parameter is a set of flags that controls the generation process. Currently, only the least significant bit has meaning - it specifies whether the first waveform segment should be logic zero or logic one. Which value you should choose depends on the external circuitry that you are driving, particularly the idle state that it might need.

The fifth and last parameter is optional. If it is present, it is a "repeat count" that specifies how many times the data values in the array should be utilized. If you omit the fifth parameter, the data values are used just once and you get a waveform that corresponds to the duration values.

The capabilities of OutputCaptureEx() are exploited in OutBurst() by specifying duration of the equal-length high and low times of the square wave at the desired frequency (i.e. two equal segment duration values). Then, the iteration capability is used to repeat that one cycle a number of times so that the desired burst duration is achieved.

Does that help?