Case statement question
turbosupra
Posts: 1,088
Wow, this is humbling ... I cannot get this case statement to work for the life of me, what am I doing wrong here? Thanks for joining me in this time of humbling embarrassment
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 byteLimit = 50 STR_MAX_LENGTH = 128 VAR OBJ pst : "Parallax Serial Terminal" PUB main returnValue := hexToAscii(string("00")) pst.Str(String(pst#NL, "returnValue is: ")) pst.Str(returnValue) pst.Str(String(pst#NL, pst#NL)) PUB hexToAscii(hex) : returnValue returnValue := 0 pst.Str(String(pst#NL, "hex is ")) pst.Dec(hex) pst.Str(String(pst#NL)) Case hex pst.Str(String(pst#NL, "about to go to NUL ")) : pst.Str(String(pst#NL)): "00" : returnValue := string("NUL") pst.Str(String(pst#NL, "went to NUL ")) pst.Str(String(pst#NL)) pst.Str(String(pst#NL, "about to go to SOH ")): pst.Str(String(pst#NL)): "01" : returnValue := string("SOH") pst.Str(String(pst#NL, "went to SOH ")) pst.Str(String(pst#NL)) {"02" : "STX" "03" : "ETX" "04" : "EOT" "05" : "ENQ" "06" : "ACK" "07" : "BEL" "08" : "BS" "09" : "HT" "0A" : "LF" } Other : returnValue := string("Error") return returnValue
Comments
You can't have extra debug statements after you use "case".
You can't check for strings just a single value. You could use "0" instead of "00" etc.
Duane
You could try
Thanks for the reply. So are you saying I cannot use "00" as a case MatchExpression? Since I'm building a Hex translator, 00 is one of the values for hex. I also wanted to have a decimal to ascii converter, where there will also be 0-128, but if I understand you correctly I can only use 0-9 (single value)? That's a shame if you can only compare numbers and not strings, to the case statement?
In your case, hex is a pointer to a string. You can convert it to a number that can be used in the case construct like this:
Your case comparison values with then be $00, $01, $02 ...
-Phil
SPIN has only a few commands for strings.
almost everything has to be done in 32bit integers.
if-conditions, case-conditions repeat until-conditions repeat while-conditions acept only 32bit integer-values
the compiler accepts things like
the compiler "translates the above to
a single character can be translated into its ASCII-code
This makes only sense for a single character. Not for multiple characters
If you want use more than a single character you have to use the command "StrComp" which can compare two byte-arrays if each byte is euqal to the other byte or not.
My suggestion for comparing strings is to use StrComp constants.
receiving the ASCII-coded digits "1001", "1002" converting this digitSEQUENCE "1" "0" "0" "1" into the integer-value 1001
and after this conversion to integer-values using the constant-names
keep the questions coming
best regards
Stefan
Thank you very much. I used strcomp as you advised. I don't believe there is a native cast or convert function from string to dec or hex, and back, so I am going to have to figure out how to write that to finish up this object. Maybe using bytemove or lookdownz as PhiPi suggested?
I have not ever used lookdownz, so I will read up on that and try that. Thank you!
Here the link.
http://forums.parallax.com/showthread.php?134823-DAT-length-including-HEX-00
I posted some code to convert hex to and from ASCII and JonnyMac posted a more elegant solution.
Duane (hopefully still sane)
I did do my due diligence and search for about a 1/2 hour before posting ... I will check that out now.
My comment wasn't a condemning you. I was expressing my frustration over losing my mind.
I was sure I had posted the link to the hex to ASCII stuff earlier, but obviously I hadn't.
I haven't been the least bit annoyed by your posts. (I had been temporarily and unjustly annoyed when I thought I had previously posted the link.)
Now, I'm just annoyed at myself.
Please continue to ask your questions.
Duane
What am I doing wrong here? If you set your value to 12 and you set your pointer to valueAscii, and then run rtu2asc(value, @valueAscii) it returns a value of 0C or 12 in hex. I thought this was to convert to Ascii?
Thanks!
' value := 12
' rtu2asc(value, @valueAscii)
' pst.Str(@valueAscii)
' valueAscii = 0C
I'm not sure what you are trying to do.
What kind of data are you starting with and what do you want to do with it?
Can you give and example of data in and data out?
I'll write a small example program for you (assuming it's within my ability) once I understand what you are trying to do.
Duane
Thank you for that. I am actually trying to create my own object for formatting strings, all the while trying to teach myself how the propeller handles strings since it is not native. I have gathered a bunch of different string methods from the forum and I am trying to build test examples.
I wrote a test program that used all of the quoted functions, the only one I could not get to work was the "rtu2asc" method, as it returned "0C" instead of "C" when it was given an input of "12" ... besides that was not truly ascii, but a hexadecimal output anyway.
I did however write an if/elseif method that translates from decimal and hex to ascii, I just left it at work unfortunately. Are you able to get the rtu2asc to work? If so, how?
In my case, I wanted to send data to another Propeller chip. In my communication protocol I use 1 to indicate the start of the header and 2 to indicate the start of text. I also use 13 as an end of message marker. A problem arises when I want to send 13 as data. The Propeller instead of using the value will think it is the end of the message. One way of getting around this problem is to send the data as ASCII character. Since the first printed ASCII character is a space (I suppose it's debatable if it's a printed character). The ASCII code for a space is 32 with the other printed characters having values greater than 32. This allows the numbers 0 to 31 to be used as control characters.
Now let's say I want to send a data value of 13. I could send it as ASCII decimal and send "1" (ASCII 49) and "3" (ASCII 51). In this case the number is two characters. Now let's suppose the value we're sending is a single byte. Depending on the value of the byte we could send anywhere between one and three digits (ie "2", "5", "5"). In many cases, it's easier to use ASCII hexadecimal since we know any byte value can be represented as two characters. Now to send 13, we'd send "0" (ASCII 48) and "D" (ASCII 68). In my communication protocol and the one JonnyMac is using, we want each byte to be represented as two ASCII characters. This is why 12 came back as "0" and "C". This way we know the "C" is 12 and not 192 ($C0) plus the value of the following character.
Duane
Can I see your serial code if you don't mind?
Yes,
So far, any code I've written is available for the asking.
I'll look through my projects for a good example and post it within the day.
Duane
I've attached three archives to this post.
These files are part of a project I'm working on.
MecanumRemote is used by a USB Propeller Protoboard. This board has a PlayStation 2 controller attached to it. The Propeller reads the controller information and sends it to the robot via a Nordic module.
The controller information is received by another Propeller Protoboard (non-USB). This board is programmed with the files in the MecanumMotor archive. This board controls the robot's motors. Besides communication with the remote Propeller, this board is also connected with a third Propeller Protoboard with a wired serial connection.
The third board uses the files in the MecanumVision archive. This board uses Hanno's method of capturing video with the Propeller. The board also controls 120 LEDs in a 12 x 10 array. It can display the captured video on this array or use it to display text and patterns.
I decided to share these files since they have examples of both wired communication and wireless communication.
For wired communication I use a modified version of Tim Moore's four port serial object. The modified version has a large rx buffer so I don't need to keep moving incoming data to a different buffer. The program just waits for an end of message character to be received and then processes the message. This is done by monitoring the variable "rxFlag". The serial object increments "rxFlag" each time an end of message character is received. Here's the code.
Once a new message is detected it is transfered to "tempBuffer" by the method "FlushBuffer". "FlushBuffer" also increments "oldRxFlag" so the program will be ready to detect the next new message.
I use several debugging methods. "SafeBug" and "TBug" are a couple of these methods. "TBug" is short for TV Debug since originally I used it to display debug information to both a serial terminal and to a NTSC monitor. I find it useful to easily change my debugging screens since I only need to change the calls to the debugging object within these debugging methods instead of having to change many call through out the program.
"SafeBug" uses the size of the buffer as a guide of how many characters to display rather than relying on a terminating zero. I was having trouble with program bugs that would clear the serial terminal by including non-displayed ASCII codes in the serial communication line. "SafeBug" watches the characters that are being sent to the serial terminal and changes any non-printed codes to ASCII representations of their hexadecimal values (for example 0 will be displayed "<$00>).
In the code I just posted, you can see I use the values 1 and 2 to indicate the start of a new message (tempBuffer[0] and tempBuffer[1]). Following these two start values come a character representing the target board for the message (in this case "v") followed by the character identifying the originating Propeller board ("w"). These two characters are even more important with wireless messages so a board will know if the message is intended for that board or not.
In some projects I have messages that need to be passed from one board to another since not all the boards have wireless connections. The target board my have a wired connection to a wireless enabled board. The messages can hop from board to board until they arrive at their destination.
As an example, the motor control board (board "w") has a method "PassThroughRx" which will pass a message received from board "v" via its wired connection to board "u" (the PlayStation 2 board). I don't think I'm using this capability yet in this project. I do use these type of message hopping strategies in some of my other projects.
Wireless messages have an extra character in the beginning of the message. Here's code for two different message buffers.
You can see "nordicTxBuffer has a zero after the "w" (the originating boards ID). The extra byte is to hold a counter that increments with each unique message transmitted. Since this project just streams the controller information from one board to another, I don't use this extra byte. In other projects, it is important that each message is received. In these cases the receiving board will transmit an acknowledgment with this same value to indicate that message had been received. By using this counter, the receiving board can determine if the transmission is a new message or a retransmission of a previous message.
Earlier you were asking about hexadecimal data.
Here's an example of my wish to send hexadecimal ASCII characters.
In this case, I want to send the three bytes used to tune the PID algorithm. Each byte is converted to two ASCII hexadecimal characters and placed in the appropriate places in the out going buffer.
Here's the "Hex" method called in the above code.
I also have a corresponding "FromAsciiHex" to change the two character back to a single byte value.
Okay, I think that's about it for now. Sorry for such a long discourse. I wanted to provide some background to all the code I've attached.
Here's a list of methods in each program that should be useful in learning about strings and Prop to Prop communication (at least the way I do these things).
MecanumRemote
MainLoop
SendData
Hex
FromAsciiHex
FlushBuffer
TbugTx
MecanumMotor
MainLoop
PassThroughRx
SendPidInfo
MecanumVision
MainLoop
This project is far from completed. There are a lot of dead ends in the present code. I choose to use this project as an example since it uses the features you were asking about. I also think this is a pretty cool project. The LED array is a lot of fun. Especially being able to see a live video image on the array.
I haven't cleaned up the code prior to posting it. There are bound to be lots of mistakes in it. It's not very well commented. I normally wouldn't post code in this condition but I'm willing to post any code I've written so far if asked.
I've actually recently switched back to the original treads on this robot. One reason is I thought it would be easier to get the four motors working together in a less complicated fashion than required to drive Mecanum wheels and secondly, I need a robot to drive across the insulation in our attic to pull some wire across the atic to a vent opening (I'm install a CCTV system and I don't want to crawl through the attic). The treads should do much better on the insultation than Mecanum wheels.
Duane