Serial communication issue

Hello, I am new to xojo and I am trying to interface with an arduino though the serial connection. The trouble I am having is that I cannot read any data from the arduino, The DataAvailable event of the serial control does not fire. I have read all of the serial related forum entries and I still cannot get any action. The arduino serial monitor works fine. Terminal programs including Putty work fine. Is there a trick that I am missing? Thanks for reading. Using V2017r3.

Did you subclass the serial control or drag it out onto the pasteboard?

if you are changing serial port settings after its open make sure you call serial.reset

Failing that post a link to a simple test project showing the problem, there are plenty of users on here with an arduino that can test the project and point you in the right direction.

I don’t know what subclass the serial control means. I just drug it form the library panel and placed it on the form.

I am using the example that reads serial data form a scanner. I know I will have to parse the serial stream. But I would think that the DataAvailable event would fire.

In the arduino sketch I just have a Serial.println(“serial pint test”); in the continuous loop. Very basic. I am just trying to get started.
I have tried Serial.write too in case I can send only one byte at a time.

In putty I just connect to the COM port and reset the arduino and the serial stream starts so i know the arduino is sending serial data.

I just tested an arduino mega 2650 R3 and the DataAvailable fires as expected.

I tested it with Xojo 2017r3 on Windows 10 Pro 1709 . From the Serial port Bar Code Reader example I commented out the If and End If and left in the OutputArea.Text line and it worked as expected.

Here is the code I used on the arduino (modded blink demo):

[quote]void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(9600, SERIAL_8N1);
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second

int bytesSent = Serial.write(“hello”);
}[/quote]

Thank you for your help. What I have found is that If I set the DataTerminalReady to true with a button then reset the serial controller it works. Does that make sense?

I added this to the connect button
Else // Connect to the serial port
SerialController.SerialPort = System.SerialPort(SerialPortsPopupMenu.ListIndex) // Set the serial port to the index of the one chosen in the popup menu
SerialController.DataTerminalReady=TRUE
SerialController.Reset

What arduino are you using?

I have tried with an uno r3 but the board I am wanting to interface with is the zero.

There’s a few google hits about certain boards requiring DTR set high before the arduino will output data, probably to stop buffers filling with nothing connected. As putty sets DTR high by default that would explain why it was working for you and also why my test worked out of the box with Xojo. We learn something every day :slight_smile: Glad you got it working.

Thank you for your help.

Your RS232 Cable… How many wires 2-3 & 7?

It is usb

Hello I am still having an issue with the serial controller. I am sure it is do to my lack of expedience with xojo. Maybe someone can see what I am doing wrong.

I am communicating with an arduino mega board. In a button I send a string with a number for the mega to process. The mega is processing the sent data fine. In one button I send a string that is requesting data from the mega. I am seeing some strange results. I append a textarea field with the received data which shows the correct data. I am trying to process the data by spiting the incoming string via the split() function. I have to press the button several times to get a good process. If I debug the process it works perfectly every time. So I believe there is a timing issue with the serial controller and I don’t know how to resolve. Below is the code I am using in the serial controller to parse the received data I anyone has any ideas I would really appreciate some help. Thank you.

Here is the string sent from the mega board.
“0,1,1,1,1,1,0,6,6,6,6,6,6,6,0,0,0,0,0,0,0,15,15,15,15,15,15,15,0,0,0,0,0,0,0,9,1,2018,12,24,2018,^”

Baud is at 115200. I tried higher but I get garbage.

Please be kind I am still learning. I am sure there is a much more efficient wat of doing this and eventually I will figure it out.

[code]dim RxData as String=""

RxData = Me.ReadAll()
'app.SleepCurrentThread(500)

If Instr(RxData, “^”) > 0 Then
dim RxSplit() as String

RxSplit() = RxData.Split(",")

chkSun_1.Value = if (RxSplit(0) = “1”,True,false)
chkMon_2.Value = if (RxSplit(1) = “1”,True,false)
chkTue_3.Value = if (RxSplit(2) = “1”,True,false)
chkWed_4.Value = if (RxSplit(3) = “1”,True,false)
chkThu_5.Value = if (RxSplit(4) = “1”,True,false)
chkFri_6.Value = if (RxSplit(5) = “1”,True,false)
chkSat_7.Value = if (RxSplit(6) = “1”,True,false)
OccTimeStartSun_1.Hours = val(RxSplit(7))
OccTimeStartMon_2.Hours = val(RxSplit(8))
OccTimeStartTue_3.Hours = val(RxSplit(9))
OccTimeStartWed_4.Hours = val(RxSplit(10))
OccTimeStartThu_5.Hours = val(RxSplit(11))
OccTimeStartFri_6.Hours = val(RxSplit(12))
OccTimeStartSat_7.Hours = val(RxSplit(13))
OccTimeStartSun_1.Minutes = val(RxSplit(14))
OccTimeStartMon_2.Minutes = val(RxSplit(15))
OccTimeStartTue_3.Minutes = val(RxSplit(16))
OccTimeStartWed_4.Minutes = val(RxSplit(17))
OccTimeStartThu_5.Minutes = val(RxSplit(18))
OccTimeStartFri_6.Minutes = val(RxSplit(19))
OccTimeStartSat_7.Minutes = val(RxSplit(20))
OccTimeEndSun_1.Hours = val(RxSplit(21))
OccTimeEndMon_2.Hours = val(RxSplit(22))
OccTimeEndTue_3.Hours = val(RxSplit(23))
OccTimeEndWed_4.Hours = val(RxSplit(24))
OccTimeEndThu_5.Hours = val(RxSplit(25))
OccTimeEndFri_6.Hours = val(RxSplit(26))
OccTimeEndSat_7.Hours = val(RxSplit(27))
OccTimeEndSun_1.Minutes = val(RxSplit(28))
OccTimeEndMon_2.Minutes = val(RxSplit(29))
OccTimeEndTue_3.Minutes = val(RxSplit(30))
OccTimeEndWed_4.Minutes = val(RxSplit(31))
OccTimeEndThu_5.Minutes = val(RxSplit(32))
OccTimeEndFri_6.Minutes = val(RxSplit(33))
OccTimeEndSat_7.Minutes = val(RxSplit(34))
OccDateStart.Month = val(RxSplit(35))
OccDateStart.Day = val(RxSplit(36))
OccDateStart.Year = val(RxSplit(37))
OccDateEnd.Month = val(RxSplit(38))
OccDateEnd.Day = val(RxSplit(39))
OccDateEnd.Year = val(RxSplit(40))
OutputArea.AppendText(“Download of Schedule Complete”)
OutputArea.AppendText(EndOfLine)

else

OutputArea.AppendText(RxData)
txtHiddenRxData.text = RxData

end if
txtHiddenCalledFrom.Text = “”
'txtHiddenRxData.Text = “”
Exception err
If err IsA OutOfBoundsException Then
OutputArea.Text=OutputArea.Text+“Error with Download of Schedule, please try again”+EndOfLine
End If
[/code]

Usually what you have to do in the DataAvailable event is to check the BytesAvailable property. You’ll end up getting something like this:

dim s as string while me.BytesAvailable > 0 s = s + me.readall me.poll wend

Because it an event you may not have ALL of the data when the event fires. Doing this will at least make sure you get everything it has at that point in time.

This last bit is critical. You will have to check for the terminator “^” and if it it’s not there save the string you have and use that as the basis for the next time you get data.

[code]dim s as string = sLeftOver
while BytesAvailable > 0
s = s + me.readall
me.poll
wend

if s.Instr("^") = 0 then
//no terminator
sLeftOver = s
return
end
[/code]

You might also have to deal with the possibility of having more than one message too that I won’t get into here. Serial comms is messy and we’re not even talking about the possibility of having bad data.

This is off the top of my head so I apologize for any errors.

Thank you Bob Keeney you have solved my issue. I did forget to mention this code is in the DataAvailable event as I guess you knew.
Here is the final code that gives me a good download every time.

[code]dim RxData as String = gRxLeftOver

while me.BytesAvailable > 0
RxData = RxData + me.readall
me.poll
wend

if gRxCalledFrom = 21 then // 21 parse download schedule

If Instr(RxData, “^”) > 0 Then
dim RxSplit() as String
RxSplit() = RxData.Split(",")

chkSun_1.Value = if (RxSplit(0) = "1",True,false)
chkMon_2.Value = if (RxSplit(1) = "1",True,false)
chkTue_3.Value = if (RxSplit(2) = "1",True,false)
chkWed_4.Value = if (RxSplit(3) = "1",True,false)
chkThu_5.Value = if (RxSplit(4) = "1",True,false)
chkFri_6.Value = if (RxSplit(5) = "1",True,false)
chkSat_7.Value = if (RxSplit(6) = "1",True,false)
OccTimeStartSun_1.Hours = val(RxSplit(7))
OccTimeStartMon_2.Hours = val(RxSplit(8))
OccTimeStartTue_3.Hours = val(RxSplit(9))
OccTimeStartWed_4.Hours = val(RxSplit(10))
OccTimeStartThu_5.Hours = val(RxSplit(11))
OccTimeStartFri_6.Hours = val(RxSplit(12))
OccTimeStartSat_7.Hours = val(RxSplit(13))
OccTimeStartSun_1.Minutes = val(RxSplit(14))
OccTimeStartMon_2.Minutes = val(RxSplit(15))
OccTimeStartTue_3.Minutes = val(RxSplit(16))
OccTimeStartWed_4.Minutes = val(RxSplit(17))
OccTimeStartThu_5.Minutes = val(RxSplit(18))
OccTimeStartFri_6.Minutes = val(RxSplit(19))
OccTimeStartSat_7.Minutes = val(RxSplit(20))
OccTimeEndSun_1.Hours = val(RxSplit(21))
OccTimeEndMon_2.Hours = val(RxSplit(22))
OccTimeEndTue_3.Hours = val(RxSplit(23))
OccTimeEndWed_4.Hours = val(RxSplit(24))
OccTimeEndThu_5.Hours = val(RxSplit(25))
OccTimeEndFri_6.Hours = val(RxSplit(26))
OccTimeEndSat_7.Hours = val(RxSplit(27))
OccTimeEndSun_1.Minutes = val(RxSplit(28))
OccTimeEndMon_2.Minutes = val(RxSplit(29))
OccTimeEndTue_3.Minutes = val(RxSplit(30))
OccTimeEndWed_4.Minutes = val(RxSplit(31))
OccTimeEndThu_5.Minutes = val(RxSplit(32))
OccTimeEndFri_6.Minutes = val(RxSplit(33))
OccTimeEndSat_7.Minutes = val(RxSplit(34))
OccDateStart.Month = val(RxSplit(35))
OccDateStart.Day = val(RxSplit(36))
OccDateStart.Year = val(RxSplit(37))
OccDateEnd.Month = val(RxSplit(38))
OccDateEnd.Day = val(RxSplit(39))
OccDateEnd.Year = val(RxSplit(40))

OutputArea.AppendText("Download of Schedule Complete" + EndOfLine)
gRxLeftOver = ""
gRxCalledFrom = 0

else
//no terminator
gRxLeftover = RxData
return
end if

else
OutputArea.AppendText(RxData + EndOfLine)
end if

Exception err
If err IsA OutOfBoundsException Then
OutputArea.Text=OutputArea.Text+“Error with Download of Schedule, please try again”+EndOfLine
End If
[/code]