|
|
| Author |
Message |
DH* Guest
|
|
Posted: 09 January 2006, 14:28 PM Post subject: How would you do this in ZBasic? |
|
|
How would you do this in ZBasic?
Code fragments below have all parameters declared. It's easier to follow the flow without including them.
This fragment is at the top of my main loop. It looks for a start pulse that differs depending on which of three protocols is incoming.
| Code: | 'ip is Input Polarity
If (GetPin(11) = ip) Then
Register.TCCR1A = 0 'reset Timer1
Register.TCNT1H = 0
Register.TCNT1L = 0
Register.TIFR = TOV1 'TOV1 = bx0000_0100
Register.TCCR1B = 2 'start Timer1
Do
Loop Until (GetPin(11) = 0)
LowByte = Register.TCNT1L 'read Timer1
HighByte= Register.TCNT1H
PulseWidth = CInt(HighByte) * &H100 + CInt(LowByte)
End If |
This fragment is in a Sub that is called when a valid start pulse is detected.
| Code: |
If PulseWidth < 2500 Then
bits = 20
ElseIf PulseWidth < 4000 Then
bits = 44
Else
bits = 32
End If
For n = 0 To bits
Register.TCCR1A = 0 'reset Timer1
Register.TCNT1H = 0
Register.TCNT1L = 0
Register.TIFR = TOV1
Register.TCCR1B = 2 'start Timer1
Call WaitForInterrupt(bxPinRisingEdge)
LowByte = Register.TCNT1L 'read Timer1
HighByte= Register.TCNT1H
PulseTrain(n) = CInt(HighByte) * 256 + CInt(LowByte)
Next |
This was written for the original BX-24 (~16K instructions/sec). I'm hoping the ZX-24 will be fast enough that I can check (before the assignment to PulseTrain) for too long/short bit periods. Now I have to wait for n bits and then test each for validity.
All of the codes are transmitted multiple times so missing one is not crucial.
One problem is that the capture of the start pulse isn't very precise. The main loop may come around in the middle of a start pulse making it hard to determine how many data bits to expect.
With BasicX I was severely limited by memory and RAM and could not afford the overhead required to make the first routine a separate task.
The codes can be either RF or IR. With RF there's continuous noise on the input so the first fragment gets executed for a lot of short pulses. With IR the line is noise free.
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 09 January 2006, 16:50 PM Post subject: |
|
|
The code should work as written. The execution time (per instruction) will likely be about half of that for the BX-24. You can save a little time by using the MakeWord() function:
| Code: | | PulseWidth = CInt(MakeWord(LowByte, HighByte)) |
I'm a little puzzled by the line:
| Code: | | Loop Until (GetPin(11) = 0) |
If you're trying to measure the width of a "start pulse" that could be either polarity, it seems to me that the condition should be:
| Code: | | Loop Until (GetPin(11) <> ip) |
You may be able to employ RCTime() to replace much of the initial code. This code might accomplish the same objective:
| Code: | 'ip is Input Polarity
If (GetPin(11) = ip) Then
' set timer resolution to 542nS
Register.TimerSpeed2 = 2
' measure the time the input stays in the initial state
PulseWidth = RCTime(11, ip)
' restore default timer resolution
Register.TimerSpeed2 = 1
Else
PulseWidth = 0
End If |
One side effect of using RCTime() is that the pin will be changed to zxInputTriState. This is a problem only if you need a pullup but you can add an external pullup to solve that problem.
Since RCTime() will return immediately if the input is not in the specified state, the code below will probably do the same thing:
| Code: | ' set timer resolution to 542nS
Register.TimerSpeed2 = 2
' measure the time the input stays in the initial state
PulseWidth = RCTime(11, ip)
' restore default timer resolution
Register.TimerSpeed2 = 1 |
You also may be able to use this technique in the pulse width measurement subroutine.
Regarding the latency problem, using WaitForInterrupt() in a separate task would probably solve it. Depending on the complexity of the code in the task, you might be able to get by with as little as 30 to 50 bytes for the task stack and you might even be able to get it below 20 bytes.
|
|
| Back to top |
|
 |
DH* Guest
|
|
Posted: 09 January 2006, 17:17 PM Post subject: |
|
|
That was a quick edit of some existing code - I missed the
| Code: | | Loop Until (GetPin(11) = 0) |
I'm mostly interested in improving the accuracy of the start pulse. There are two protocols with identical start pulses but with different spaces that follow and with a different bit pattern that I would like to handle.
There are already a few hundred boards in use (with BX-24). I'd prefer not to have existing users add a pull-up. But if they want to upgrade to a ZX-24 to get added features I'm sure you won't mind that.
Moving the start pulse test to another task would probably be best but I'm still concerned about the overhead. While you offer a lot more RAM I currently use four instantiations of the BX-24's software Com3 UART reconfiguring it on the fly. With the ZX-24 I can make all permanent but their queues will eat up much of the additional RAM.
Another feature I had asked NetMedia for was a version of OutputCapture that could specify a carrier frequency and a number of cycles to send. This would make it easy to send IR codes.
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 09 January 2006, 17:42 PM Post subject: |
|
|
| Quote: | | I'm mostly interested in improving the accuracy of the start pulse. |
The higher speed of the ZX will help in this regard. Still, the latency problem will depend a lot on how much other work is being done. I understand your desire to avoid using a separate task. One of the costs of that design decision may be less accuracy than is otherwise attainable.
| Quote: | | There are already a few hundred boards in use (with BX-24). I'd prefer not to have existing users add a pull-up. |
Depending on the time frame and other factors, you may want to consider using a ZX-44 (or ZX-40) instead. They are much better OEM solutions than the ZX-24.
Just to be clear, an external pullup is not required in order to use the RCTime() method. I was simply pointing out that one side effect of invoking RCTime() is that it will change the pin to zxInputTriState. If the pin is already in that state then that fact is inconsequential. On the other hand, if your external circuitry relies on the (weak) pullup of the ZX chip, then an external pullup would be required to replace it.
|
|
| Back to top |
|
 |
DH* Guest
|
|
Posted: 09 January 2006, 18:56 PM Post subject: |
|
|
| Quote: | | Depending on the time frame and other factors, you may want to consider using a ZX-44 (or ZX-40) instead. They are much better OEM solutions than the ZX-24. |
This is not an OEM product. It is not even a product. It was a DIY project. I supplied the firmware, a Windows interface app, PDF documentation, a board design (bare boards were available at cost + S&H) and a bill of materials with Mouser P/Ns.
Had I wanted to do it as a product I would have used a PIC or Atmel AVR.
All I'm looking for is a way to add some features that the BX-24 would not allow. All existing users will have to do is unplug their BX-24, plug in a ZX-24 and download new firmware. I'm not sure how many would consider the added features worth the cost of the ZX-24. Nor am I sure how many would build it new given the higher cost of the ZX-24.
I've attached the user manual.
| Description: |
| This is the user manual for the BX24-AHT DIY project. |
|
 Download |
| Filename: |
manual.zip |
| Filesize: |
143.32 KB |
| Downloaded: |
2837 Time(s) |
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 09 January 2006, 19:23 PM Post subject: |
|
|
| Now I understand. Your name was familiar to me but I didn't make the connection to the BX24 AHT Yahoo group.
|
|
| Back to top |
|
 |
|