Arduino serial port additional problem

A problem with serial Arduino to PC communication was mostly solved in post RESOLVED! Trying to send data to PC over USB (serial port) - Programming Questions - Arduino Forum

This post is in regard to an issue that was discovered after the initial problem was resolved.

The issue is the communication between the PC and Arduino will only work if the Arduino Serial Monitor is run before trying to read the data from the PC.

Here are the scenarios that fail:

  • Upload sketch to arduino then start the PC serial read program - fails with read timeouts
  • Reset arduino then start PC reader - fails with read timeouts
  • Start the PC reader and then reset the Arduino - fails with read timeouts
  • If the PC has the port open, the arduino Serial Monitor can't open it and vice versa.

The only scenarios I have found that work are:
Upload the sketch, start the Serial monitor, exit the serial monitor because the PC can't connect to the busy port, then start the PC program.

The working scenario also works whenever the Serial Monitor is started and stopped. It does not require re-uploading the sketch.

I need to know what the Serial Monitor is doing to get the arduino sending data and then figure out how to do that in the PC program.

Does this make a difference

 SerialPort.Open()
        SerialPort.ReadTimeout = 50

        SerialPort.DtrEnable = False
        Threading.Thread.Sleep(20)
        SerialPort.DtrEnable = True
        SerialPort.ReadExisting()

No.
the problem is that if I put the pc on it for debugging it works perfectly.
almost no mistakes or stuckers.
but I get the PC off and let him work on his own power (11.5 volts fixed), he goes stuck almost immediately.
If I connect the thermostat to rx tx then it will not work at all.
then the uno will only stay in different places in the program.
now the uno is also up to the neck full of connections and I'm afraid it's just too much for the uno and I better switch to the mega.

but I'm not sure if this is the problem

I'm not certain who bartsmetsers is replying to.

To sumguy, I don't know who you are or what you do, but you sure know your serial com stuff.

All I did was add the one line SerialPort.DtrEnable = True after the open and it solves the problem.

It seems to be working just fine now in all the scenarios that previously did not work so do you think I should I add the rest of the code too or just leave it with setting DTR true?.

I actually typed the instruction in reverse, this is what I meant to write

SerialPort.Open()
        SerialPort.ReadTimeout = 50

        SerialPort.DtrEnable = True
        Threading.Thread.Sleep(20)
        SerialPort.DtrEnable = False

        SerialPort.ReadExisting()

the code toggles DTR and resets your arduino which the Serial Monitor is doing and which VS should be doing. I would probably use all the above code, it is not doing any harm and the timeout is better.

I just tried it and no go. I have to have DTR True for it to work.

Here is what I found about DTR at wikipedia:
The DTR signal is present on pin 20 of the 22-wire RS-232 interface using a DB-25 connector, and on pin 4 of a newer DE-9 serial port. The signal is asserted (logic "1") by raising the voltage of the pin from negative to positive. Dropping the signal back to its negative state indicates to the modem that the communications session shall be terminated.

Hi,
Can you post your working code please?

It will help to provide an answer to this thread.

Thanks.. Tom.. :slight_smile:

Here is the code that has been working 100% for me. Much credit to sumguy for help with the serial code and with the delegate.

Imports System.IO.Ports

Public Class Form1
    Dim WithEvents SerialPort As New SerialPort
    Dim Incoming As String
        Dim Count As Integer = 0

    Public Delegate Sub myDelegate(ByVal sData As String)

    Private Sub Text_Out(ByVal sData As String)
        RichTextBox1.AppendText(sData.ToString)
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        With SerialPort
            .PortName = "COM13"
            .BaudRate = 115200
            .DataBits = 8
            .Parity = Parity.None
            .StopBits = StopBits.One
            .Handshake = Handshake.RequestToSend
            .ReadTimeout = 20
        End With
        SerialPort.Open()
        SerialPort.DtrEnable = True
    End Sub

    Private Sub SerialPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort.DataReceived

        Do While SerialPort.BytesToRead > 0
            Try
                Incoming = SerialPort.ReadLine
                Me.BeginInvoke((New myDelegate(AddressOf Text_Out)), Incoming)
            Catch ex As Exception
                ' MessageBox.Show(ex.Message) 
            End Try
        Loop

    End Sub
End Class

Hi, change the HandShake.RequestToSend back to Handshake.None and use the last code that I posted which was the following

    SerialPort.Open()
        SerialPort.DtrEnable = True
        Threading.Thread.Sleep(20)
        SerialPort.DtrEnable = False

this should reset your arduino when the serial port is opened.

This has the added benefit of being able to re-use that code to reset the arduino during run time if needed perhaps by assigning to a button click like this example

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        SerialPort.DtrEnable = True
        Threading.Thread.Sleep(20)
        SerialPort.DtrEnable = False
        SerialPort.ReadExisting()
    End Sub

EDIT: I just realized you have a Leonardo, I have not checked the above code on a Leonardo just the Uno and Mega so you may have to go back to the plan that works.

Here is the code that works with my Arduino Leonardo. With DTR high, it receive data just fine, with it low, it stops immediately.

    Private Sub ComSetup()

        With serialPort
            .PortName = "COM13"
            .BaudRate = 115200
            .DataBits = 8
            .Parity = Parity.None
            .StopBits = StopBits.One
            .Handshake = Handshake.RequestToSend
            .ReadTimeout = 20

            Try
                .Open()
                .DtrEnable = True
            Catch Ex As Exception
                MessageBox.Show(Ex.Message)
                Application.Exit()
            End Try
        End With

    End Sub