Error opening Com Port to Teensy 3.2 via usb from software on Windows

Status
Not open for further replies.

Antian

Member
Using Teensy 3.2
Windows 10 x64
Visual Studio 2019

I can send/receive data to Arduino's (1.8.13) serial monitor just fine using serial.read / serial.write ... etc.

Problem is when connecting to com port (3 in my case) using C language in VS2019. Almost all tutorials on this subject use the same methods (I'll post my code below) to make a connection. In my case when trying to establish connection with teensy, I get microsofts HANDLE error _INVALID_HANDLE_VALUE code 2 which means _FILE_NOT_FOUND, in other words can't find device on com port 3.
I'm not sure if its a windows issue or the teensy. If I run this code as HANDLE port = CreateFile("COM3", ) .... no connection is established, but if I run as CreateFileA or as (L"COM3")... then it acts like a port is established but see no data going through. Microsoft says to only use CreateFile because it's a macro that will make the correct actions based on the device.

I've literally tried copy/paste tutorial code examples (on both ends) to test with and get same results.
I'll place the C code and then the arduino code below.


Code:
					BOOL* Status;
					const char* ComPort = "\\\\.\\COM3";
					HANDLE port = CreateFile(ComPort,			//port name
						GENERIC_READ | GENERIC_WRITE,			//Read/Write   				
						0,										// No Sharing                               
						NULL,									// No Security                             
						OPEN_EXISTING,							// Open existing port only                     
						0,										// Non Overlapped I/O                           
						NULL);									// Null for Comm Devices

					printf_s("port: %d\n", port);

					if (port == INVALID_HANDLE_VALUE) {
						//CHAR error = GetLastError;
						printf_s("\nSerial port failed Reason: %d\n", GetLastError());
						printf_s("%d", GetLastError());
					}
					else {
						printf_s("\nSerial port successful\n");
					}
					DCB dcb = { 0 };							// Initializing DCB structure
					dcb.DCBlength = sizeof(dcb);

					Status = GetCommState(port, &dcb);

					if (!GetCommState(port, &dcb)) {
						printf_s("CSerialCommHelper: Failed to Get Comm State Reason: %d\n", GetLastError());
					}

					dcb.BaudRate = CBR_9600;							// Setting BaudRate = 9600
					dcb.ByteSize = 8;									// Setting ByteSize = 8
					dcb.StopBits = ONESTOPBIT;							// Setting StopBits = 1
					dcb.Parity = NOPARITY;								// Setting Parity = None

					Status = SetCommState(port, &dcb);
					if (!SetCommState(port, &dcb)) {
						printf_s("CSerialCommHelper: Failed to Set Comm State Reason: %d\n", GetLastError());
					}

					COMMTIMEOUTS timeouts = { 0 };
					timeouts.ReadIntervalTimeout = 50;								// in milliseconds
					timeouts.ReadTotalTimeoutConstant = 50;							// in milliseconds
					timeouts.ReadTotalTimeoutMultiplier = 10;						// in milliseconds
					timeouts.WriteTotalTimeoutConstant = 50;						// in milliseconds
					timeouts.WriteTotalTimeoutMultiplier = 10;						// in milliseconds


					int SerialBuffer = 0;
					int BytesWritten = 0;
					SerialBuffer = 123;
					Status = WriteFile(port,
						SerialBuffer,
						sizeof(SerialBuffer),
						&BytesWritten,
						NULL);

					printf_s("port: %d, SerialBuffer: %d, BytesWritten: %d\n",port, SerialBuffer, BytesWritten);


					CloseHandle(port);												//Closing the Serial Port
				}
				Sleep(1000);
			}




ARDUINO CODE:

Code:
int inByte = 0;         // incoming serial byte

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  
}

void loop() {

  while (Serial.available()) {
    // get incoming byte:
    inByte = Serial.read();
    Serial.write("\nValue Read:\n",inByte);
  }
  if( inByte > 0){
  led();
  }
}

 
  void led(){
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);                  // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);                
  }
 
It has been awhile since I played with this...

But most of the examples I see show using overlapped...

