Shop OBEX P1 Docs P2 Docs Learn Events
problems with SERIN and BS2 — Parallax Forums

problems with SERIN and BS2

I have a wind gauge which outputs data as an 18 byte array - output 9800/7/E/1
Useful data (the digits) are in bytes 12 and 14 respectively
I want to transmit this data to two 7 segment displays (common cathode) via two shift registers, leave the digits displayed for 20 seconds and then blank the displays to await the next data set

I am happy with the wiring

When the wind gauge sends the data I get a response on the displays but it rarely reflects the data displayed on the gauge itself
Any advice would be most welcome

The code is shown below

' {$STAMP BS2}
' {$PBASIC 2.5}

serData VAR Byte(18)

dPin PIN 0 'pin 14
latch PIN 1 'pin 12
clock PIN 2 'pin 11

x VAR Byte
y VAR Byte

' ....set up......
LOW latch


SERIN 16,16468,[STR serData\18]

'I know Select Case might be better here

IF serdata(12)= 48 THEN x=63 'number 0
IF serdata(14)= 48 THEN y=63

IF serdata(12)= 49 THEN x=6 'number 1
IF serdata(14)= 49 THEN y=6

IF serdata(14)= 50 THEN x = 91
IF serdata(16)= 50 THEN y = 91

IF serdata(14)= 51 THEN x = 79
IF serdata(16)= 51 THEN y = 79

IF serdata(14)= 52 THEN x = 102
IF serdata(16)= 52 THEN y = 102

IF serdata(14)= 53 THEN x = 109
IF serdata(16)= 53 THEN y = 109

IF serdata(14)= 54 THEN x = 124 '6
IF serdata(16)= 54 THEN y = 124

IF serdata(14)= 55 THEN x = 7 '7
IF serdata(16)= 55 THEN y = 7

IF serdata(14)= 56 THEN x = 127 '8
IF serdata(16)= 56 THEN y = 127

IF serdata(14)= 57 THEN x = 103 '9
IF serdata(16)= 57 THEN y = 103


SHIFTOUT dPin,clock,MSBFIRST,[x]
SHIFTOUT dPin,clock,MSBFIRST,[y]
PULSOUT latch,1

PAUSE 20000

'clear displays
SHIFTOUT dPin,clock,MSBFIRST,[0]
SHIFTOUT dPin,clock,MSBFIRST,[0]
PULSOUT latch,1

END
«1

