In a world filled with inexpensive embedded processor development boards and modules, I am amazed at the lack of articles by techs, for techs, about using these devices in their test environments. And so we have a first: Documentation of a test and analysis situation using the Basic Atom. More importantly, I show how to break out of the mind set that says you are limited to the settings given in the manual. In this case, how to use EXTINT for both high-to-low (H2L) and low-to -high (L2H) edge detection at RB0 in the same program. Complete with pictures and diagrams. (Thanx, Basic Micro!)
The project started as an attempt to implement a snoop device between two devices at work, the PDI and SRB, which communicate using half duplex at 19200 Baud. For this job we needed to capture both streams reliably, ensure the two streams were separated on the display, and printed out in HEX (00 - FF). It would be a real plus if the data could be captured in a file on the fly, then made available to analyze in detail later. With a Basic Atom in hand, Foxit Software's Koala Term and MicroSoft Excel, this was cake. Mostly.
THE HARDWARE is a breadboard with a five pin connector for importing the power and signals from the PDI; an EL Products OEM Atom board; the signals from the PDI and SRB being diode ORed to the USART's RxD pin; the TxD pin going to a RS232 adapter made for breadboard use; and the DIR signal wired to P0 (RB0 on the PIC). All this is seen in later pictures. Using the USART means we are using an independent internal peripheral that operates largely free of the processor's intervention. Using bit-bang (software controlled) serial communications is fraught with problems. It is prone to error. And the USART has the ability to monitor the ninth bit in addressable serial communications among multiple devices. We use nine bits a lot at work, and may be used eventually to signal whether a packet is a command or data. Never ignore a good freebie...
The devices under study talk using the RS-485 protocol. The single ended signal from the processor is converted to differential using an LTC1481 IC or equivalent. Being half duplex means there has to be some way to control which direction the traffic is going. There is a gate in the chip for transmitting, another for receiving, and each has its own enable pin. Since we do half duplex, only one direction at a time is used. Thus, we short the enable pins and call them DIR. We have a connector at the PDI that we use for traffic monitoring, and the DIR is available in a pin, along with TxD and RxD. When the DIR is low, traffic is transmitted from the SRB; when high, it's from the PDI. DIR is important here because it allows us to determine when to do a carriage return, which allows us to print the device's name as a prompt at the start of each line. When DIR goes low we know to anticipate traffic from the SRB, so start the new line with a "SRB>". When high, we do a new line and print "PDI>" first thing. The concept is easy enough to grasp, but the implementation proved elusive.
Using an "IF-THEN" like
IF IN0 = 0 THEN ; look for DIR to go low
HSEROUT [13, "SRB> "] ; Get ready for SRB traffic
ENDIF
IF IN0 = 1 THEN ; look for DIR to go high
HSEROUT [13, "PDI> "] ; Get ready for PDI traffic
ENDIF
proved to be slow and awkward. The USART can collect characters damn fast and gets immediate service from the PIC because it uses interrupts. So, as the program is slogging through all the IF-THEN conditionals, the screen is printing characters before and after the prompts. If interrupts are the problem, then they must used for the solution.
But which one?
Checking the manual (vers. 3.000) shows two possibilities, RBINT and EXTINT. Since RBINT uses any of four pins on the B Port, and need only change levels to produce an interrupt, this seemed the likely candidate. But try as I might, with great effort and experimentation, I could not find a satisfactory way to use this interrupt. Every change in level produced five interrupts! So I got five new lines with prompts! The Microchip data sheet for the 16F87x series was no help
in this case. (but was very helpful later, as you will see!)
EXTINT was the only choice left. Problem: the user can define this interrupt initially
only as H2L or L2H. I found the compiler would not let me redefine the edge to detect later in the code using the original syntax. I got a compiler error when I tried it. Earlier experience with an Atom Pro project, with Nathan's help, suggested the solution. Although not mentioned in the manual, you can assign values to registers, even to bit level, using register names and bit definitions. And, as mentioned earlier, reading the MicroChip data sheets for this PIC series showed the answer: INTEDG. INTEDG is the bit in a register that tells this interrupt which edge to detect, high-going (bit set, or 1) or low-going (bit cleared, or 0). The register names and their bits are in the processor definitions for the different Atoms. You can literally change settings in the registers on the fly in code which allows you to do things unmentioned in the examples. But that's another book...
AND NOW THE CODE...
Code:
; PDI/SRB_Snooper 30APR2009 by KenJ
; Monitors DIR signal at PDI's 1481, puts out <CR> when
; level changes. SRB and PDI transmit data are diode ORed to USART.
; USART TxD sends all serial traffic from PDI and SRB to PC serial port.
; Using OEM Atom Board. LED at P1 is driven by Atom to show
; serial activity is present; P2 is connected to DIR pins to show
; DIR pins are active and changing.
; VARIABLE ASSIGNMENT(S)
CHAR VAR BYTE
CNTR VAR LONG ; For future use
; INITIALIZATION(S)
; Set up Interrupts
oninterrupt extint, IH_EXTINT
setextint ext_H2L ; detect high-to-low edge initially
ENABLE extint
; End of interrupt set up
SETPULLUPS PU_ON ; Enable weak pullups on PortB
TRISB = %11111101
SETHSERIAL H19200 ; Set USART for 19200 Baud, RxD and TxD
HIGH 1 ; Turn on LED on P1
CNTR = 0
MAIN:
HSERIN [CHAR]
HSEROUT [HEX CHAR2, " "]
TOGGLE 1 ; Creates rapidly blinking LED if traffic is present
GOTO MAIN
DISABLE ; Disable INTs from here on down
; SUBROUTINE(S)
None
; INTERRUPT HANDLER(S)
IH_EXTINT ; Start of Edge-Detect Interrupt Routine
; check out edge bit in INTEDG. 1=L2H, 0=H2L
IF INTEDG = 1 THEN ; If set for L2H
HSEROUT [13, "PDI> "] ; Get ready to show PDI data
INTEDG = 0 ; Change it to H2L
ELSE
HSEROUT [13, "SRB> "] ; Get ready to show SRB data
INTEDG = 1 ; Must have been H2L to start with, now make it L2H
ENDIF
RESUME ; End of Interrupt
END ; Just in case!
This produces a constant stream of traffic to a terminal program on the PC, like so:
PDI> 62 0A 59 06 C0 A4 5C FF 00 FF 00 FF 00 35 5C
SRB> C2
PDI> 62 0A 59 06 C0 A4 5B FF 00 FF 00 FF 00 2C 18
SRB> C2
Both devices have their outputs reported on separate lines, thanks to EXTINT and INTEDG, in clearly legible double-digit HEX. The HEX modifier, seen in the code as "HEX CHAR2", guarantees this. Love that compiler!
Shown later in a picture is the simple patch board used originally to try and track this traffic. It simply sends the original bit stream to the terminal program. This of course produced weird screens of meandering graphical symbols. Control codes made the screen blank out and killed the program in unpredictable ways. It is useful in other situations, but not in this case.
But this isn't really helpful if hundreds of lines of data fly by faster than you can read them. Or if you need to capture and study an overnight event the next day. You need software to capture the streaming data to a file and another to study and analyze the data later. In my case, Koala Term did the data capture and Excel picked it apart.
Foxit Software provides a fully usable download of their Koala Term software on downloads.com. This times out in 30 days or so, then it is $39 to buy. You can't find this on their web site, but the manual is available under their support section. Near as I can see, this hasn't been updated since 2007. And it has a glaring limitation: it only works with COM1 to 4. If you have a laptop or PC with no serial port built in, you'll need to get a plug in board or get a USB adapter. USB solutions use higher COM numbers, like 12 or 24. You'll have to get into the device manager on your PC and redefine these down to the lower COM numbers.
But, this is a great piece of software otherwise. If you have used any terminal software before, this is quick to learn and use, and has tons of useful features. To capture a file you simply click the Capture icon after you get the session up and running. Click it again to stop. This produces an ASCII file be to be studied later. Beware, this can lead to huge file sizes when run overnight. Which brings us to Excel...
If you don't have it yet, and you want to study and analyze large data files of hex values, and you don't have any other software available to you, get Excel. Or any equivalent spreadsheet program. Even the open source spreadsheets should be adequate.
You need only import the ASCII data in the file using the Import Wizard. If you were careful to write the code to keep everything separated by spaces, you will end up with data issued to their own cells. It is now a simple matter to use the AutoFilters and Conditional Search functions to mine the data, which is a real blessing when you start with a 20MB file from an overnight run!
At the end of this article I provide a clip from an Excel sheet. This starts with some lines of typical traffic, then several lines of initialization traffic ( I hit the Reset!) between the two devices, then a return to typical traffic. If you suspected this unexpected Reset was happening randomly and wanted to find this difference in traffic in a file from a 24 hour capture session, AutoFilters suddenly are gold in the bank!
And so it goes. I had an itch, and the Atom and some enginuity scratched it. The inexpensive Atom(Pro), in any form, and the free, truly powerful compiler make the tech's job much easier when applied with forethought.
What follows now are the commented pictures and diagrams mentioned earlier. I hope you found this example informative and helpful.
Take care,
Ken Jennejohn
AKA kenjj