Code:
void Comport4()
{
	hComm = CreateFile(L"\\\\.\\COM4",   // com4 is ready to communicate ==> open the port
		GENERIC_READ | GENERIC_WRITE,
		0,
		0,
		OPEN_EXISTING,
		[COLOR="#FF0000"]FILE_FLAG_OVERLAPPED[/COLOR],
		0);
	if (hComm == INVALID_HANDLE_VALUE)
	{
Not sure if it would help or not.
 
Here's some serial port code I wrote years ago which definitely did work on Windows.
 

Attachments

  • serial.cpp
    27.6 KB · Views: 60
  • serial.h
    997 bytes · Views: 61
Use CreateFileA.

This is probably why you don't see anything when it establishes the connection:
Code:
					int SerialBuffer = 0;
					int BytesWritten = 0;
					SerialBuffer = 123;
					Status = WriteFile(port,
						SerialBuffer,
						sizeof(SerialBuffer),
						&BytesWritten,
						NULL);
You should be specifying an address as the second argument to WriteFile, but you are passing 123 as the address.
Try changing the code to this.
Code:
					char *SerialBuffer = "test";
					int BytesWritten = 0;
					Status = WriteFile(port,
						SerialBuffer,
						sizeof(SerialBuffer),
						&BytesWritten,
						NULL);

Pete
 
Update - That source above linked to @luni - and I found the simpler sample I was looking for - IIRC it was tried to work to talk to Teensy ...

Code:
[B][URL="https://github.com/luni64/SerialTester"]github.com/luni64/SerialTester[/URL][/B]

It has a VS solution file here : github.com/luni64/SerialTester/tree/master/src/software

Then it has 'firmware' folder above that has corresponding sketches to test.
 
Thank you everyone for taking the time to read and reply.
To el_supremo --- Thanks for pointing that out. While it might be 'A' problem, it didn't solve the solution.
To defragster --- I'll come back to that one later if need be, but I'm not familiar with C#.
To PaulStoffregen --- wow!!! that's a lot for someone of my ability to digest, but it's cool cause now I can use it to learn some linux communication too.
I'm in the process of going through your code.

However, I thought I'd shed some light from another discussion I had elsewhere in that I may be confusing/mixing methods.
This low level stuff is obviously over my head. The following is our conversation.

-----------------------------------------
USB and serial port are very different.
If you really want serial then use a USB to serial device converter (FTDI chip) that creates a classic COM port through a driver.
If you want true USB then you want to find a c USB class module that will let you cretae a handle to a HID (the only generic USB class you can create without a licence from MS).
-----------------------------------------
Thank you for the information, all this is obviously over my head. I'll have to research what you've described.
My thinking is if I can send data back and forth to the arduino serial monitor software using just the usb cable
then surely it's just a matter of changing where the data is coming from(i.e.: game values).

-----------------------------------------
It should be possible to send stuff using the ARDUINO virtual COM port.
You should see a COM port listed in your system hardware if all the drivers are installed OK.
Never tried it though so I am not sure what the limitations would be but
I guess the ARDUINO has an FTDI chip attached to the USB connector and just passes the serial data to the chip,
you might need to change some jumpers as I guess at the moment its connected to the programming pins of the ARDUINO
 
Justa sec. How are you testing this?
Code:
    inByte = Serial.read();
    Serial.write("\nValue Read:\n",inByte);
If your Teensy is reading data from the PC's COM3, the string that you write back also goes to that COM port. If you are trying to read from COM3 and write to the serial monitor, it won't work.
The code on the PC which writes the test string to the Teensy must also read back the response from the teensy. If that is what you are doing, post all the PC code.

Pete
 
I did initially write the Serial.write function but realized the serial monitor could not be used at same time, so I simple told it that if ANY value was received by inByte;
to start blinking the light just so I know I had some form of data going through before proceeding.
It was suggested that I try an app called hyperterminal to see if any connection was made. The result was it did return the Serial.write function "Value Read %d" and the light started blinking as instructed.
Still leaves me wondering why no value by the C program is being sent to the teensy.
 
This statement isn't correct:
Code:
    Serial.write("\nValue Read:\n",inByte);
This form of Serial.write requires the address of a buffer as the first argument and the length of that buffer as the second argument. It will interpret inByte as the length of the string, not as the character to be printed.
Try this:
Code:
    Serial.printf("\nValue Read: '%c'\n",inByte);

Pete
 
Pete,
I already caught that error from your last post and fixed it as well, but that wasn't the total problem, though part of it for sure.
Also you pointed out "char *SerialBuffer " was also helpful in further solving the problem, thought still no data passed through.

The reason for no data throughput was because I had visual studio set to x64. When set to x86 it worked.
The reason for x64 was the program I was writing to interact with, it was my understanding had to use x64.
Thanks to everyone for their time. Now I can move forward with the project.
 
Last edited:
Status
Not open for further replies.
Back
Top