I am sure this has been covered but I don't know how to build a query to search for answers. I am sending from an arduino serial port "h", a 2 digit value, a comma and another 2 digit value and an "f" so the serial stream looks like this:
h62,56fh34,54fh22,78f...
At the comport in puredata I just see a 3digit number?
What I want is to recognize the 2 number pairs by parsing the h as a header, the first number then the second number and f as a footer. The first 2 digit value is an x value. The second is a y value. These are coming from ultrasonic sensors.
Where can I find a deeper explanation of how to accept a packet structure and parse it in pure data?
Is thare an easier or better way? Thank-you.
-
how to use serial data sent with header and footer and comma delimiters
-
If I understand correctly, you want to break apart a complex symbol and access the values inside. There's no perfect method for doing this, but it is possible. Here are some options:
-
If you don't mind using externals, you can use Zexy's [symbol2list] to convert the symbol into a list of characters. You need to loadbang the right-hand inlet with [symbol( so that this will work. I'm not sure how this will respond to the commas, but with any luck you will get "list h 6 2 /, 5 6 ..." which you can then unpack. You'll then need to recombine the the 2nd and 3rd digits to get the original number.
-
If this doesn't work, then you can use [list fromsymbol] to convert to ASCII characters. After isolating the correct digits, you'll then have the fun of converting them back to the original values.
In either case, one thing that will have a big impact on the complexity is, do the numbers always correspond to the same digits? Ie. will you be getting symbols that look like "h2,141fh.." , where the first number is only 1 digit long and the second is 3, as opposed to the 2 and 2 in your example? If so, then you'll probably need to iterate the list and calculate the placement of the values based on delimiters, ie. "the first number begins after 'h' and ends before the comma; the second number begins after the comma and ends before the 'f'". Difficult, but not impossible.
-
-
tx. @liamg
-
@lulu_joe13 Do you get "h62,56fh34,54fh22,78f..."
You suggest that you just get "a 3 digit number". What is that number? If that is all you get then [comport] is probably splitting the message based on the commas. Almost all programs use a comma to say "new message" (Pd does this) which means the data relationship you are looking for has been split already in the wrong place.If you are getting the message you posted then this will work........parse.zip (Vanilla).
It should be easier in Extended.
Getting to symbols is relatively easy but to get to floats again you will need [symbol2list]
I have included it as an abstraction in case you do not have it in your distribution.
David. -
@whale-av You can use [coll] or [text] or even [struct] to chart out symbols and their corresponding floats, so when a symbol is received, it spits out the float that goes with it. That is one way to get symbols back to floats without externals... In extended or newer, cyclone has [tosymbol] and [fromsymbol] which are also handy for atom conversions... and [list-drip] may also come in handy for your purposes.
A hackier but useful method that I have successfully used to parse incoming serial data with tricky delimiters is to use the [shell] object. make a script in a separate file that writes the incoming data from the com port to a temporary file and then call that script from the shell object. If the script is not too complex, you can type it in a message right in pd as well. For instance:
|tail -f /tmp/COM3 -n 3(
|
[shell]
|
tof/to_ascii_code
|
iterHere is a demo of how I did this when I was receiving MIDI from a program which was running in a virtual machine and sending midi data through the virtual comport. comport-midi.pd
-
@th8a Looks good! Thanks for the heads up on such use of [struct]
I am trying hard to like Vanilla.... so solving the problem was really easy using a couple of tools that I made earlier. One makes use of [list-drip], but as an abstraction for Vanilla made by Mathieu Bouchard, and they both use an abstraction of [l2s] made by Cuinjune (... [list2symbol].... for Google search).
Of course it would be much easier in Extended.
But I stopped coding at Fortran3 and Pascal....... and I'm too old to start again! The command prompt can be tricky in Windows with Pd.
I am trying hard with tk/tcl though.....
Does anyone know how to open a tcl widget in the running instance of Wish..... so as to make use of ::pdsend with the current Pd runtime.... (Windows..... but all OS would be good to know)? Google is being un-friendly. It's easy to pop up a widget, but it always opens a second instance of Wish.
David. -
This should also work in vanilla:
comport.pdOutput:
print: 62 56
print: 34 54
print: 22 78 -
@whale-av Yeaa...vanilla is kind of like being a drummer on stage with only a kick and a snare. The show could go on, but you'd have to modify your approach quite a bit... The advantage being compatibility and portability.
Unfortunately, tk/tcl is a bit mysterious to me. I just started learning code a couple years ago, and that language might be a generation or so before me. I also am using Linux instead of Windows, but I can tell you that pdsend can be accessed right through the terminal. I don't think it requires opening the tcl environment beyond just a running instance of pd. It may even be the same in windows. just pdsend <port> "whatever whatever." Not 100 on that in Windows though...
-
Tx all. Slow but steady, here. Nice to have such sharp help!
-
OK. So, I asked the wrong question. How do I take a stream of values coming through the serial port and format a list?
I receive the value 104 which is encoded h
Then an encoded digit, lets call it $1
Then an encoded digit, lets call it $2
Then the value 44 which is a comma
Then an encoded digit, lets call it $3
Then an encoded digit, lets call it $4
Then the value 102 which is fStream looks like this and f is a float variable.
104
f
f
44
f
f
102 over and overI know I can take ($1 - 48) x 10 + ($2 - 48) = sensor value x
($3 - 48) x 10 + ($4 - 48) = sensor value yHow do I make a list like reactivision or hid? So I can use route? I know this is alot to ask about with the little understanding I have, so I am extra grateful for any help.
-
@ingox if I feed comport.pd with my serial port I get nothing like the formatted output you show?
-
@lulu_joe13 This might work:
comport3.pdLike the previous version, it doesn't check for the consistency of the messages, just assumes that they come in the right order. If anything goes wrong, the counter and the list need to be reset.
A little update with some minimal consistency checking: comport4.pd (not very reliable though...)
-
@ingox @lulu_joe13 ....... check this thoroughly when you have a moment.......parse2.pd
It can cope with any data (including values of 44 and 102 and 104..... i.e. the same values as the header separator and footer) and the "worst" it will do is repeat the last data set up to 6 times before moving on......
If that is a problem then try this, which removes repeated lists (of the 4 "data" floats)............parse3.pd
David. -
@whale-av I can think of a few ways to do this. the best way depends on what you are going for. If externals are an option, cyclone can do it in just a few objects.
]comport]
|
[zl group 6]
|
[zl iter 3]
|
[route 102 44]A simple way in vanilla would be this
-
@whale-av Yes, i took your approach, modified it a little bit and put everything together. Should be very tight now: parse2b.pd
-
@ingox Ah! Yes...... I missed the data range 48 plus.......
Good idea to constrain the data range!
..... but where do you find "57 or less"?
In the OP there was data of 78......
What do you know that I don't?..... is the "78" a misprint by @lulu_joe13 ?
David. -
@whale-av 78 will be the result of 7 * 10 + 8, where 7 is 55 in ASCII and 8 is 56 in ASCII.
-
@ingox Ah!...... mixed data in the OP..... well spotted!
I am getting old and more easily confused.
David. -
Thanx to all. It'll probably take weeks to figure out what you all did. But, the longest journey starts with one step...
If you want to see where x and y come from then look at the link below. In this iteration I am calculating the hypotenuse of a triangle on the arduino and sending that one value as a midi note number to pd. Now, I am sending the x and y so I can have 2 values to use in pd. Depending on the image printed the sequence changes but is unique and repeatable for each image. -
@whale-av. Dang. Works like a charm! Tx to all. Again.
-
badass!