I had one of those aha moments last night. While you, Kuroneko, and I were discussing this, he posted this source:
repeat
fds.dec(fds.rx)
fds.tx(32)
At first it didn't work, but then I retried, and it worked. So that was my first awakening. Then the night before last, he provided some other source code, at the time I thought it was interesting, but I truly didn't understand the significance of it or what he was truly trying to demonstrate to me. After I got the repeat above to function properly, I reviewed his prior code more thoroughly, and by altering values in that code, I now have a much more thorough understanding of what is actually happening and what I need to do to accomplish the communications I seek. From your source I was learning displaying and parsing the communications, and from his I was learning the communication protocol. I needed to understand both yours and his samples to get a good grasp on things. And I think I am truly getting there.
I think my main problem now is attaching the CRC data and testing that. And I think it all boils done to what is the best way to do it.
The main message as you know is <stx><command><command param><etx>
However adding the CRC data is another issue, as Dave Hein just informed me the CRC could also contain stx or etx. Besides resolving that possibility I am wondering whether to format the transmission as:
I would imagine that the later example would execute much faster, but it would give me an extra parsing operation of finding the period and seprating the command from the command parameter, but that should not be a problem as your code clearly demonstrates.
Anyhow, I truly appreciate the source code that you have provided, and the patience that you and Kuroneko have had with me in this matter. I know that I have been thick headed with it, but I was just having trouble grasping the whole picture.
However adding the CRC data is another issue, as Dave Hein just informed me the CRC could also contain STX or ETX.
That's easy enough to deal with. Just encode the 16 bit value into 24 bit and make sure that you never generate bytes that contain STX or ETX. Attached is an example (which borrows the encoding from UTF-8 with the exception that the encoding isn't minimal, i.e. always 3 bytes). The core functions encode a 16 bit CRC into a 24 bit STX/ETX-free CRC and vice versa.
That's the idea (and only one of many ways of doing it). Once you have the 24 bit value you still have to decide in which order to send the bytes (I'd start with %1110xxxx followed by %10xxxxxx) but in the end it isn't really important as long as the parameters for en/decoding are in the right format.
I still have a lot of studying to do, pertaining the samples that you and Jon have provided. Windows and Perl programming was so much easier for me than this stuff There was an enormous amount of information available from which to learn and study. However, with your's, Jon's, and Dave Hein's examples and assistance, I believe I should have ample information at this point to accomplish a nice serial comm setup, but I truly don't believe that it will be done overnight There is still a lot of studying and testing to do.
Marko, is your previous code example open source?
Anyhow, I truly appreciate your help Marko. I would have been truly lost without your's and Jon's assistance.
I was wondering where Chigasaki was located, so I looked it up. It is actually a pretty decent sized city. So do you have one of those magnificant ocean views?
Not quite but it's only about 10 min walk to the beach (basically we don't live high enough to see the ocean). What I do see nearly every day is Mt Fuji.
After a discussion with Heater, I came up with a way to bypass the possible interference of parsing for ETX and getting the CRC. However, now I am having trouble getting good CRC values and comparing them. I think it is because of the BUFFER_SIZE declarations.
Could you please take a look at the following attachment, and possibly tell me what I am doing wrong.
When sending the message you calculate the wrong CRC. ComputeCRC(@DataString, DataSize) should be used witout @. On the receiver side you reuse Index which means your CRC re-calculation on the payload goes wrong. Use ComputeCRC(@MessageBuffer, strsize(@MessageBuffer)) instead. One remaining issue is that the CRC is missing a byte for as yet unknown reasons. I report back.
One remaining issue is that the CRC is missing a byte for as yet unknown reasons.
REPEAT WHILE (Char := Receiver.Rx) <> US
MessageBuffer[Index] := Char
Index++
' [COLOR="red"]REPEAT UNTIL Receiver.Rx <> US[/COLOR]
Terminal.Str(string("Unit seperator has been bypassed", CR))
The red line is not required. The repeat loop right in front already consumes the US.
That said, I don't quite see the advantage of an ASCII CRC but in the end that's your decision.
Is the crc providing error checking for me? I am no expert, but I read that it did. At this point in the program, I would send an ACK back to the sender to indicate that the data was valid, and then both Props could proceed with other tasks. If what I read was correct, you got to keep in mind that these are machine instructions that I will be passing, I can't have errors in my instructions, because I don't want to babysit the machine.
That's not what I meant. Lets say the CRC is $FFFF, so the tail of the message is sent as "65535", US, ETX (ASCII encoded). That's 5+2 bytes. If you were to get more comfortable with binary data you'd send 3 bytes + ETX ($FFFF encoded is $EFBFBF) i.e. $BF, $BF, $EF, ETX. On the receiver side you simply know that you should expect 3 bytes after the US and before ETX. I modified your example for binary transfer.
I mean with the current code, how are you going to compare the CRC values?
Have you thought of dropping the crc gimmick?
'
Most INTERNET protocols have dropped it,
'
I would use a NODE set-up, But there might be something I'm missing that your trying to do.
'
I use a NODE set-up, I send the data packet twice. the NODE I sent it to looks at the two packets and if they are the same =, They run the instruction, If the packets aren't = they request another packet send.
@Marko - I don't know the answer to your last question. I wish I knew that stuff but I don't. I looked at the code, but I don't understand it. With the code you suggest, how will I compare those values?
@Walt - Good evening. At this point I am a man on a mission. This is not just for me, it is for everyone that don't know how to do it, including myself. This thread has provided me with a fairly good understanding of how serial communication is accomplished with the prop. There are no good solid examples for beginners like me. Hopefully when I am done, someone with a thick skull like me might be able to say aha. Your method sounds like a quick easy fix to get me going, but then this would go unfinished. Between Kuroneko, JonnyMac, and I, there is a lot of time devoted to this so far. I would like it to end up as a fairly decent example by tomorrow.
@Marko - I don't know the answer to your last question. I wish I knew that stuff but I don't. I looked at the code, but I don't understand it. With the code you suggest, how will I compare those values?
Your code does this:
re-calculate CRC of payload (result is long)
get CRC string (result is string)
So the problem here is that you'd have to convert the long into a string and use strcomp() or convert the CRC string into a (binary) long probably by using a 3rd party object. That seems rather long-winded and inefficient (which is what MagIO2 tried to get accross in the other thread).
With the binary transfer you get:
re-calculate CRC of payload (result is long)
get CRC binary value (result is long)
and then all you have to do is
if crc_expected == crc_received ' crc_received is the [COLOR="red"]decoded[/COLOR] value (when sent encoded)
' very nice
Apologies, crc_received is meant to be the value after decoding. The code fragment was only supposed to show the simplicity of comparing two longs. I added a comment.
With the code like it is, with the three different com objects, can the Receiver com now send an ACK back to the Sender com?
Yes, they are cross-linked (pins 1 and 0). All the sender has to do is listen.
As for (not) understanding, which part is giving you trouble? It all boils down to that bytes are sent over the link. Meaning is not important down there as protocol stuff happens at a higher level. So the only change is the encoding of the CRC. Previously it was sent as ASCII string (human readable), now it's sent raw. You'll get there eventually.
I don't expect you to explain it to me, that would take to much time and effort on your part. Besides, I can tell that it would be a hard thing for me to grasp in a short time. I normally learn much better by reading and having numerous examples that I can study over a period of time.
I am now going to try to fit the ACK in there and get that working (HOPEFULLY).
As always, thank you very much Marko. I would have been lost without your gracious assistance.
The objective is to send 24 bits stored in CRC (3 bytes, encoded). The bytes are organised in the long like this $00KKLLMM (top byte isn't used). Furthermore the tx method expects a byte as parameter (parameters always occupy a long on the stack but only parameter.byte[0] is actually used). The loop runs 3 times.
send $MM, adjust CRC by shifting it right -> $0000KKLL, CRC.byte[0] is now $LL
send $LL, adjust CRC by shifting it right -> $000000KK
send $KK, adjust CRC (not strictly required)
You'd get the same effect with this version but it requires a local variable:
repeat n from 0 to 2
Sender.Tx(CRC.byte[n])
or (we know that neither $KK, $LL nor $MM are zeroA) like this:
So the actual byte value is entered into crc, but it is at the left and we want it on the right, so we keep shifting until we get it exactly where we want it?
This will assign a byte value to a long. Inside the long it looks like $000000FF. So a byte assignment goes to the right. In order to fill the next one (storage.byte[1]) you can use either of the methods below:
The red code makes sure that the 8 bits are zero as we use an OR operation to insert our value (this can be omitted when we know that those bits are zero). The first version has to do the same but it's done by the SPIN interpreter for you (behind the scenes).
As for getting the value where we want it, yes, we need to shift bytes on the left to the right so that the tx function finds them in the right location. Re: entering a byte, not quite sure what you mean here. CRC is a long and filled with the result of encodeCRC which returns a 24 bit value. What we want is extracting bytes (in fact all 3 of them).
@Marko - Thanks for the lesson, I appreciate that.
@All Others - I know a lot of people are looking at this thread, so I thought I would leave the latest sample before going off to sleep. Feel free to work on it and post suggestions. It is a Prop2Prop simulation program, designed to help me learn. Thanks Marko and thanks Jon.
Here is the latest rendition. The project has been renamed to PropToPropSim. I just hope it helps someone in the future. If it does, please drop me a post.
Comments
That was a pretty cool sample.
I had one of those aha moments last night. While you, Kuroneko, and I were discussing this, he posted this source:
At first it didn't work, but then I retried, and it worked. So that was my first awakening. Then the night before last, he provided some other source code, at the time I thought it was interesting, but I truly didn't understand the significance of it or what he was truly trying to demonstrate to me. After I got the repeat above to function properly, I reviewed his prior code more thoroughly, and by altering values in that code, I now have a much more thorough understanding of what is actually happening and what I need to do to accomplish the communications I seek. From your source I was learning displaying and parsing the communications, and from his I was learning the communication protocol. I needed to understand both yours and his samples to get a good grasp on things. And I think I am truly getting there.
I think my main problem now is attaching the CRC data and testing that. And I think it all boils done to what is the best way to do it.
The main message as you know is <stx><command><command param><etx>
However adding the CRC data is another issue, as Dave Hein just informed me the CRC could also contain stx or etx. Besides resolving that possibility I am wondering whether to format the transmission as:
<stx><command><us><crc><us><command param><us><crc><etx>
or
<stx><command.command param><us><crc><etx>
I would imagine that the later example would execute much faster, but it would give me an extra parsing operation of finding the period and seprating the command from the command parameter, but that should not be a problem as your code clearly demonstrates.
Anyhow, I truly appreciate the source code that you have provided, and the patience that you and Kuroneko have had with me in this matter. I know that I have been thick headed with it, but I was just having trouble grasping the whole picture.
Thanks Jon
Bruce
That's easy enough to deal with. Just encode the 16 bit value into 24 bit and make sure that you never generate bytes that contain STX or ETX. Attached is an example (which borrows the encoding from UTF-8 with the exception that the encoding isn't minimal, i.e. always 3 bytes). The core functions encode a 16 bit CRC into a 24 bit STX/ETX-free CRC and vice versa.
Sorry it took so long to get back to you on this, but I had other chores to do for a day. That sounds excellent.
Okay, so first I create the 16 bit CRC using the ComputeCRC, and then I run it through encodeCRC, to make it STX and ETX free?
Bruce
I still have a lot of studying to do, pertaining the samples that you and Jon have provided. Windows and Perl programming was so much easier for me than this stuff There was an enormous amount of information available from which to learn and study. However, with your's, Jon's, and Dave Hein's examples and assistance, I believe I should have ample information at this point to accomplish a nice serial comm setup, but I truly don't believe that it will be done overnight There is still a lot of studying and testing to do.
Marko, is your previous code example open source?
Anyhow, I truly appreciate your help Marko. I would have been truly lost without your's and Jon's assistance.
Bruce
Feel free to ab/use it as you see fit.
I was wondering where Chigasaki was located, so I looked it up. It is actually a pretty decent sized city. So do you have one of those magnificant ocean views?
Bruce
Is it a nice place to live? I always liked mountains and the ocean.
Bruce
After a discussion with Heater, I came up with a way to bypass the possible interference of parsing for ETX and getting the CRC. However, now I am having trouble getting good CRC values and comparing them. I think it is because of the BUFFER_SIZE declarations.
Could you please take a look at the following attachment, and possibly tell me what I am doing wrong.
Bruce
You are a very good and kind person
Bruce
That said, I don't quite see the advantage of an ASCII CRC but in the end that's your decision.
That's beautiful Marko!!!!!!!!!!!!!
Now I can go forward. THANK YOU VERY MUCH!!!!!!!
Is the crc providing error checking for me? I am no expert, but I read that it did. At this point in the program, I would send an ACK back to the sender to indicate that the data was valid, and then both Props could proceed with other tasks. If what I read was correct, you got to keep in mind that these are machine instructions that I will be passing, I can't have errors in my instructions, because I don't want to babysit the machine.
Thanks Marko
Bruce
I mean with the current code, how are you going to compare the CRC values?
'
Most INTERNET protocols have dropped it,
'
I would use a NODE set-up, But there might be something I'm missing that your trying to do.
'
I use a NODE set-up, I send the data packet twice. the NODE I sent it to looks at the two packets and if they are the same =, They run the instruction, If the packets aren't = they request another packet send.
@Walt - Good evening. At this point I am a man on a mission. This is not just for me, it is for everyone that don't know how to do it, including myself. This thread has provided me with a fairly good understanding of how serial communication is accomplished with the prop. There are no good solid examples for beginners like me. Hopefully when I am done, someone with a thick skull like me might be able to say aha. Your method sounds like a quick easy fix to get me going, but then this would go unfinished. Between Kuroneko, JonnyMac, and I, there is a lot of time devoted to this so far. I would like it to end up as a fairly decent example by tomorrow.
Bruce
- re-calculate CRC of payload (result is long)
- get CRC string (result is string)
So the problem here is that you'd have to convert the long into a string and use strcomp() or convert the CRC string into a (binary) long probably by using a 3rd party object. That seems rather long-winded and inefficient (which is what MagIO2 tried to get accross in the other thread).With the binary transfer you get:
- re-calculate CRC of payload (result is long)
- get CRC binary value (result is long)
and then all you have to do isI must be doing something wrong because they do not equal
You are a genius. Okay that works for me, even though I don't understand it. I will have to study that subject later. This is how I did it.
Bruce
Don't apologize, it's perfect. I just wish I understood it.
With the code like it is, with the three different com objects, can the Receiver com now send an ACK back to the Sender com?
Bruce
Yes, they are cross-linked (pins 1 and 0). All the sender has to do is listen.
As for (not) understanding, which part is giving you trouble? It all boils down to that bytes are sent over the link. Meaning is not important down there as protocol stuff happens at a higher level. So the only change is the encoding of the CRC. Previously it was sent as ASCII string (human readable), now it's sent raw. You'll get there eventually.
Which part is giving me trouble? Look below
I don't expect you to explain it to me, that would take to much time and effort on your part. Besides, I can tell that it would be a hard thing for me to grasp in a short time. I normally learn much better by reading and having numerous examples that I can study over a period of time.
I am now going to try to fit the ACK in there and get that working (HOPEFULLY).
As always, thank you very much Marko. I would have been lost without your gracious assistance.
Bruce
The objective is to send 24 bits stored in CRC (3 bytes, encoded). The bytes are organised in the long like this $00KKLLMM (top byte isn't used). Furthermore the tx method expects a byte as parameter (parameters always occupy a long on the stack but only parameter.byte[0] is actually used). The loop runs 3 times.
- send $MM, adjust CRC by shifting it right -> $0000KKLL, CRC.byte[0] is now $LL
- send $LL, adjust CRC by shifting it right -> $000000KK
- send $KK, adjust CRC (not strictly required)
You'd get the same effect with this version but it requires a local variable: or (we know that neither $KK, $LL nor $MM are zeroA) like this:A because we encoded them like this
So the actual byte value is entered into crc, but it is at the left and we want it on the right, so we keep shifting until we get it exactly where we want it?
Bruce
CRC is a long, we enter a byte but it goes to the left instead of the right. So then we shift to get it to the right. Something like that?
As for getting the value where we want it, yes, we need to shift bytes on the left to the right so that the tx function finds them in the right location. Re: entering a byte, not quite sure what you mean here. CRC is a long and filled with the result of encodeCRC which returns a 24 bit value. What we want is extracting bytes (in fact all 3 of them).
@All Others - I know a lot of people are looking at this thread, so I thought I would leave the latest sample before going off to sleep. Feel free to work on it and post suggestions. It is a Prop2Prop simulation program, designed to help me learn. Thanks Marko and thanks Jon.
Here is the latest rendition. The project has been renamed to PropToPropSim. I just hope it helps someone in the future. If it does, please drop me a post.
Bruce