Comments

  • Hi, welcome to the forum.
    You can append code by insetting it between the code formatter. Use the big "C" in the formatting bar above.

    I would approach your problem by putting a
    DEBUG STR SerData\18
    
    right after the SERIN. That way you can determine for sure whether the problem is on the input end or output end.
  • LOOKUP would work really well here:
    LOOKUP (serdata[12] - "0"), [63, 1, 91, 79, and so on], x
    
  • thanks

    I did think about using LOOKUP
    I'll try it

    any idea why my previous method was failing?

    David Cooke
  • Do you know you are consistently getting valid data into the SERDATA array? Did you display it?
  • thanks
    I might be a bit dim here but I cannot determine how to see the debug when the BS is only connected to the wind gauge and not to the PC
    I upload the programme into the BS, then disconnect the PC and connect the wind gauge
    I then start the wind gauge which (hopefully) uploads the 18 byte array into the BS
    At what stage should I see the debug?

    re the programme, I've made some changes as you suggested but I thought that Lookdown as well as Lookup might be required - see below
    I've tried this new code but it is still not giving consistent results (as you imply I do not know whether the BS is receiving all the bytes)

    I attach a screenshot showing the output from the wind gauge as seen by Hyperterminal (first array shows 0.0 m/s, the second 0.2 m/s) - ignore the first few bytes in the row- that was me manually typing
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    serData VAR Byte(18)
    
    dPin PIN 0 'pin 14
    latch PIN 1 'pin 12
    clock PIN 2 'pin 11
    
    x VAR Byte
    y VAR Byte
    index1 VAR Nib
    index2 VAR Nib
    
    ' ....set up......
    LOW latch
    
    
    SERIN 16,16468,[STR serData\18]
    
    DEBUG STR SerData\18
    
    'first 7 segment display
    LOOKDOWN serData(12), [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], index1 
    
    DEBUG DEC index1
    
    LOOKUP index1, [63, 1, 91, 79, 102,109,124,7,127,103  ], x   
    
    DEBUG x
    
    'second 7 segment displa
    LOOKDOWN serData(14), [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], index2 
    
    DEBUG DEC index2
    
    LOOKUP index2, [63, 1, 91, 79, 102,109,124,7,127,103  ], y  
    
    DEBUG y
    
    SHIFTOUT dPin,clock,MSBFIRST,[x]
    SHIFTOUT dPin,clock,MSBFIRST,[y]
    PULSOUT latch,1
    
    PAUSE 20000
    
    'clear displays
    SHIFTOUT dPin,clock,MSBFIRST,[0]
    SHIFTOUT dPin,clock,MSBFIRST,[0]
    PULSOUT latch,1
    
    END
    
    1920 x 1080 - 288K
  • Ah. I did not notice you were using the PC port to receive the data from the wind gauge.

    Can you change it so that you are using a different pin for the gauge? Then you could remain connected to the PC and DEBUG would work.

    OR, can you connect another display (say a serial LCD)?

    I suspect what is happening is this: When you start the SERIN, you start getting data in the middle of the 18 byte stream (because that is where the gauge happens to be).
    That way the useful bytes would show up most anywhere in the buffer. If that is what is happening, you have two choices:

    1. Get the wind gauge to send data at 4800 baud and use the WAIT formatter to get aligned with a frame (BS-2 doesn't WAIT well at 9600).
    2. Scan the buffer "by hand" to find the beginning of a frame and then calculate the offset to the useful bytes.
  • thanks for your help here

    could I take a wire from the Tx pin on the wind gauge inserting this into one of the I/O pins on the BS?
    I understand that pin 16 handles a lot of the serial data processing on the Stamp and that using a different Pin might need more formatting
  • I just noticed your baud constant 16468 is for 8-bit, no parity. And the gauge is sending 7-bit even parity (top line of original post).

    Take a look at table 5.97 on page 397. There are three other entries for 9600. Using your original program, I would try each of them. Inverted, not inverted / 8-bit, 7-bit even.

    If one of those doesn't magically fix everything, and you need to resort to debug,

    If you have a resistor in the range of 100 to 1000 ohms, I would put it in series just to protect the BS-2 input pin from anything odd the gauge might be putting out. Then you will have to sort out 8-bit/ 7-bit E.

    In your code two comments above, in the third and fifth DEBUG, you need to use a DEC or BIN8 formatter.
  • thanks
    I'll do some soldering and get back to you
    it might take a day or two
  • I've soldered a wire onto pin 3 on the wind gauge (Tx) and another wire onto pin 5 of the wind gauge. I get -5.6v across those two wires and I think that this is the expected finding if pin 3 is the Tx pin
    I understand that no other connections are required

    I then put the Tx wire into PIN 15 on the Stamp and the other wire into GND
    I made PIN 15 on the Stamp an Input

    At least I can now see the DEBUG terminal
    initially I could see the STR data but after a few runs all I was getting was a timeout error

    Is it possible the Stamp is simply failing to capture the bytes (by the way, I cannot alter the baud rate of the wind gauge)

    the new code looks like this
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    serData VAR Byte(18)
    
    dPin PIN 0     'pin 14 on shift register
    latch PIN 1    'pin 12 on shift register
    clock PIN 2    'pin 11 on shift register
    
    windgauge PIN 15
    
    x VAR Byte
    y VAR Byte
    
    index1 VAR Nib
    index2 VAR Nib
    
    ' ....set up......
    
    LOW latch
    INPUT 15
    
    
    'I tried all 4 combinations of 9600/E/N/7/8/1 and the best seems to be 9600/N/8/1 inverted even though the device is meant to be 9600/E/7/1
    
    SERIN 15,16468,15000,No_Data,[STR serData\18]
    
    No_Data:
    CLS, "Timeout error"
    STOP
    
    DEBUG STR SerData\18
    
    'first 7 segment display
    LOOKDOWN serData(12), [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], index1 
    
    DEBUG DEC index1
    
    LOOKUP index1, [63, 1, 91, 79, 102,109,124,7,127,103  ], x   
    
    DEBUG DEC x
    
    'second 7 segment display
    LOOKDOWN serData(14), [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], index2 
    
    DEBUG DEC index2
    
    LOOKUP index2, [63, 1, 91, 79, 102,109,124,7,127,103  ], y  
    
    DEBUG DEC y
    
    SHIFTOUT dPin,clock,MSBFIRST,[x]
    SHIFTOUT dPin,clock,MSBFIRST,[y]
    PULSOUT latch,1
    
    PAUSE 20000
    
    'clear displays
    SHIFTOUT dPin,clock,MSBFIRST,[0]
    SHIFTOUT dPin,clock,MSBFIRST,[0]
    PULSOUT latch,1
    
    END
    
  • David,
    On the DB-9 connector, is pin 3 negative with respect to pin 5? If so, you are driving the BS-2 I/O 15 negative with respect to ground.

    But if you are using a serial Board of Education, you were connecting pin that pin directly to Sin (BS-2 pin 1), so that would be the same. No RS-232 converter on BofA.

    I see you have a 15 second timeout. How often is the wind gauge expected to transmit a frame?

    No need to make pin 15 an INPUT; SERIN does that. But it doesn't hurt anything, that's not the problem.

    When you could see the STR data, did it make sense? Did it look like a proper frame?

    I believe the BS-2 is able to capture serial data using the STR formatter at up to 38400 baud. I have personally done experiments to determine the max baud rates for various formatters and that is what I measured. If only you could put a logic analyzer right on I/O 15.
  • thanks Tom
    using the multimeter with the positive on pin 3 (wind gauge) and the negative on pin 5 (GND) I get (- 5.6v)
    is that OK?

    The BS2 is not a BofE device

    I put the 15 second pause because I only wanted to display the actual reading for a short while - it is for track and field and the next event might have a very different reading. The gauge itself will only output after a race - that might amount to 50 in the whole day

    Using the Debug STR serData(18), I got very mixed results with the different baudmodes
    most were nonsense
    Some looked similar to the readings I get using hyperterminal but seemed to be deficient in bytes and then later with the same baudmode no data at all (and hence a 'timeout error')
    I know the gauge is consistently sending good data to a PC via hyperterminal
    I am beginning to think that the BS is incapable of capturing the data reliably but I cannot see any explanation - is the data coming too fast? is flow control required?

    If I change the code slightly , giving the BS actual figures for serData the two displays work fine

    It would appear that the problem is the input, not the subsequent processing of the data

    any further help would be much appreciated


  • thanks Tom
    using the multimeter with the positive on pin 3 (wind gauge) and the negative on pin 5 (GND) I get (- 5.6v)
    is that OK?

    No, that is totally not okay. The BS-2 is looking for TTL levels, +5 and ground.

    You need a level shifter, like a MAX232.

    I absolutely agree that the problem is with the input, especially since you point out that you can force actual figures for serData and get the results you expect.

    Someone else on this forum may have an idea for shifting levels that is better (cheaper, easier, faster). If so, I hope they will disclose it.
  • thanks Tom
    can I invite other people to comment?
  • two other thoughts
    1. although it is -5.6v when the wind gauge is idle, might it jump to +5.6v when transmitting - if so, this happens so fast that I probably wont see it on the multimeter and I dont have an oscilloscope
    2. the USB-serial adapter that I use between the PC and the BS has a voltage of -8.8v on pin 3 as well!
  • Well, I learned something today. When I download a program into the BS-2 using a USBtoRS232 adapter (28030), I see -6/+6 on the SIN pin! That is not what I expected; I expected to see ground / +5. Live and learn.

    If it is okay on Sin, it must be okay on I/O15. So I take back what I said about a level shifter.

    It would be good for someone who knows for sure (parallax?) (Mike Green?) to comment here.

    So back to the problem. You are able to consistently read and display the frames using some terminal program running on a PC. How is it configured (8-bit/7-bit/parity/no parity/etc)? That will tell you what baud constant you will have to end up using.

    Can you direct the gauge output to the terminal program and the BS-2 at the same time?
  • the terminal programme (hyperterminal) accurately captures the data from the wind gauge every time at 9800/7/E/1/no flow control

    so, that must be the correct setting for the BS
    the BS manual does mention that the BS may not capture reliably at rates abov 4800 bps

    I cannot think of any way of transmitting data to the PC and the BS at the same time but I'll think about it
  • I see the BS-2 does check parity if programmed for parity. I don't know how much that slows it down.

    When programmed for no parity, 8 bits, I know it can do STR at 38400, though.

    How about this: I imagine the parity bit comes last. IIRC, 232 is low order bit first, so the parity bit would show up as $80, if you received 7-even as 8-none.
    SERIN pin, 9600 8N Inverted, [STR serData \18]
    FOR x = 0 to 17
      serData[x] = serData[x] & $7F    'drop parity bit
      DEBUG HEX2 serData[x], " "        'see what it is
      NEXT
    

    Other than that, I'm about out of ideas.
  • David,

    Thinking perhaps the BS-2 couldn't receive data with parity as fast as without parity, I set up an experiment in which I sent data
    with parity (7E Inverted) from a sender (BS-2px as it turned out) at 9600 baud. Looking at the signal with an analyzer, it appeared
    precisely as I expected. The only difference was that it was GRD/+5V rather than -6/+6. The timing was exact; there was the equivalent
    of just about 2 1/2 stop bits between characters.

    Ironically, I found an error in Table 5.99 (24792 s/b 24972) but that makes no difference in your problem.

    A BS-2 (Homework Board) was able to receive (using STR) and display the data consistently. So I do not not believe it is a case of BS-2 can't keep up.
    I increased the baud rate to 19,200 and it worked perfectly there, as well.

    At this point, I am at loss to tell you what is going on. Sorry, wish I could have helped. tc
  • I ran this new programme and it produced interesting results
    I attach a screen shot
    basically, both 24660 and 16468 produced good data on the DEBUG screens showing 18 bytes
    when the wind speed was 00.00 it showed 30 (HEX) which would be 48 ASCII and 0 in decimal
    when the wind speed was 00.10 it showed correctly 31 (HEX)
    I noticed though that the bytes that I am interested in are 13 and 15 (either side of the decimal point) and not 12 and 14
    how can I modify the original programme to take into account that the data is being received by the BS but only looks good on the DEBUG when $7F is added?
    thanks - i hope that you can still help here
  • Whoa! Well, good news.
    All you have to do is get rid of the parity bit of each byte:
      SERIN pin, baud, [STR serData\18]         'get the raw data with parity
      FOR x = 0 to 17
          serData[x] = serData[x] & $7F           'force off the parity bit
          NEXT                                        'of each byte
    
    Now you have a buffer with nice clean ASCII characters and you can process the bytes you want.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2017-07-07 00:15
    So, David,
    It looks like your wind gauge returns 00.00 through 99.99.

    1. Are you going to round up if the hundredths is greater than 4?
    2. What happens when it returns something greater than 09.94?

    Edit: "Any computer program will expand to fill the available memory". EndEdit
  • thanks
    I'll rewrite the main programme with those changes
    although the wind gauge could, in theory, record up to +/- 99.99 m/s, in practice we only record and display up to +/- 9.9 m/s (so I only need two 7-segment displays + a few LED for the +/- sign). Subsequently I only need the digits either side of the decimal point.
    The strongest wind I've recorded (here in the UK) is 6.6 m/s and then I had to tie the wind gauge to a post- if we had >10m/s I think that we would abandon the athletics meeting

    I'll write again today when I've tried the new programme. I've learnt a lot from this and I was sure that there would be a solution - thanks again
  • success!

    I attach a photo showing the wind gauge displaying 0.1 m/s and my 7 segment displays showing the same

    thanks for your help

    -I would be grateful if you could explain how adding the HEX $7F overcame the parity problem
    -I'll put the definitive programme on the forum later (probably tomorrow)
    1632 x 1224 - 646K
  • Consider the ASCII char "1" (numeral one). It has the value dec 49, hex 31, binary 0011_0001.

    When it is transmitted with even parity, the sender appends an addition binary 1 so as to make the total number of 1's even (4).
    1011 0001        'hex 31 with the high order bit set.  Not ASCII "1"
    0111 1111        'constant $7F:  note bit 7 is a zero
    0011 0001       'result of bit-wise AND operation: ASCII "1"
    

    That explains why 8-bit ASCII needed to have the high-order bit removed. I am unable to explain why
    receiving 7-bit E didn't work. The BS-2 strips off the parity bit in that case.

    Yeah, 10 m/s works out to about 22 mph (for us non-metric types). Wouldn't want people throwing javelins
  • would you mind if I posted the solution with my schematic on You Tube?

    The device manual gives rather scanty information regarding the remote (output) port on the wind gauge and You Tube video would be very helpful
  • Of course I don't mind. Be sure and post a pointer here so we can look at it.

    One thing: If you are going to talk about the program, the LOOKDOWN really isn't needful.
    'first 7 segment display
    LOOKDOWN serData(12), [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], index1 
    
    DEBUG DEC index1
    
    LOOKUP index1, [63, 1, 91, 79, 102,109,124,7,127,103  ], x
    

    You can do the exact same thing as the lockdown LOOKDOWN with
    index 1 = serData(12) - "0"
    

    This takes advantage of ASCII having the numbers adjacent and in order.
  • thanks Tom
    I'll play around with your programming suggestion
    in the meantime, this is the working code (the windgauge will output once a second if required (in continuous mode). This seems to be a fixed setting so I had to add another 'PAUSE' at the end of the programme to stop the displays flashing once a second (if i used the continuous mode)
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    serData VAR Byte(18)     ' 18 Byte array from the wind gauge
    
    dPin PIN 0    'pin 14  ON THE SHIFT REGISTER
    latch PIN 1   'pin 12   ON THE SHIFT REGISTER
    clock PIN 2   'pin 11    ON THE SHIFT REGISTER
    
    NEG_or_POS          PIN 6
    dp                  PIN 10    ' decimal point
    GILL_WIND_GAUGE     PIN 15     ' from pin 3 on the wind gauge DB9
    
    
    x VAR Byte
    y VAR Byte
    index1 VAR Nib
    index2 VAR Nib
    
    '.................SET UP
    
    DO
    
    LOW LATCH
    HIGH dp
    
    '...................PROGRAMME.......
    
    
    SERIN 15,24660,[STR serData\18] '9600\1\E
    
    FOR x =0 TO 17
    
      serData(x) = serData(x) & $7F
    
    NEXT
    
    IF serData (10)=45 THEN HIGH NEG_or_POS ELSE LOW NEG_or_POS   ' sets segment g high on display 3 if w/s negative
    
    LOOKDOWN serData(12),["0","1","2","3","4","5","6","7","8","9"], index1
    
    LOOKUP index1,[63,6,91,79,102,109,124,7,127,103],x      ' this is the left hand display
    
    LOOKDOWN serData(14),[ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ], index2
    
    LOOKUP index2,[63,6,91,79,102,109,124,7,127,103],y      'this the right hand display
    
    ' shift data
    SHIFTOUT dPin,clock,MSBFIRST,[x]
    SHIFTOUT dPin,clock,MSBFIRST,[y]
    PULSOUT latch,5
    
    PAUSE 10000
    
    'clear displays
    SHIFTOUT dPin,clock,MSBFIRST,[0]
    SHIFTOUT dPin,clock,MSBFIRST,[0]
    PULSOUT latch,5
    
    LOW NEG_or_POS  ' reset +/- display
    
    PAUSE 5000  ' if wind gauge set to continuous
    
    
    LOOP  ' wait for next data
    
  • I couldn't figure out why you didn't want to keep the readout constantly updated but then: Of course you want to know the velocity as of when the event happened. Adding a pushbutton switch would open up more options.

    I would maybe add a little defensive programming: right after you do the ANDs to clean up the serData, you could make sure you got a good frame by testing say, the first two bytes for "!". If they weren't correct, you could just SERIN another frame (would happen within one second).
  • the coding solution above has proved to be perfect but I now have a new BS Homework board which has no serial interface
    although I can programme through the mini-USB, I cannot determine how to download the data into the BS from the wind gauge without an RS 232 interface
Sign In or Register to comment.