Shop OBEX P1 Docs P2 Docs Learn Events
Parsing a serial String — Parallax Forums

Parsing a serial String

Greetings,

My project involves a control system for my water well for my house. It will read the well level from a Eno Scientific Well Watch 660 depth sensor, hooked to a 310 monitor. The sensor bounces a sound wave down the well and measures the water level. So if it measures 300ft, and my pump is 474ft down, I've got 174ft of water in the well = good. If it reads 474... my well is out of water, and it'll automatically use a reserve tank. I've already got this all wired up, and can use the XBEE example to repeat the Well Watch string on the serial terminal no problem, but that's as far as I can get. I'm working in SPIN.

The sensor spits out a RS232 string as follows, it's going through a MAX3232 of course:

>>2019/03/09 11:59:03 0 D 316.04 Ft

Date/time/ I don't know what the 0 is, and the D stands for Depth. I need some help and code example like above please! I've been trying to figure out the mechanics of the above weather parsing setup, however, it's a bit over my head. I'm interested in extracting the hours, and the feet (in whole feet is fine, don't need the decimal place) out of that string. I'm not familiar with working with byte arrays, and the parsing is beyond me too...Thanks for your help!

Jeremy

Comments

  • Hey Thanks, I've read that one, the weather station example is close to mine, but I still don't know enough to deal with the differences. I understand the gist of it, accumulating the string in a byte array, where it's really just a bunch of ascii bytes, then reading out them and changing them to a normal value is a bit over my head. I have the example of the Propeller book too, where they parse out a NMEA string from a GPS. I've been chewing on this problem for a while, and thought it was time to ask for help.
  • what language are you using?
  • Hello, Yes, I'm working in Spin.

  • Here is a typical string.
    >>2019/03/09 11:59:03 0 D 316.04 Ft
    

    You must have read it into a string, probably defined as MyString[20] or so. Think about how to convert the hours into an integer. Something like
    Hours := (MyString[14] - "0") * 10     'convert ascii to decimal for tens of hours
      Hours := Hours + (MyString[15] - "0" )  'add in units of hours
    

    Computing the depth is similar.
  • Francis BauerFrancis Bauer Posts: 364
    edited 2019-03-10 02:01
    Hello, Yes, I'm working in Spin.

    I've attached a modified version of jonnymac's Weather spin example from 2015, see "ParseWaterWellData.spin" file.

    I've tweaked it to parse your Well Data. Hopefully these modifications will give you enough information on how to parse your data. Let us know how it goes...

    The program outputs the following:

    Test String: >>2019/03/09 11:59:03 0 D 316.04 Ft

    Number of Data Fields: 5
    Data Date String: 2019/03/09
    Data Time String: 11:59:03
    Data Pad Char: 0
    Data D Char: D
    Data Depth String: 316.04
    Data Depth Decimal: 316
    Data Unit: Ft


    NOTE: In the program I added 2 to the Test Input Data pointer to skip over the two ">" characters, which I assumed were part of the actual string you are receiving from your sensor. If they aren't remove the '+ 2'.
  • Thank you for that - I should have included in my initial post, that my data is coming into Pin 20, at 9600 - can you tell me how to adapt that code so that it does the input buffering as well? I understand that the serial objects usually have a buffer, but I have little idea how to utilize it. Thank you for your help - this will definately move my project along!
  • The shortcut way to parse your string is to use a "regular expression" (regex). Attached is an example that parses out your various fields into numbers. Here's a thread that describes the object used for the parsing:

    https://forums.parallax.com/discussion/117496

    I apologize for the obfuscation resulting from Parallax still not supporting the noparse bbCode. (Grrrrr! C'mon guys, what's up with that? Really. Get it together for cripes sake!)

    -Phil
  • Thanks for all the help!!

    Well the below is how I got it done. Another part of this problem for me was how to deal with the byte and strings... Since I'm not too familiar with both of them, the XBee manual gave me some inspiration on how just to crunch it as its coming in. After all, what I'm doing isn't too sophisticated, the bits are coming in a 9600, and the Prop is running much faster that that! This gets me the Depth, and maybe later I'll work on getting the hours out too.



    repeat
    WW.rxFlush
    Depth := 0
    repeat until InData == "D" 'waiting for a D for Depth.
    InData :=WW.rx
    WW.rxFlush 'take out the trash, I'm just interested in the Depth
    InData := WW.rx 'init InData ,wait for next byte
    repeat until InData <> 32
    InData := WW.rx
    WW.rxFlush 'clear out the spaces before the depth.

    D1 := InData 'Byte D1 is hundreds, ascii
    D2 := WW.rx 'wait for next byte, 10's ascii
    D3 := WW.rx 'wait for next byte. ascii Depth should always be between 200-500
    D1 := D1-48 'convert from ascii to dec
    D2 := D2-48
    D3 := D3-48
    Depth := Depth + D1*100
    Depth := Depth + D2 * 10
    Depth := Depth + D3
    Depth := 474-Depth
  • AribaAriba Posts: 2,690
    A simple way to synchronize to the hours and depth and parse it on the fly:
    repeat
      repeat until ser.rx == "/"
      repeat until ser.rx == " "
      hour = (ser.rx - "0") * 10
      hour += ser.rx - "0"
      repeat until ser.rx == "D"
      ser.rx
      depth = (ser.rx - "0") * 100
      depth += (ser.rx - "0") * 10
      depth += ser.rx - "0"
    

    Andy
  • @Jtravers555
    I wrote a tutorial in Prop C to write a library. It parses a string. Look at it. It may help. If you need it ported to Spin let me know I will try to help. It parses a string.
Sign In or Register to comment.