![]() |
Forum Index : Microcontroller and PC projects : Sending and receivin hex using Serial Com
Page 1 of 2 ![]() ![]() |
|||||
Author | Message | ||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hello all, I have the serial communications thing down, but have come across a strange one, (for me anyway). I have a board hooked up to com1 on uMite. I need to be able to send one byte commands to it (i.e. D7 or E0) and also receive back a hex response code. I am stuck on sending ascii. How in the world do you send and receive hex??? Thanks again!!!!! |
||||
hitsware Guru ![]() Joined: 23/11/2012 Location: United StatesPosts: 535 |
A purely uninformed guess : hex notation with ascii characters ? |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9491 |
I am pretty sure you can send bytes in hex or decimal or binary. Will check.... Decimal: PRINT #1,13 Hex: PRINT #1,0x0C Have not found out how to do binary yet - %01010101 does not work as a test, cos uM does not know what that means... Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6220 |
Most devices are looking for a byte and the datasheets use HEX as a convenience. They could just as easily list the commands in decimal but it doesn't look as sophisticated. You could convert the HEX to decimal but that is not really needed. To send a command such as D7, you need to add the &H to the front of the HEX value. PRINT #1, CHR$(&HD7) To display a byte as HEX use the HEX$(x) command. x= &HD7
PRINT x ' gives the decimal value of the HEX number PRINT HEX$(x) ' prints a number as a HEX formatted string PRINT &HD7 PRINT CHR$(&HD7)' prints the byte as a character for sending to the device Jim VK7JH MMedit |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9491 |
Jim - I wonder if that works for binary? Is there an &B kind of switch? Where did you read that, by the way, so I can read up on this myself? ...not that this is normally needed, but only for my interest... EDIT: Yes, &B works for binary too - PRINT CHR$(&B01010101) - this prints a capital U on the screen, which is what was expected. Smoke makes things work. When the smoke gets out, it stops! |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
The PRINT #1,CHR$(&HD7) work brilliantly!!! THANK YOU!!!! The module sends back a response code also in Hex. What do I do with the S$=INPUT$(1,#1) serial input to receive as Hex? I am guessing ascii to hex conversion? |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9491 |
HEX sometimes takes a bit to get used to, but it is the base system for all computers anywhere. Glad it works for you. ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Why does this code... INPUT "COMMAND = ";A X = HEX$(A) PRINT "HEX = ";X PRINT #1, CHR$(X) give me this error... COMMAND = ? 01 [2] X = Hex$(A) Error: Expected a number > Isn't 1 considered a number in this scenario? Do I need to enter &H first? |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
You need: X$=HEX$(A) ![]() WW and change CHR$(X) to CHR$(A) that should get you going . . . . |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
I have assumed in your last post that you are entering in a decimal value that you wish to send to your module based on the fact you convert the input to hex and then print the hex conversion on screen. IF however you are wanting to enter a two character hex value (i.e. D7) and then send this to your module then you will need a bit more code. Let us know what you intend inputting (hex or decimal)! WW |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi WhiteWizzard, I'm trying to enter a command byte, 0 to 255 (A) and send it out the serial port as a hex byte. Problem #1...So far when I send 1, it outputs 1, instead of 01. Problem #2 is if I change CHR$(X) to CHR$(A) I am not getting the Hex version of A to send out of the serial port. Problem #3 is that the device responds with Hex so I need to take the data from the input buffer and convert it to Ascii? Decimal?. Loss of hair coming.... My first venture using purely hex commands and hex responses. I appreciate your input. PS your boards are running since you sent them. I love working with them!!! Also, Thanks to all for your help. uMite is making my wife a bit jealous for my time. |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
I don't have a micromite with me at moment, but as a quick test for problems 1 & 2 can you try: input a x$=hex$(a) x$="&h" + x$ print #1, chr$(val(x$)) |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9491 |
If you are only wanting to send bytes, they don't HAVE to be HEX - this is just the preferred standard. You could send decimal equivalents: ? = 3F hex or 63 decimal. You could PRINT #1,CHR$(63) or PRINT #1,"?" or PRINT #1,&H3F etc. You also don't NEED to receive bytes back from the device as HEX - you could accept them as decimal. The only exception to that, is that some devices use ASCII HEX, and you send TWO bytes for a single HEX byte, such as the character "3" and the character "F" for 3F. This is not that common though, and if your device just sends and receives bytes, you could just use the decimal equivalent, and save yourself some hairs. ![]() Naturally, you would need to do some conversion from HEX to DECIMAL, so that you know what you are sending and receiving, but I often prefer decimal over working with HEX - but that is just me... Windows Calculator will do all the work for you - crank it up(or type 'calc' in the RUN box), set it to Programmer mode, type your decimal or hex value, and click the appropriate base standard radio button, and calc will show you the value. Smoke makes things work. When the smoke gets out, it stops! |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2927 |
Thanks G, you just saved me typing that! Won't this work? PRINT #1, A |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9491 |
If the value of A is what you want, then it should work. What device are you talking to, Jim? If it makes you feel any better, Jim, I have been on the road you are on now - we all have at some point, and if you are anything like me, HEX will be confusing the hell out of you.... ![]() That's why I still prefer to work with decimal, but that is a personal choice. The character "?" is 63 decimal, 3F hex, 00111111 binary or 77 in Octal. ?, 63, 3F, 00111111, 77 - all means exactly the same byte value!(in different bases) Wonderfully confusing, isn't it?! (rhetorical!) ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
Frank N. Furter Guru ![]() Joined: 28/05/2012 Location: GermanyPosts: 936 |
Hi all, take a look on Roman Black's site. You can find a very useful dec, hex, bin converter: HexCon 1.0 Frank |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3998 |
The questions 1. how many start/data/stop bits does the device want/send per character? (The default tends to be 8N1 or the like and usually "just works" but do check.) 2. what does the device want: 1 or 2 bytes (where byte is sometimes called octet or sometimes just called a character, and means 8 bits)? 3. does it want any terminator(s) after that/those? If it does NOT then at the end of your PRINT #1,something add a semi-colon to get PRINT #1,something; so you suppress the CR LF that otherwise are auto-output 4. what does it send back: 1 or 2 bytes (see #1)? 5. does it send any terminator(s)? If it wants a single byte and they've chosen hex notation (that's all it is: a way of representing a number, you can use decimal or binary it's still the same number!) then you likely want PRINT #1,CHR$(&HD7); That just tells MMBasic that you want it to: A. treat &HD7 as a number (which in decimal we'd write as 215) B. use the CHR$ function to convert the number to a single character (aka byte) C. print it (send it) without adding anything else PRINT #1,CHR$(215); would do the same. If there's a way to get a D7 byte into a string (I'll show it as x) then PRINT #1,"x"; would also do the same but how would you get that funny character in? Well, you probably don't even want to because it'll be less than obvious what it is so program readability would tank. If the device doc uses hex, I'd stick to hex for readability - when you or anyone else looks at the code some time in the future it'll be far quicker to match doc & code. Next, if the device sends back one byte and the doc shows (i.e. represents) it as hex... When you use S$=INPUT$(1,#1) (caution, I've not checked that syntax) then you already have the byte. If the device sends any terminators don't forget to read and discard them. What to do with S$? Well, you either compare against it or convert if from a 1-byte string (which is what it is) to a number then compare the number. You can do things like: IF S$ = CHR$(&HD7) ... just as with the original PRINT above, the CHR$(&HD7) creates a single byte string (aka character). Or you can do: IF ASC(S$) = &HD7 ... since ASC takes a character and gives you it as a number. In case the device sends 2 bytes, you'd want S$=INPUT$(2,#1) and if those two bytes were a letter D then a digit 7 i.e. "D" then "7", which together in Basic are "D7" then you'd use either: IF S$ = "D7" ... or IF VAL("&H" + S$) = &HD7 ... Why VAL??? Because it's a way to do at runtime what Basic can do as your program is entered. You could always write things like: X = &HD7 as X = VAL("&HD7") and they do the same (set X to decimal 215) but the latter is slower, uses more memory and is harder to read. A quick addition: ASC and CHR$ are known as inverse functions because: X = (any number within the range for a byte, i.e. 0 to 255 aka 0 to &HFF) S$ = CHR$(X) X = ASC(S$) results in X not changing. That's why I knew to go for ASC to match the CHR$ I'd already used as I was writing the above. John |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi All, I woke up this morning to a lot of good info from all of you on the other side of the pond. Thanks for all the effort. Grogster, the unit I am trying to work with is the MDfly mp3 player, here is the link. I did get everything to work, but was stuck on the format of the serial data being in hex. When I get home again, I will play with all of your suggestions and get back with results. Thanks also JohnS for all that info. As I play, I will try and give results based on what you described. I have two projects going with this product, both are clocks with different sounds for time markers, ie. on the hour, half hour, etc. One will have Tibetan gongs, bells and chimes for a friend of mine and the other with authentic recordings of different guns being shot for another person who apparently loves guns to the point of actually having high end recordings (mp3s) of these guns being fired. (Weird, I know, but....) I truly appreciate this forum and am learning a bunch. I experiment almost daily with the uMite. It has opened a few doors for me. Thankfully my work has multiple large format CNC routers, CNC lasers, large format digital printers, engravers and lots of drops of acrylic, wood, aluminum, etc. Combining this with all the cool things uMite can do, the possibilities are endless. |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9491 |
I just bought a couple of those MP3 players from MDFLY myself, so once they arrive, I will have a play(no pun intended), and let you know the results. I have read through the basic PDF, but I was planning to send decimal with this unit when I get mine. Provided you convert from HEX to Decimal correctly, then the module itself won't care one jot about the base standard, so long as the byte value is correct for the given command. I'll let you know when my modules arrive! EDIT: As all the commands are single-byte ones, you could setup a whole lot of variables such as PLAY=&HEA and STOP=&HFA, then you could just open the port and PRINT #1,PLAY or PRINT #1,STOP kind of thing. Not sure if STOP is a variable name you are allowed to use, or if it is resevered by MMBasic - would have to check, but you get the general idea... ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6220 |
Looking at the datasheet, the simplest way is to stick with HEX Wherever the datasheet has 0x.. for a code, MMBasic needs &H.. 0xC8 to play track 200, converts to PRINT #1, CHR$(&HC8); @Grogster, I wouldn't use STOP or PLAY as variables. STOP is a keyword and PLAY is used on the maximite. A good method, if you do want to use variable names is to preface them with something unique. For this project I would suggest MDFLY_STOP etc. Jim VK7JH MMedit |
||||
Page 1 of 2 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |