I’m experiencing some confounding outcomes when reading from a serial connection in Arduino. The Arduino code below should turn on an LED for one second depending upon the text string received.
The strings are sent by a VB.net app (code attached) to an Arduino Leonardo through its USB connection. Each string is sent in ASCII and terminated with Environment.NewLine. I have also tried terminating with vbCr, vbLf, vbCrLf, vbNewLine.
If I send the string “abc” and evaluate the string using this code in Arduino
if (SerialMessageForCode == "abc")
the LED does not turn on.
However, if I send the string “xyz” and evaluate the string using this code
if (SerialMessageForCode.indexOf("xyz") != -1)
the LED does turn on.
Why will sending “abc” never trigger the LED in the Arduino code? I have commented the null character line SerialMessage[SerialMessage_char] = '\0';
from the sketch, but am getting the same problem. It is as if a non-printing character causes the string SerialMessageForCode
not to equal "abc"
The Arduino sketch accurately sends back each message received and if I send “abc”, then “abc” will be sent by the Arduino back to the VB app and the VB app will correctly display "abc" in the textbox.
I've been working on troubleshooting this for over 6 hours and am running out of ideas.
Arduino Code:
const unsigned int SerialMessageLength = 20;
const int LED10 = 10;
String IncomingMessage;
String SerialMessage;
String SerialMessageForCode;
void setup()
{
pinMode(LED10, OUTPUT);
Serial.begin(9600);
Serial.print("Arduino ready");
}
void loop()
{
while (Serial.available() > 0)
{
static char SerialMessage[SerialMessageLength];
static unsigned int SerialMessage_char = 0;
char inByte = Serial.read();
if (inByte != '\n' && (SerialMessage_char < SerialMessageLength -1) )
{
SerialMessage[SerialMessage_char] = inByte;
SerialMessage_char++;
}
else
{
SerialMessage[SerialMessage_char] = '\0';
SerialMessageForCode = SerialMessage;
SerialMessage_char = 0;
SerialMessageForCode = SerialMessage;
Serial.print(SerialMessageForCode);
flushSerial();
}
}
if (SerialMessageForCode.indexOf("xyz") != -1)
{
SerialMessageForCode = "";
digitalWrite(LED10, HIGH);
delay(1000);
digitalWrite(LED10, LOW);
}
if (SerialMessageForCode == "abc")
{
SerialMessageForCode = "";
digitalWrite(LED10, HIGH);
delay(1000);
digitalWrite(LED10, LOW);
}
}
void flushSerial()
{
while (Serial.available())
{
Serial.read();
}
}
The VB.Net form has the following controls:
TextBoxMessage
TextBoxSerialComm
ButtonSend
ButtonReset
LabelStatus
VB.Net Code:
Imports System.Configuration
Imports System.Diagnostics
Imports System.Drawing
Imports System.IO
Imports System.IO.Ports
Imports System.Management
Public Class Form1
Dim WithEvents ArduinoConnection As New IO.Ports.SerialPort
Public ArduinoPort As String
Public ArduinoDetected As Boolean
Public ArduinoNotDetected As String
Public ArduinoState As String
Public DataSentFromArduino As String
Public CurrentMessage As String
Private DataReceivedToCheckForEcho As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connectionScope As New ManagementScope()
Dim serialQuery As New SelectQuery("SELECT * FROM Win32_SerialPort")
Dim searcher As New ManagementObjectSearcher(connectionScope, serialQuery)
Try
For Each item As ManagementObject In searcher.[Get]()
Dim desc As String = item("Description").ToString()
Dim deviceId As String = item("DeviceID").ToString()
If desc.Contains("Arduino") Then
ArduinoDetected = True
ArduinoPort = deviceId
LabelStatus.Text = "Arduino found " + ArduinoPort.ToString()
End If
Next
Catch exception As ManagementException
ArduinoDetected = False
ArduinoNotDetected = exception.Message
End Try
If ArduinoDetected = False Then
LabelStatus.Text = "Arduino not found"
Else
CreateArduinoConnection()
End If
End Sub
Private Sub CreateArduinoConnection()
Try
If ArduinoConnection.IsOpen = True Then
ArduinoConnection.Close()
End If
ArduinoConnection.PortName = ArduinoPort
ArduinoConnection.BaudRate = 9600
ArduinoConnection.DtrEnable = True
ArduinoConnection.RtsEnable = True
ArduinoConnection.DataBits = 8
ArduinoConnection.Parity = Parity.None
ArduinoConnection.StopBits = StopBits.One
ArduinoConnection.Handshake = Handshake.None
ArduinoConnection.Encoding = System.Text.Encoding.ASCII
ArduinoConnection.Open()
Catch ex As Exception
MessageBox.Show("Could not connect" _
, "Problem", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1)
End Try
End Sub
Private Sub ButtonSend_Click(sender As Object, e As EventArgs) Handles ButtonSend.Click
Dim TextToSend As String = TextBoxMessage.Text
SendMessageToArduino(TextToSend)
TextBoxMessage.Text = ""
End Sub
Private Sub SendMessageToArduino(ByVal Message As String)
CurrentMessage = Message
If ArduinoConnection.IsOpen Then
ArduinoConnection.DiscardInBuffer()
ArduinoConnection.Write(Message + vbNewLine) '(Message + Environment.NewLine)
Else
MessageBox.Show("Could not send" _
, "Problem", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1)
End If
End Sub
Private Sub ArduinoConnectionDataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ArduinoConnection.DataReceived
DataSentFromArduino = ArduinoConnection.ReadExisting()
Invoke(SafelyReadDataFromSerialThread, DataSentFromArduino)
End Sub
Delegate Sub myMethodDelegate(ByVal [text] As String)
Dim SafelyReadDataFromSerialThread As New myMethodDelegate(AddressOf UseDataSentFromArduino_InUIThread)
Private Sub UseDataSentFromArduino_InUIThread(ByVal myString As String)
TextBoxSerialComm.AppendText(DataSentFromArduino + Environment.NewLine)
End Sub
Private Sub ButtonReset_Click(sender As Object, e As EventArgs) Handles ButtonReset.Click
If ArduinoConnection.IsOpen Then
ArduinoConnection.Close()
End If
ArduinoConnection.BaudRate = 1200
ArduinoConnection.Open()
ArduinoConnection.Close()
TimerRestartArduino.Enabled = True
TimerRestartArduino.Interval = 10000
End Sub
Private Sub TimerRestartArduino_Tick(sender As Object, e As EventArgs) Handles TimerRestartArduino.Tick
TimerRestartArduino.Enabled = False
CreateArduinoConnection()
End Sub
End Class