Write HEX value to serialport

Hi everyone, I’m facing a problem on my program. I’m creating a small hardware configuration program through serial communication. My device accepts hexadecimal values from 01 to 3E for configuration. I tried using the usual format of serial.write, but it didn’t work. I found several examples on the Internet, but I don’t know how to implement them. Attached, I send the part of the program where I go to write the values in hexadecimal. Can someone help me? I’m new in Xojo and I have small experience.

If Me.Caption = "Not Send" Then // Disconnect from the serial port Serial1.Close Me.Caption = "Send" SerialPortsPopupMenu.Enabled = True PortListUpdater.Mode = Timer.ModeMultiple ' turn it on Else // Connect to the serial port // Set the serial port to the index of the one chosen in the popup menu Serial1.SerialPort = System.SerialPort(SerialPortsPopupMenu.ListIndex) If Serial1.Open Then Me.Caption = "Send" SerialPortsPopupMenu.Enabled = False PortListUpdater.Mode = Timer.ModeOff Serial1.Write(TextField1.Text) Serial1.Write(TextField6.Text) Serial1.Write(TextField7.Text) Serial1.Write(TextField8.Text) Serial1.Write(TextField9.Text) Serial1.Write(TextField10.Text) Serial1.Write(TextField11.Text) Serial1.Write(TextField12.Text) Serial1.Write(TextField13.Text) Serial1.Write(TextField14.Text) Serial1.Write(TextField15.Text) Else Beep MsgBox("The selected serial port could not be opened.") End If End If

Regards

Did you tried using EncodeHex (https://documentation.xojo.com/api/text/encoding_text/encodehex.html)?

As an example;

Serial1.Write(TextField1.Text)

Becomes;

Serial1.Write(EncodeHex(TextField1.Text))

You may need to add carriage returns and/or line feeds after the values depending on your device/protocol.

Or maybe is DecodeHex. I’m not in front of a computer, but is one of the two. I think you want decodehex.

Hi @LangueR it works with DecodeHex. Can I ask you the last question? When I go to read the serial, I don’t see all data, Sometimes I have white spaces, how can I solve them?

Put your code to read from the device in the DataAvailable event. Or, what I think works better in Xojo, put your Serial1.read code on a timer that “polls” the port every 100ms or so.

I add in DataAvaible event Serial.Poll. But not change the my problem

you can search the forum, for this and the documentation.

The DataAvailable event can send it all but it’s not always the case. you should use Serial.LookAhead to see if all your data is there then read it using Serial.ReadAll or Serial.Read(NUMBYTES).

http://documentation.xojo.com/api/deprecated/serial.html
Quote from this docs page:

http://documentation.xojo.com/DataAvailable_event

Hi @Derk Jochems , I have this in DataAvaible:

If Instr(Me.LookAhead(Encodings.ASCII), Chr(13) + Chr(10)) > 0 Then TextArea1.Text = TextArea1.Text + Me.ReadAll(Encodings.ASCII) End If

[quote=440881:@Mario Castaldo]Hi @Derk Jochems , I have this in DataAvaible:

If Instr(Me.LookAhead(Encodings.ASCII), Chr(13) + Chr(10)) > 0 Then TextArea1.Text = TextArea1.Text + Me.ReadAll(Encodings.ASCII) End If[/quote]

You are reading the entire buffer Using “me.lookahead” and then reading all content.
When the DataAvailable event is raised, you could get a string like “my string is” and in another datavailble event you can get “complete” you may want to get “my string is complete” instead.

So check the buffer using me.lookahead (keeps the data in the buffer). If all expected data is there, then you read the part that is completed. (it’s chunked).

your in the right way. the only thing is you use “Me.ReadAll” and you don’t check if the end is actually “Chr(13) + Chr(10)”
You may wanna try Me.Read(Count,[encoding]) .

Instr returns an integer, you can store it, compare it and then if it’s > 0 Read the line part until you got "Chr(13) + Chr(10).


Dim EOLStart As Integer = Instr(Me.LookAhead(Encodings.ASCII), Chr(13) + Chr(10)) // Same as EndOfLine.Windows
Dim Line As String

Do // Loop at least once to check the data

EOLStart = Instr(Me.LookAhead(Encodings.ASCII), Chr(13) + Chr(10)) // Get the EOL position

Line = Me.Read(EOLStart+2, Encodings.ASCII) // You should check the output of this in the debugger
// EOLStart should read Chr(13) + Chr(10) too.

TextArea1.Append Line // Adds the line to the textarea.

Loop Until EOLStart < 1

Untested code, but it should give you a clue.

Why not create a timer that fires every 100ms with the following code:

TextArea1.Text = TextArea1.Text + Serial1.ReadAll(Encodings.ASCII)

But isn’t that the equivalent of this in the DataAvailable event of the serial?

TextArea1.Text = TextArea1.Text + me.ReadAll(Encodings.ASCII)

No need for a timer and the system polls the serial port much more frequently.

Hi @Tim Hare , @LangueR , @Derk Jochems thanks for your answer. if I don’t know if you understood my problem well. Right now, when the device wants to write something about my program, it does, but in the wrong way. Sometimes some characters don’t come out and sometimes it doesn’t break automatically. I don’t see this problem on Hercules. Please help me. I’m running out of ideas

That is because probably you don’t understand the dataavailable event.

It can send all data bit is NOT guaranteed to do so.
Sometimes you get only a part and sometimes you get more than you want. You have to filter your data.

What do you mean by does not Break properly?

You might wanna set the correct baud rate. And other properties before the .Open call

Using lookahead keeps it in the buffer (so it remains available in the next time dataavailble is fired)
Using .Read or .ReadAll removes it from the buffer

@Derk Jochems look at this picture. On the right is what I want to see on the left screen. On the right I send to my device a command to get values, on the left if I click view config by the same command. If I press the command several times, it gives me everything wrong “see monitor”. With Hercules, no problem

Right side seems to set values as they please.
Left you visualise what you actually read.

What device is this?

A device of Texas Instruments

Well that does ‘t say anything to me. Protocol and device could give better understanding of it’s usage

I don’t think it’s a problem with the device. Otherwise, it didn’t even work on Hercules. Is the code I used wrong?

if InStr(me.LookAhead(Encodings.ASCII), chr(13)+chr(10)) > 0 then TextArea1.text = TextArea1.Text + Me.Readall(Encodings.ASCII) Serial1.Poll end if

are you sure of the encoding ?
are you sure of the chr(13)+chr(10) in each line ?

@Jean-Yves Pochez I think of yes. I haven’t idea.

I’m not sure if this will help or not. Here is the DataAvailable code I have for EVERY serial device I work with:

[code]Dim s As String

While me.BytesAvailable > 0
s = s + me.ReadAll

me.Poll
Wend

SendDataToListeners(s)[/code]

I work with multiple barcode readers, bill acceptors, lightning and emf detectors, and card dispensers with no issues serial-wise. The biggest issue I have is that cheap Prolific USB to serial converters don’t always work and the last byte doesn’t like to be consumed but that’s a driver issue.

This code doesn’t filter out any unwanted characters (noise) and will not guarantee a very large string is completely received as it’s not checking for a terminator.