Shop OBEX P1 Docs P2 Docs Learn Events
BS2 Communication Code Help — Parallax Forums

BS2 Communication Code Help

qxoticqxotic Posts: 47
edited 2011-09-12 09:24 in BASIC Stamp
I have a working model using an encoder chip for a keypad door entry program. I am building a second one but if possible would like to use a keypad remaining from a commercial system. Here is the information on it:

It uses Special ABA Data Format as follows:
All characters are sent as a 5 bit value.
First 4 bits of each character are the data value LSB first
The last bit of each character is odd parity

First 13 0's are sent as lead in

Next the Start Character is sent
The start character is a "B" with odd parity bit

Each entered character is now sent as 5 bits per character with odd parity and LSB first. Max. of 12 characters

After all the keyed in characters have been sent, then the END Sentinal is sent which is an "F" with odd parity

Next the LRC code is sent as a 5 bit character with odd parity. The LRC code is created by XORing all of the characters sent including the Start Characters the Digit Characters and the End Sentinal. It is calculated as a 4 bit value from XORing all the previous characters. Its value is then sent as a 5 bit value, the 5th bit beign its own odd parity.

Finally 7 0 bits are sent as lead out.

Clock pulse is 200 uSec
Interbit delay is 750 uSec

This information was given to me by the Mfg. Given this, is it possible to use this with the BS2?

Thank you,
Daniel

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-08-16 15:41
    It would help if you could post a link to the manufacturer's information or attach a copy of that information to one of your messages (use Go Advanced button to do attachments). I assume from your mention of a clock that you're talking about a clocked synchronous protocol of some sort in which case you'd use the SHIFTIN statement to receive the data. The SHIFTIN statement allows you to receive specified numbers of bits, so there'd be no problem handling 13 bits here and 7 bits there and some number of 5 bit values. You're not going to get a 7-bit ASCII character "B" or "F" into 5 bits with a parity bit, so maybe you're talking about hexadecimal values. I think this'll work with a BS2, but that'll depend on the details.
  • qxoticqxotic Posts: 47
    edited 2011-08-17 06:57
    Mike,

    Thank you for your reply. I did contact the Mfg. and what I wrote above is exactly what they sent me concerning the data specifications. This was a special model so their website did not cover it.

    They sent some I/O specifications also as follows:
    Input 1 <Low>= Green LED On <High>= Green LED off
    Input 2 <Low>= Red LED On <High>= Red LED off
    Input 3 NONE
    Input 4 <Low>= Invert Data <High>= Normal Data

    Output 1 <Clock> Goes low to clock in data
    Output 2 <Data> Output determined by Input 4
    Input 3 <Low> 0=Low & 1=High (inv)
    Input 3 ,High> 0=High & 1=Low (nor)
    Output 3 NONE
    Output 4 <CCTV> with 30 sec timer goes low for CCTV on

    Clock Pulse is 200 uSec
    Interbit delay is 750 uSec

    The Red LED blinks with each key press
    Tone is output with each keypress
    ---Key Specifications----

    * is the Enter Key
    # is the Clear Key
    The clear delay is set at 10 seconds
    If over 12 data keys are pressed before enter, there is no output from the keypad.

    ---Purpose----
    Drive Essex internal keypad micro as a Multi Bit ABA Type Clock and Data keypad
    Special version # and * keys reversed
    Outputs on only enter, 9 extra leada 0's

    http://www.keyless.com/tech.htm This is the website, but the keypads I have are special versions of their KTP line.

    Above herein and my first post are exactly what the Mfg. sent me when I asked them about the communications protocol for the keypad I have.
    You must be correct that it is hexadecimal because they do state it is 5 bits.
    I have a homework board set up for testing, the final version will be a BS2pe Module.

    I will research and refresh my memory on the SHIFTIN command.

    Thank you,
    Daniel
  • qxoticqxotic Posts: 47
    edited 2011-08-17 07:13
    I do have the following information on the pins of the keypad-
    Blue wire = Red LED
    Black wire = earth ground -(was not used previously)
    Gray wire = CCTV (was not used previously)
    Brown wire = Green LED
    Yellow wire = -V
    Violet wire = IN4 (was not used previously)
    Orange wire = +V
    Green wire = Data
    Red wire = Clock/Strobe

    Thank you,
    Daniel
  • qxoticqxotic Posts: 47
    edited 2011-09-07 06:43
    I am ready to start testing with my homework board. Can someone suggest the code I should try to see if I can capture the input from the keypad?

    Thank you.
    Daniel
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-07 08:39
    I haven't looked at this thread since my message #2 and, on looking at your reply #3, I realized that SHIFTIN won't work because SHIFTIN has the clock pulses coming from the Stamp rather than, in your case, coming from the keypad. Assuming that your clock/strobe is connected to I/O pin CLK and your data is connected to I/O pin DTA, your code would have to look something like this:
    error:  ' start over from the beginning
    counter = 0
    do until CLK = 1 : loop  ' make sure clock is high initially
    section1:
    do until CLK = 0 : loop  ' wait for leading edge of clock pulse
    if DTA <> 0 then goto error  ' quit if leading bit is in error
    counter = counter + 1  ' require 13 leading bits
    if counter < 13 then goto section1
    counter = 0
    dataValue = 0
    section2:
    do until CLK = 0 : loop  ' wait for leading edge of clock pulse
    dataValue.bit0(counter) = DTA  ' get data bit from LSB to MSB
    counter = counter + 1
    if counter < 6 then goto section2
    ' do something with the received character
    
    Note that this may not work with a Homework Board because of speed. You've got only about 700us to process each bit and most operations take at least around 150us. You can probably speed things up enough by "unrolling" the loops so, instead of keeping a counter for the leading bit number and doing a loop, you duplicate the code 13 times (do, if, do, if, do, if, ...). You'd do the same thing for the 6 data bits. The BS2pe is about 50% faster, so there's a little more leeway.
  • qxoticqxotic Posts: 47
    edited 2011-09-07 13:23
    Mike,

    Thank you for the great help. Since the homework board may not work I'm getting my carrier board set up.... work meeting tomorrow so hopefully I'll make some more progress on Friday. Thank you very much! I am a hobbyist.. and this is something I rarely deal with so takes a while to get my mind focused and on the right path on this stuff.

    Daniel
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-07 14:50
    Try the Homework Board. It might work. There's information here (under "app-notes") on execution timing for various statements and Stamp models. There's lots of other useful information as well.

    In the example I gave, I didn't check that the clock went high again before looking for it to go low. I assumed that the code would take at least 200us to execute, so the clock would go high when the Stamp was looking at the data line. That may not work with the BS2pe because it's faster.
    bChar   con   ("B" & %11111) | %000000  ' least significant 5 bits plus odd parity
    fChar   con   ("F" & %11111) | %100000
    CLK   pin   4
    DTA   pin   5
    result   var   byte
    startSeq:
    if CLK = 0 then startSeq  ' wait for initial high
    startBit1:
    if CLK = 1 then startBit1  ' 1st clock pulse
    if DTA = 1 then startSeq  ' error
    startBit2:
    if CLK = 1 then startBit2  ' 2nd clock pulse
    if DTA = 1 then startSeq  ' error
    startBit3:
    if CLK = 1 then startBit3  ' 3rd clock pulse
    if DTA = 1 then startSeq  ' error
    ... same thing for bits 4-12
    startBit13:
    if CLK = 1 then startBit13  ' 13th clock pulse
    if DTA = 1 then startSeq  ' error
    result = 0
    dataBit1:
    if CLK = 1 then dataBit1  ' 1st clock pulse
    result.bit0 = DTA
    dataBit2:
    if CLK = 1 then dataBit2  ' 2nd clock pulse
    result.bit1 = DTA
    ... same thing for bits 3-5
    dataBit6:
    if CLK = 1 then dataBit6  ' 6th clock pulse
    result.bit5 = DTA
    if result <> bChar then startSeq  ' not the start character
    ... and so on
    
  • qxoticqxotic Posts: 47
    edited 2011-09-09 09:35
    Mike,

    I got the 2p3 up and running and was doing some testing with your first code. I don't think from your last code that I have it set up right... if I run it it with the following code it just displays "END" should I add something to look for the clock to go low since I am using the 2pe? I will try to make some corrections after reading your link and new code and see if I can make some progress. Thank you... Daniel
    ' {$STAMP BS2pe}
    ' {$PBASIC 2.5}

    'test program to read from Essex keypad

    CLK PIN 3 ' keypad strobe pin
    DTA PIN 4 'keypad data pin

    counter VAR Byte

    dataValue VAR Word

    counter = 0

    dataValue = 0

    DEBUG CLS , CR

    error: ' start over from beginning
    DO UNTIL CLK = 1 : LOOP 'make sure clock is high initially

    section1:
    DO UNTIL CLK = 0 : LOOP ' wait for leading edge of clock pulse
    IF DTA <> 0 THEN GOTO error 'quit if leading bit is in error
    counter = counter + 1 'require 13 leading bits

    IF counter < 13 THEN GOTO section1
    counter = 0
    dataValue = 0

    section2:
    DO UNTIL CLK = 0 : LOOP ' wait for leading edge of clock pulse
    dataValue.BIT0(counter)= DTA 'get data bit from LSB to MSB
    counter = counter + 1
    IF counter < 6 THEN GOTO section2
    DEBUG dataValue.BIT0(counter), CR


    DEBUG "END", CR
    END
  • qxoticqxotic Posts: 47
    edited 2011-09-09 12:48
    still studying up on the communications. Is it possible to catch the entire string at once and work backwards to the information I am looking for? If I understand the documentation, nothing is sent until the * or enter is pressed (it does seem to work that way from what I have observed) and then it sends the leading 0's followed by a "B" then the data and then ends with an "F". Would it be easier to catch the string then lop off the F and look at the four numbers before it?

    I am either not catching the data input or don't understand how to properly write the code to display it yet.

    Thank you,
    Daniel
  • qxoticqxotic Posts: 47
    edited 2011-09-09 13:36
    I tried some simple code to see if I could catch anything.. using just the portion of the code below I have observed the following:
    If I enter 3 or less numbers and then press star I have to do a second entry before the counter is up high enough to end the program. If I enter 4 numbers and then press star it displays 0 for result and 21 for counter. If I raise the counter number it does not always reach the END entering four numbers... If I lower it enough it will reach the end entering 3 numbers. My final code would be trying to read 4 numbers.

    CLK PIN 3 ' keypad strobe pin
    DTA PIN 4 'keypad data pin

    counter VAR Byte
    result VAR Word


    DEBUG "start", CR
    section2:
    DO UNTIL CLK = 0 : LOOP ' wait for leading edge of clock pulse

    result.BIT0(counter)= DTA 'get data bit from LSB to MSB
    counter = counter + 1
    IF counter < 21 THEN GOTO section2
    DEBUG ?result
    DEBUG ?counter
    DEBUG "END", CR
    END
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-09 15:08
    Your idea is reasonable, but there are two issues:

    1) The BS2 is a fairly slow processor. Its basic instructions execute only slightly faster than the clock you're getting from the keypad and there's very little the BS2 can do up until the next bit (and clock) comes in. Storing the data in a buffer of some sort is even slower since you have to do subscripting and keep a counter, etc.

    2) There's limited space available in the BS2 (only 26 bytes) for a buffer and you have to keep some bytes for use as counters or other variables in your program.

    The "unrolled" code technique is an attempt to speed things up as much as possible and to use only a few variables.

    Coding would be easier using a more capable Stamp like the BS2px or a much faster, but different microcontroller like the Propeller. I made the coding suggestion because you might get the task done with a BS2 and really careful coding.

    Regarding your message #11 ... You're probably missing some bits. It would be interesting to look at what you do have as bits (use DEBUG BIN16 result to see the bits) to see if there's a pattern
  • qxoticqxotic Posts: 47
    edited 2011-09-12 07:24
    Mike,
    I tried this
    DO UNTIL CLK = 0 : LOOP ' wait for leading edge of clock pulse
    DEBUG BIN16 ?DTA
    result.BIT0(counter)= DTA 'get data bit from LSB to MSB
    counter = counter + 1
    IF counter < 21 THEN GOTO section2
    DEBUG ?result
    DEBUG ?counter
    DEBUG "END", CR

    and got this :
    start
    DTA = %0000000000000000
    DTA = %0000000000000000
    repeats 0's several times.. then after enough entries the program ends.

    I don't seem to be catching anything.. do I have it coded right to read the data from pin 4? Clock is on pin 3.
    Thank you.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-12 07:33
    With the DEBUG statement there, this can't possibly work. The DEBUG statement takes way too much time (about 25ms).

    As I mentioned before, this scheme is not likely to work with a BS2 and the serial timings you've described. That's why I posted the "unrolled" loop code in #5 which avoids the additional overhead of the subscripting and keeping a counter.
  • qxoticqxotic Posts: 47
    edited 2011-09-12 08:03
    I put in the "unrolled" code. It does get to the end of the code... past the DataBit6 as verified by a debug after the DataBit6 line... without it I get no display which I am guessing is because it goes back to startseq and does not make it through again? When I debug ?result after the DataBit6 I still get 0

    Is the problem that the timing has to be just right to catch the bchar at the correct time?
    Is it possible to use the unrolled code and catch bits until the clock goes to 0 and then display what I am catching? At some point here I should be able to catch something other than one of the leading 0's shouldn't I?

    Thankful for the help.
    Daniel
  • Mike GreenMike Green Posts: 23,101
    edited 2011-09-12 09:00
    The problem here is that the timing is very tight and there's not good documentation on the exact timing of all the various PBasic interpretive codes. I'd probably do some experimenting with a logic analyzer or oscilloscope to see just how much leeway there is. Frankly, this project would be a lot easier with a faster microcontroller. The stuff that I posted in #6 might work with a BS2px for example because it's much faster. You could also use a cheap, small, simple AVR or PIC microcontroller just to decode this keypad and present the keycodes to the BS2 in an easier to use form, but you'd have to learn that microcontroller's assembly language and development environment.

    Given your project description (a keypad-based entry system), you'd probably be better off removing the electronics from the existing keypad, making direct connections to the (probably) 4x4 keyboard, and scanning the keyboard directly with the Stamp using sample code readily available (and tested).
  • qxoticqxotic Posts: 47
    edited 2011-09-12 09:24
    I appreciate the time you've given I'll use the encoder and 3x4 keypad I have and leave this keypad for another day.. and some disassembly..

    Thank you again for your suggestions, it was worth a try.

    Daniel
Sign In or Register to comment.